From c23f114d3cfbb29b8734b87213d1ec0de404197b Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 27 Apr 2017 11:05:07 +0800 Subject: MdeModulePkg: Move to new location Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- MdeModulePkg/Core/Dxe/Dispatcher/Dependency.c | 442 --- MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c | 1384 --------- MdeModulePkg/Core/Dxe/DxeCore.uni | 22 - MdeModulePkg/Core/Dxe/DxeCoreExtra.uni | 20 - MdeModulePkg/Core/Dxe/DxeMain.h | 2951 -------------------- MdeModulePkg/Core/Dxe/DxeMain.inf | 208 -- MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c | 938 ------- MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c | 285 -- MdeModulePkg/Core/Dxe/Event/Event.c | 782 ------ MdeModulePkg/Core/Dxe/Event/Event.h | 97 - MdeModulePkg/Core/Dxe/Event/Timer.c | 301 -- MdeModulePkg/Core/Dxe/Event/Tpl.c | 148 - MdeModulePkg/Core/Dxe/FwVol/Ffs.c | 233 -- MdeModulePkg/Core/Dxe/FwVol/FwVol.c | 775 ----- MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c | 135 - MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h | 408 --- MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c | 529 ---- MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c | 52 - MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c | 712 ----- MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.h | 244 -- MdeModulePkg/Core/Dxe/Gcd/Gcd.c | 2614 ----------------- MdeModulePkg/Core/Dxe/Gcd/Gcd.h | 46 - MdeModulePkg/Core/Dxe/Hand/DriverSupport.c | 964 ------- MdeModulePkg/Core/Dxe/Hand/Handle.c | 1553 ---------- MdeModulePkg/Core/Dxe/Hand/Handle.h | 270 -- MdeModulePkg/Core/Dxe/Hand/Locate.c | 712 ----- MdeModulePkg/Core/Dxe/Hand/Notify.c | 291 -- MdeModulePkg/Core/Dxe/Image/Image.c | 1942 ------------- MdeModulePkg/Core/Dxe/Image/Image.h | 113 - MdeModulePkg/Core/Dxe/Library/Library.c | 106 - MdeModulePkg/Core/Dxe/Mem/Imem.h | 156 -- MdeModulePkg/Core/Dxe/Mem/MemData.c | 26 - MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c | 1794 ------------ MdeModulePkg/Core/Dxe/Mem/Page.c | 1977 ------------- MdeModulePkg/Core/Dxe/Mem/Pool.c | 764 ----- MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c | 288 -- .../Core/Dxe/Misc/InstallConfigurationTable.c | 171 -- MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c | 268 -- MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c | 1141 -------- MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c | 1379 --------- MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c | 72 - MdeModulePkg/Core/Dxe/Misc/Stall.c | 113 - .../Dxe/SectionExtraction/CoreSectionExtraction.c | 1605 ----------- MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c | 77 - MdeModulePkg/Core/DxeIplPeim/DxeIpl.h | 243 -- MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 141 - MdeModulePkg/Core/DxeIplPeim/DxeIpl.uni | 24 - MdeModulePkg/Core/DxeIplPeim/DxeIplExtra.uni | 20 - MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 827 ------ MdeModulePkg/Core/DxeIplPeim/Ebc/DxeLoadFunc.c | 73 - MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c | 435 --- MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.S | 80 - MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.asm | 88 - .../Core/DxeIplPeim/Ia32/IdtVectorAsm.nasm | 77 - MdeModulePkg/Core/DxeIplPeim/Ipf/DxeLoadFunc.c | 85 - MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c | 120 - MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c | 353 --- MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h | 231 -- MdeModulePkg/Core/Pei/BootMode/BootMode.c | 86 - MdeModulePkg/Core/Pei/CpuIo/CpuIo.c | 541 ---- MdeModulePkg/Core/Pei/Dependency/Dependency.c | 253 -- MdeModulePkg/Core/Pei/Dependency/Dependency.h | 32 - MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 1353 --------- MdeModulePkg/Core/Pei/FwVol/FwVol.c | 2329 --------------- MdeModulePkg/Core/Pei/FwVol/FwVol.h | 377 --- MdeModulePkg/Core/Pei/Hob/Hob.c | 168 -- MdeModulePkg/Core/Pei/Image/Image.c | 932 ------- MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 307 -- MdeModulePkg/Core/Pei/PciCfg2/PciCfg2.c | 128 - MdeModulePkg/Core/Pei/PeiCore.uni | 27 - MdeModulePkg/Core/Pei/PeiCoreExtra.uni | 19 - MdeModulePkg/Core/Pei/PeiMain.h | 1745 ------------ MdeModulePkg/Core/Pei/PeiMain.inf | 134 - MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 475 ---- MdeModulePkg/Core/Pei/Ppi/Ppi.c | 646 ----- MdeModulePkg/Core/Pei/Reset/Reset.c | 108 - MdeModulePkg/Core/Pei/Security/Security.c | 151 - MdeModulePkg/Core/Pei/StatusCode/StatusCode.c | 74 - MdeModulePkg/Core/PiSmmCore/Dependency.c | 388 --- MdeModulePkg/Core/PiSmmCore/Dispatcher.c | 1504 ---------- MdeModulePkg/Core/PiSmmCore/Handle.c | 532 ---- .../Core/PiSmmCore/InstallConfigurationTable.c | 161 -- MdeModulePkg/Core/PiSmmCore/Locate.c | 499 ---- .../Core/PiSmmCore/MemoryAttributesTable.c | 1520 ---------- MdeModulePkg/Core/PiSmmCore/Notify.c | 202 -- MdeModulePkg/Core/PiSmmCore/Page.c | 1121 -------- MdeModulePkg/Core/PiSmmCore/PiSmmCore.c | 686 ----- MdeModulePkg/Core/PiSmmCore/PiSmmCore.h | 1218 -------- MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf | 120 - MdeModulePkg/Core/PiSmmCore/PiSmmCore.uni | 21 - MdeModulePkg/Core/PiSmmCore/PiSmmCoreExtra.uni | 19 - MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h | 125 - MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 1745 ------------ MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf | 95 - MdeModulePkg/Core/PiSmmCore/PiSmmIpl.uni | 21 - MdeModulePkg/Core/PiSmmCore/PiSmmIplExtra.uni | 19 - MdeModulePkg/Core/PiSmmCore/Pool.c | 365 --- MdeModulePkg/Core/PiSmmCore/Smi.c | 312 --- MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c | 1327 --------- MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c | 2852 ------------------- MdeModulePkg/Core/RuntimeDxe/Crc32.c | 115 - MdeModulePkg/Core/RuntimeDxe/Runtime.c | 427 --- MdeModulePkg/Core/RuntimeDxe/Runtime.h | 134 - MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf | 65 - MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.uni | 23 - MdeModulePkg/Core/RuntimeDxe/RuntimeDxeExtra.uni | 19 - 106 files changed, 57425 deletions(-) delete mode 100644 MdeModulePkg/Core/Dxe/Dispatcher/Dependency.c delete mode 100644 MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c delete mode 100644 MdeModulePkg/Core/Dxe/DxeCore.uni delete mode 100644 MdeModulePkg/Core/Dxe/DxeCoreExtra.uni delete mode 100644 MdeModulePkg/Core/Dxe/DxeMain.h delete mode 100644 MdeModulePkg/Core/Dxe/DxeMain.inf delete mode 100644 MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c delete mode 100644 MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c delete mode 100644 MdeModulePkg/Core/Dxe/Event/Event.c delete mode 100644 MdeModulePkg/Core/Dxe/Event/Event.h delete mode 100644 MdeModulePkg/Core/Dxe/Event/Timer.c delete mode 100644 MdeModulePkg/Core/Dxe/Event/Tpl.c delete mode 100644 MdeModulePkg/Core/Dxe/FwVol/Ffs.c delete mode 100644 MdeModulePkg/Core/Dxe/FwVol/FwVol.c delete mode 100644 MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c delete mode 100644 MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h delete mode 100644 MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c delete mode 100644 MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c delete mode 100644 MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c delete mode 100644 MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.h delete mode 100644 MdeModulePkg/Core/Dxe/Gcd/Gcd.c delete mode 100644 MdeModulePkg/Core/Dxe/Gcd/Gcd.h delete mode 100644 MdeModulePkg/Core/Dxe/Hand/DriverSupport.c delete mode 100644 MdeModulePkg/Core/Dxe/Hand/Handle.c delete mode 100644 MdeModulePkg/Core/Dxe/Hand/Handle.h delete mode 100644 MdeModulePkg/Core/Dxe/Hand/Locate.c delete mode 100644 MdeModulePkg/Core/Dxe/Hand/Notify.c delete mode 100644 MdeModulePkg/Core/Dxe/Image/Image.c delete mode 100644 MdeModulePkg/Core/Dxe/Image/Image.h delete mode 100644 MdeModulePkg/Core/Dxe/Library/Library.c delete mode 100644 MdeModulePkg/Core/Dxe/Mem/Imem.h delete mode 100644 MdeModulePkg/Core/Dxe/Mem/MemData.c delete mode 100644 MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c delete mode 100644 MdeModulePkg/Core/Dxe/Mem/Page.c delete mode 100644 MdeModulePkg/Core/Dxe/Mem/Pool.c delete mode 100644 MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c delete mode 100644 MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c delete mode 100644 MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c delete mode 100644 MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c delete mode 100644 MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c delete mode 100644 MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c delete mode 100644 MdeModulePkg/Core/Dxe/Misc/Stall.c delete mode 100644 MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c delete mode 100644 MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c delete mode 100644 MdeModulePkg/Core/DxeIplPeim/DxeIpl.h delete mode 100644 MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf delete mode 100644 MdeModulePkg/Core/DxeIplPeim/DxeIpl.uni delete mode 100644 MdeModulePkg/Core/DxeIplPeim/DxeIplExtra.uni delete mode 100644 MdeModulePkg/Core/DxeIplPeim/DxeLoad.c delete mode 100644 MdeModulePkg/Core/DxeIplPeim/Ebc/DxeLoadFunc.c delete mode 100644 MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c delete mode 100644 MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.S delete mode 100644 MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.asm delete mode 100644 MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.nasm delete mode 100644 MdeModulePkg/Core/DxeIplPeim/Ipf/DxeLoadFunc.c delete mode 100644 MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c delete mode 100644 MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c delete mode 100644 MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h delete mode 100644 MdeModulePkg/Core/Pei/BootMode/BootMode.c delete mode 100644 MdeModulePkg/Core/Pei/CpuIo/CpuIo.c delete mode 100644 MdeModulePkg/Core/Pei/Dependency/Dependency.c delete mode 100644 MdeModulePkg/Core/Pei/Dependency/Dependency.h delete mode 100644 MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c delete mode 100644 MdeModulePkg/Core/Pei/FwVol/FwVol.c delete mode 100644 MdeModulePkg/Core/Pei/FwVol/FwVol.h delete mode 100644 MdeModulePkg/Core/Pei/Hob/Hob.c delete mode 100644 MdeModulePkg/Core/Pei/Image/Image.c delete mode 100644 MdeModulePkg/Core/Pei/Memory/MemoryServices.c delete mode 100644 MdeModulePkg/Core/Pei/PciCfg2/PciCfg2.c delete mode 100644 MdeModulePkg/Core/Pei/PeiCore.uni delete mode 100644 MdeModulePkg/Core/Pei/PeiCoreExtra.uni delete mode 100644 MdeModulePkg/Core/Pei/PeiMain.h delete mode 100644 MdeModulePkg/Core/Pei/PeiMain.inf delete mode 100644 MdeModulePkg/Core/Pei/PeiMain/PeiMain.c delete mode 100644 MdeModulePkg/Core/Pei/Ppi/Ppi.c delete mode 100644 MdeModulePkg/Core/Pei/Reset/Reset.c delete mode 100644 MdeModulePkg/Core/Pei/Security/Security.c delete mode 100644 MdeModulePkg/Core/Pei/StatusCode/StatusCode.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/Dependency.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/Dispatcher.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/Handle.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/InstallConfigurationTable.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/Locate.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/Notify.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/Page.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmCore.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmCore.h delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmCore.uni delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmCoreExtra.uni delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmIpl.uni delete mode 100644 MdeModulePkg/Core/PiSmmCore/PiSmmIplExtra.uni delete mode 100644 MdeModulePkg/Core/PiSmmCore/Pool.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/Smi.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c delete mode 100644 MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c delete mode 100644 MdeModulePkg/Core/RuntimeDxe/Crc32.c delete mode 100644 MdeModulePkg/Core/RuntimeDxe/Runtime.c delete mode 100644 MdeModulePkg/Core/RuntimeDxe/Runtime.h delete mode 100644 MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf delete mode 100644 MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.uni delete mode 100644 MdeModulePkg/Core/RuntimeDxe/RuntimeDxeExtra.uni (limited to 'MdeModulePkg/Core') diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dependency.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dependency.c deleted file mode 100644 index 1d8a57b879..0000000000 --- a/MdeModulePkg/Core/Dxe/Dispatcher/Dependency.c +++ /dev/null @@ -1,442 +0,0 @@ -/** @file - DXE Dispatcher Dependency Evaluator. - - This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine - if a driver can be scheduled for execution. The criteria for - schedulability is that the dependency expression is satisfied. - -Copyright (c) 2006 - 2010, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - -// -// Global stack used to evaluate dependency expressions -// -BOOLEAN *mDepexEvaluationStack = NULL; -BOOLEAN *mDepexEvaluationStackEnd = NULL; -BOOLEAN *mDepexEvaluationStackPointer = NULL; - -// -// Worker functions -// - - -/** - Grow size of the Depex stack - - @retval EFI_SUCCESS Stack successfully growed. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -GrowDepexStack ( - VOID - ) -{ - BOOLEAN *NewStack; - UINTN Size; - - Size = DEPEX_STACK_SIZE_INCREMENT; - if (mDepexEvaluationStack != NULL) { - Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack); - } - - NewStack = AllocatePool (Size * sizeof (BOOLEAN)); - if (NewStack == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (mDepexEvaluationStack != NULL) { - // - // Copy to Old Stack to the New Stack - // - CopyMem ( - NewStack, - mDepexEvaluationStack, - (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (BOOLEAN) - ); - - // - // Free The Old Stack - // - FreePool (mDepexEvaluationStack); - } - - // - // Make the Stack pointer point to the old data in the new stack - // - mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack); - mDepexEvaluationStack = NewStack; - mDepexEvaluationStackEnd = NewStack + Size; - - return EFI_SUCCESS; -} - - - -/** - Push an element onto the Boolean Stack. - - @param Value BOOLEAN to push. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -PushBool ( - IN BOOLEAN Value - ) -{ - EFI_STATUS Status; - - // - // Check for a stack overflow condition - // - if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) { - // - // Grow the stack - // - Status = GrowDepexStack (); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Push the item onto the stack - // - *mDepexEvaluationStackPointer = Value; - mDepexEvaluationStackPointer++; - - return EFI_SUCCESS; -} - - - -/** - Pop an element from the Boolean stack. - - @param Value BOOLEAN to pop. - - @retval EFI_SUCCESS The value was popped onto the stack. - @retval EFI_ACCESS_DENIED The pop operation underflowed the stack. - -**/ -EFI_STATUS -PopBool ( - OUT BOOLEAN *Value - ) -{ - // - // Check for a stack underflow condition - // - if (mDepexEvaluationStackPointer == mDepexEvaluationStack) { - return EFI_ACCESS_DENIED; - } - - // - // Pop the item off the stack - // - mDepexEvaluationStackPointer--; - *Value = *mDepexEvaluationStackPointer; - return EFI_SUCCESS; -} - - - -/** - Preprocess dependency expression and update DriverEntry to reflect the - state of Before, After, and SOR dependencies. If DriverEntry->Before - or DriverEntry->After is set it will never be cleared. If SOR is set - it will be cleared by CoreSchedule(), and then the driver can be - dispatched. - - @param DriverEntry DriverEntry element to update . - - @retval EFI_SUCCESS It always works. - -**/ -EFI_STATUS -CorePreProcessDepex ( - IN EFI_CORE_DRIVER_ENTRY *DriverEntry - ) -{ - UINT8 *Iterator; - - Iterator = DriverEntry->Depex; - if (*Iterator == EFI_DEP_SOR) { - DriverEntry->Unrequested = TRUE; - } else { - DriverEntry->Dependent = TRUE; - } - - if (*Iterator == EFI_DEP_BEFORE) { - DriverEntry->Before = TRUE; - } else if (*Iterator == EFI_DEP_AFTER) { - DriverEntry->After = TRUE; - } - - if (DriverEntry->Before || DriverEntry->After) { - CopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID)); - } - - return EFI_SUCCESS; -} - - - -/** - This is the POSTFIX version of the dependency evaluator. This code does - not need to handle Before or After, as it is not valid to call this - routine in this case. The SOR is just ignored and is a nop in the grammer. - POSTFIX means all the math is done on top of the stack. - - @param DriverEntry DriverEntry element to update. - - @retval TRUE If driver is ready to run. - @retval FALSE If driver is not ready to run or some fatal error - was found. - -**/ -BOOLEAN -CoreIsSchedulable ( - IN EFI_CORE_DRIVER_ENTRY *DriverEntry - ) -{ - EFI_STATUS Status; - UINT8 *Iterator; - BOOLEAN Operator; - BOOLEAN Operator2; - EFI_GUID DriverGuid; - VOID *Interface; - - Operator = FALSE; - Operator2 = FALSE; - - if (DriverEntry->After || DriverEntry->Before) { - // - // If Before or After Depex skip as CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter () - // processes them. - // - return FALSE; - } - - DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - - if (DriverEntry->Depex == NULL) { - // - // A NULL Depex means treat the driver like an UEFI 2.0 thing. - // - Status = CoreAllEfiServicesAvailable (); - DEBUG ((DEBUG_DISPATCH, " All UEFI Services Available = ")); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, "FALSE\n RESULT = FALSE\n")); - return FALSE; - } - DEBUG ((DEBUG_DISPATCH, "TRUE\n RESULT = TRUE\n")); - return TRUE; - } - - // - // Clean out memory leaks in Depex Boolean stack. Leaks are only caused by - // incorrectly formed DEPEX expressions - // - mDepexEvaluationStackPointer = mDepexEvaluationStack; - - - Iterator = DriverEntry->Depex; - - while (TRUE) { - // - // Check to see if we are attempting to fetch dependency expression instructions - // past the end of the dependency expression. - // - if (((UINTN)Iterator - (UINTN)DriverEntry->Depex) >= DriverEntry->DepexSize) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Attempt to fetch past end of depex)\n")); - return FALSE; - } - - // - // Look at the opcode of the dependency expression instruction. - // - switch (*Iterator) { - case EFI_DEP_BEFORE: - case EFI_DEP_AFTER: - // - // For a well-formed Dependency Expression, the code should never get here. - // The BEFORE and AFTER are processed prior to this routine's invocation. - // If the code flow arrives at this point, there was a BEFORE or AFTER - // that were not the first opcodes. - // - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected BEFORE or AFTER opcode)\n")); - ASSERT (FALSE); - case EFI_DEP_SOR: - // - // These opcodes can only appear once as the first opcode. If it is found - // at any other location, then the dependency expression evaluates to FALSE - // - if (Iterator != DriverEntry->Depex) { - DEBUG ((DEBUG_DISPATCH, " SOR\n")); - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected SOR opcode)\n")); - return FALSE; - } - DEBUG ((DEBUG_DISPATCH, " SOR = Requested\n")); - // - // Otherwise, it is the first opcode and should be treated as a NOP. - // - break; - - case EFI_DEP_PUSH: - // - // Push operator is followed by a GUID. Test to see if the GUID protocol - // is installed and push the boolean result on the stack. - // - CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID)); - - Status = CoreLocateProtocol (&DriverGuid, NULL, &Interface); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = FALSE\n", &DriverGuid)); - Status = PushBool (FALSE); - } else { - DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = TRUE\n", &DriverGuid)); - *Iterator = EFI_DEP_REPLACE_TRUE; - Status = PushBool (TRUE); - } - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Iterator += sizeof (EFI_GUID); - break; - - case EFI_DEP_AND: - DEBUG ((DEBUG_DISPATCH, " AND\n")); - Status = PopBool (&Operator); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PopBool (&Operator2); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PushBool ((BOOLEAN)(Operator && Operator2)); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_OR: - DEBUG ((DEBUG_DISPATCH, " OR\n")); - Status = PopBool (&Operator); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PopBool (&Operator2); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PushBool ((BOOLEAN)(Operator || Operator2)); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_NOT: - DEBUG ((DEBUG_DISPATCH, " NOT\n")); - Status = PopBool (&Operator); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PushBool ((BOOLEAN)(!Operator)); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_TRUE: - DEBUG ((DEBUG_DISPATCH, " TRUE\n")); - Status = PushBool (TRUE); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_FALSE: - DEBUG ((DEBUG_DISPATCH, " FALSE\n")); - Status = PushBool (FALSE); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_END: - DEBUG ((DEBUG_DISPATCH, " END\n")); - Status = PopBool (&Operator); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - DEBUG ((DEBUG_DISPATCH, " RESULT = %a\n", Operator ? "TRUE" : "FALSE")); - return Operator; - - case EFI_DEP_REPLACE_TRUE: - CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID)); - DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = TRUE\n", &DriverGuid)); - - Status = PushBool (TRUE); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Iterator += sizeof (EFI_GUID); - break; - - default: - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unknown opcode)\n")); - goto Done; - } - - // - // Skip over the Dependency Op Code we just processed in the switch. - // The math is done out of order, but it should not matter. That is - // we may add in the sizeof (EFI_GUID) before we account for the OP Code. - // This is not an issue, since we just need the correct end result. You - // need to be careful using Iterator in the loop as it's intermediate value - // may be strange. - // - Iterator++; - } - -Done: - return FALSE; -} - - diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c deleted file mode 100644 index 5686d94e6a..0000000000 --- a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c +++ /dev/null @@ -1,1384 +0,0 @@ -/** @file - DXE Dispatcher. - - Step #1 - When a FV protocol is added to the system every driver in the FV - is added to the mDiscoveredList. The SOR, Before, and After Depex are - pre-processed as drivers are added to the mDiscoveredList. If an Apriori - file exists in the FV those drivers are addeded to the - mScheduledQueue. The mFvHandleList is used to make sure a - FV is only processed once. - - Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and - start it. After mScheduledQueue is drained check the - mDiscoveredList to see if any item has a Depex that is ready to - be placed on the mScheduledQueue. - - Step #3 - Adding to the mScheduledQueue requires that you process Before - and After dependencies. This is done recursively as the call to add - to the mScheduledQueue checks for Before and recursively adds - all Befores. It then addes the item that was passed in and then - processess the After dependecies by recursively calling the routine. - - Dispatcher Rules: - The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3 - is the state diagram for the DXE dispatcher - - Depex - Dependency Expresion. - SOR - Schedule On Request - Don't schedule if this bit is set. - -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - -// -// The Driver List contains one copy of every driver that has been discovered. -// Items are never removed from the driver list. List of EFI_CORE_DRIVER_ENTRY -// -LIST_ENTRY mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList); - -// -// Queue of drivers that are ready to dispatch. This queue is a subset of the -// mDiscoveredList.list of EFI_CORE_DRIVER_ENTRY. -// -LIST_ENTRY mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue); - -// -// List of handles who's Fv's have been parsed and added to the mFwDriverList. -// -LIST_ENTRY mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList); // list of KNOWN_HANDLE - -// -// Lock for mDiscoveredList, mScheduledQueue, gDispatcherRunning. -// -EFI_LOCK mDispatcherLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL); - - -// -// Flag for the DXE Dispacher. TRUE if dispatcher is execuing. -// -BOOLEAN gDispatcherRunning = FALSE; - -// -// Module globals to manage the FwVol registration notification event -// -EFI_EVENT mFwVolEvent; -VOID *mFwVolEventRegistration; - -// -// List of file types supported by dispatcher -// -EFI_FV_FILETYPE mDxeFileTypes[] = { - EFI_FV_FILETYPE_DRIVER, - EFI_FV_FILETYPE_COMBINED_SMM_DXE, - EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER, - EFI_FV_FILETYPE_DXE_CORE, - EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE -}; - -typedef struct { - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH File; - EFI_DEVICE_PATH_PROTOCOL End; -} FV_FILEPATH_DEVICE_PATH; - -FV_FILEPATH_DEVICE_PATH mFvDevicePath; - -// -// Function Prototypes -// -/** - Insert InsertedDriverEntry onto the mScheduledQueue. To do this you - must add any driver with a before dependency on InsertedDriverEntry first. - You do this by recursively calling this routine. After all the Befores are - processed you can add InsertedDriverEntry to the mScheduledQueue. - Then you can add any driver with an After dependency on InsertedDriverEntry - by recursively calling this routine. - - @param InsertedDriverEntry The driver to insert on the ScheduledLink Queue - -**/ -VOID -CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter ( - IN EFI_CORE_DRIVER_ENTRY *InsertedDriverEntry - ); - -/** - Event notification that is fired every time a FV dispatch protocol is added. - More than one protocol may have been added when this event is fired, so you - must loop on CoreLocateHandle () to see how many protocols were added and - do the following to each FV: - If the Fv has already been processed, skip it. If the Fv has not been - processed then mark it as being processed, as we are about to process it. - Read the Fv and add any driver in the Fv to the mDiscoveredList.The - mDiscoveredList is never free'ed and contains variables that define - the other states the DXE driver transitions to.. - While you are at it read the A Priori file into memory. - Place drivers in the A Priori list onto the mScheduledQueue. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -CoreFwVolEventProtocolNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Convert FvHandle and DriverName into an EFI device path - - @param Fv Fv protocol, needed to read Depex info out of - FLASH. - @param FvHandle Handle for Fv, needed in the - EFI_CORE_DRIVER_ENTRY so that the PE image can be - read out of the FV at a later time. - @param DriverName Name of driver to add to mDiscoveredList. - - @return Pointer to device path constructed from FvHandle and DriverName - -**/ -EFI_DEVICE_PATH_PROTOCOL * -CoreFvToDevicePath ( - IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, - IN EFI_HANDLE FvHandle, - IN EFI_GUID *DriverName - ); - -/** - Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry, - and initilize any state variables. Read the Depex from the FV and store it - in DriverEntry. Pre-process the Depex to set the SOR, Before and After state. - The Discovered list is never free'ed and contains booleans that represent the - other possible DXE driver states. - - @param Fv Fv protocol, needed to read Depex info out of - FLASH. - @param FvHandle Handle for Fv, needed in the - EFI_CORE_DRIVER_ENTRY so that the PE image can be - read out of the FV at a later time. - @param DriverName Name of driver to add to mDiscoveredList. - @param Type Fv File Type of file to add to mDiscoveredList. - - @retval EFI_SUCCESS If driver was added to the mDiscoveredList. - @retval EFI_ALREADY_STARTED The driver has already been started. Only one - DriverName may be active in the system at any one - time. - -**/ -EFI_STATUS -CoreAddToDriverList ( - IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, - IN EFI_HANDLE FvHandle, - IN EFI_GUID *DriverName, - IN EFI_FV_FILETYPE Type - ); - -/** - Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle. - - @param Fv The FIRMWARE_VOLUME protocol installed on the FV. - @param FvHandle The handle which FVB protocol installed on. - @param DriverName The driver guid specified. - - @retval EFI_OUT_OF_RESOURCES No enough memory or other resource. - @retval EFI_VOLUME_CORRUPTED Corrupted volume. - @retval EFI_SUCCESS Function successfully returned. - -**/ -EFI_STATUS -CoreProcessFvImageFile ( - IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, - IN EFI_HANDLE FvHandle, - IN EFI_GUID *DriverName - ); - - -/** - Enter critical section by gaining lock on mDispatcherLock. - -**/ -VOID -CoreAcquireDispatcherLock ( - VOID - ) -{ - CoreAcquireLock (&mDispatcherLock); -} - - -/** - Exit critical section by releasing lock on mDispatcherLock. - -**/ -VOID -CoreReleaseDispatcherLock ( - VOID - ) -{ - CoreReleaseLock (&mDispatcherLock); -} - - -/** - Read Depex and pre-process the Depex for Before and After. If Section Extraction - protocol returns an error via ReadSection defer the reading of the Depex. - - @param DriverEntry Driver to work on. - - @retval EFI_SUCCESS Depex read and preprossesed - @retval EFI_PROTOCOL_ERROR The section extraction protocol returned an error - and Depex reading needs to be retried. - @retval Error DEPEX not found. - -**/ -EFI_STATUS -CoreGetDepexSectionAndPreProccess ( - IN EFI_CORE_DRIVER_ENTRY *DriverEntry - ) -{ - EFI_STATUS Status; - EFI_SECTION_TYPE SectionType; - UINT32 AuthenticationStatus; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - - - Fv = DriverEntry->Fv; - - // - // Grab Depex info, it will never be free'ed. - // - SectionType = EFI_SECTION_DXE_DEPEX; - Status = Fv->ReadSection ( - DriverEntry->Fv, - &DriverEntry->FileName, - SectionType, - 0, - &DriverEntry->Depex, - (UINTN *)&DriverEntry->DepexSize, - &AuthenticationStatus - ); - if (EFI_ERROR (Status)) { - if (Status == EFI_PROTOCOL_ERROR) { - // - // The section extraction protocol failed so set protocol error flag - // - DriverEntry->DepexProtocolError = TRUE; - } else { - // - // If no Depex assume UEFI 2.0 driver model - // - DriverEntry->Depex = NULL; - DriverEntry->Dependent = TRUE; - DriverEntry->DepexProtocolError = FALSE; - } - } else { - // - // Set Before, After, and Unrequested state information based on Depex - // Driver will be put in Dependent or Unrequested state - // - CorePreProcessDepex (DriverEntry); - DriverEntry->DepexProtocolError = FALSE; - } - - return Status; -} - - -/** - Check every driver and locate a matching one. If the driver is found, the Unrequested - state flag is cleared. - - @param FirmwareVolumeHandle The handle of the Firmware Volume that contains - the firmware file specified by DriverName. - @param DriverName The Driver name to put in the Dependent state. - - @retval EFI_SUCCESS The DriverName was found and it's SOR bit was - cleared - @retval EFI_NOT_FOUND The DriverName does not exist or it's SOR bit was - not set. - -**/ -EFI_STATUS -EFIAPI -CoreSchedule ( - IN EFI_HANDLE FirmwareVolumeHandle, - IN EFI_GUID *DriverName - ) -{ - LIST_ENTRY *Link; - EFI_CORE_DRIVER_ENTRY *DriverEntry; - - // - // Check every driver - // - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE); - if (DriverEntry->FvHandle == FirmwareVolumeHandle && - DriverEntry->Unrequested && - CompareGuid (DriverName, &DriverEntry->FileName)) { - // - // Move the driver from the Unrequested to the Dependent state - // - CoreAcquireDispatcherLock (); - DriverEntry->Unrequested = FALSE; - DriverEntry->Dependent = TRUE; - CoreReleaseDispatcherLock (); - - DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_SUCCESS\n", DriverName)); - - return EFI_SUCCESS; - } - } - - DEBUG ((DEBUG_DISPATCH, "Schedule FFS(%g) - EFI_NOT_FOUND\n", DriverName)); - - return EFI_NOT_FOUND; -} - - - -/** - Convert a driver from the Untrused back to the Scheduled state. - - @param FirmwareVolumeHandle The handle of the Firmware Volume that contains - the firmware file specified by DriverName. - @param DriverName The Driver name to put in the Scheduled state - - @retval EFI_SUCCESS The file was found in the untrusted state, and it - was promoted to the trusted state. - @retval EFI_NOT_FOUND The file was not found in the untrusted state. - -**/ -EFI_STATUS -EFIAPI -CoreTrust ( - IN EFI_HANDLE FirmwareVolumeHandle, - IN EFI_GUID *DriverName - ) -{ - LIST_ENTRY *Link; - EFI_CORE_DRIVER_ENTRY *DriverEntry; - - // - // Check every driver - // - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE); - if (DriverEntry->FvHandle == FirmwareVolumeHandle && - DriverEntry->Untrusted && - CompareGuid (DriverName, &DriverEntry->FileName)) { - // - // Transition driver from Untrusted to Scheduled state. - // - CoreAcquireDispatcherLock (); - DriverEntry->Untrusted = FALSE; - DriverEntry->Scheduled = TRUE; - InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink); - CoreReleaseDispatcherLock (); - - return EFI_SUCCESS; - } - } - return EFI_NOT_FOUND; -} - -/** - This is the main Dispatcher for DXE and it exits when there are no more - drivers to run. Drain the mScheduledQueue and load and start a PE - image for each driver. Search the mDiscoveredList to see if any driver can - be placed on the mScheduledQueue. If no drivers are placed on the - mScheduledQueue exit the function. On exit it is assumed the Bds() - will be called, and when the Bds() exits the Dispatcher will be called - again. - - @retval EFI_ALREADY_STARTED The DXE Dispatcher is already running - @retval EFI_NOT_FOUND No DXE Drivers were dispatched - @retval EFI_SUCCESS One or more DXE Drivers were dispatched - -**/ -EFI_STATUS -EFIAPI -CoreDispatcher ( - VOID - ) -{ - EFI_STATUS Status; - EFI_STATUS ReturnStatus; - LIST_ENTRY *Link; - EFI_CORE_DRIVER_ENTRY *DriverEntry; - BOOLEAN ReadyToRun; - EFI_EVENT DxeDispatchEvent; - - - if (gDispatcherRunning) { - // - // If the dispatcher is running don't let it be restarted. - // - return EFI_ALREADY_STARTED; - } - - gDispatcherRunning = TRUE; - - Status = CoreCreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - EfiEventEmptyFunction, - NULL, - &gEfiEventDxeDispatchGuid, - &DxeDispatchEvent - ); - if (EFI_ERROR (Status)) { - return Status; - } - - ReturnStatus = EFI_NOT_FOUND; - do { - // - // Drain the Scheduled Queue - // - while (!IsListEmpty (&mScheduledQueue)) { - DriverEntry = CR ( - mScheduledQueue.ForwardLink, - EFI_CORE_DRIVER_ENTRY, - ScheduledLink, - EFI_CORE_DRIVER_ENTRY_SIGNATURE - ); - - // - // Load the DXE Driver image into memory. If the Driver was transitioned from - // Untrused to Scheduled it would have already been loaded so we may need to - // skip the LoadImage - // - if (DriverEntry->ImageHandle == NULL && !DriverEntry->IsFvImage) { - DEBUG ((DEBUG_INFO, "Loading driver %g\n", &DriverEntry->FileName)); - Status = CoreLoadImage ( - FALSE, - gDxeCoreImageHandle, - DriverEntry->FvFileDevicePath, - NULL, - 0, - &DriverEntry->ImageHandle - ); - - // - // Update the driver state to reflect that it's been loaded - // - if (EFI_ERROR (Status)) { - CoreAcquireDispatcherLock (); - - if (Status == EFI_SECURITY_VIOLATION) { - // - // Take driver from Scheduled to Untrused state - // - DriverEntry->Untrusted = TRUE; - } else { - // - // The DXE Driver could not be loaded, and do not attempt to load or start it again. - // Take driver from Scheduled to Initialized. - // - // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned - // - DriverEntry->Initialized = TRUE; - } - - DriverEntry->Scheduled = FALSE; - RemoveEntryList (&DriverEntry->ScheduledLink); - - CoreReleaseDispatcherLock (); - - // - // If it's an error don't try the StartImage - // - continue; - } - } - - CoreAcquireDispatcherLock (); - - DriverEntry->Scheduled = FALSE; - DriverEntry->Initialized = TRUE; - RemoveEntryList (&DriverEntry->ScheduledLink); - - CoreReleaseDispatcherLock (); - - - if (DriverEntry->IsFvImage) { - // - // Produce a firmware volume block protocol for FvImage so it gets dispatched from. - // - Status = CoreProcessFvImageFile (DriverEntry->Fv, DriverEntry->FvHandle, &DriverEntry->FileName); - } else { - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN), - &DriverEntry->ImageHandle, - sizeof (DriverEntry->ImageHandle) - ); - ASSERT (DriverEntry->ImageHandle != NULL); - - Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL); - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END), - &DriverEntry->ImageHandle, - sizeof (DriverEntry->ImageHandle) - ); - } - - ReturnStatus = EFI_SUCCESS; - } - - // - // Now DXE Dispatcher finished one round of dispatch, signal an event group - // so that SMM Dispatcher get chance to dispatch SMM Drivers which depend - // on UEFI protocols - // - if (!EFI_ERROR (ReturnStatus)) { - CoreSignalEvent (DxeDispatchEvent); - } - - // - // Search DriverList for items to place on Scheduled Queue - // - ReadyToRun = FALSE; - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR (Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE); - - if (DriverEntry->DepexProtocolError){ - // - // If Section Extraction Protocol did not let the Depex be read before retry the read - // - Status = CoreGetDepexSectionAndPreProccess (DriverEntry); - } - - if (DriverEntry->Dependent) { - if (CoreIsSchedulable (DriverEntry)) { - CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); - ReadyToRun = TRUE; - } - } else { - if (DriverEntry->Unrequested) { - DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - DEBUG ((DEBUG_DISPATCH, " SOR = Not Requested\n")); - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE\n")); - } - } - } - } while (ReadyToRun); - - // - // Close DXE dispatch Event - // - CoreCloseEvent (DxeDispatchEvent); - - gDispatcherRunning = FALSE; - - return ReturnStatus; -} - - -/** - Insert InsertedDriverEntry onto the mScheduledQueue. To do this you - must add any driver with a before dependency on InsertedDriverEntry first. - You do this by recursively calling this routine. After all the Befores are - processed you can add InsertedDriverEntry to the mScheduledQueue. - Then you can add any driver with an After dependency on InsertedDriverEntry - by recursively calling this routine. - - @param InsertedDriverEntry The driver to insert on the ScheduledLink Queue - -**/ -VOID -CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter ( - IN EFI_CORE_DRIVER_ENTRY *InsertedDriverEntry - ) -{ - LIST_ENTRY *Link; - EFI_CORE_DRIVER_ENTRY *DriverEntry; - - // - // Process Before Dependency - // - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE); - if (DriverEntry->Before && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) { - DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - DEBUG ((DEBUG_DISPATCH, " BEFORE FFS(%g) = ", &DriverEntry->BeforeAfterGuid)); - if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) { - // - // Recursively process BEFORE - // - DEBUG ((DEBUG_DISPATCH, "TRUE\n END\n RESULT = TRUE\n")); - CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); - } else { - DEBUG ((DEBUG_DISPATCH, "FALSE\n END\n RESULT = FALSE\n")); - } - } - } - - // - // Convert driver from Dependent to Scheduled state - // - CoreAcquireDispatcherLock (); - - InsertedDriverEntry->Dependent = FALSE; - InsertedDriverEntry->Scheduled = TRUE; - InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink); - - CoreReleaseDispatcherLock (); - - // - // Process After Dependency - // - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE); - if (DriverEntry->After && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) { - DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - DEBUG ((DEBUG_DISPATCH, " AFTER FFS(%g) = ", &DriverEntry->BeforeAfterGuid)); - if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) { - // - // Recursively process AFTER - // - DEBUG ((DEBUG_DISPATCH, "TRUE\n END\n RESULT = TRUE\n")); - CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); - } else { - DEBUG ((DEBUG_DISPATCH, "FALSE\n END\n RESULT = FALSE\n")); - } - } - } -} - - -/** - Return TRUE if the Fv has been processed, FALSE if not. - - @param FvHandle The handle of a FV that's being tested - - @retval TRUE Fv protocol on FvHandle has been processed - @retval FALSE Fv protocol on FvHandle has not yet been processed - -**/ -BOOLEAN -FvHasBeenProcessed ( - IN EFI_HANDLE FvHandle - ) -{ - LIST_ENTRY *Link; - KNOWN_HANDLE *KnownHandle; - - for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) { - KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE); - if (KnownHandle->Handle == FvHandle) { - return TRUE; - } - } - return FALSE; -} - - -/** - Remember that Fv protocol on FvHandle has had it's drivers placed on the - mDiscoveredList. This fucntion adds entries on the mFvHandleList if new - entry is different from one in mFvHandleList by checking FvImage Guid. - Items are never removed/freed from the mFvHandleList. - - @param FvHandle The handle of a FV that has been processed - - @return A point to new added FvHandle entry. If FvHandle with the same FvImage guid - has been added, NULL will return. - -**/ -KNOWN_HANDLE * -FvIsBeingProcesssed ( - IN EFI_HANDLE FvHandle - ) -{ - EFI_STATUS Status; - EFI_GUID FvNameGuid; - BOOLEAN FvNameGuidIsFound; - UINT32 ExtHeaderOffset; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_FV_BLOCK_MAP_ENTRY *BlockMap; - UINTN LbaOffset; - UINTN Index; - EFI_LBA LbaIndex; - LIST_ENTRY *Link; - KNOWN_HANDLE *KnownHandle; - - FwVolHeader = NULL; - - // - // Get the FirmwareVolumeBlock protocol on that handle - // - FvNameGuidIsFound = FALSE; - Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb); - if (!EFI_ERROR (Status)) { - // - // Get the full FV header based on FVB protocol. - // - ASSERT (Fvb != NULL); - Status = GetFwVolHeader (Fvb, &FwVolHeader); - if (!EFI_ERROR (Status)) { - ASSERT (FwVolHeader != NULL); - if (VerifyFvHeaderChecksum (FwVolHeader) && FwVolHeader->ExtHeaderOffset != 0) { - ExtHeaderOffset = (UINT32) FwVolHeader->ExtHeaderOffset; - BlockMap = FwVolHeader->BlockMap; - LbaIndex = 0; - LbaOffset = 0; - // - // Find LbaIndex and LbaOffset for FV extension header based on BlockMap. - // - while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) { - for (Index = 0; Index < BlockMap->NumBlocks && ExtHeaderOffset >= BlockMap->Length; Index ++) { - ExtHeaderOffset -= BlockMap->Length; - LbaIndex ++; - } - // - // Check whether FvExtHeader is crossing the multi block range. - // - if (Index < BlockMap->NumBlocks) { - LbaOffset = ExtHeaderOffset; - break; - } - BlockMap++; - } - // - // Read FvNameGuid from FV extension header. - // - Status = ReadFvbData (Fvb, &LbaIndex, &LbaOffset, sizeof (FvNameGuid), (UINT8 *) &FvNameGuid); - if (!EFI_ERROR (Status)) { - FvNameGuidIsFound = TRUE; - } - } - CoreFreePool (FwVolHeader); - } - } - - if (FvNameGuidIsFound) { - // - // Check whether the FV image with the found FvNameGuid has been processed. - // - for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) { - KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE); - if (CompareGuid (&FvNameGuid, &KnownHandle->FvNameGuid)) { - DEBUG ((EFI_D_ERROR, "FvImage on FvHandle %p and %p has the same FvNameGuid %g.\n", FvHandle, KnownHandle->Handle, FvNameGuid)); - return NULL; - } - } - } - - KnownHandle = AllocateZeroPool (sizeof (KNOWN_HANDLE)); - ASSERT (KnownHandle != NULL); - - KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE; - KnownHandle->Handle = FvHandle; - if (FvNameGuidIsFound) { - CopyGuid (&KnownHandle->FvNameGuid, &FvNameGuid); - } - InsertTailList (&mFvHandleList, &KnownHandle->Link); - return KnownHandle; -} - - - - -/** - Convert FvHandle and DriverName into an EFI device path - - @param Fv Fv protocol, needed to read Depex info out of - FLASH. - @param FvHandle Handle for Fv, needed in the - EFI_CORE_DRIVER_ENTRY so that the PE image can be - read out of the FV at a later time. - @param DriverName Name of driver to add to mDiscoveredList. - - @return Pointer to device path constructed from FvHandle and DriverName - -**/ -EFI_DEVICE_PATH_PROTOCOL * -CoreFvToDevicePath ( - IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, - IN EFI_HANDLE FvHandle, - IN EFI_GUID *DriverName - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *FvDevicePath; - EFI_DEVICE_PATH_PROTOCOL *FileNameDevicePath; - - // - // Remember the device path of the FV - // - Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath); - if (EFI_ERROR (Status)) { - FileNameDevicePath = NULL; - } else { - // - // Build a device path to the file in the FV to pass into gBS->LoadImage - // - EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName); - SetDevicePathEndNode (&mFvDevicePath.End); - - FileNameDevicePath = AppendDevicePath ( - FvDevicePath, - (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath - ); - } - - return FileNameDevicePath; -} - - - -/** - Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry, - and initilize any state variables. Read the Depex from the FV and store it - in DriverEntry. Pre-process the Depex to set the SOR, Before and After state. - The Discovered list is never free'ed and contains booleans that represent the - other possible DXE driver states. - - @param Fv Fv protocol, needed to read Depex info out of - FLASH. - @param FvHandle Handle for Fv, needed in the - EFI_CORE_DRIVER_ENTRY so that the PE image can be - read out of the FV at a later time. - @param DriverName Name of driver to add to mDiscoveredList. - @param Type Fv File Type of file to add to mDiscoveredList. - - @retval EFI_SUCCESS If driver was added to the mDiscoveredList. - @retval EFI_ALREADY_STARTED The driver has already been started. Only one - DriverName may be active in the system at any one - time. - -**/ -EFI_STATUS -CoreAddToDriverList ( - IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, - IN EFI_HANDLE FvHandle, - IN EFI_GUID *DriverName, - IN EFI_FV_FILETYPE Type - ) -{ - EFI_CORE_DRIVER_ENTRY *DriverEntry; - - - // - // Create the Driver Entry for the list. ZeroPool initializes lots of variables to - // NULL or FALSE. - // - DriverEntry = AllocateZeroPool (sizeof (EFI_CORE_DRIVER_ENTRY)); - ASSERT (DriverEntry != NULL); - if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) { - DriverEntry->IsFvImage = TRUE; - } - - DriverEntry->Signature = EFI_CORE_DRIVER_ENTRY_SIGNATURE; - CopyGuid (&DriverEntry->FileName, DriverName); - DriverEntry->FvHandle = FvHandle; - DriverEntry->Fv = Fv; - DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName); - - CoreGetDepexSectionAndPreProccess (DriverEntry); - - CoreAcquireDispatcherLock (); - - InsertTailList (&mDiscoveredList, &DriverEntry->Link); - - CoreReleaseDispatcherLock (); - - return EFI_SUCCESS; -} - - -/** - Check if a FV Image type file (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) is - described by a EFI_HOB_FIRMWARE_VOLUME2 Hob. - - @param FvNameGuid The FV image guid specified. - @param DriverName The driver guid specified. - - @retval TRUE This file is found in a EFI_HOB_FIRMWARE_VOLUME2 - Hob. - @retval FALSE Not found. - -**/ -BOOLEAN -FvFoundInHobFv2 ( - IN CONST EFI_GUID *FvNameGuid, - IN CONST EFI_GUID *DriverName - ) -{ - EFI_PEI_HOB_POINTERS HobFv2; - - HobFv2.Raw = GetHobList (); - - while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) { - // - // Compare parent FvNameGuid and FileGuid both. - // - if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName) && - CompareGuid (FvNameGuid, &HobFv2.FirmwareVolume2->FvName)) { - return TRUE; - } - HobFv2.Raw = GET_NEXT_HOB (HobFv2); - } - - return FALSE; -} - - - -/** - Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle. - - @param Fv The FIRMWARE_VOLUME protocol installed on the FV. - @param FvHandle The handle which FVB protocol installed on. - @param DriverName The driver guid specified. - - @retval EFI_OUT_OF_RESOURCES No enough memory or other resource. - @retval EFI_VOLUME_CORRUPTED Corrupted volume. - @retval EFI_SUCCESS Function successfully returned. - -**/ -EFI_STATUS -CoreProcessFvImageFile ( - IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, - IN EFI_HANDLE FvHandle, - IN EFI_GUID *DriverName - ) -{ - EFI_STATUS Status; - EFI_SECTION_TYPE SectionType; - UINT32 AuthenticationStatus; - VOID *Buffer; - VOID *AlignedBuffer; - UINTN BufferSize; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - UINT32 FvAlignment; - EFI_DEVICE_PATH_PROTOCOL *FvFileDevicePath; - - // - // Read the first (and only the first) firmware volume section - // - SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE; - FvHeader = NULL; - FvAlignment = 0; - Buffer = NULL; - BufferSize = 0; - AlignedBuffer = NULL; - Status = Fv->ReadSection ( - Fv, - DriverName, - SectionType, - 0, - &Buffer, - &BufferSize, - &AuthenticationStatus - ); - if (!EFI_ERROR (Status)) { - // - // Evaluate the authentication status of the Firmware Volume through - // Security Architectural Protocol - // - if (gSecurity != NULL) { - FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName); - Status = gSecurity->FileAuthenticationState ( - gSecurity, - AuthenticationStatus, - FvFileDevicePath - ); - if (FvFileDevicePath != NULL) { - FreePool (FvFileDevicePath); - } - - if (Status != EFI_SUCCESS) { - // - // Security check failed. The firmware volume should not be used for any purpose. - // - if (Buffer != NULL) { - FreePool (Buffer); - } - return Status; - } - } - - // - // FvImage should be at its required alignment. - // - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer; - // - // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume - // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from - // its initial linked location and maintain its alignment. - // - if ((FvHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) { - // - // Get FvHeader alignment - // - FvAlignment = 1 << ((FvHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16); - // - // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value. - // - if (FvAlignment < 8) { - FvAlignment = 8; - } - // - // Allocate the aligned buffer for the FvImage. - // - AlignedBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), (UINTN) FvAlignment); - if (AlignedBuffer == NULL) { - FreePool (Buffer); - return EFI_OUT_OF_RESOURCES; - } else { - // - // Move FvImage into the aligned buffer and release the original buffer. - // - CopyMem (AlignedBuffer, Buffer, BufferSize); - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) AlignedBuffer; - CoreFreePool (Buffer); - Buffer = NULL; - } - } - // - // Produce a FVB protocol for the file - // - Status = ProduceFVBProtocolOnBuffer ( - (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, - (UINT64)BufferSize, - FvHandle, - AuthenticationStatus, - NULL - ); - } - - if (EFI_ERROR (Status)) { - // - // ReadSection or Produce FVB failed, Free data buffer - // - if (Buffer != NULL) { - FreePool (Buffer); - } - - if (AlignedBuffer != NULL) { - FreeAlignedPages (AlignedBuffer, EFI_SIZE_TO_PAGES (BufferSize)); - } - } - - return Status; -} - - -/** - Event notification that is fired every time a FV dispatch protocol is added. - More than one protocol may have been added when this event is fired, so you - must loop on CoreLocateHandle () to see how many protocols were added and - do the following to each FV: - If the Fv has already been processed, skip it. If the Fv has not been - processed then mark it as being processed, as we are about to process it. - Read the Fv and add any driver in the Fv to the mDiscoveredList.The - mDiscoveredList is never free'ed and contains variables that define - the other states the DXE driver transitions to.. - While you are at it read the A Priori file into memory. - Place drivers in the A Priori list onto the mScheduledQueue. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -CoreFwVolEventProtocolNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - EFI_STATUS GetNextFileStatus; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - EFI_DEVICE_PATH_PROTOCOL *FvDevicePath; - EFI_HANDLE FvHandle; - UINTN BufferSize; - EFI_GUID NameGuid; - UINTN Key; - EFI_FV_FILETYPE Type; - EFI_FV_FILE_ATTRIBUTES Attributes; - UINTN Size; - EFI_CORE_DRIVER_ENTRY *DriverEntry; - EFI_GUID *AprioriFile; - UINTN AprioriEntryCount; - UINTN Index; - LIST_ENTRY *Link; - UINT32 AuthenticationStatus; - UINTN SizeOfBuffer; - VOID *DepexBuffer; - KNOWN_HANDLE *KnownHandle; - - FvHandle = NULL; - - while (TRUE) { - BufferSize = sizeof (EFI_HANDLE); - Status = CoreLocateHandle ( - ByRegisterNotify, - NULL, - mFwVolEventRegistration, - &BufferSize, - &FvHandle - ); - if (EFI_ERROR (Status)) { - // - // If no more notification events exit - // - return; - } - - if (FvHasBeenProcessed (FvHandle)) { - // - // This Fv has already been processed so lets skip it! - // - continue; - } - - // - // Since we are about to process this Fv mark it as processed. - // - KnownHandle = FvIsBeingProcesssed (FvHandle); - if (KnownHandle == NULL) { - // - // The FV with the same FV name guid has already been processed. - // So lets skip it! - // - continue; - } - - Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv); - if (EFI_ERROR (Status) || Fv == NULL) { - // - // FvHandle must have Firmware Volume2 protocol thus we should never get here. - // - ASSERT (FALSE); - continue; - } - - Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath); - if (EFI_ERROR (Status)) { - // - // The Firmware volume doesn't have device path, can't be dispatched. - // - continue; - } - - // - // Discover Drivers in FV and add them to the Discovered Driver List. - // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER - // EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core - // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb - // - for (Index = 0; Index < sizeof (mDxeFileTypes) / sizeof (EFI_FV_FILETYPE); Index++) { - // - // Initialize the search key - // - Key = 0; - do { - Type = mDxeFileTypes[Index]; - GetNextFileStatus = Fv->GetNextFile ( - Fv, - &Key, - &Type, - &NameGuid, - &Attributes, - &Size - ); - if (!EFI_ERROR (GetNextFileStatus)) { - if (Type == EFI_FV_FILETYPE_DXE_CORE) { - // - // If this is the DXE core fill in it's DevicePath & DeviceHandle - // - if (gDxeCoreLoadedImage->FilePath == NULL) { - if (CompareGuid (&NameGuid, gDxeCoreFileName)) { - // - // Maybe One specail Fv cantains only one DXE_CORE module, so its device path must - // be initialized completely. - // - EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid); - SetDevicePathEndNode (&mFvDevicePath.End); - - gDxeCoreLoadedImage->FilePath = DuplicateDevicePath ( - (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath - ); - gDxeCoreLoadedImage->DeviceHandle = FvHandle; - } - } - } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) { - // - // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already - // been extracted. - // - if (FvFoundInHobFv2 (&KnownHandle->FvNameGuid, &NameGuid)) { - continue; - } - - // - // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has SMM depex section. - // - DepexBuffer = NULL; - SizeOfBuffer = 0; - Status = Fv->ReadSection ( - Fv, - &NameGuid, - EFI_SECTION_SMM_DEPEX, - 0, - &DepexBuffer, - &SizeOfBuffer, - &AuthenticationStatus - ); - if (!EFI_ERROR (Status)) { - // - // If SMM depex section is found, this FV image is invalid to be supported. - // ASSERT FALSE to report this FV image. - // - FreePool (DepexBuffer); - ASSERT (FALSE); - } - - // - // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has DXE depex section. - // - DepexBuffer = NULL; - SizeOfBuffer = 0; - Status = Fv->ReadSection ( - Fv, - &NameGuid, - EFI_SECTION_DXE_DEPEX, - 0, - &DepexBuffer, - &SizeOfBuffer, - &AuthenticationStatus - ); - if (EFI_ERROR (Status)) { - // - // If no depex section, produce a firmware volume block protocol for it so it gets dispatched from. - // - CoreProcessFvImageFile (Fv, FvHandle, &NameGuid); - } else { - // - // If depex section is found, this FV image will be dispatched until its depex is evaluated to TRUE. - // - FreePool (DepexBuffer); - CoreAddToDriverList (Fv, FvHandle, &NameGuid, Type); - } - } else { - // - // Transition driver from Undiscovered to Discovered state - // - CoreAddToDriverList (Fv, FvHandle, &NameGuid, Type); - } - } - } while (!EFI_ERROR (GetNextFileStatus)); - } - - // - // Read the array of GUIDs from the Apriori file if it is present in the firmware volume - // - AprioriFile = NULL; - Status = Fv->ReadSection ( - Fv, - &gAprioriGuid, - EFI_SECTION_RAW, - 0, - (VOID **)&AprioriFile, - &SizeOfBuffer, - &AuthenticationStatus - ); - if (!EFI_ERROR (Status)) { - AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID); - } else { - AprioriEntryCount = 0; - } - - // - // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes - // drivers not in the current FV and these must be skipped since the a priori list - // is only valid for the FV that it resided in. - // - - for (Index = 0; Index < AprioriEntryCount; Index++) { - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE); - if (CompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) && - (FvHandle == DriverEntry->FvHandle)) { - CoreAcquireDispatcherLock (); - DriverEntry->Dependent = FALSE; - DriverEntry->Scheduled = TRUE; - InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink); - CoreReleaseDispatcherLock (); - DEBUG ((DEBUG_DISPATCH, "Evaluate DXE DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (Apriori)\n")); - break; - } - } - } - - // - // Free data allocated by Fv->ReadSection () - // - CoreFreePool (AprioriFile); - } -} - - - -/** - Initialize the dispatcher. Initialize the notification function that runs when - an FV2 protocol is added to the system. - -**/ -VOID -CoreInitializeDispatcher ( - VOID - ) -{ - mFwVolEvent = EfiCreateProtocolNotifyEvent ( - &gEfiFirmwareVolume2ProtocolGuid, - TPL_CALLBACK, - CoreFwVolEventProtocolNotify, - NULL, - &mFwVolEventRegistration - ); -} - -// -// Function only used in debug builds -// - -/** - Traverse the discovered list for any drivers that were discovered but not loaded - because the dependency experessions evaluated to false. - -**/ -VOID -CoreDisplayDiscoveredNotDispatched ( - VOID - ) -{ - LIST_ENTRY *Link; - EFI_CORE_DRIVER_ENTRY *DriverEntry; - - for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE); - if (DriverEntry->Dependent) { - DEBUG ((DEBUG_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName)); - } - } -} diff --git a/MdeModulePkg/Core/Dxe/DxeCore.uni b/MdeModulePkg/Core/Dxe/DxeCore.uni deleted file mode 100644 index 0b4450dbbe..0000000000 --- a/MdeModulePkg/Core/Dxe/DxeCore.uni +++ /dev/null @@ -1,22 +0,0 @@ -// /** @file -// This is core module in DXE phase. -// -// It provides an implementation of DXE Core that is compliant with DXE CIS. -// -// Copyright (c) 2006 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "The core module in DXE phase" - -#string STR_MODULE_DESCRIPTION #language en-US "It provides an implementation of DXE Core that is compliant with DXE CIS." - diff --git a/MdeModulePkg/Core/Dxe/DxeCoreExtra.uni b/MdeModulePkg/Core/Dxe/DxeCoreExtra.uni deleted file mode 100644 index d04eaf4958..0000000000 --- a/MdeModulePkg/Core/Dxe/DxeCoreExtra.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// DxeCore Localized Strings and Content -// -// Copyright (c) 2013 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Core DXE Services Driver" - - diff --git a/MdeModulePkg/Core/Dxe/DxeMain.h b/MdeModulePkg/Core/Dxe/DxeMain.h deleted file mode 100644 index 1a0babba71..0000000000 --- a/MdeModulePkg/Core/Dxe/DxeMain.h +++ /dev/null @@ -1,2951 +0,0 @@ -/** @file - The internal header file includes the common header files, defines - internal structure and functions used by DxeCore module. - -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _DXE_MAIN_H_ -#define _DXE_MAIN_H_ - - - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// -// attributes for reserved memory before it is promoted to system memory -// -#define EFI_MEMORY_PRESENT 0x0100000000000000ULL -#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL -#define EFI_MEMORY_TESTED 0x0400000000000000ULL - -// -// range for memory mapped port I/O on IPF -// -#define EFI_MEMORY_PORT_IO 0x4000000000000000ULL - - -/// -/// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependency expression -/// to save time. A EFI_DEP_PUSH is evaluated one an -/// replaced with EFI_DEP_REPLACE_TRUE. If PI spec's Vol 2 -/// Driver Execution Environment Core Interface use 0xff -/// as new DEPEX opcode. EFI_DEP_REPLACE_TRUE should be -/// defined to a new value that is not conflicting with PI spec. -/// -#define EFI_DEP_REPLACE_TRUE 0xff - -/// -/// Define the initial size of the dependency expression evaluation stack -/// -#define DEPEX_STACK_SIZE_INCREMENT 0x1000 - -typedef struct { - EFI_GUID *ProtocolGuid; - VOID **Protocol; - EFI_EVENT Event; - VOID *Registration; - BOOLEAN Present; -} EFI_CORE_PROTOCOL_NOTIFY_ENTRY; - -// -// DXE Dispatcher Data structures -// - -#define KNOWN_HANDLE_SIGNATURE SIGNATURE_32('k','n','o','w') -typedef struct { - UINTN Signature; - LIST_ENTRY Link; // mFvHandleList - EFI_HANDLE Handle; - EFI_GUID FvNameGuid; -} KNOWN_HANDLE; - - -#define EFI_CORE_DRIVER_ENTRY_SIGNATURE SIGNATURE_32('d','r','v','r') -typedef struct { - UINTN Signature; - LIST_ENTRY Link; // mDriverList - - LIST_ENTRY ScheduledLink; // mScheduledQueue - - EFI_HANDLE FvHandle; - EFI_GUID FileName; - EFI_DEVICE_PATH_PROTOCOL *FvFileDevicePath; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - - VOID *Depex; - UINTN DepexSize; - - BOOLEAN Before; - BOOLEAN After; - EFI_GUID BeforeAfterGuid; - - BOOLEAN Dependent; - BOOLEAN Unrequested; - BOOLEAN Scheduled; - BOOLEAN Untrusted; - BOOLEAN Initialized; - BOOLEAN DepexProtocolError; - - EFI_HANDLE ImageHandle; - BOOLEAN IsFvImage; - -} EFI_CORE_DRIVER_ENTRY; - -// -//The data structure of GCD memory map entry -// -#define EFI_GCD_MAP_SIGNATURE SIGNATURE_32('g','c','d','m') -typedef struct { - UINTN Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINT64 EndAddress; - UINT64 Capabilities; - UINT64 Attributes; - EFI_GCD_MEMORY_TYPE GcdMemoryType; - EFI_GCD_IO_TYPE GcdIoType; - EFI_HANDLE ImageHandle; - EFI_HANDLE DeviceHandle; -} EFI_GCD_MAP_ENTRY; - - -#define LOADED_IMAGE_PRIVATE_DATA_SIGNATURE SIGNATURE_32('l','d','r','i') - -typedef struct { - UINTN Signature; - /// Image handle - EFI_HANDLE Handle; - /// Image type - UINTN Type; - /// If entrypoint has been called - BOOLEAN Started; - /// The image's entry point - EFI_IMAGE_ENTRY_POINT EntryPoint; - /// loaded image protocol - EFI_LOADED_IMAGE_PROTOCOL Info; - /// Location in memory - EFI_PHYSICAL_ADDRESS ImageBasePage; - /// Number of pages - UINTN NumberOfPages; - /// Original fixup data - CHAR8 *FixupData; - /// Tpl of started image - EFI_TPL Tpl; - /// Status returned by started image - EFI_STATUS Status; - /// Size of ExitData from started image - UINTN ExitDataSize; - /// Pointer to exit data from started image - VOID *ExitData; - /// Pointer to pool allocation for context save/restore - VOID *JumpBuffer; - /// Pointer to buffer for context save/restore - BASE_LIBRARY_JUMP_BUFFER *JumpContext; - /// Machine type from PE image - UINT16 Machine; - /// EBC Protocol pointer - EFI_EBC_PROTOCOL *Ebc; - /// Runtime image list - EFI_RUNTIME_IMAGE_ENTRY *RuntimeData; - /// Pointer to Loaded Image Device Path Protocol - EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; - /// PeCoffLoader ImageContext - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - /// Status returned by LoadImage() service. - EFI_STATUS LoadImageStatus; -} LOADED_IMAGE_PRIVATE_DATA; - -#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ - CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE) - -#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I','P','R','C') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS CodeSegmentBase; - UINT64 CodeSegmentSize; -} IMAGE_PROPERTIES_RECORD_CODE_SECTION; - -#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS ImageBase; - UINT64 ImageSize; - UINTN CodeSegmentCount; - LIST_ENTRY CodeSegmentList; -} IMAGE_PROPERTIES_RECORD; - -// -// DXE Core Global Variables -// -extern EFI_SYSTEM_TABLE *gDxeCoreST; -extern EFI_RUNTIME_SERVICES *gDxeCoreRT; -extern EFI_DXE_SERVICES *gDxeCoreDS; -extern EFI_HANDLE gDxeCoreImageHandle; - -extern BOOLEAN gMemoryMapTerminated; - -extern EFI_DECOMPRESS_PROTOCOL gEfiDecompress; - -extern EFI_RUNTIME_ARCH_PROTOCOL *gRuntime; -extern EFI_CPU_ARCH_PROTOCOL *gCpu; -extern EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer; -extern EFI_METRONOME_ARCH_PROTOCOL *gMetronome; -extern EFI_TIMER_ARCH_PROTOCOL *gTimer; -extern EFI_SECURITY_ARCH_PROTOCOL *gSecurity; -extern EFI_SECURITY2_ARCH_PROTOCOL *gSecurity2; -extern EFI_BDS_ARCH_PROTOCOL *gBds; -extern EFI_SMM_BASE2_PROTOCOL *gSmmBase2; - -extern EFI_TPL gEfiCurrentTpl; - -extern EFI_GUID *gDxeCoreFileName; -extern EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage; - -extern EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1]; - -extern BOOLEAN gDispatcherRunning; -extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate; - -extern EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE gLoadModuleAtFixAddressConfigurationTable; -extern BOOLEAN gLoadFixedAddressCodeMemoryReady; -// -// Service Initialization Functions -// - - - -/** - Called to initialize the pool. - -**/ -VOID -CoreInitializePool ( - VOID - ); - - -/** - Called to initialize the memory map and add descriptors to - the current descriptor list. - The first descriptor that is added must be general usable - memory as the addition allocates heap. - - @param Type The type of memory to add - @param Start The starting address in the memory range Must be - page aligned - @param NumberOfPages The number of pages in the range - @param Attribute Attributes of the memory to add - - @return None. The range is added to the memory map - -**/ -VOID -CoreAddMemoryDescriptor ( - IN EFI_MEMORY_TYPE Type, - IN EFI_PHYSICAL_ADDRESS Start, - IN UINT64 NumberOfPages, - IN UINT64 Attribute - ); - - -/** - Release memory lock on mGcdMemorySpaceLock. - -**/ -VOID -CoreReleaseGcdMemoryLock ( - VOID - ); - - -/** - Acquire memory lock on mGcdMemorySpaceLock. - -**/ -VOID -CoreAcquireGcdMemoryLock ( - VOID - ); - - -/** - External function. Initializes memory services based on the memory - descriptor HOBs. This function is responsible for priming the memory - map, so memory allocations and resource allocations can be made. - The first part of this function can not depend on any memory services - until at least one memory descriptor is provided to the memory services. - - @param HobStart The start address of the HOB. - @param MemoryBaseAddress Start address of memory region found to init DXE - core. - @param MemoryLength Length of memory region found to init DXE core. - - @retval EFI_SUCCESS Memory services successfully initialized. - -**/ -EFI_STATUS -CoreInitializeMemoryServices ( - IN VOID **HobStart, - OUT EFI_PHYSICAL_ADDRESS *MemoryBaseAddress, - OUT UINT64 *MemoryLength - ); - - - -/** - External function. Initializes the GCD and memory services based on the memory - descriptor HOBs. This function is responsible for priming the GCD map and the - memory map, so memory allocations and resource allocations can be made. The - HobStart will be relocated to a pool buffer. - - @param HobStart The start address of the HOB - @param MemoryBaseAddress Start address of memory region found to init DXE - core. - @param MemoryLength Length of memory region found to init DXE core. - - @retval EFI_SUCCESS GCD services successfully initialized. - -**/ -EFI_STATUS -CoreInitializeGcdServices ( - IN OUT VOID **HobStart, - IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress, - IN UINT64 MemoryLength - ); - - -/** - Initializes "event" support. - - @retval EFI_SUCCESS Always return success - -**/ -EFI_STATUS -CoreInitializeEventServices ( - VOID - ); - - -/** - Add the Image Services to EFI Boot Services Table and install the protocol - interfaces for this image. - - @param HobStart The HOB to initialize - - @return Status code. - -**/ -EFI_STATUS -CoreInitializeImageServices ( - IN VOID *HobStart - ); - - -/** - Creates an event that is fired everytime a Protocol of a specific type is installed. - -**/ -VOID -CoreNotifyOnProtocolInstallation ( - VOID - ); - - -/** - Return TRUE if all AP services are available. - - @retval EFI_SUCCESS All AP services are available - @retval EFI_NOT_FOUND At least one AP service is not available - -**/ -EFI_STATUS -CoreAllEfiServicesAvailable ( - VOID - ); - - -/** - Calcualte the 32-bit CRC in a EFI table using the service provided by the - gRuntime service. - - @param Hdr Pointer to an EFI standard header - -**/ -VOID -CalculateEfiHdrCrc ( - IN OUT EFI_TABLE_HEADER *Hdr - ); - - -/** - Called by the platform code to process a tick. - - @param Duration The number of 100ns elapsed since the last call - to TimerTick - -**/ -VOID -EFIAPI -CoreTimerTick ( - IN UINT64 Duration - ); - - -/** - Initialize the dispatcher. Initialize the notification function that runs when - an FV2 protocol is added to the system. - -**/ -VOID -CoreInitializeDispatcher ( - VOID - ); - - -/** - This is the POSTFIX version of the dependency evaluator. This code does - not need to handle Before or After, as it is not valid to call this - routine in this case. The SOR is just ignored and is a nop in the grammer. - POSTFIX means all the math is done on top of the stack. - - @param DriverEntry DriverEntry element to update. - - @retval TRUE If driver is ready to run. - @retval FALSE If driver is not ready to run or some fatal error - was found. - -**/ -BOOLEAN -CoreIsSchedulable ( - IN EFI_CORE_DRIVER_ENTRY *DriverEntry - ); - - -/** - Preprocess dependency expression and update DriverEntry to reflect the - state of Before, After, and SOR dependencies. If DriverEntry->Before - or DriverEntry->After is set it will never be cleared. If SOR is set - it will be cleared by CoreSchedule(), and then the driver can be - dispatched. - - @param DriverEntry DriverEntry element to update . - - @retval EFI_SUCCESS It always works. - -**/ -EFI_STATUS -CorePreProcessDepex ( - IN EFI_CORE_DRIVER_ENTRY *DriverEntry - ); - - - -/** - Terminates all boot services. - - @param ImageHandle Handle that identifies the exiting image. - @param MapKey Key to the latest memory map. - - @retval EFI_SUCCESS Boot Services terminated - @retval EFI_INVALID_PARAMETER MapKey is incorrect. - -**/ -EFI_STATUS -EFIAPI -CoreExitBootServices ( - IN EFI_HANDLE ImageHandle, - IN UINTN MapKey - ); - - -/** - Make sure the memory map is following all the construction rules, - it is the last time to check memory map error before exit boot services. - - @param MapKey Memory map key - - @retval EFI_INVALID_PARAMETER Memory map not consistent with construction - rules. - @retval EFI_SUCCESS Valid memory map. - -**/ -EFI_STATUS -CoreTerminateMemoryMap ( - IN UINTN MapKey - ); - - -/** - Signals all events in the EventGroup. - - @param EventGroup The list to signal - -**/ -VOID -CoreNotifySignalList ( - IN EFI_GUID *EventGroup - ); - - - -/** - Boot Service called to add, modify, or remove a system configuration table from - the EFI System Table. - - @param Guid Pointer to the GUID for the entry to add, update, or - remove - @param Table Pointer to the configuration table for the entry to add, - update, or remove, may be NULL. - - @return EFI_SUCCESS Guid, Table pair added, updated, or removed. - @return EFI_INVALID_PARAMETER Input GUID not valid. - @return EFI_NOT_FOUND Attempted to delete non-existant entry - @return EFI_OUT_OF_RESOURCES Not enough memory available - -**/ -EFI_STATUS -EFIAPI -CoreInstallConfigurationTable ( - IN EFI_GUID *Guid, - IN VOID *Table - ); - - - -/** - Raise the task priority level to the new level. - High level is implemented by disabling processor interrupts. - - @param NewTpl New task priority level - - @return The previous task priority level - -**/ -EFI_TPL -EFIAPI -CoreRaiseTpl ( - IN EFI_TPL NewTpl - ); - - - -/** - Lowers the task priority to the previous value. If the new - priority unmasks events at a higher priority, they are dispatched. - - @param NewTpl New, lower, task priority - -**/ -VOID -EFIAPI -CoreRestoreTpl ( - IN EFI_TPL NewTpl - ); - - - -/** - Introduces a fine-grained stall. - - @param Microseconds The number of microseconds to stall execution. - - @retval EFI_SUCCESS Execution was stalled for at least the requested - amount of microseconds. - @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet - -**/ -EFI_STATUS -EFIAPI -CoreStall ( - IN UINTN Microseconds - ); - - - -/** - Sets the system's watchdog timer. - - @param Timeout The number of seconds to set the watchdog timer to. - A value of zero disables the timer. - @param WatchdogCode The numeric code to log on a watchdog timer timeout - event. The firmware reserves codes 0x0000 to 0xFFFF. - Loaders and operating systems may use other timeout - codes. - @param DataSize The size, in bytes, of WatchdogData. - @param WatchdogData A data buffer that includes a Null-terminated Unicode - string, optionally followed by additional binary data. - The string is a description that the call may use to - further indicate the reason to be logged with a - watchdog event. - - @return EFI_SUCCESS Timeout has been set - @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet - @return EFI_UNSUPPORTED System does not have a timer (currently not used) - @return EFI_DEVICE_ERROR Could not complete due to hardware error - -**/ -EFI_STATUS -EFIAPI -CoreSetWatchdogTimer ( - IN UINTN Timeout, - IN UINT64 WatchdogCode, - IN UINTN DataSize, - IN CHAR16 *WatchdogData OPTIONAL - ); - - - -/** - Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which - Calls the private one which contains a BOOLEAN parameter for notifications - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - - @return Status code - -**/ -EFI_STATUS -EFIAPI -CoreInstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface - ); - - -/** - Installs a protocol interface into the boot services environment. - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - @param Notify indicates whether notify the notification list - for this protocol - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SUCCESS Protocol interface successfully installed - -**/ -EFI_STATUS -CoreInstallProtocolInterfaceNotify ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface, - IN BOOLEAN Notify - ); - - - -/** - Installs a list of protocol interface into the boot services environment. - This function calls InstallProtocolInterface() in a loop. If any error - occures all the protocols added by this function are removed. This is - basically a lib function to save space. - - @param Handle The handle to install the protocol handlers on, - or NULL if a new handle is to be allocated - @param ... EFI_GUID followed by protocol instance. A NULL - terminates the list. The pairs are the - arguments to InstallProtocolInterface(). All the - protocols are added to Handle. - - @retval EFI_SUCCESS All the protocol interface was installed. - @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. - @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in - the handle database. - @retval EFI_INVALID_PARAMETER Handle is NULL. - @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. - -**/ -EFI_STATUS -EFIAPI -CoreInstallMultipleProtocolInterfaces ( - IN OUT EFI_HANDLE *Handle, - ... - ); - - - -/** - Uninstalls a list of protocol interface in the boot services environment. - This function calls UnisatllProtocolInterface() in a loop. This is - basically a lib function to save space. - - @param Handle The handle to uninstall the protocol - @param ... EFI_GUID followed by protocol instance. A NULL - terminates the list. The pairs are the - arguments to UninstallProtocolInterface(). All - the protocols are added to Handle. - - @return Status code - -**/ -EFI_STATUS -EFIAPI -CoreUninstallMultipleProtocolInterfaces ( - IN EFI_HANDLE Handle, - ... - ); - - - -/** - Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. - - @param UserHandle Handle on which the interface is to be - reinstalled - @param Protocol The numeric ID of the interface - @param OldInterface A pointer to the old interface - @param NewInterface A pointer to the new interface - - @retval EFI_SUCCESS The protocol interface was installed - @retval EFI_NOT_FOUND The OldInterface on the handle was not found - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - -**/ -EFI_STATUS -EFIAPI -CoreReinstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *OldInterface, - IN VOID *NewInterface - ); - - - -/** - Uninstalls all instances of a protocol:interfacer from a handle. - If the last protocol interface is remove from the handle, the - handle is freed. - - @param UserHandle The handle to remove the protocol handler from - @param Protocol The protocol, of protocol:interface, to remove - @param Interface The interface, of protocol:interface, to remove - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Protocol interface successfully uninstalled. - -**/ -EFI_STATUS -EFIAPI -CoreUninstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ); - - - -/** - Queries a handle to determine if it supports a specified protocol. - - @param UserHandle The handle being queried. - @param Protocol The published unique identifier of the protocol. - @param Interface Supplies the address where a pointer to the - corresponding Protocol Interface is returned. - - @return The requested protocol interface for the handle - -**/ -EFI_STATUS -EFIAPI -CoreHandleProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ); - - - -/** - Locates the installed protocol handler for the handle, and - invokes it to obtain the protocol interface. Usage information - is registered in the protocol data base. - - @param UserHandle The handle to obtain the protocol interface on - @param Protocol The ID of the protocol - @param Interface The location to return the protocol interface - @param ImageHandle The handle of the Image that is opening the - protocol interface specified by Protocol and - Interface. - @param ControllerHandle The controller handle that is requiring this - interface. - @param Attributes The open mode of the protocol interface - specified by Handle and Protocol. - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Get the protocol interface. - -**/ -EFI_STATUS -EFIAPI -CoreOpenProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface OPTIONAL, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE ControllerHandle, - IN UINT32 Attributes - ); - - - -/** - Return information about Opened protocols in the system - - @param UserHandle The handle to close the protocol interface on - @param Protocol The ID of the protocol - @param EntryBuffer A pointer to a buffer of open protocol - information in the form of - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. - @param EntryCount Number of EntryBuffer entries - -**/ -EFI_STATUS -EFIAPI -CoreOpenProtocolInformation ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, - OUT UINTN *EntryCount - ); - - - -/** - Closes a protocol on a handle that was opened using OpenProtocol(). - - @param UserHandle The handle for the protocol interface that was - previously opened with OpenProtocol(), and is - now being closed. - @param Protocol The published unique identifier of the protocol. - It is the caller's responsibility to pass in a - valid GUID. - @param AgentHandle The handle of the agent that is closing the - protocol interface. - @param ControllerHandle If the agent that opened a protocol is a driver - that follows the EFI Driver Model, then this - parameter is the controller handle that required - the protocol interface. If the agent does not - follow the EFI Driver Model, then this parameter - is optional and may be NULL. - - @retval EFI_SUCCESS The protocol instance was closed. - @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a - valid EFI_HANDLE. - @retval EFI_NOT_FOUND Can not find the specified protocol or - AgentHandle. - -**/ -EFI_STATUS -EFIAPI -CoreCloseProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN EFI_HANDLE AgentHandle, - IN EFI_HANDLE ControllerHandle - ); - - - -/** - Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated - from pool. - - @param UserHandle The handle from which to retrieve the list of - protocol interface GUIDs. - @param ProtocolBuffer A pointer to the list of protocol interface GUID - pointers that are installed on Handle. - @param ProtocolBufferCount A pointer to the number of GUID pointers present - in ProtocolBuffer. - - @retval EFI_SUCCESS The list of protocol interface GUIDs installed - on Handle was returned in ProtocolBuffer. The - number of protocol interface GUIDs was returned - in ProtocolBufferCount. - @retval EFI_INVALID_PARAMETER Handle is NULL. - @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. - @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - results. - -**/ -EFI_STATUS -EFIAPI -CoreProtocolsPerHandle ( - IN EFI_HANDLE UserHandle, - OUT EFI_GUID ***ProtocolBuffer, - OUT UINTN *ProtocolBufferCount - ); - - - -/** - Add a new protocol notification record for the request protocol. - - @param Protocol The requested protocol to add the notify - registration - @param Event The event to signal - @param Registration Returns the registration record - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully returned the registration record - that has been added - -**/ -EFI_STATUS -EFIAPI -CoreRegisterProtocolNotify ( - IN EFI_GUID *Protocol, - IN EFI_EVENT Event, - OUT VOID **Registration - ); - - -/** - Removes all the events in the protocol database that match Event. - - @param Event The event to search for in the protocol - database. - - @return EFI_SUCCESS when done searching the entire database. - -**/ -EFI_STATUS -CoreUnregisterProtocolNotify ( - IN EFI_EVENT Event - ); - - -/** - Locates the requested handle(s) and returns them in Buffer. - - @param SearchType The type of search to perform to locate the - handles - @param Protocol The protocol to search for - @param SearchKey Dependant on SearchType - @param BufferSize On input the size of Buffer. On output the - size of data returned. - @param Buffer The buffer to return the results in - - @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is - returned in BufferSize. - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully found the requested handle(s) and - returns them in Buffer. - -**/ -EFI_STATUS -EFIAPI -CoreLocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ); - - - -/** - Locates the handle to a device on the device path that best matches the specified protocol. - - @param Protocol The protocol to search for. - @param DevicePath On input, a pointer to a pointer to the device - path. On output, the device path pointer is - modified to point to the remaining part of the - devicepath. - @param Device A pointer to the returned device handle. - - @retval EFI_SUCCESS The resulting handle was returned. - @retval EFI_NOT_FOUND No handles matched the search. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -CoreLocateDevicePath ( - IN EFI_GUID *Protocol, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device - ); - - - -/** - Function returns an array of handles that support the requested protocol - in a buffer allocated from pool. This is a version of CoreLocateHandle() - that allocates a buffer for the caller. - - @param SearchType Specifies which handle(s) are to be returned. - @param Protocol Provides the protocol to search by. This - parameter is only valid for SearchType - ByProtocol. - @param SearchKey Supplies the search key depending on the - SearchType. - @param NumberHandles The number of handles returned in Buffer. - @param Buffer A pointer to the buffer to return the requested - array of handles that support Protocol. - - @retval EFI_SUCCESS The result array of handles was returned. - @retval EFI_NOT_FOUND No handles match the search. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - matching results. - @retval EFI_INVALID_PARAMETER One or more parameters are not valid. - -**/ -EFI_STATUS -EFIAPI -CoreLocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ); - - - -/** - Return the first Protocol Interface that matches the Protocol GUID. If - Registration is passed in, return a Protocol Instance that was just add - to the system. If Registration is NULL return the first Protocol Interface - you find. - - @param Protocol The protocol to search for - @param Registration Optional Registration Key returned from - RegisterProtocolNotify() - @param Interface Return the Protocol interface (instance). - - @retval EFI_SUCCESS If a valid Interface is returned - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Protocol interface not found - -**/ -EFI_STATUS -EFIAPI -CoreLocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *Registration OPTIONAL, - OUT VOID **Interface - ); - - -/** - return handle database key. - - - @return Handle database key. - -**/ -UINT64 -CoreGetHandleDatabaseKey ( - VOID - ); - - -/** - Go connect any handles that were created or modified while a image executed. - - @param Key The Key to show that the handle has been - created/modified - -**/ -VOID -CoreConnectHandlesByKey ( - UINT64 Key - ); - - - -/** - Connects one or more drivers to a controller. - - @param ControllerHandle The handle of the controller to which driver(s) are to be connected. - @param DriverImageHandle A pointer to an ordered list handles that support the - EFI_DRIVER_BINDING_PROTOCOL. - @param RemainingDevicePath A pointer to the device path that specifies a child of the - controller specified by ControllerHandle. - @param Recursive If TRUE, then ConnectController() is called recursively - until the entire tree of controllers below the controller specified - by ControllerHandle have been created. If FALSE, then - the tree of controllers is only expanded one level. - - @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. - 2) No drivers were connected to ControllerHandle, but - RemainingDevicePath is not NULL, and it is an End Device - Path Node. - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances - present in the system. - 2) No drivers were connected to ControllerHandle. - @retval EFI_SECURITY_VIOLATION - The user has no permission to start UEFI device drivers on the device path - associated with the ControllerHandle or specified by the RemainingDevicePath. - -**/ -EFI_STATUS -EFIAPI -CoreConnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *DriverImageHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, - IN BOOLEAN Recursive - ); - - - -/** - Disonnects a controller from a driver - - @param ControllerHandle ControllerHandle The handle of - the controller from which - driver(s) are to be - disconnected. - @param DriverImageHandle DriverImageHandle The driver to - disconnect from ControllerHandle. - @param ChildHandle ChildHandle The handle of the - child to destroy. - - @retval EFI_SUCCESS One or more drivers were - disconnected from the controller. - @retval EFI_SUCCESS On entry, no drivers are managing - ControllerHandle. - @retval EFI_SUCCESS DriverImageHandle is not NULL, - and on entry DriverImageHandle is - not managing ControllerHandle. - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, - and it is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it - is not a valid EFI_HANDLE. - @retval EFI_OUT_OF_RESOURCES There are not enough resources - available to disconnect any - drivers from ControllerHandle. - @retval EFI_DEVICE_ERROR The controller could not be - disconnected because of a device - error. - -**/ -EFI_STATUS -EFIAPI -CoreDisconnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE DriverImageHandle OPTIONAL, - IN EFI_HANDLE ChildHandle OPTIONAL - ); - - - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform - @param MemoryType The type of memory to turn the allocated pages - into - @param NumberOfPages The number of pages to allocate - @param Memory A pointer to receive the base allocated memory - address - - @return Status. On success, Memory is filled in with the base address allocated - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in - spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory - ); - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed - @param NumberOfPages The number of pages to free - - @retval EFI_NOT_FOUND Could not find the entry that covers the range - @retval EFI_INVALID_PARAMETER Address not aligned - @return EFI_SUCCESS -Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - -/** - This function returns a copy of the current memory map. The map is an array of - memory descriptors, each of which describes a contiguous block of memory. - - @param MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -CoreGetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ); - - - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreInternalAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreePool ( - IN VOID *Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreInternalFreePool ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ); - -/** - Loads an EFI image into memory and returns a handle to the image. - - @param BootPolicy If TRUE, indicates that the request originates - from the boot manager, and that the boot - manager is attempting to load FilePath as a - boot selection. - @param ParentImageHandle The caller's image handle. - @param FilePath The specific file path from which the image is - loaded. - @param SourceBuffer If not NULL, a pointer to the memory location - containing a copy of the image to be loaded. - @param SourceSize The size in bytes of SourceBuffer. - @param ImageHandle Pointer to the returned image handle that is - created when the image is successfully loaded. - - @retval EFI_SUCCESS The image was loaded into memory. - @retval EFI_NOT_FOUND The FilePath was not found. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - @retval EFI_UNSUPPORTED The image type is not supported, or the device - path cannot be parsed to locate the proper - protocol for loading the file. - @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient - resources. - @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not - understood. - @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. - @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the - image from being loaded. NULL is returned in *ImageHandle. - @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a - valid EFI_LOADED_IMAGE_PROTOCOL. However, the current - platform policy specifies that the image should not be started. - -**/ -EFI_STATUS -EFIAPI -CoreLoadImage ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - OUT EFI_HANDLE *ImageHandle - ); - - - -/** - Unloads an image. - - @param ImageHandle Handle that identifies the image to be - unloaded. - - @retval EFI_SUCCESS The image has been unloaded. - @retval EFI_UNSUPPORTED The image has been started, and does not support - unload. - @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. - -**/ -EFI_STATUS -EFIAPI -CoreUnloadImage ( - IN EFI_HANDLE ImageHandle - ); - - - -/** - Transfer control to a loaded image's entry point. - - @param ImageHandle Handle of image to be started. - @param ExitDataSize Pointer of the size to ExitData - @param ExitData Pointer to a pointer to a data buffer that - includes a Null-terminated string, - optionally followed by additional binary data. - The string is a description that the caller may - use to further indicate the reason for the - image's exit. - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. - @retval EFI_SUCCESS Successfully transfer control to the image's - entry point. - -**/ -EFI_STATUS -EFIAPI -CoreStartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ); - - - -/** - Terminates the currently loaded EFI image and returns control to boot services. - - @param ImageHandle Handle that identifies the image. This - parameter is passed to the image on entry. - @param Status The image's exit code. - @param ExitDataSize The size, in bytes, of ExitData. Ignored if - ExitStatus is EFI_SUCCESS. - @param ExitData Pointer to a data buffer that includes a - Null-terminated Unicode string, optionally - followed by additional binary data. The string - is a description that the caller may use to - further indicate the reason for the image's - exit. - - @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current - image. - @retval EFI_SUCCESS Successfully terminates the currently loaded - EFI image. - @retval EFI_ACCESS_DENIED Should never reach there. - @retval EFI_OUT_OF_RESOURCES Could not allocate pool - -**/ -EFI_STATUS -EFIAPI -CoreExit ( - IN EFI_HANDLE ImageHandle, - IN EFI_STATUS Status, - IN UINTN ExitDataSize, - IN CHAR16 *ExitData OPTIONAL - ); - - - -/** - Creates an event. - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -CoreCreateEvent ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL - IN VOID *NotifyContext, OPTIONAL - OUT EFI_EVENT *Event - ); - - - -/** - Creates an event in a group. - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param EventGroup GUID for EventGroup if NULL act the same as - gBS->CreateEvent(). - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -CoreCreateEventEx ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL - IN CONST VOID *NotifyContext, OPTIONAL - IN CONST EFI_GUID *EventGroup, OPTIONAL - OUT EFI_EVENT *Event - ); - -/** - Creates a general-purpose event structure - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param EventGroup GUID for EventGroup if NULL act the same as - gBS->CreateEvent(). - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -CoreCreateEventInternal ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL - IN CONST VOID *NotifyContext, OPTIONAL - IN CONST EFI_GUID *EventGroup, OPTIONAL - OUT EFI_EVENT *Event - ); - -/** - Sets the type of timer and the trigger time for a timer event. - - @param UserEvent The timer event that is to be signaled at the - specified time - @param Type The type of time that is specified in - TriggerTime - @param TriggerTime The number of 100ns units until the timer - expires - - @retval EFI_SUCCESS The event has been set to be signaled at the - requested time - @retval EFI_INVALID_PARAMETER Event or Type is not valid - -**/ -EFI_STATUS -EFIAPI -CoreSetTimer ( - IN EFI_EVENT UserEvent, - IN EFI_TIMER_DELAY Type, - IN UINT64 TriggerTime - ); - - - -/** - Signals the event. Queues the event to be notified if needed. - - @param UserEvent The event to signal . - - @retval EFI_INVALID_PARAMETER Parameters are not valid. - @retval EFI_SUCCESS The event was signaled. - -**/ -EFI_STATUS -EFIAPI -CoreSignalEvent ( - IN EFI_EVENT UserEvent - ); - - - -/** - Stops execution until an event is signaled. - - @param NumberOfEvents The number of events in the UserEvents array - @param UserEvents An array of EFI_EVENT - @param UserIndex Pointer to the index of the event which - satisfied the wait condition - - @retval EFI_SUCCESS The event indicated by Index was signaled. - @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification - function or Event was not a valid type - @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION - -**/ -EFI_STATUS -EFIAPI -CoreWaitForEvent ( - IN UINTN NumberOfEvents, - IN EFI_EVENT *UserEvents, - OUT UINTN *UserIndex - ); - - - -/** - Closes an event and frees the event structure. - - @param UserEvent Event to close - - @retval EFI_INVALID_PARAMETER Parameters are not valid. - @retval EFI_SUCCESS The event has been closed - -**/ -EFI_STATUS -EFIAPI -CoreCloseEvent ( - IN EFI_EVENT UserEvent - ); - - - -/** - Check the status of an event. - - @param UserEvent The event to check - - @retval EFI_SUCCESS The event is in the signaled state - @retval EFI_NOT_READY The event is not in the signaled state - @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL - -**/ -EFI_STATUS -EFIAPI -CoreCheckEvent ( - IN EFI_EVENT UserEvent - ); - - -/** - Adds reserved memory, system memory, or memory-mapped I/O resources to the - global coherency domain of the processor. - - @param GcdMemoryType Memory type of the memory space. - @param BaseAddress Base address of the memory space. - @param Length Length of the memory space. - @param Capabilities alterable attributes of the memory space. - - @retval EFI_SUCCESS Merged this memory space into GCD map. - -**/ -EFI_STATUS -EFIAPI -CoreAddMemorySpace ( - IN EFI_GCD_MEMORY_TYPE GcdMemoryType, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Capabilities - ); - - -/** - Allocates nonexistent memory, reserved memory, system memory, or memorymapped - I/O resources from the global coherency domain of the processor. - - @param GcdAllocateType The type of allocate operation - @param GcdMemoryType The desired memory type - @param Alignment Align with 2^Alignment - @param Length Length to allocate - @param BaseAddress Base address to allocate - @param ImageHandle The image handle consume the allocated space. - @param DeviceHandle The device handle consume the allocated space. - - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND No descriptor contains the desired space. - @retval EFI_SUCCESS Memory space successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocateMemorySpace ( - IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType, - IN EFI_GCD_MEMORY_TYPE GcdMemoryType, - IN UINTN Alignment, - IN UINT64 Length, - IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE DeviceHandle OPTIONAL - ); - - -/** - Frees nonexistent memory, reserved memory, system memory, or memory-mapped - I/O resources from the global coherency domain of the processor. - - @param BaseAddress Base address of the memory space. - @param Length Length of the memory space. - - @retval EFI_SUCCESS Space successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreeMemorySpace ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ); - - -/** - Removes reserved memory, system memory, or memory-mapped I/O resources from - the global coherency domain of the processor. - - @param BaseAddress Base address of the memory space. - @param Length Length of the memory space. - - @retval EFI_SUCCESS Successfully remove a segment of memory space. - -**/ -EFI_STATUS -EFIAPI -CoreRemoveMemorySpace ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ); - - -/** - Retrieves the descriptor for a memory region containing a specified address. - - @param BaseAddress Specified start address - @param Descriptor Specified length - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully get memory space descriptor. - -**/ -EFI_STATUS -EFIAPI -CoreGetMemorySpaceDescriptor ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor - ); - - -/** - Modifies the attributes for a memory region in the global coherency domain of the - processor. - - @param BaseAddress Specified start address - @param Length Specified length - @param Attributes Specified attributes - - @retval EFI_SUCCESS The attributes were set for the memory region. - @retval EFI_INVALID_PARAMETER Length is zero. - @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory - resource range specified by BaseAddress and Length. - @retval EFI_UNSUPPORTED The bit mask of attributes is not support for the memory resource - range specified by BaseAddress and Length. - @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by - BaseAddress and Length cannot be modified. - @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of - the memory resource range. - @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU architectural protocol is - not available yet. - -**/ -EFI_STATUS -EFIAPI -CoreSetMemorySpaceAttributes ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes - ); - - -/** - Modifies the capabilities for a memory region in the global coherency domain of the - processor. - - @param BaseAddress The physical address that is the start address of a memory region. - @param Length The size in bytes of the memory region. - @param Capabilities The bit mask of capabilities that the memory region supports. - - @retval EFI_SUCCESS The capabilities were set for the memory region. - @retval EFI_INVALID_PARAMETER Length is zero. - @retval EFI_UNSUPPORTED The capabilities specified by Capabilities do not include the - memory region attributes currently in use. - @retval EFI_ACCESS_DENIED The capabilities for the memory resource range specified by - BaseAddress and Length cannot be modified. - @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the capabilities - of the memory resource range. -**/ -EFI_STATUS -EFIAPI -CoreSetMemorySpaceCapabilities ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Capabilities - ); - - -/** - Returns a map of the memory resources in the global coherency domain of the - processor. - - @param NumberOfDescriptors Number of descriptors. - @param MemorySpaceMap Descriptor array - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SUCCESS Successfully get memory space map. - -**/ -EFI_STATUS -EFIAPI -CoreGetMemorySpaceMap ( - OUT UINTN *NumberOfDescriptors, - OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **MemorySpaceMap - ); - - -/** - Adds reserved I/O or I/O resources to the global coherency domain of the processor. - - @param GcdIoType IO type of the segment. - @param BaseAddress Base address of the segment. - @param Length Length of the segment. - - @retval EFI_SUCCESS Merged this segment into GCD map. - @retval EFI_INVALID_PARAMETER Parameter not valid - -**/ -EFI_STATUS -EFIAPI -CoreAddIoSpace ( - IN EFI_GCD_IO_TYPE GcdIoType, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ); - - -/** - Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency - domain of the processor. - - @param GcdAllocateType The type of allocate operation - @param GcdIoType The desired IO type - @param Alignment Align with 2^Alignment - @param Length Length to allocate - @param BaseAddress Base address to allocate - @param ImageHandle The image handle consume the allocated space. - @param DeviceHandle The device handle consume the allocated space. - - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND No descriptor contains the desired space. - @retval EFI_SUCCESS IO space successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocateIoSpace ( - IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType, - IN EFI_GCD_IO_TYPE GcdIoType, - IN UINTN Alignment, - IN UINT64 Length, - IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE DeviceHandle OPTIONAL - ); - - -/** - Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency - domain of the processor. - - @param BaseAddress Base address of the segment. - @param Length Length of the segment. - - @retval EFI_SUCCESS Space successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreeIoSpace ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ); - - -/** - Removes reserved I/O or I/O resources from the global coherency domain of the - processor. - - @param BaseAddress Base address of the segment. - @param Length Length of the segment. - - @retval EFI_SUCCESS Successfully removed a segment of IO space. - -**/ -EFI_STATUS -EFIAPI -CoreRemoveIoSpace ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ); - - -/** - Retrieves the descriptor for an I/O region containing a specified address. - - @param BaseAddress Specified start address - @param Descriptor Specified length - - @retval EFI_INVALID_PARAMETER Descriptor is NULL. - @retval EFI_SUCCESS Successfully get the IO space descriptor. - -**/ -EFI_STATUS -EFIAPI -CoreGetIoSpaceDescriptor ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - OUT EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor - ); - - -/** - Returns a map of the I/O resources in the global coherency domain of the processor. - - @param NumberOfDescriptors Number of descriptors. - @param IoSpaceMap Descriptor array - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SUCCESS Successfully get IO space map. - -**/ -EFI_STATUS -EFIAPI -CoreGetIoSpaceMap ( - OUT UINTN *NumberOfDescriptors, - OUT EFI_GCD_IO_SPACE_DESCRIPTOR **IoSpaceMap - ); - - -/** - This is the main Dispatcher for DXE and it exits when there are no more - drivers to run. Drain the mScheduledQueue and load and start a PE - image for each driver. Search the mDiscoveredList to see if any driver can - be placed on the mScheduledQueue. If no drivers are placed on the - mScheduledQueue exit the function. On exit it is assumed the Bds() - will be called, and when the Bds() exits the Dispatcher will be called - again. - - @retval EFI_ALREADY_STARTED The DXE Dispatcher is already running - @retval EFI_NOT_FOUND No DXE Drivers were dispatched - @retval EFI_SUCCESS One or more DXE Drivers were dispatched - -**/ -EFI_STATUS -EFIAPI -CoreDispatcher ( - VOID - ); - -/** - Check every driver and locate a matching one. If the driver is found, the Unrequested - state flag is cleared. - - @param FirmwareVolumeHandle The handle of the Firmware Volume that contains - the firmware file specified by DriverName. - @param DriverName The Driver name to put in the Dependent state. - - @retval EFI_SUCCESS The DriverName was found and it's SOR bit was - cleared - @retval EFI_NOT_FOUND The DriverName does not exist or it's SOR bit was - not set. - -**/ -EFI_STATUS -EFIAPI -CoreSchedule ( - IN EFI_HANDLE FirmwareVolumeHandle, - IN EFI_GUID *DriverName - ); - - -/** - Convert a driver from the Untrused back to the Scheduled state. - - @param FirmwareVolumeHandle The handle of the Firmware Volume that contains - the firmware file specified by DriverName. - @param DriverName The Driver name to put in the Scheduled state - - @retval EFI_SUCCESS The file was found in the untrusted state, and it - was promoted to the trusted state. - @retval EFI_NOT_FOUND The file was not found in the untrusted state. - -**/ -EFI_STATUS -EFIAPI -CoreTrust ( - IN EFI_HANDLE FirmwareVolumeHandle, - IN EFI_GUID *DriverName - ); - - -/** - This routine is the driver initialization entry point. It initializes the - libraries, and registers two notification functions. These notification - functions are responsible for building the FV stack dynamically. - - @param ImageHandle The image handle. - @param SystemTable The system table. - - @retval EFI_SUCCESS Function successfully returned. - -**/ -EFI_STATUS -EFIAPI -FwVolDriverInit ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - - -/** - Entry point of the section extraction code. Initializes an instance of the - section extraction interface and installs it on a new handle. - - @param ImageHandle A handle for the image that is initializing this driver - @param SystemTable A pointer to the EFI system table - - @retval EFI_SUCCESS Driver initialized successfully - @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources - -**/ -EFI_STATUS -EFIAPI -InitializeSectionExtraction ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - - -/** - This DXE service routine is used to process a firmware volume. In - particular, it can be called by BDS to process a single firmware - volume found in a capsule. - - @param FvHeader pointer to a firmware volume header - @param Size the size of the buffer pointed to by FvHeader - @param FVProtocolHandle the handle on which a firmware volume protocol - was produced for the firmware volume passed in. - - @retval EFI_OUT_OF_RESOURCES if an FVB could not be produced due to lack of - system resources - @retval EFI_VOLUME_CORRUPTED if the volume was corrupted - @retval EFI_SUCCESS a firmware volume protocol was produced for the - firmware volume - -**/ -EFI_STATUS -EFIAPI -CoreProcessFirmwareVolume ( - IN VOID *FvHeader, - IN UINTN Size, - OUT EFI_HANDLE *FVProtocolHandle - ); - -// -//Functions used during debug buils -// - -/** - Displays Architectural protocols that were not loaded and are required for DXE - core to function. Only used in Debug Builds. - -**/ -VOID -CoreDisplayMissingArchProtocols ( - VOID - ); - - -/** - Traverse the discovered list for any drivers that were discovered but not loaded - because the dependency experessions evaluated to false. - -**/ -VOID -CoreDisplayDiscoveredNotDispatched ( - VOID - ); - - -/** - Place holder function until all the Boot Services and Runtime Services are - available. - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg0 ( - VOID - ); - - -/** - Place holder function until all the Boot Services and Runtime Services are - available. - - @param Arg1 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg1 ( - UINTN Arg1 - ); - - -/** - Place holder function until all the Boot Services and Runtime Services are available. - - @param Arg1 Undefined - @param Arg2 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg2 ( - UINTN Arg1, - UINTN Arg2 - ); - - -/** - Place holder function until all the Boot Services and Runtime Services are available. - - @param Arg1 Undefined - @param Arg2 Undefined - @param Arg3 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg3 ( - UINTN Arg1, - UINTN Arg2, - UINTN Arg3 - ); - - -/** - Place holder function until all the Boot Services and Runtime Services are available. - - @param Arg1 Undefined - @param Arg2 Undefined - @param Arg3 Undefined - @param Arg4 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg4 ( - UINTN Arg1, - UINTN Arg2, - UINTN Arg3, - UINTN Arg4 - ); - - -/** - Place holder function until all the Boot Services and Runtime Services are available. - - @param Arg1 Undefined - @param Arg2 Undefined - @param Arg3 Undefined - @param Arg4 Undefined - @param Arg5 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg5 ( - UINTN Arg1, - UINTN Arg2, - UINTN Arg3, - UINTN Arg4, - UINTN Arg5 - ); - - -/** - Given a compressed source buffer, this function retrieves the size of the - uncompressed buffer and the size of the scratch buffer required to decompress - the compressed source buffer. - - The GetInfo() function retrieves the size of the uncompressed buffer and the - temporary scratch buffer required to decompress the buffer specified by Source - and SourceSize. If the size of the uncompressed buffer or the size of the - scratch buffer cannot be determined from the compressed data specified by - Source and SourceData, then EFI_INVALID_PARAMETER is returned. Otherwise, the - size of the uncompressed buffer is returned in DestinationSize, the size of - the scratch buffer is returned in ScratchSize, and EFI_SUCCESS is returned. - The GetInfo() function does not have scratch buffer available to perform a - thorough checking of the validity of the source data. It just retrieves the - "Original Size" field from the beginning bytes of the source data and output - it as DestinationSize. And ScratchSize is specific to the decompression - implementation. - - @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance. - @param Source The source buffer containing the compressed data. - @param SourceSize The size, in bytes, of the source buffer. - @param DestinationSize A pointer to the size, in bytes, of the - uncompressed buffer that will be generated when the - compressed buffer specified by Source and - SourceSize is decompressed. - @param ScratchSize A pointer to the size, in bytes, of the scratch - buffer that is required to decompress the - compressed buffer specified by Source and - SourceSize. - - @retval EFI_SUCCESS The size of the uncompressed data was returned in - DestinationSize and the size of the scratch buffer - was returned in ScratchSize. - @retval EFI_INVALID_PARAMETER The size of the uncompressed data or the size of - the scratch buffer cannot be determined from the - compressed data specified by Source and - SourceSize. - -**/ -EFI_STATUS -EFIAPI -DxeMainUefiDecompressGetInfo ( - IN EFI_DECOMPRESS_PROTOCOL *This, - IN VOID *Source, - IN UINT32 SourceSize, - OUT UINT32 *DestinationSize, - OUT UINT32 *ScratchSize - ); - - -/** - Decompresses a compressed source buffer. - - The Decompress() function extracts decompressed data to its original form. - This protocol is designed so that the decompression algorithm can be - implemented without using any memory services. As a result, the Decompress() - Function is not allowed to call AllocatePool() or AllocatePages() in its - implementation. It is the caller's responsibility to allocate and free the - Destination and Scratch buffers. - If the compressed source data specified by Source and SourceSize is - sucessfully decompressed into Destination, then EFI_SUCCESS is returned. If - the compressed source data specified by Source and SourceSize is not in a - valid compressed data format, then EFI_INVALID_PARAMETER is returned. - - @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance. - @param Source The source buffer containing the compressed data. - @param SourceSize SourceSizeThe size of source data. - @param Destination On output, the destination buffer that contains - the uncompressed data. - @param DestinationSize The size of the destination buffer. The size of - the destination buffer needed is obtained from - EFI_DECOMPRESS_PROTOCOL.GetInfo(). - @param Scratch A temporary scratch buffer that is used to perform - the decompression. - @param ScratchSize The size of scratch buffer. The size of the - scratch buffer needed is obtained from GetInfo(). - - @retval EFI_SUCCESS Decompression completed successfully, and the - uncompressed buffer is returned in Destination. - @retval EFI_INVALID_PARAMETER The source buffer specified by Source and - SourceSize is corrupted (not in a valid - compressed format). - -**/ -EFI_STATUS -EFIAPI -DxeMainUefiDecompress ( - IN EFI_DECOMPRESS_PROTOCOL *This, - IN VOID *Source, - IN UINT32 SourceSize, - IN OUT VOID *Destination, - IN UINT32 DestinationSize, - IN OUT VOID *Scratch, - IN UINT32 ScratchSize - ); - -/** - SEP member function. This function creates and returns a new section stream - handle to represent the new section stream. - - @param SectionStreamLength Size in bytes of the section stream. - @param SectionStream Buffer containing the new section stream. - @param SectionStreamHandle A pointer to a caller allocated UINTN that on - output contains the new section stream handle. - - @retval EFI_SUCCESS The section stream is created successfully. - @retval EFI_OUT_OF_RESOURCES memory allocation failed. - @retval EFI_INVALID_PARAMETER Section stream does not end concident with end - of last section. - -**/ -EFI_STATUS -EFIAPI -OpenSectionStream ( - IN UINTN SectionStreamLength, - IN VOID *SectionStream, - OUT UINTN *SectionStreamHandle - ); - - - -/** - SEP member function. Retrieves requested section from section stream. - - @param SectionStreamHandle The section stream from which to extract the - requested section. - @param SectionType A pointer to the type of section to search for. - @param SectionDefinitionGuid If the section type is EFI_SECTION_GUID_DEFINED, - then SectionDefinitionGuid indicates which of - these types of sections to search for. - @param SectionInstance Indicates which instance of the requested - section to return. - @param Buffer Double indirection to buffer. If *Buffer is - non-null on input, then the buffer is caller - allocated. If Buffer is NULL, then the buffer - is callee allocated. In either case, the - required buffer size is returned in *BufferSize. - @param BufferSize On input, indicates the size of *Buffer if - *Buffer is non-null on input. On output, - indicates the required size (allocated size if - callee allocated) of *Buffer. - @param AuthenticationStatus A pointer to a caller-allocated UINT32 that - indicates the authentication status of the - output buffer. If the input section's - GuidedSectionHeader.Attributes field - has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID - bit as clear, AuthenticationStatus must return - zero. Both local bits (19:16) and aggregate - bits (3:0) in AuthenticationStatus are returned - by ExtractSection(). These bits reflect the - status of the extraction operation. The bit - pattern in both regions must be the same, as - the local and aggregate authentication statuses - have equivalent meaning at this level. If the - function returns anything other than - EFI_SUCCESS, the value of *AuthenticationStatus - is undefined. - @param IsFfs3Fv Indicates the FV format. - - @retval EFI_SUCCESS Section was retrieved successfully - @retval EFI_PROTOCOL_ERROR A GUID defined section was encountered in the - section stream with its - EFI_GUIDED_SECTION_PROCESSING_REQUIRED bit set, - but there was no corresponding GUIDed Section - Extraction Protocol in the handle database. - *Buffer is unmodified. - @retval EFI_NOT_FOUND An error was encountered when parsing the - SectionStream. This indicates the SectionStream - is not correctly formatted. - @retval EFI_NOT_FOUND The requested section does not exist. - @retval EFI_OUT_OF_RESOURCES The system has insufficient resources to process - the request. - @retval EFI_INVALID_PARAMETER The SectionStreamHandle does not exist. - @retval EFI_WARN_TOO_SMALL The size of the caller allocated input buffer is - insufficient to contain the requested section. - The input buffer is filled and section contents - are truncated. - -**/ -EFI_STATUS -EFIAPI -GetSection ( - IN UINTN SectionStreamHandle, - IN EFI_SECTION_TYPE *SectionType, - IN EFI_GUID *SectionDefinitionGuid, - IN UINTN SectionInstance, - IN VOID **Buffer, - IN OUT UINTN *BufferSize, - OUT UINT32 *AuthenticationStatus, - IN BOOLEAN IsFfs3Fv - ); - - -/** - SEP member function. Deletes an existing section stream - - @param StreamHandleToClose Indicates the stream to close - @param FreeStreamBuffer TRUE - Need to free stream buffer; - FALSE - No need to free stream buffer. - - @retval EFI_SUCCESS The section stream is closed sucessfully. - @retval EFI_OUT_OF_RESOURCES Memory allocation failed. - @retval EFI_INVALID_PARAMETER Section stream does not end concident with end - of last section. - -**/ -EFI_STATUS -EFIAPI -CloseSectionStream ( - IN UINTN StreamHandleToClose, - IN BOOLEAN FreeStreamBuffer - ); - -/** - Creates and initializes the DebugImageInfo Table. Also creates the configuration - table and registers it into the system table. - - Note: - This function allocates memory, frees it, and then allocates memory at an - address within the initial allocation. Since this function is called early - in DXE core initialization (before drivers are dispatched), this should not - be a problem. - -**/ -VOID -CoreInitializeDebugImageInfoTable ( - VOID - ); - - -/** - Update the CRC32 in the Debug Table. - Since the CRC32 service is made available by the Runtime driver, we have to - wait for the Runtime Driver to be installed before the CRC32 can be computed. - This function is called elsewhere by the core when the runtime architectural - protocol is produced. - -**/ -VOID -CoreUpdateDebugTableCrc32 ( - VOID - ); - - -/** - Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates - the table if it's not large enough to accomidate another entry. - - @param ImageInfoType type of debug image information - @param LoadedImage pointer to the loaded image protocol for the image being - loaded - @param ImageHandle image handle for the image being loaded - -**/ -VOID -CoreNewDebugImageInfoEntry ( - IN UINT32 ImageInfoType, - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_HANDLE ImageHandle - ); - - -/** - Removes and frees an entry from the DebugImageInfo Table. - - @param ImageHandle image handle for the image being unloaded - -**/ -VOID -CoreRemoveDebugImageInfoEntry ( - EFI_HANDLE ImageHandle - ); - - -/** - This routine consumes FV hobs and produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate. - - @param ImageHandle The image handle. - @param SystemTable The system table. - - @retval EFI_SUCCESS Successfully initialized firmware volume block - driver. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockDriverInit ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -/** - - Get FVB authentication status - - @param FvbProtocol FVB protocol. - - @return Authentication status. - -**/ -UINT32 -GetFvbAuthenticationStatus ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol - ); - -/** - This routine produces a firmware volume block protocol on a given - buffer. - - @param BaseAddress base address of the firmware volume image - @param Length length of the firmware volume image - @param ParentHandle handle of parent firmware volume, if this image - came from an FV image file and section in another firmware - volume (ala capsules) - @param AuthenticationStatus Authentication status inherited, if this image - came from an FV image file and section in another firmware volume. - @param FvProtocol Firmware volume block protocol produced. - - @retval EFI_VOLUME_CORRUPTED Volume corrupted. - @retval EFI_OUT_OF_RESOURCES No enough buffer to be allocated. - @retval EFI_SUCCESS Successfully produced a FVB protocol on given - buffer. - -**/ -EFI_STATUS -ProduceFVBProtocolOnBuffer ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN EFI_HANDLE ParentHandle, - IN UINT32 AuthenticationStatus, - OUT EFI_HANDLE *FvProtocol OPTIONAL - ); - - -/** - Raising to the task priority level of the mutual exclusion - lock, and then acquires ownership of the lock. - - @param Lock The lock to acquire - - @return Lock owned - -**/ -VOID -CoreAcquireLock ( - IN EFI_LOCK *Lock - ); - - -/** - Initialize a basic mutual exclusion lock. Each lock - provides mutual exclusion access at it's task priority - level. Since there is no-premption (at any TPL) or - multiprocessor support, acquiring the lock only consists - of raising to the locks TPL. - - @param Lock The EFI_LOCK structure to initialize - - @retval EFI_SUCCESS Lock Owned. - @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. - -**/ -EFI_STATUS -CoreAcquireLockOrFail ( - IN EFI_LOCK *Lock - ); - - -/** - Releases ownership of the mutual exclusion lock, and - restores the previous task priority level. - - @param Lock The lock to release - - @return Lock unowned - -**/ -VOID -CoreReleaseLock ( - IN EFI_LOCK *Lock - ); - -/** - Read data from Firmware Block by FVB protocol Read. - The data may cross the multi block ranges. - - @param Fvb The FW_VOL_BLOCK_PROTOCOL instance from which to read data. - @param StartLba Pointer to StartLba. - On input, the start logical block index from which to read. - On output,the end logical block index after reading. - @param Offset Pointer to Offset - On input, offset into the block at which to begin reading. - On output, offset into the end block after reading. - @param DataSize Size of data to be read. - @param Data Pointer to Buffer that the data will be read into. - - @retval EFI_SUCCESS Successfully read data from firmware block. - @retval others -**/ -EFI_STATUS -ReadFvbData ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb, - IN OUT EFI_LBA *StartLba, - IN OUT UINTN *Offset, - IN UINTN DataSize, - OUT UINT8 *Data - ); - -/** - Given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and - copy the real length volume header into it. - - @param Fvb The FW_VOL_BLOCK_PROTOCOL instance from which to - read the volume header - @param FwVolHeader Pointer to pointer to allocated buffer in which - the volume header is returned. - - @retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated. - @retval EFI_SUCCESS Successfully read volume header to the allocated - buffer. - @retval EFI_INVALID_PARAMETER The FV Header signature is not as expected or - the file system could not be understood. - -**/ -EFI_STATUS -GetFwVolHeader ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb, - OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader - ); - -/** - Verify checksum of the firmware volume header. - - @param FvHeader Points to the firmware volume header to be checked - - @retval TRUE Checksum verification passed - @retval FALSE Checksum verification failed - -**/ -BOOLEAN -VerifyFvHeaderChecksum ( - IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader - ); - -/** - Initialize memory profile. - - @param HobStart The start address of the HOB. - -**/ -VOID -MemoryProfileInit ( - IN VOID *HobStart - ); - -/** - Install memory profile protocol. - -**/ -VOID -MemoryProfileInstallProtocol ( - VOID - ); - -/** - Register image to memory profile. - - @param DriverEntry Image info. - @param FileType Image file type. - - @return EFI_SUCCESS Register successfully. - @return EFI_UNSUPPORTED Memory profile unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCES No enough resource for this register. - -**/ -EFI_STATUS -RegisterMemoryProfileImage ( - IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry, - IN EFI_FV_FILETYPE FileType - ); - -/** - Unregister image from memory profile. - - @param DriverEntry Image info. - - @return EFI_SUCCESS Unregister successfully. - @return EFI_UNSUPPORTED Memory profile unsupported, - or memory profile for the image is not required. - @return EFI_NOT_FOUND The image is not found. - -**/ -EFI_STATUS -UnregisterMemoryProfileImage ( - IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry - ); - -/** - Update memory profile information. - - @param CallerAddress Address of caller who call Allocate or Free. - @param Action This Allocate or Free action. - @param MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param Size Buffer size. - @param Buffer Buffer address. - @param ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -CoreUpdateProfile ( - IN EFI_PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ); - -/** - Internal function. Converts a memory range to use new attributes. - - @param Start The first address of the range Must be page - aligned - @param NumberOfPages The number of pages to convert - @param NewAttributes The new attributes value for the range. - -**/ -VOID -CoreUpdateMemoryAttributes ( - IN EFI_PHYSICAL_ADDRESS Start, - IN UINT64 NumberOfPages, - IN UINT64 NewAttributes - ); - -/** - Initialize PropertiesTable support. -**/ -VOID -EFIAPI -CoreInitializePropertiesTable ( - VOID - ); - -/** - Initialize MemoryAttrubutesTable support. -**/ -VOID -EFIAPI -CoreInitializeMemoryAttributesTable ( - VOID - ); - -/** - Initialize Memory Protection support. -**/ -VOID -EFIAPI -CoreInitializeMemoryProtection ( - VOID - ); - -/** - Install MemoryAttributesTable on memory allocation. - - @param[in] MemoryType EFI memory type. -**/ -VOID -InstallMemoryAttributesTableOnMemoryAllocation ( - IN EFI_MEMORY_TYPE MemoryType - ); - -/** - Insert image record. - - @param RuntimeImage Runtime image information -**/ -VOID -InsertImageRecord ( - IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage - ); - -/** - Remove Image record. - - @param RuntimeImage Runtime image information -**/ -VOID -RemoveImageRecord ( - IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage - ); - -/** - Protect UEFI image. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol -**/ -VOID -ProtectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath - ); - -/** - Unprotect UEFI image. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol -**/ -VOID -UnprotectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath - ); - -/** - ExitBootServices Callback function for memory protection. -**/ -VOID -MemoryProtectionExitBootServicesCallback ( - VOID - ); - -/** - Manage memory permission attributes on a memory range, according to the - configured DXE memory protection policy. - - @param OldType The old memory type of the range - @param NewType The new memory type of the range - @param Memory The base address of the range - @param Length The size of the range (in bytes) - - @return EFI_SUCCESS If the the CPU arch protocol is not installed yet - @return EFI_SUCCESS If no DXE memory protection policy has been configured - @return EFI_SUCCESS If OldType and NewType use the same permission attributes - @return other Return value of gCpu->SetMemoryAttributes() - -**/ -EFI_STATUS -EFIAPI -ApplyMemoryProtectionPolicy ( - IN EFI_MEMORY_TYPE OldType, - IN EFI_MEMORY_TYPE NewType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINT64 Length - ); - -#endif diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf deleted file mode 100644 index 30d5984f7c..0000000000 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ /dev/null @@ -1,208 +0,0 @@ -## @file -# This is core module in DXE phase. -# -# It provides an implementation of DXE Core that is compliant with DXE CIS. -# -# Copyright (c) 2006 - 2017, 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 -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = DxeCore - MODULE_UNI_FILE = DxeCore.uni - FILE_GUID = D6A2CB7F-6A18-4e2f-B43B-9920A733700A - MODULE_TYPE = DXE_CORE - VERSION_STRING = 1.0 - - - ENTRY_POINT = DxeMain - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only) -# - -[Sources] - DxeMain.h - SectionExtraction/CoreSectionExtraction.c - Image/Image.c - Image/Image.h - Misc/DebugImageInfo.c - Misc/Stall.c - Misc/SetWatchdogTimer.c - Misc/InstallConfigurationTable.c - Misc/PropertiesTable.c - Misc/MemoryAttributesTable.c - Misc/MemoryProtection.c - Library/Library.c - Hand/DriverSupport.c - Hand/Notify.c - Hand/Locate.c - Hand/Handle.c - Hand/Handle.h - Gcd/Gcd.c - Gcd/Gcd.h - Mem/Pool.c - Mem/Page.c - Mem/MemData.c - Mem/Imem.h - Mem/MemoryProfileRecord.c - FwVolBlock/FwVolBlock.c - FwVolBlock/FwVolBlock.h - FwVol/FwVolWrite.c - FwVol/FwVolRead.c - FwVol/FwVolAttrib.c - FwVol/Ffs.c - FwVol/FwVol.c - FwVol/FwVolDriver.h - Event/Tpl.c - Event/Timer.c - Event/Event.c - Event/Event.h - Dispatcher/Dependency.c - Dispatcher/Dispatcher.c - DxeMain/DxeProtocolNotify.c - DxeMain/DxeMain.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - BaseMemoryLib - CacheMaintenanceLib - UefiDecompressLib - PerformanceLib - HobLib - BaseLib - UefiLib - DebugLib - DxeCoreEntryPoint - PeCoffLib - PeCoffGetEntryPointLib - PeCoffExtraActionLib - ExtractGuidedSectionLib - MemoryAllocationLib - UefiBootServicesTableLib - DevicePathLib - ReportStatusCodeLib - TimerLib - DxeServicesLib - DebugAgentLib - CpuExceptionHandlerLib - PcdLib - -[Guids] - gEfiEventMemoryMapChangeGuid ## PRODUCES ## Event - gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event - ## CONSUMES ## Event - ## PRODUCES ## Event - gEfiEventExitBootServicesGuid - gEfiHobMemoryAllocModuleGuid ## CONSUMES ## HOB - gEfiFirmwareFileSystem2Guid ## CONSUMES ## GUID # Used to compare with FV's file system guid and get the FV's file system format - gEfiFirmwareFileSystem3Guid ## CONSUMES ## GUID # Used to compare with FV's file system guid and get the FV's file system format - gAprioriGuid ## SOMETIMES_CONSUMES ## File - gEfiDebugImageInfoTableGuid ## PRODUCES ## SystemTable - gEfiHobListGuid ## PRODUCES ## SystemTable - gEfiDxeServicesTableGuid ## PRODUCES ## SystemTable - ## PRODUCES ## SystemTable - ## SOMETIMES_CONSUMES ## HOB - gEfiMemoryTypeInformationGuid - gEfiEventDxeDispatchGuid ## PRODUCES ## Event - gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_PRODUCES ## SystemTable - ## PRODUCES ## Event - ## CONSUMES ## Event - gIdleLoopEventGuid - gEventExitBootServicesFailedGuid ## SOMETIMES_PRODUCES ## Event - gEfiVectorHandoffTableGuid ## SOMETIMES_PRODUCES ## SystemTable - gEdkiiMemoryProfileGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol - gEfiPropertiesTableGuid ## SOMETIMES_PRODUCES ## SystemTable - gEfiMemoryAttributesTableGuid ## SOMETIMES_PRODUCES ## SystemTable - gEfiEndOfDxeEventGroupGuid ## SOMETIMES_CONSUMES ## Event - -[Ppis] - gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB - -[Protocols] - ## PRODUCES - ## SOMETIMES_CONSUMES - gEfiDecompressProtocolGuid - gEfiLoadPeImageProtocolGuid ## SOMETIMES_PRODUCES # Produces when PcdFrameworkCompatibilitySupport is set - gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadFileProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadFile2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiBusSpecificDriverOverrideProtocolGuid ## SOMETIMES_CONSUMES - gEfiDriverFamilyOverrideProtocolGuid ## SOMETIMES_CONSUMES - gEfiPlatformDriverOverrideProtocolGuid ## SOMETIMES_CONSUMES - gEfiDriverBindingProtocolGuid ## SOMETIMES_CONSUMES - ## PRODUCES - ## CONSUMES - ## NOTIFY - gEfiFirmwareVolumeBlockProtocolGuid - ## PRODUCES - ## CONSUMES - ## NOTIFY - gEfiFirmwareVolume2ProtocolGuid - ## PRODUCES - ## CONSUMES - gEfiDevicePathProtocolGuid - gEfiLoadedImageProtocolGuid ## PRODUCES - gEfiLoadedImageDevicePathProtocolGuid ## PRODUCES - gEfiHiiPackageListProtocolGuid ## SOMETIMES_PRODUCES - gEfiEbcProtocolGuid ## SOMETIMES_CONSUMES - gEfiSmmBase2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES - - # Arch Protocols - gEfiBdsArchProtocolGuid ## CONSUMES - gEfiCpuArchProtocolGuid ## CONSUMES - gEfiMetronomeArchProtocolGuid ## CONSUMES - gEfiMonotonicCounterArchProtocolGuid ## CONSUMES - gEfiRealTimeClockArchProtocolGuid ## CONSUMES - gEfiResetArchProtocolGuid ## CONSUMES - gEfiRuntimeArchProtocolGuid ## CONSUMES - gEfiSecurityArchProtocolGuid ## CONSUMES - gEfiSecurity2ArchProtocolGuid ## SOMETIMES_CONSUMES - gEfiTimerArchProtocolGuid ## CONSUMES - gEfiVariableWriteArchProtocolGuid ## CONSUMES - gEfiVariableArchProtocolGuid ## CONSUMES - gEfiCapsuleArchProtocolGuid ## CONSUMES - gEfiWatchdogTimerArchProtocolGuid ## CONSUMES - -[FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressRuntimeCodePageNumber ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdMaxEfiSystemTablePointerAddress ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy ## CONSUMES - -# [Hob] -# RESOURCE_DESCRIPTOR ## CONSUMES -# MEMORY_ALLOCATION ## CONSUMES -# FIRMWARE_VOLUME ## CONSUMES -# UNDEFINED ## CONSUMES # CPU -# -# [Event] -# EVENT_TYPE_RELATIVE_TIMER ## PRODUCES # DxeCore signals timer event. -# EVENT_TYPE_PERIODIC_TIMER ## PRODUCES # DxeCore signals timer event. -# - -[UserExtensions.TianoCore."ExtraFiles"] - DxeCoreExtra.uni diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c deleted file mode 100644 index 91e94a78d2..0000000000 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c +++ /dev/null @@ -1,938 +0,0 @@ -/** @file - DXE Core Main Entry Point - -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - -// -// DXE Core Global Variables for Protocols from PEI -// -EFI_HANDLE mDecompressHandle = NULL; - -// -// DXE Core globals for Architecture Protocols -// -EFI_SECURITY_ARCH_PROTOCOL *gSecurity = NULL; -EFI_SECURITY2_ARCH_PROTOCOL *gSecurity2 = NULL; -EFI_CPU_ARCH_PROTOCOL *gCpu = NULL; -EFI_METRONOME_ARCH_PROTOCOL *gMetronome = NULL; -EFI_TIMER_ARCH_PROTOCOL *gTimer = NULL; -EFI_BDS_ARCH_PROTOCOL *gBds = NULL; -EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer = NULL; - -// -// DXE Core globals for optional protocol dependencies -// -EFI_SMM_BASE2_PROTOCOL *gSmmBase2 = NULL; - -// -// DXE Core Global used to update core loaded image protocol handle -// -EFI_GUID *gDxeCoreFileName; -EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage; - -// -// DXE Core Module Variables -// -EFI_BOOT_SERVICES mBootServices = { - { - EFI_BOOT_SERVICES_SIGNATURE, // Signature - EFI_BOOT_SERVICES_REVISION, // Revision - sizeof (EFI_BOOT_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - (EFI_RAISE_TPL) CoreRaiseTpl, // RaiseTPL - (EFI_RESTORE_TPL) CoreRestoreTpl, // RestoreTPL - (EFI_ALLOCATE_PAGES) CoreAllocatePages, // AllocatePages - (EFI_FREE_PAGES) CoreFreePages, // FreePages - (EFI_GET_MEMORY_MAP) CoreGetMemoryMap, // GetMemoryMap - (EFI_ALLOCATE_POOL) CoreAllocatePool, // AllocatePool - (EFI_FREE_POOL) CoreFreePool, // FreePool - (EFI_CREATE_EVENT) CoreCreateEvent, // CreateEvent - (EFI_SET_TIMER) CoreSetTimer, // SetTimer - (EFI_WAIT_FOR_EVENT) CoreWaitForEvent, // WaitForEvent - (EFI_SIGNAL_EVENT) CoreSignalEvent, // SignalEvent - (EFI_CLOSE_EVENT) CoreCloseEvent, // CloseEvent - (EFI_CHECK_EVENT) CoreCheckEvent, // CheckEvent - (EFI_INSTALL_PROTOCOL_INTERFACE) CoreInstallProtocolInterface, // InstallProtocolInterface - (EFI_REINSTALL_PROTOCOL_INTERFACE) CoreReinstallProtocolInterface, // ReinstallProtocolInterface - (EFI_UNINSTALL_PROTOCOL_INTERFACE) CoreUninstallProtocolInterface, // UninstallProtocolInterface - (EFI_HANDLE_PROTOCOL) CoreHandleProtocol, // HandleProtocol - (VOID *) NULL, // Reserved - (EFI_REGISTER_PROTOCOL_NOTIFY) CoreRegisterProtocolNotify, // RegisterProtocolNotify - (EFI_LOCATE_HANDLE) CoreLocateHandle, // LocateHandle - (EFI_LOCATE_DEVICE_PATH) CoreLocateDevicePath, // LocateDevicePath - (EFI_INSTALL_CONFIGURATION_TABLE) CoreInstallConfigurationTable, // InstallConfigurationTable - (EFI_IMAGE_LOAD) CoreLoadImage, // LoadImage - (EFI_IMAGE_START) CoreStartImage, // StartImage - (EFI_EXIT) CoreExit, // Exit - (EFI_IMAGE_UNLOAD) CoreUnloadImage, // UnloadImage - (EFI_EXIT_BOOT_SERVICES) CoreExitBootServices, // ExitBootServices - (EFI_GET_NEXT_MONOTONIC_COUNT) CoreEfiNotAvailableYetArg1, // GetNextMonotonicCount - (EFI_STALL) CoreStall, // Stall - (EFI_SET_WATCHDOG_TIMER) CoreSetWatchdogTimer, // SetWatchdogTimer - (EFI_CONNECT_CONTROLLER) CoreConnectController, // ConnectController - (EFI_DISCONNECT_CONTROLLER) CoreDisconnectController, // DisconnectController - (EFI_OPEN_PROTOCOL) CoreOpenProtocol, // OpenProtocol - (EFI_CLOSE_PROTOCOL) CoreCloseProtocol, // CloseProtocol - (EFI_OPEN_PROTOCOL_INFORMATION) CoreOpenProtocolInformation, // OpenProtocolInformation - (EFI_PROTOCOLS_PER_HANDLE) CoreProtocolsPerHandle, // ProtocolsPerHandle - (EFI_LOCATE_HANDLE_BUFFER) CoreLocateHandleBuffer, // LocateHandleBuffer - (EFI_LOCATE_PROTOCOL) CoreLocateProtocol, // LocateProtocol - (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces - (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces - (EFI_CALCULATE_CRC32) CoreEfiNotAvailableYetArg3, // CalculateCrc32 - (EFI_COPY_MEM) CopyMem, // CopyMem - (EFI_SET_MEM) SetMem, // SetMem - (EFI_CREATE_EVENT_EX) CoreCreateEventEx // CreateEventEx -}; - -EFI_DXE_SERVICES mDxeServices = { - { - DXE_SERVICES_SIGNATURE, // Signature - DXE_SERVICES_REVISION, // Revision - sizeof (DXE_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - (EFI_ADD_MEMORY_SPACE) CoreAddMemorySpace, // AddMemorySpace - (EFI_ALLOCATE_MEMORY_SPACE) CoreAllocateMemorySpace, // AllocateMemorySpace - (EFI_FREE_MEMORY_SPACE) CoreFreeMemorySpace, // FreeMemorySpace - (EFI_REMOVE_MEMORY_SPACE) CoreRemoveMemorySpace, // RemoveMemorySpace - (EFI_GET_MEMORY_SPACE_DESCRIPTOR) CoreGetMemorySpaceDescriptor, // GetMemorySpaceDescriptor - (EFI_SET_MEMORY_SPACE_ATTRIBUTES) CoreSetMemorySpaceAttributes, // SetMemorySpaceAttributes - (EFI_GET_MEMORY_SPACE_MAP) CoreGetMemorySpaceMap, // GetMemorySpaceMap - (EFI_ADD_IO_SPACE) CoreAddIoSpace, // AddIoSpace - (EFI_ALLOCATE_IO_SPACE) CoreAllocateIoSpace, // AllocateIoSpace - (EFI_FREE_IO_SPACE) CoreFreeIoSpace, // FreeIoSpace - (EFI_REMOVE_IO_SPACE) CoreRemoveIoSpace, // RemoveIoSpace - (EFI_GET_IO_SPACE_DESCRIPTOR) CoreGetIoSpaceDescriptor, // GetIoSpaceDescriptor - (EFI_GET_IO_SPACE_MAP) CoreGetIoSpaceMap, // GetIoSpaceMap - (EFI_DISPATCH) CoreDispatcher, // Dispatch - (EFI_SCHEDULE) CoreSchedule, // Schedule - (EFI_TRUST) CoreTrust, // Trust - (EFI_PROCESS_FIRMWARE_VOLUME) CoreProcessFirmwareVolume, // ProcessFirmwareVolume - (EFI_SET_MEMORY_SPACE_CAPABILITIES)CoreSetMemorySpaceCapabilities, // SetMemorySpaceCapabilities -}; - -EFI_SYSTEM_TABLE mEfiSystemTableTemplate = { - { - EFI_SYSTEM_TABLE_SIGNATURE, // Signature - EFI_SYSTEM_TABLE_REVISION, // Revision - sizeof (EFI_SYSTEM_TABLE), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - NULL, // FirmwareVendor - 0, // FirmwareRevision - NULL, // ConsoleInHandle - NULL, // ConIn - NULL, // ConsoleOutHandle - NULL, // ConOut - NULL, // StandardErrorHandle - NULL, // StdErr - NULL, // RuntimeServices - &mBootServices, // BootServices - 0, // NumberOfConfigurationTableEntries - NULL // ConfigurationTable -}; - -EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = { - { - EFI_RUNTIME_SERVICES_SIGNATURE, // Signature - EFI_RUNTIME_SERVICES_REVISION, // Revision - sizeof (EFI_RUNTIME_SERVICES), // HeaderSize - 0, // CRC32 - 0 // Reserved - }, - (EFI_GET_TIME) CoreEfiNotAvailableYetArg2, // GetTime - (EFI_SET_TIME) CoreEfiNotAvailableYetArg1, // SetTime - (EFI_GET_WAKEUP_TIME) CoreEfiNotAvailableYetArg3, // GetWakeupTime - (EFI_SET_WAKEUP_TIME) CoreEfiNotAvailableYetArg2, // SetWakeupTime - (EFI_SET_VIRTUAL_ADDRESS_MAP) CoreEfiNotAvailableYetArg4, // SetVirtualAddressMap - (EFI_CONVERT_POINTER) CoreEfiNotAvailableYetArg2, // ConvertPointer - (EFI_GET_VARIABLE) CoreEfiNotAvailableYetArg5, // GetVariable - (EFI_GET_NEXT_VARIABLE_NAME) CoreEfiNotAvailableYetArg3, // GetNextVariableName - (EFI_SET_VARIABLE) CoreEfiNotAvailableYetArg5, // SetVariable - (EFI_GET_NEXT_HIGH_MONO_COUNT) CoreEfiNotAvailableYetArg1, // GetNextHighMonotonicCount - (EFI_RESET_SYSTEM) CoreEfiNotAvailableYetArg4, // ResetSystem - (EFI_UPDATE_CAPSULE) CoreEfiNotAvailableYetArg3, // UpdateCapsule - (EFI_QUERY_CAPSULE_CAPABILITIES) CoreEfiNotAvailableYetArg4, // QueryCapsuleCapabilities - (EFI_QUERY_VARIABLE_INFO) CoreEfiNotAvailableYetArg4 // QueryVariableInfo -}; - -EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate = { - INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.ImageHead), - INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.EventHead), - - // - // Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will - // prevent people from having pointer math bugs in their code. - // now you have to use *DescriptorSize to make things work. - // - sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)), - EFI_MEMORY_DESCRIPTOR_VERSION, - 0, - NULL, - NULL, - FALSE, - FALSE -}; - -EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = &gRuntimeTemplate; - -// -// DXE Core Global Variables for the EFI System Table, Boot Services Table, -// DXE Services Table, and Runtime Services Table -// -EFI_DXE_SERVICES *gDxeCoreDS = &mDxeServices; -EFI_SYSTEM_TABLE *gDxeCoreST = NULL; - -// -// For debug initialize gDxeCoreRT to template. gDxeCoreRT must be allocated from RT memory -// but gDxeCoreRT is used for ASSERT () and DEBUG () type macros so lets give it -// a value that will not cause debug infrastructure to crash early on. -// -EFI_RUNTIME_SERVICES *gDxeCoreRT = &mEfiRuntimeServicesTableTemplate; -EFI_HANDLE gDxeCoreImageHandle = NULL; - -BOOLEAN gMemoryMapTerminated = FALSE; - -// -// EFI Decompress Protocol -// -EFI_DECOMPRESS_PROTOCOL gEfiDecompress = { - DxeMainUefiDecompressGetInfo, - DxeMainUefiDecompress -}; - -// -// For Loading modules at fixed address feature, the configuration table is to cache the top address below which to load -// Runtime code&boot time code -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE gLoadModuleAtFixAddressConfigurationTable = {0, 0}; - -// Main entry point to the DXE Core -// - -/** - Main entry point to DXE Core. - - @param HobStart Pointer to the beginning of the HOB List from PEI. - - @return This function should never return. - -**/ -VOID -EFIAPI -DxeMain ( - IN VOID *HobStart - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS MemoryBaseAddress; - UINT64 MemoryLength; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Index; - EFI_HOB_GUID_TYPE *GuidHob; - EFI_VECTOR_HANDOFF_INFO *VectorInfoList; - EFI_VECTOR_HANDOFF_INFO *VectorInfo; - VOID *EntryPoint; - - // - // Setup the default exception handlers - // - VectorInfoList = NULL; - GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart); - if (GuidHob != NULL) { - VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob)); - } - Status = InitializeCpuExceptionHandlers (VectorInfoList); - ASSERT_EFI_ERROR (Status); - - // - // Initialize Debug Agent to support source level debug in DXE phase - // - InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_CORE, HobStart, NULL); - - // - // Initialize Memory Services - // - CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength); - - MemoryProfileInit (HobStart); - - // - // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData - // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table - // - gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate); - ASSERT (gDxeCoreST != NULL); - - gDxeCoreRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate); - ASSERT (gDxeCoreRT != NULL); - - gDxeCoreST->RuntimeServices = gDxeCoreRT; - - // - // Start the Image Services. - // - Status = CoreInitializeImageServices (HobStart); - ASSERT_EFI_ERROR (Status); - - // - // Initialize the Global Coherency Domain Services - // - Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength); - ASSERT_EFI_ERROR (Status); - - // - // Call constructor for all libraries - // - ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST); - PERF_END (NULL,"PEI", NULL, 0) ; - PERF_START (NULL,"DXE", NULL, 0) ; - - // - // Report DXE Core image information to the PE/COFF Extra Action Library - // - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreLoadedImage->ImageBase; - ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*)(UINTN)ImageContext.ImageAddress); - ImageContext.SizeOfHeaders = PeCoffGetSizeOfHeaders ((VOID*)(UINTN)ImageContext.ImageAddress); - Status = PeCoffLoaderGetEntryPoint ((VOID*)(UINTN)ImageContext.ImageAddress, &EntryPoint); - if (Status == EFI_SUCCESS) { - ImageContext.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint; - } - ImageContext.Handle = (VOID *)(UINTN)gDxeCoreLoadedImage->ImageBase; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - PeCoffLoaderRelocateImageExtraAction (&ImageContext); - - // - // Install the DXE Services Table into the EFI System Tables's Configuration Table - // - Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS); - ASSERT_EFI_ERROR (Status); - - // - // Install the HOB List into the EFI System Tables's Configuration Table - // - Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart); - ASSERT_EFI_ERROR (Status); - - // - // Install Memory Type Information Table into the EFI System Tables's Configuration Table - // - Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation); - ASSERT_EFI_ERROR (Status); - - // - // If Loading modules At fixed address feature is enabled, install Load moduels at fixed address - // Configuration Table so that user could easily to retrieve the top address to load Dxe and PEI - // Code and Tseg base to load SMM driver. - // - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { - Status = CoreInstallConfigurationTable (&gLoadFixedAddressConfigurationTableGuid, &gLoadModuleAtFixAddressConfigurationTable); - ASSERT_EFI_ERROR (Status); - } - // - // Report Status Code here for DXE_ENTRY_POINT once it is available - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT) - ); - - // - // Create the aligned system table pointer structure that is used by external - // debuggers to locate the system table... Also, install debug image info - // configuration table. - // - CoreInitializeDebugImageInfoTable (); - CoreNewDebugImageInfoEntry ( - EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, - gDxeCoreLoadedImage, - gDxeCoreImageHandle - ); - - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%p\n", HobStart)); - - DEBUG_CODE_BEGIN (); - EFI_PEI_HOB_POINTERS Hob; - - for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) { - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Memory Allocation 0x%08x 0x%0lx - 0x%0lx\n", \ - Hob.MemoryAllocation->AllocDescriptor.MemoryType, \ - Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress, \ - Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + Hob.MemoryAllocation->AllocDescriptor.MemoryLength - 1)); - } - } - for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) { - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV2 Hob 0x%0lx - 0x%0lx\n", Hob.FirmwareVolume2->BaseAddress, Hob.FirmwareVolume2->BaseAddress + Hob.FirmwareVolume2->Length - 1)); - } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) { - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV Hob 0x%0lx - 0x%0lx\n", Hob.FirmwareVolume->BaseAddress, Hob.FirmwareVolume->BaseAddress + Hob.FirmwareVolume->Length - 1)); - } - } - DEBUG_CODE_END (); - - // - // Initialize the Event Services - // - Status = CoreInitializeEventServices (); - ASSERT_EFI_ERROR (Status); - - MemoryProfileInstallProtocol (); - - CoreInitializePropertiesTable (); - CoreInitializeMemoryAttributesTable (); - CoreInitializeMemoryProtection (); - - // - // Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated, - // and install configuration table - // - GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart); - if (GuidHob != NULL) { - VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob)); - VectorInfo = VectorInfoList; - Index = 1; - while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) { - VectorInfo ++; - Index ++; - } - VectorInfo = AllocateCopyPool (sizeof (EFI_VECTOR_HANDOFF_INFO) * Index, (VOID *) VectorInfoList); - ASSERT (VectorInfo != NULL); - Status = CoreInstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) VectorInfo); - ASSERT_EFI_ERROR (Status); - } - - // - // Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs - // - // These Protocols are not architectural. This implementation is sharing code between - // PEI and DXE in order to save FLASH space. These Protocols could also be implemented - // as part of the DXE Core. However, that would also require the DXE Core to be ported - // each time a different CPU is used, a different Decompression algorithm is used, or a - // different Image type is used. By placing these Protocols in PEI, the DXE Core remains - // generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform, - // and from CPU to CPU. - // - - // - // Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components - // - Status = CoreInstallMultipleProtocolInterfaces ( - &mDecompressHandle, - &gEfiDecompressProtocolGuid, &gEfiDecompress, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Register for the GUIDs of the Architectural Protocols, so the rest of the - // EFI Boot Services and EFI Runtime Services tables can be filled in. - // Also register for the GUIDs of optional protocols. - // - CoreNotifyOnProtocolInstallation (); - - // - // Produce Firmware Volume Protocols, one for each FV in the HOB list. - // - Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST); - ASSERT_EFI_ERROR (Status); - - Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST); - ASSERT_EFI_ERROR (Status); - - // - // Produce the Section Extraction Protocol - // - Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST); - ASSERT_EFI_ERROR (Status); - - // - // Initialize the DXE Dispatcher - // - PERF_START (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ; - CoreInitializeDispatcher (); - PERF_END (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ; - - // - // Invoke the DXE Dispatcher - // - PERF_START (NULL, "CoreDispatcher", "DxeMain", 0); - CoreDispatcher (); - PERF_END (NULL, "CoreDispatcher", "DxeMain", 0); - - // - // Display Architectural protocols that were not loaded if this is DEBUG build - // - DEBUG_CODE_BEGIN (); - CoreDisplayMissingArchProtocols (); - DEBUG_CODE_END (); - - // - // Display any drivers that were not dispatched because dependency expression - // evaluated to false if this is a debug build - // - DEBUG_CODE_BEGIN (); - CoreDisplayDiscoveredNotDispatched (); - DEBUG_CODE_END (); - - // - // Assert if the Architectural Protocols are not present. - // - Status = CoreAllEfiServicesAvailable (); - if (EFI_ERROR(Status)) { - // - // Report Status code that some Architectural Protocols are not present. - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MAJOR, - (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH) - ); - } - ASSERT_EFI_ERROR (Status); - - // - // Report Status code before transfer control to BDS - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT) - ); - - // - // Transfer control to the BDS Architectural Protocol - // - gBds->Entry (gBds); - - // - // BDS should never return - // - ASSERT (FALSE); - CpuDeadLoop (); - - UNREACHABLE (); -} - - - -/** - Place holder function until all the Boot Services and Runtime Services are - available. - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg0 ( - VOID - ) -{ - // - // This function should never be executed. If it does, then the architectural protocols - // have not been designed correctly. The CpuBreakpoint () is commented out for now until the - // DXE Core and all the Architectural Protocols are complete. - // - - return EFI_NOT_AVAILABLE_YET; -} - - -/** - Place holder function until all the Boot Services and Runtime Services are - available. - - @param Arg1 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg1 ( - UINTN Arg1 - ) -{ - // - // This function should never be executed. If it does, then the architectural protocols - // have not been designed correctly. The CpuBreakpoint () is commented out for now until the - // DXE Core and all the Architectural Protocols are complete. - // - - return EFI_NOT_AVAILABLE_YET; -} - - -/** - Place holder function until all the Boot Services and Runtime Services are available. - - @param Arg1 Undefined - @param Arg2 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg2 ( - UINTN Arg1, - UINTN Arg2 - ) -{ - // - // This function should never be executed. If it does, then the architectural protocols - // have not been designed correctly. The CpuBreakpoint () is commented out for now until the - // DXE Core and all the Architectural Protocols are complete. - // - - return EFI_NOT_AVAILABLE_YET; -} - - -/** - Place holder function until all the Boot Services and Runtime Services are available. - - @param Arg1 Undefined - @param Arg2 Undefined - @param Arg3 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg3 ( - UINTN Arg1, - UINTN Arg2, - UINTN Arg3 - ) -{ - // - // This function should never be executed. If it does, then the architectural protocols - // have not been designed correctly. The CpuBreakpoint () is commented out for now until the - // DXE Core and all the Architectural Protocols are complete. - // - - return EFI_NOT_AVAILABLE_YET; -} - - -/** - Place holder function until all the Boot Services and Runtime Services are available. - - @param Arg1 Undefined - @param Arg2 Undefined - @param Arg3 Undefined - @param Arg4 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg4 ( - UINTN Arg1, - UINTN Arg2, - UINTN Arg3, - UINTN Arg4 - ) -{ - // - // This function should never be executed. If it does, then the architectural protocols - // have not been designed correctly. The CpuBreakpoint () is commented out for now until the - // DXE Core and all the Architectural Protocols are complete. - // - - return EFI_NOT_AVAILABLE_YET; -} - - -/** - Place holder function until all the Boot Services and Runtime Services are available. - - @param Arg1 Undefined - @param Arg2 Undefined - @param Arg3 Undefined - @param Arg4 Undefined - @param Arg5 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -CoreEfiNotAvailableYetArg5 ( - UINTN Arg1, - UINTN Arg2, - UINTN Arg3, - UINTN Arg4, - UINTN Arg5 - ) -{ - // - // This function should never be executed. If it does, then the architectural protocols - // have not been designed correctly. The CpuBreakpoint () is commented out for now until the - // DXE Core and all the Architectural Protocols are complete. - // - - return EFI_NOT_AVAILABLE_YET; -} - - -/** - Calcualte the 32-bit CRC in a EFI table using the service provided by the - gRuntime service. - - @param Hdr Pointer to an EFI standard header - -**/ -VOID -CalculateEfiHdrCrc ( - IN OUT EFI_TABLE_HEADER *Hdr - ) -{ - UINT32 Crc; - - Hdr->CRC32 = 0; - - // - // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then - // Crc will come back as zero if we set it to zero here - // - Crc = 0; - gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc); - Hdr->CRC32 = Crc; -} - - -/** - Terminates all boot services. - - @param ImageHandle Handle that identifies the exiting image. - @param MapKey Key to the latest memory map. - - @retval EFI_SUCCESS Boot Services terminated - @retval EFI_INVALID_PARAMETER MapKey is incorrect. - -**/ -EFI_STATUS -EFIAPI -CoreExitBootServices ( - IN EFI_HANDLE ImageHandle, - IN UINTN MapKey - ) -{ - EFI_STATUS Status; - - // - // Disable Timer - // - gTimer->SetTimerPeriod (gTimer, 0); - - // - // Terminate memory services if the MapKey matches - // - Status = CoreTerminateMemoryMap (MapKey); - if (EFI_ERROR (Status)) { - // - // Notify other drivers that ExitBootServices fail - // - CoreNotifySignalList (&gEventExitBootServicesFailedGuid); - return Status; - } - - gMemoryMapTerminated = TRUE; - - // - // Notify other drivers that we are exiting boot services. - // - CoreNotifySignalList (&gEfiEventExitBootServicesGuid); - - // - // Report that ExitBootServices() has been called - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES) - ); - - // - // Disable interrupt of Debug timer. - // - SaveAndSetDebugTimerInterrupt (FALSE); - - // - // Disable CPU Interrupts - // - gCpu->DisableInterrupt (gCpu); - - MemoryProtectionExitBootServicesCallback(); - - // - // Clear the non-runtime values of the EFI System Table - // - gDxeCoreST->BootServices = NULL; - gDxeCoreST->ConIn = NULL; - gDxeCoreST->ConsoleInHandle = NULL; - gDxeCoreST->ConOut = NULL; - gDxeCoreST->ConsoleOutHandle = NULL; - gDxeCoreST->StdErr = NULL; - gDxeCoreST->StandardErrorHandle = NULL; - - // - // Recompute the 32-bit CRC of the EFI System Table - // - CalculateEfiHdrCrc (&gDxeCoreST->Hdr); - - // - // Zero out the Boot Service Table - // - ZeroMem (gBS, sizeof (EFI_BOOT_SERVICES)); - gBS = NULL; - - // - // Update the AtRuntime field in Runtiem AP. - // - gRuntime->AtRuntime = TRUE; - - return Status; -} - - -/** - Given a compressed source buffer, this function retrieves the size of the - uncompressed buffer and the size of the scratch buffer required to decompress - the compressed source buffer. - - The GetInfo() function retrieves the size of the uncompressed buffer and the - temporary scratch buffer required to decompress the buffer specified by Source - and SourceSize. If the size of the uncompressed buffer or the size of the - scratch buffer cannot be determined from the compressed data specified by - Source and SourceData, then EFI_INVALID_PARAMETER is returned. Otherwise, the - size of the uncompressed buffer is returned in DestinationSize, the size of - the scratch buffer is returned in ScratchSize, and EFI_SUCCESS is returned. - The GetInfo() function does not have scratch buffer available to perform a - thorough checking of the validity of the source data. It just retrieves the - "Original Size" field from the beginning bytes of the source data and output - it as DestinationSize. And ScratchSize is specific to the decompression - implementation. - - @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance. - @param Source The source buffer containing the compressed data. - @param SourceSize The size, in bytes, of the source buffer. - @param DestinationSize A pointer to the size, in bytes, of the - uncompressed buffer that will be generated when the - compressed buffer specified by Source and - SourceSize is decompressed. - @param ScratchSize A pointer to the size, in bytes, of the scratch - buffer that is required to decompress the - compressed buffer specified by Source and - SourceSize. - - @retval EFI_SUCCESS The size of the uncompressed data was returned in - DestinationSize and the size of the scratch buffer - was returned in ScratchSize. - @retval EFI_INVALID_PARAMETER The size of the uncompressed data or the size of - the scratch buffer cannot be determined from the - compressed data specified by Source and - SourceSize. - -**/ -EFI_STATUS -EFIAPI -DxeMainUefiDecompressGetInfo ( - IN EFI_DECOMPRESS_PROTOCOL *This, - IN VOID *Source, - IN UINT32 SourceSize, - OUT UINT32 *DestinationSize, - OUT UINT32 *ScratchSize - ) -{ - if (Source == NULL || DestinationSize == NULL || ScratchSize == NULL) { - return EFI_INVALID_PARAMETER; - } - return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize); -} - - -/** - Decompresses a compressed source buffer. - - The Decompress() function extracts decompressed data to its original form. - This protocol is designed so that the decompression algorithm can be - implemented without using any memory services. As a result, the Decompress() - Function is not allowed to call AllocatePool() or AllocatePages() in its - implementation. It is the caller's responsibility to allocate and free the - Destination and Scratch buffers. - If the compressed source data specified by Source and SourceSize is - successfully decompressed into Destination, then EFI_SUCCESS is returned. If - the compressed source data specified by Source and SourceSize is not in a - valid compressed data format, then EFI_INVALID_PARAMETER is returned. - - @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance. - @param Source The source buffer containing the compressed data. - @param SourceSize SourceSizeThe size of source data. - @param Destination On output, the destination buffer that contains - the uncompressed data. - @param DestinationSize The size of the destination buffer. The size of - the destination buffer needed is obtained from - EFI_DECOMPRESS_PROTOCOL.GetInfo(). - @param Scratch A temporary scratch buffer that is used to perform - the decompression. - @param ScratchSize The size of scratch buffer. The size of the - scratch buffer needed is obtained from GetInfo(). - - @retval EFI_SUCCESS Decompression completed successfully, and the - uncompressed buffer is returned in Destination. - @retval EFI_INVALID_PARAMETER The source buffer specified by Source and - SourceSize is corrupted (not in a valid - compressed format). - -**/ -EFI_STATUS -EFIAPI -DxeMainUefiDecompress ( - IN EFI_DECOMPRESS_PROTOCOL *This, - IN VOID *Source, - IN UINT32 SourceSize, - IN OUT VOID *Destination, - IN UINT32 DestinationSize, - IN OUT VOID *Scratch, - IN UINT32 ScratchSize - ) -{ - EFI_STATUS Status; - UINT32 TestDestinationSize; - UINT32 TestScratchSize; - - if (Source == NULL || Destination== NULL || Scratch == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = UefiDecompressGetInfo (Source, SourceSize, &TestDestinationSize, &TestScratchSize); - if (EFI_ERROR (Status)) { - return Status; - } - - if (ScratchSize < TestScratchSize || DestinationSize < TestDestinationSize) { - return RETURN_INVALID_PARAMETER; - } - - return UefiDecompress (Source, Destination, Scratch); -} diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c deleted file mode 100644 index ea7c6107b4..0000000000 --- a/MdeModulePkg/Core/Dxe/DxeMain/DxeProtocolNotify.c +++ /dev/null @@ -1,285 +0,0 @@ -/** @file - This file deals with Architecture Protocol (AP) registration in - the Dxe Core. The mArchProtocols[] array represents a list of - events that represent the Architectural Protocols. - -Copyright (c) 2006 - 2014, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - -// -// DXE Core Global Variables for all of the Architectural Protocols. -// If a protocol is installed mArchProtocols[].Present will be TRUE. -// -// CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event -// and mArchProtocols[].Registration as it creates events for every array -// entry. -// -EFI_CORE_PROTOCOL_NOTIFY_ENTRY mArchProtocols[] = { - { &gEfiSecurityArchProtocolGuid, (VOID **)&gSecurity, NULL, NULL, FALSE }, - { &gEfiCpuArchProtocolGuid, (VOID **)&gCpu, NULL, NULL, FALSE }, - { &gEfiMetronomeArchProtocolGuid, (VOID **)&gMetronome, NULL, NULL, FALSE }, - { &gEfiTimerArchProtocolGuid, (VOID **)&gTimer, NULL, NULL, FALSE }, - { &gEfiBdsArchProtocolGuid, (VOID **)&gBds, NULL, NULL, FALSE }, - { &gEfiWatchdogTimerArchProtocolGuid, (VOID **)&gWatchdogTimer, NULL, NULL, FALSE }, - { &gEfiRuntimeArchProtocolGuid, (VOID **)&gRuntime, NULL, NULL, FALSE }, - { &gEfiVariableArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE }, - { &gEfiVariableWriteArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE }, - { &gEfiCapsuleArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE }, - { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE }, - { &gEfiResetArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE }, - { &gEfiRealTimeClockArchProtocolGuid, (VOID **)NULL, NULL, NULL, FALSE }, - { NULL, (VOID **)NULL, NULL, NULL, FALSE } -}; - -// -// Optional protocols that the DXE Core will use if they are present -// -EFI_CORE_PROTOCOL_NOTIFY_ENTRY mOptionalProtocols[] = { - { &gEfiSecurity2ArchProtocolGuid, (VOID **)&gSecurity2, NULL, NULL, FALSE }, - { &gEfiSmmBase2ProtocolGuid, (VOID **)&gSmmBase2, NULL, NULL, FALSE }, - { NULL, (VOID **)NULL, NULL, NULL, FALSE } -}; - -// -// Following is needed to display missing architectural protocols in debug builds -// -typedef struct { - EFI_GUID *ProtocolGuid; - CHAR8 *GuidString; -} GUID_TO_STRING_PROTOCOL_ENTRY; - -GLOBAL_REMOVE_IF_UNREFERENCED CONST GUID_TO_STRING_PROTOCOL_ENTRY mMissingProtocols[] = { - { &gEfiSecurityArchProtocolGuid, "Security" }, - { &gEfiCpuArchProtocolGuid, "CPU" }, - { &gEfiMetronomeArchProtocolGuid, "Metronome" }, - { &gEfiTimerArchProtocolGuid, "Timer" }, - { &gEfiBdsArchProtocolGuid, "Bds" }, - { &gEfiWatchdogTimerArchProtocolGuid, "Watchdog Timer" }, - { &gEfiRuntimeArchProtocolGuid, "Runtime" }, - { &gEfiVariableArchProtocolGuid, "Variable" }, - { &gEfiVariableWriteArchProtocolGuid, "Variable Write" }, - { &gEfiCapsuleArchProtocolGuid, "Capsule" }, - { &gEfiMonotonicCounterArchProtocolGuid, "Monotonic Counter" }, - { &gEfiResetArchProtocolGuid, "Reset" }, - { &gEfiRealTimeClockArchProtocolGuid, "Real Time Clock" }, - { NULL, "" } -}; - -/** - Return TRUE if all AP services are available. - - @retval EFI_SUCCESS All AP services are available - @retval EFI_NOT_FOUND At least one AP service is not available - -**/ -EFI_STATUS -CoreAllEfiServicesAvailable ( - VOID - ) -{ - EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry; - - for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) { - if (!Entry->Present) { - return EFI_NOT_FOUND; - } - } - return EFI_SUCCESS; -} - - -/** - Notification event handler registered by CoreNotifyOnArchProtocolInstallation (). - This notify function is registered for every architectural protocol. This handler - updates mArchProtocol[] array entry with protocol instance data and sets it's - present flag to TRUE. If any constructor is required it is executed. The EFI - System Table headers are updated. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -GenericProtocolNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry; - VOID *Protocol; - LIST_ENTRY *Link; - LIST_ENTRY TempLinkNode; - - Protocol = NULL; - - // - // Get Entry from Context - // - Entry = (EFI_CORE_PROTOCOL_NOTIFY_ENTRY *)Context; - - // - // See if the expected protocol is present in the handle database - // - Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol); - if (EFI_ERROR (Status)) { - return; - } - - // - // Mark the protocol as present - // - Entry->Present = TRUE; - - // - // Update protocol global variable if one exists. Entry->Protocol points to a global variable - // if one exists in the DXE core for this Architectural Protocol - // - if (Entry->Protocol != NULL) { - *(Entry->Protocol) = Protocol; - } - - // - // Do special operations for Architectural Protocols - // - - if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) { - // - // Register the Core timer tick handler with the Timer AP - // - gTimer->RegisterHandler (gTimer, CoreTimerTick); - } - - if (CompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) { - // - // When runtime architectural protocol is available, updates CRC32 in the Debug Table - // - CoreUpdateDebugTableCrc32 (); - - // - // Update the Runtime Architectural protocol with the template that the core was - // using so there would not need to be a dependency on the Runtime AP - // - - // - // Copy all the registered Image to new gRuntime protocol - // - for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) { - CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY)); - InsertTailList (&gRuntime->ImageHead, Link); - } - // - // Copy all the registered Event to new gRuntime protocol - // - for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) { - CopyMem (&TempLinkNode, Link, sizeof(LIST_ENTRY)); - InsertTailList (&gRuntime->EventHead, Link); - } - - // - // Clean up gRuntimeTemplate - // - gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead; - gRuntimeTemplate.ImageHead.BackLink = &gRuntimeTemplate.ImageHead; - gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead; - gRuntimeTemplate.EventHead.BackLink = &gRuntimeTemplate.EventHead; - } - - // - // It's over kill to do them all every time, but it saves a lot of code. - // - CalculateEfiHdrCrc (&gDxeCoreRT->Hdr); - CalculateEfiHdrCrc (&gBS->Hdr); - CalculateEfiHdrCrc (&gDxeCoreST->Hdr); - CalculateEfiHdrCrc (&gDxeCoreDS->Hdr); -} - -/** - Creates an event for each entry in a table that is fired everytime a Protocol - of a specific type is installed. - - @param Entry Pointer to EFI_CORE_PROTOCOL_NOTIFY_ENTRY. - -**/ -VOID -CoreNotifyOnProtocolEntryTable ( - EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry - ) -{ - EFI_STATUS Status; - - for (; Entry->ProtocolGuid != NULL; Entry++) { - // - // Create the event - // - Status = CoreCreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - GenericProtocolNotify, - Entry, - &Entry->Event - ); - ASSERT_EFI_ERROR(Status); - - // - // Register for protocol notifactions on this event - // - Status = CoreRegisterProtocolNotify ( - Entry->ProtocolGuid, - Entry->Event, - &Entry->Registration - ); - ASSERT_EFI_ERROR(Status); - } -} - -/** - Creates an events for the Architectural Protocols and the optional protocols - that are fired everytime a Protocol of a specific type is installed. - -**/ -VOID -CoreNotifyOnProtocolInstallation ( - VOID - ) -{ - CoreNotifyOnProtocolEntryTable (mArchProtocols); - CoreNotifyOnProtocolEntryTable (mOptionalProtocols); -} - - -/** - Displays Architectural protocols that were not loaded and are required for DXE - core to function. Only used in Debug Builds. - -**/ -VOID -CoreDisplayMissingArchProtocols ( - VOID - ) -{ - EFI_CORE_PROTOCOL_NOTIFY_ENTRY *Entry; - CONST GUID_TO_STRING_PROTOCOL_ENTRY *MissingEntry; - - for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) { - if (!Entry->Present) { - for (MissingEntry = mMissingProtocols; MissingEntry->ProtocolGuid != NULL; MissingEntry++) { - if (CompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) { - DEBUG ((DEBUG_ERROR, "\n%a Arch Protocol not present!!\n", MissingEntry->GuidString)); - break; - } - } - } - } -} diff --git a/MdeModulePkg/Core/Dxe/Event/Event.c b/MdeModulePkg/Core/Dxe/Event/Event.c deleted file mode 100644 index 86ca369d56..0000000000 --- a/MdeModulePkg/Core/Dxe/Event/Event.c +++ /dev/null @@ -1,782 +0,0 @@ -/** @file - UEFI Event support functions implemented in this file. - -Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
-(C) Copyright 2015 Hewlett Packard Enterprise Development LP
-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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "DxeMain.h" -#include "Event.h" - -/// -/// gEfiCurrentTpl - Current Task priority level -/// -EFI_TPL gEfiCurrentTpl = TPL_APPLICATION; - -/// -/// gEventQueueLock - Protects the event queues -/// -EFI_LOCK gEventQueueLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL); - -/// -/// gEventQueue - A list of event's to notify for each priority level -/// -LIST_ENTRY gEventQueue[TPL_HIGH_LEVEL + 1]; - -/// -/// gEventPending - A bitmask of the EventQueues that are pending -/// -UINTN gEventPending = 0; - -/// -/// gEventSignalQueue - A list of events to signal based on EventGroup type -/// -LIST_ENTRY gEventSignalQueue = INITIALIZE_LIST_HEAD_VARIABLE (gEventSignalQueue); - -/// -/// Enumerate the valid types -/// -UINT32 mEventTable[] = { - /// - /// 0x80000200 Timer event with a notification function that is - /// queue when the event is signaled with SignalEvent() - /// - EVT_TIMER | EVT_NOTIFY_SIGNAL, - /// - /// 0x80000000 Timer event without a notification function. It can be - /// signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent(). - /// - EVT_TIMER, - /// - /// 0x00000100 Generic event with a notification function that - /// can be waited on with CheckEvent() or WaitForEvent() - /// - EVT_NOTIFY_WAIT, - /// - /// 0x00000200 Generic event with a notification function that - /// is queue when the event is signaled with SignalEvent() - /// - EVT_NOTIFY_SIGNAL, - /// - /// 0x00000201 ExitBootServicesEvent. - /// - EVT_SIGNAL_EXIT_BOOT_SERVICES, - /// - /// 0x60000202 SetVirtualAddressMapEvent. - /// - EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, - - /// - /// 0x00000000 Generic event without a notification function. - /// It can be signaled with SignalEvent() and checked with CheckEvent() - /// or WaitForEvent(). - /// - 0x00000000, - /// - /// 0x80000100 Timer event with a notification function that can be - /// waited on with CheckEvent() or WaitForEvent() - /// - EVT_TIMER | EVT_NOTIFY_WAIT, -}; - -/// -/// gIdleLoopEvent - Event which is signalled when the core is idle -/// -EFI_EVENT gIdleLoopEvent = NULL; - - -/** - Enter critical section by acquiring the lock on gEventQueueLock. - -**/ -VOID -CoreAcquireEventLock ( - VOID - ) -{ - CoreAcquireLock (&gEventQueueLock); -} - - -/** - Exit critical section by releasing the lock on gEventQueueLock. - -**/ -VOID -CoreReleaseEventLock ( - VOID - ) -{ - CoreReleaseLock (&gEventQueueLock); -} - - - -/** - Initializes "event" support. - - @retval EFI_SUCCESS Always return success - -**/ -EFI_STATUS -CoreInitializeEventServices ( - VOID - ) -{ - UINTN Index; - - for (Index=0; Index <= TPL_HIGH_LEVEL; Index++) { - InitializeListHead (&gEventQueue[Index]); - } - - CoreInitializeTimer (); - - CoreCreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - EfiEventEmptyFunction, - NULL, - &gIdleLoopEventGuid, - &gIdleLoopEvent - ); - - return EFI_SUCCESS; -} - - - -/** - Dispatches all pending events. - - @param Priority The task priority level of event notifications - to dispatch - -**/ -VOID -CoreDispatchEventNotifies ( - IN EFI_TPL Priority - ) -{ - IEVENT *Event; - LIST_ENTRY *Head; - - CoreAcquireEventLock (); - ASSERT (gEventQueueLock.OwnerTpl == Priority); - Head = &gEventQueue[Priority]; - - // - // Dispatch all the pending notifications - // - while (!IsListEmpty (Head)) { - - Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE); - RemoveEntryList (&Event->NotifyLink); - - Event->NotifyLink.ForwardLink = NULL; - - // - // Only clear the SIGNAL status if it is a SIGNAL type event. - // WAIT type events are only cleared in CheckEvent() - // - if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) { - Event->SignalCount = 0; - } - - CoreReleaseEventLock (); - - // - // Notify this event - // - ASSERT (Event->NotifyFunction != NULL); - Event->NotifyFunction (Event, Event->NotifyContext); - - // - // Check for next pending event - // - CoreAcquireEventLock (); - } - - gEventPending &= ~(UINTN)(1 << Priority); - CoreReleaseEventLock (); -} - - - -/** - Queues the event's notification function to fire. - - @param Event The Event to notify - -**/ -VOID -CoreNotifyEvent ( - IN IEVENT *Event - ) -{ - - // - // Event database must be locked - // - ASSERT_LOCKED (&gEventQueueLock); - - // - // If the event is queued somewhere, remove it - // - - if (Event->NotifyLink.ForwardLink != NULL) { - RemoveEntryList (&Event->NotifyLink); - Event->NotifyLink.ForwardLink = NULL; - } - - // - // Queue the event to the pending notification list - // - - InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink); - gEventPending |= (UINTN)(1 << Event->NotifyTpl); -} - - - - -/** - Signals all events in the EventGroup. - - @param EventGroup The list to signal - -**/ -VOID -CoreNotifySignalList ( - IN EFI_GUID *EventGroup - ) -{ - LIST_ENTRY *Link; - LIST_ENTRY *Head; - IEVENT *Event; - - CoreAcquireEventLock (); - - Head = &gEventSignalQueue; - for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) { - Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE); - if (CompareGuid (&Event->EventGroup, EventGroup)) { - CoreNotifyEvent (Event); - } - } - - CoreReleaseEventLock (); -} - - -/** - Creates an event. - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -CoreCreateEvent ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL - IN VOID *NotifyContext, OPTIONAL - OUT EFI_EVENT *Event - ) -{ - return CoreCreateEventEx (Type, NotifyTpl, NotifyFunction, NotifyContext, NULL, Event); -} - - - -/** - Creates an event in a group. - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param EventGroup GUID for EventGroup if NULL act the same as - gBS->CreateEvent(). - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -CoreCreateEventEx ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL - IN CONST VOID *NotifyContext, OPTIONAL - IN CONST EFI_GUID *EventGroup, OPTIONAL - OUT EFI_EVENT *Event - ) -{ - // - // If it's a notify type of event, check for invalid NotifyTpl - // - if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) != 0) { - if (NotifyTpl != TPL_APPLICATION && - NotifyTpl != TPL_CALLBACK && - NotifyTpl != TPL_NOTIFY) { - return EFI_INVALID_PARAMETER; - } - } - - return CoreCreateEventInternal (Type, NotifyTpl, NotifyFunction, NotifyContext, EventGroup, Event); -} - -/** - Creates a general-purpose event structure - - @param Type The type of event to create and its mode and - attributes - @param NotifyTpl The task priority level of event notifications - @param NotifyFunction Pointer to the events notification function - @param NotifyContext Pointer to the notification functions context; - corresponds to parameter "Context" in the - notification function - @param EventGroup GUID for EventGroup if NULL act the same as - gBS->CreateEvent(). - @param Event Pointer to the newly created event if the call - succeeds; undefined otherwise - - @retval EFI_SUCCESS The event structure was created - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - @retval EFI_OUT_OF_RESOURCES The event could not be allocated - -**/ -EFI_STATUS -EFIAPI -CoreCreateEventInternal ( - IN UINT32 Type, - IN EFI_TPL NotifyTpl, - IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL - IN CONST VOID *NotifyContext, OPTIONAL - IN CONST EFI_GUID *EventGroup, OPTIONAL - OUT EFI_EVENT *Event - ) -{ - EFI_STATUS Status; - IEVENT *IEvent; - INTN Index; - - - if (Event == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check to make sure no reserved flags are set - // - Status = EFI_INVALID_PARAMETER; - for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) { - if (Type == mEventTable[Index]) { - Status = EFI_SUCCESS; - break; - } - } - if(EFI_ERROR (Status)) { - return EFI_INVALID_PARAMETER; - } - - // - // Convert Event type for pre-defined Event groups - // - if (EventGroup != NULL) { - // - // For event group, type EVT_SIGNAL_EXIT_BOOT_SERVICES and EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE - // are not valid - // - if ((Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) || (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE)) { - return EFI_INVALID_PARAMETER; - } - if (CompareGuid (EventGroup, &gEfiEventExitBootServicesGuid)) { - Type = EVT_SIGNAL_EXIT_BOOT_SERVICES; - } else if (CompareGuid (EventGroup, &gEfiEventVirtualAddressChangeGuid)) { - Type = EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE; - } - } else { - // - // Convert EFI 1.10 Events to their UEFI 2.0 CreateEventEx mapping - // - if (Type == EVT_SIGNAL_EXIT_BOOT_SERVICES) { - EventGroup = &gEfiEventExitBootServicesGuid; - } else if (Type == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) { - EventGroup = &gEfiEventVirtualAddressChangeGuid; - } - } - - // - // If it's a notify type of event, check its parameters - // - if ((Type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) != 0) { - // - // Check for an invalid NotifyFunction or NotifyTpl - // - if ((NotifyFunction == NULL) || - (NotifyTpl <= TPL_APPLICATION) || - (NotifyTpl >= TPL_HIGH_LEVEL)) { - return EFI_INVALID_PARAMETER; - } - - } else { - // - // No notification needed, zero ignored values - // - NotifyTpl = 0; - NotifyFunction = NULL; - NotifyContext = NULL; - } - - // - // Allocate and initialize a new event structure. - // - if ((Type & EVT_RUNTIME) != 0) { - IEvent = AllocateRuntimeZeroPool (sizeof (IEVENT)); - } else { - IEvent = AllocateZeroPool (sizeof (IEVENT)); - } - if (IEvent == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - IEvent->Signature = EVENT_SIGNATURE; - IEvent->Type = Type; - - IEvent->NotifyTpl = NotifyTpl; - IEvent->NotifyFunction = NotifyFunction; - IEvent->NotifyContext = (VOID *)NotifyContext; - if (EventGroup != NULL) { - CopyGuid (&IEvent->EventGroup, EventGroup); - IEvent->ExFlag |= EVT_EXFLAG_EVENT_GROUP; - } - - *Event = IEvent; - - if ((Type & EVT_RUNTIME) != 0) { - // - // Keep a list of all RT events so we can tell the RT AP. - // - IEvent->RuntimeData.Type = Type; - IEvent->RuntimeData.NotifyTpl = NotifyTpl; - IEvent->RuntimeData.NotifyFunction = NotifyFunction; - IEvent->RuntimeData.NotifyContext = (VOID *) NotifyContext; - IEvent->RuntimeData.Event = (EFI_EVENT *) IEvent; - InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link); - } - - CoreAcquireEventLock (); - - if ((Type & EVT_NOTIFY_SIGNAL) != 0x00000000) { - // - // The Event's NotifyFunction must be queued whenever the event is signaled - // - InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink); - } - - CoreReleaseEventLock (); - - // - // Done - // - return EFI_SUCCESS; -} - - - - -/** - Signals the event. Queues the event to be notified if needed. - - @param UserEvent The event to signal . - - @retval EFI_INVALID_PARAMETER Parameters are not valid. - @retval EFI_SUCCESS The event was signaled. - -**/ -EFI_STATUS -EFIAPI -CoreSignalEvent ( - IN EFI_EVENT UserEvent - ) -{ - IEVENT *Event; - - Event = UserEvent; - - if (Event == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Event->Signature != EVENT_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireEventLock (); - - // - // If the event is not already signalled, do so - // - - if (Event->SignalCount == 0x00000000) { - Event->SignalCount++; - - // - // If signalling type is a notify function, queue it - // - if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) { - if ((Event->ExFlag & EVT_EXFLAG_EVENT_GROUP) != 0) { - // - // The CreateEventEx() style requires all members of the Event Group - // to be signaled. - // - CoreReleaseEventLock (); - CoreNotifySignalList (&Event->EventGroup); - CoreAcquireEventLock (); - } else { - CoreNotifyEvent (Event); - } - } - } - - CoreReleaseEventLock (); - return EFI_SUCCESS; -} - - - -/** - Check the status of an event. - - @param UserEvent The event to check - - @retval EFI_SUCCESS The event is in the signaled state - @retval EFI_NOT_READY The event is not in the signaled state - @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL - -**/ -EFI_STATUS -EFIAPI -CoreCheckEvent ( - IN EFI_EVENT UserEvent - ) -{ - IEVENT *Event; - EFI_STATUS Status; - - Event = UserEvent; - - if (Event == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Event->Signature != EVENT_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_NOT_READY; - - if ((Event->SignalCount == 0) && ((Event->Type & EVT_NOTIFY_WAIT) != 0)) { - - // - // Queue the wait notify function - // - CoreAcquireEventLock (); - if (Event->SignalCount == 0) { - CoreNotifyEvent (Event); - } - CoreReleaseEventLock (); - } - - // - // If the even looks signalled, get the lock and clear it - // - - if (Event->SignalCount != 0) { - CoreAcquireEventLock (); - - if (Event->SignalCount != 0) { - Event->SignalCount = 0; - Status = EFI_SUCCESS; - } - - CoreReleaseEventLock (); - } - - return Status; -} - - - -/** - Stops execution until an event is signaled. - - @param NumberOfEvents The number of events in the UserEvents array - @param UserEvents An array of EFI_EVENT - @param UserIndex Pointer to the index of the event which - satisfied the wait condition - - @retval EFI_SUCCESS The event indicated by Index was signaled. - @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification - function or Event was not a valid type - @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION - -**/ -EFI_STATUS -EFIAPI -CoreWaitForEvent ( - IN UINTN NumberOfEvents, - IN EFI_EVENT *UserEvents, - OUT UINTN *UserIndex - ) -{ - EFI_STATUS Status; - UINTN Index; - - // - // Can only WaitForEvent at TPL_APPLICATION - // - if (gEfiCurrentTpl != TPL_APPLICATION) { - return EFI_UNSUPPORTED; - } - - if (NumberOfEvents == 0) { - return EFI_INVALID_PARAMETER; - } - - if (UserEvents == NULL) { - return EFI_INVALID_PARAMETER; - } - - for(;;) { - - for(Index = 0; Index < NumberOfEvents; Index++) { - - Status = CoreCheckEvent (UserEvents[Index]); - - // - // provide index of event that caused problem - // - if (Status != EFI_NOT_READY) { - if (UserIndex != NULL) { - *UserIndex = Index; - } - return Status; - } - } - - // - // Signal the Idle event - // - CoreSignalEvent (gIdleLoopEvent); - } -} - - -/** - Closes an event and frees the event structure. - - @param UserEvent Event to close - - @retval EFI_INVALID_PARAMETER Parameters are not valid. - @retval EFI_SUCCESS The event has been closed - -**/ -EFI_STATUS -EFIAPI -CoreCloseEvent ( - IN EFI_EVENT UserEvent - ) -{ - EFI_STATUS Status; - IEVENT *Event; - - Event = UserEvent; - - if (Event == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Event->Signature != EVENT_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - // - // If it's a timer event, make sure it's not pending - // - if ((Event->Type & EVT_TIMER) != 0) { - CoreSetTimer (Event, TimerCancel, 0); - } - - CoreAcquireEventLock (); - - // - // If the event is queued somewhere, remove it - // - - if (Event->RuntimeData.Link.ForwardLink != NULL) { - RemoveEntryList (&Event->RuntimeData.Link); - } - - if (Event->NotifyLink.ForwardLink != NULL) { - RemoveEntryList (&Event->NotifyLink); - } - - if (Event->SignalLink.ForwardLink != NULL) { - RemoveEntryList (&Event->SignalLink); - } - - CoreReleaseEventLock (); - - // - // If the event is registered on a protocol notify, then remove it from the protocol database - // - if ((Event->ExFlag & EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION) != 0) { - CoreUnregisterProtocolNotify (Event); - } - - // - // To avoid the Event to be signalled wrongly after closed, - // clear the Signature of Event before free pool. - // - Event->Signature = 0; - Status = CoreFreePool (Event); - ASSERT_EFI_ERROR (Status); - - return Status; -} - diff --git a/MdeModulePkg/Core/Dxe/Event/Event.h b/MdeModulePkg/Core/Dxe/Event/Event.h deleted file mode 100644 index 4c02900b93..0000000000 --- a/MdeModulePkg/Core/Dxe/Event/Event.h +++ /dev/null @@ -1,97 +0,0 @@ -/** @file - UEFI Event support functions and structure. - -Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
-(C) Copyright 2015 Hewlett Packard Enterprise Development LP
-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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EVENT_H__ -#define __EVENT_H__ - - -#define VALID_TPL(a) ((a) <= TPL_HIGH_LEVEL) -extern UINTN gEventPending; - -/// -/// Set if Event is part of an event group -/// -#define EVT_EXFLAG_EVENT_GROUP 0x01 -/// -/// Set if Event is registered on a protocol notify -/// -#define EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION 0x02 - -// -// EFI_EVENT -// - -/// -/// Timer event information -/// -typedef struct { - LIST_ENTRY Link; - UINT64 TriggerTime; - UINT64 Period; -} TIMER_EVENT_INFO; - -#define EVENT_SIGNATURE SIGNATURE_32('e','v','n','t') -typedef struct { - UINTN Signature; - UINT32 Type; - UINT32 SignalCount; - /// - /// Entry if the event is registered to be signalled - /// - LIST_ENTRY SignalLink; - /// - /// Notification information for this event - /// - EFI_TPL NotifyTpl; - EFI_EVENT_NOTIFY NotifyFunction; - VOID *NotifyContext; - EFI_GUID EventGroup; - LIST_ENTRY NotifyLink; - UINT8 ExFlag; - /// - /// A list of all runtime events - /// - EFI_RUNTIME_EVENT_ENTRY RuntimeData; - TIMER_EVENT_INFO Timer; -} IEVENT; - -// -// Internal prototypes -// - - -/** - Dispatches all pending events. - - @param Priority The task priority level of event notifications - to dispatch - -**/ -VOID -CoreDispatchEventNotifies ( - IN EFI_TPL Priority - ); - - -/** - Initializes timer support. - -**/ -VOID -CoreInitializeTimer ( - VOID - ); - -#endif diff --git a/MdeModulePkg/Core/Dxe/Event/Timer.c b/MdeModulePkg/Core/Dxe/Event/Timer.c deleted file mode 100644 index 6cd4e6c185..0000000000 --- a/MdeModulePkg/Core/Dxe/Event/Timer.c +++ /dev/null @@ -1,301 +0,0 @@ -/** @file - Core Timer Services - -Copyright (c) 2006 - 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "DxeMain.h" -#include "Event.h" - -// -// Internal data -// - -LIST_ENTRY mEfiTimerList = INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList); -EFI_LOCK mEfiTimerLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL - 1); -EFI_EVENT mEfiCheckTimerEvent = NULL; - -EFI_LOCK mEfiSystemTimeLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_HIGH_LEVEL); -UINT64 mEfiSystemTime = 0; - -// -// Timer functions -// -/** - Inserts the timer event. - - @param Event Points to the internal structure of timer event - to be installed - -**/ -VOID -CoreInsertEventTimer ( - IN IEVENT *Event - ) -{ - UINT64 TriggerTime; - LIST_ENTRY *Link; - IEVENT *Event2; - - ASSERT_LOCKED (&mEfiTimerLock); - - // - // Get the timer's trigger time - // - TriggerTime = Event->Timer.TriggerTime; - - // - // Insert the timer into the timer database in assending sorted order - // - for (Link = mEfiTimerList.ForwardLink; Link != &mEfiTimerList; Link = Link->ForwardLink) { - Event2 = CR (Link, IEVENT, Timer.Link, EVENT_SIGNATURE); - - if (Event2->Timer.TriggerTime > TriggerTime) { - break; - } - } - - InsertTailList (Link, &Event->Timer.Link); -} - -/** - Returns the current system time. - - @return The current system time - -**/ -UINT64 -CoreCurrentSystemTime ( - VOID - ) -{ - UINT64 SystemTime; - - CoreAcquireLock (&mEfiSystemTimeLock); - SystemTime = mEfiSystemTime; - CoreReleaseLock (&mEfiSystemTimeLock); - - return SystemTime; -} - -/** - Checks the sorted timer list against the current system time. - Signals any expired event timer. - - @param CheckEvent Not used - @param Context Not used - -**/ -VOID -EFIAPI -CoreCheckTimers ( - IN EFI_EVENT CheckEvent, - IN VOID *Context - ) -{ - UINT64 SystemTime; - IEVENT *Event; - - // - // Check the timer database for expired timers - // - CoreAcquireLock (&mEfiTimerLock); - SystemTime = CoreCurrentSystemTime (); - - while (!IsListEmpty (&mEfiTimerList)) { - Event = CR (mEfiTimerList.ForwardLink, IEVENT, Timer.Link, EVENT_SIGNATURE); - - // - // If this timer is not expired, then we're done - // - if (Event->Timer.TriggerTime > SystemTime) { - break; - } - - // - // Remove this timer from the timer queue - // - - RemoveEntryList (&Event->Timer.Link); - Event->Timer.Link.ForwardLink = NULL; - - // - // Signal it - // - CoreSignalEvent (Event); - - // - // If this is a periodic timer, set it - // - if (Event->Timer.Period != 0) { - // - // Compute the timers new trigger time - // - Event->Timer.TriggerTime = Event->Timer.TriggerTime + Event->Timer.Period; - - // - // If that's before now, then reset the timer to start from now - // - if (Event->Timer.TriggerTime <= SystemTime) { - Event->Timer.TriggerTime = SystemTime; - CoreSignalEvent (mEfiCheckTimerEvent); - } - - // - // Add the timer - // - CoreInsertEventTimer (Event); - } - } - - CoreReleaseLock (&mEfiTimerLock); -} - - -/** - Initializes timer support. - -**/ -VOID -CoreInitializeTimer ( - VOID - ) -{ - EFI_STATUS Status; - - Status = CoreCreateEventInternal ( - EVT_NOTIFY_SIGNAL, - TPL_HIGH_LEVEL - 1, - CoreCheckTimers, - NULL, - NULL, - &mEfiCheckTimerEvent - ); - ASSERT_EFI_ERROR (Status); -} - - -/** - Called by the platform code to process a tick. - - @param Duration The number of 100ns elapsed since the last call - to TimerTick - -**/ -VOID -EFIAPI -CoreTimerTick ( - IN UINT64 Duration - ) -{ - IEVENT *Event; - - // - // Check runtiem flag in case there are ticks while exiting boot services - // - CoreAcquireLock (&mEfiSystemTimeLock); - - // - // Update the system time - // - mEfiSystemTime += Duration; - - // - // If the head of the list is expired, fire the timer event - // to process it - // - if (!IsListEmpty (&mEfiTimerList)) { - Event = CR (mEfiTimerList.ForwardLink, IEVENT, Timer.Link, EVENT_SIGNATURE); - - if (Event->Timer.TriggerTime <= mEfiSystemTime) { - CoreSignalEvent (mEfiCheckTimerEvent); - } - } - - CoreReleaseLock (&mEfiSystemTimeLock); -} - - - -/** - Sets the type of timer and the trigger time for a timer event. - - @param UserEvent The timer event that is to be signaled at the - specified time - @param Type The type of time that is specified in - TriggerTime - @param TriggerTime The number of 100ns units until the timer - expires - - @retval EFI_SUCCESS The event has been set to be signaled at the - requested time - @retval EFI_INVALID_PARAMETER Event or Type is not valid - -**/ -EFI_STATUS -EFIAPI -CoreSetTimer ( - IN EFI_EVENT UserEvent, - IN EFI_TIMER_DELAY Type, - IN UINT64 TriggerTime - ) -{ - IEVENT *Event; - - Event = UserEvent; - - if (Event == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Event->Signature != EVENT_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - if ((UINT32)Type > TimerRelative || (Event->Type & EVT_TIMER) == 0) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireLock (&mEfiTimerLock); - - // - // If the timer is queued to the timer database, remove it - // - if (Event->Timer.Link.ForwardLink != NULL) { - RemoveEntryList (&Event->Timer.Link); - Event->Timer.Link.ForwardLink = NULL; - } - - Event->Timer.TriggerTime = 0; - Event->Timer.Period = 0; - - if (Type != TimerCancel) { - - if (Type == TimerPeriodic) { - if (TriggerTime == 0) { - gTimer->GetTimerPeriod (gTimer, &TriggerTime); - } - Event->Timer.Period = TriggerTime; - } - - Event->Timer.TriggerTime = CoreCurrentSystemTime () + TriggerTime; - CoreInsertEventTimer (Event); - - if (TriggerTime == 0) { - CoreSignalEvent (mEfiCheckTimerEvent); - } - } - - CoreReleaseLock (&mEfiTimerLock); - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/Dxe/Event/Tpl.c b/MdeModulePkg/Core/Dxe/Event/Tpl.c deleted file mode 100644 index 8ad0a33701..0000000000 --- a/MdeModulePkg/Core/Dxe/Event/Tpl.c +++ /dev/null @@ -1,148 +0,0 @@ -/** @file - Task priority (TPL) functions. - -Copyright (c) 2006 - 2015, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Event.h" - -/** - Set Interrupt State. - - @param Enable The state of enable or disable interrupt - -**/ -VOID -CoreSetInterruptState ( - IN BOOLEAN Enable - ) -{ - EFI_STATUS Status; - BOOLEAN InSmm; - - if (gCpu == NULL) { - return; - } - if (!Enable) { - gCpu->DisableInterrupt (gCpu); - return; - } - if (gSmmBase2 == NULL) { - gCpu->EnableInterrupt (gCpu); - return; - } - Status = gSmmBase2->InSmm (gSmmBase2, &InSmm); - if (!EFI_ERROR (Status) && !InSmm) { - gCpu->EnableInterrupt(gCpu); - } -} - - -/** - Raise the task priority level to the new level. - High level is implemented by disabling processor interrupts. - - @param NewTpl New task priority level - - @return The previous task priority level - -**/ -EFI_TPL -EFIAPI -CoreRaiseTpl ( - IN EFI_TPL NewTpl - ) -{ - EFI_TPL OldTpl; - - OldTpl = gEfiCurrentTpl; - if (OldTpl > NewTpl) { - DEBUG ((EFI_D_ERROR, "FATAL ERROR - RaiseTpl with OldTpl(0x%x) > NewTpl(0x%x)\n", OldTpl, NewTpl)); - ASSERT (FALSE); - } - ASSERT (VALID_TPL (NewTpl)); - - // - // If raising to high level, disable interrupts - // - if (NewTpl >= TPL_HIGH_LEVEL && OldTpl < TPL_HIGH_LEVEL) { - CoreSetInterruptState (FALSE); - } - - // - // Set the new value - // - gEfiCurrentTpl = NewTpl; - - return OldTpl; -} - - - - -/** - Lowers the task priority to the previous value. If the new - priority unmasks events at a higher priority, they are dispatched. - - @param NewTpl New, lower, task priority - -**/ -VOID -EFIAPI -CoreRestoreTpl ( - IN EFI_TPL NewTpl - ) -{ - EFI_TPL OldTpl; - - OldTpl = gEfiCurrentTpl; - if (NewTpl > OldTpl) { - DEBUG ((EFI_D_ERROR, "FATAL ERROR - RestoreTpl with NewTpl(0x%x) > OldTpl(0x%x)\n", NewTpl, OldTpl)); - ASSERT (FALSE); - } - ASSERT (VALID_TPL (NewTpl)); - - // - // If lowering below HIGH_LEVEL, make sure - // interrupts are enabled - // - - if (OldTpl >= TPL_HIGH_LEVEL && NewTpl < TPL_HIGH_LEVEL) { - gEfiCurrentTpl = TPL_HIGH_LEVEL; - } - - // - // Dispatch any pending events - // - while (((-2 << NewTpl) & gEventPending) != 0) { - gEfiCurrentTpl = (UINTN) HighBitSet64 (gEventPending); - if (gEfiCurrentTpl < TPL_HIGH_LEVEL) { - CoreSetInterruptState (TRUE); - } - CoreDispatchEventNotifies (gEfiCurrentTpl); - } - - // - // Set the new value - // - - gEfiCurrentTpl = NewTpl; - - // - // If lowering below HIGH_LEVEL, make sure - // interrupts are enabled - // - if (gEfiCurrentTpl < TPL_HIGH_LEVEL) { - CoreSetInterruptState (TRUE); - } - -} diff --git a/MdeModulePkg/Core/Dxe/FwVol/Ffs.c b/MdeModulePkg/Core/Dxe/FwVol/Ffs.c deleted file mode 100644 index 20dade18a2..0000000000 --- a/MdeModulePkg/Core/Dxe/FwVol/Ffs.c +++ /dev/null @@ -1,233 +0,0 @@ -/** @file - FFS file access utilities. - -Copyright (c) 2006 - 2011, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include "DxeMain.h" -#include "FwVolDriver.h" - - -/** - Get the FFS file state by checking the highest bit set in the header's state field. - - @param ErasePolarity Erase polarity attribute of the firmware volume - @param FfsHeader Points to the FFS file header - - @return FFS File state - -**/ -EFI_FFS_FILE_STATE -GetFileState ( - IN UINT8 ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -{ - EFI_FFS_FILE_STATE FileState; - UINT8 HighestBit; - - FileState = FfsHeader->State; - - if (ErasePolarity != 0) { - FileState = (EFI_FFS_FILE_STATE)~FileState; - } - - HighestBit = 0x80; - while (HighestBit != 0 && ((HighestBit & FileState) == 0)) { - HighestBit >>= 1; - } - - return (EFI_FFS_FILE_STATE) HighestBit; -} - - - -/** - Check if a block of buffer is erased. - - @param ErasePolarity Erase polarity attribute of the firmware volume - @param InBuffer The buffer to be checked - @param BufferSize Size of the buffer in bytes - - @retval TRUE The block of buffer is erased - @retval FALSE The block of buffer is not erased - -**/ -BOOLEAN -IsBufferErased ( - IN UINT8 ErasePolarity, - IN VOID *InBuffer, - IN UINTN BufferSize - ) -{ - UINTN Count; - UINT8 EraseByte; - UINT8 *Buffer; - - if(ErasePolarity == 1) { - EraseByte = 0xFF; - } else { - EraseByte = 0; - } - - Buffer = InBuffer; - for (Count = 0; Count < BufferSize; Count++) { - if (Buffer[Count] != EraseByte) { - return FALSE; - } - } - - return TRUE; -} - - - -/** - Verify checksum of the firmware volume header. - - @param FvHeader Points to the firmware volume header to be checked - - @retval TRUE Checksum verification passed - @retval FALSE Checksum verification failed - -**/ -BOOLEAN -VerifyFvHeaderChecksum ( - IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader - ) -{ - UINT16 Checksum; - - Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength); - - if (Checksum == 0) { - return TRUE; - } else { - return FALSE; - } -} - - -/** - Verify checksum of the FFS file header. - - @param FfsHeader Points to the FFS file header to be checked - - @retval TRUE Checksum verification passed - @retval FALSE Checksum verification failed - -**/ -BOOLEAN -VerifyHeaderChecksum ( - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -{ - UINT8 HeaderChecksum; - - if (IS_FFS_FILE2 (FfsHeader)) { - HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER2)); - } else { - HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER)); - } - HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File); - - if (HeaderChecksum == 0) { - return TRUE; - } else { - return FALSE; - } -} - - - -/** - Check if it's a valid FFS file header. - - @param ErasePolarity Erase polarity attribute of the firmware volume - @param FfsHeader Points to the FFS file header to be checked - @param FileState FFS file state to be returned - - @retval TRUE Valid FFS file header - @retval FALSE Invalid FFS file header - -**/ -BOOLEAN -IsValidFfsHeader ( - IN UINT8 ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader, - OUT EFI_FFS_FILE_STATE *FileState - ) -{ - *FileState = GetFileState (ErasePolarity, FfsHeader); - - switch (*FileState) { - case EFI_FILE_HEADER_VALID: - case EFI_FILE_DATA_VALID: - case EFI_FILE_MARKED_FOR_UPDATE: - case EFI_FILE_DELETED: - // - // Here we need to verify header checksum - // - return VerifyHeaderChecksum (FfsHeader); - - case EFI_FILE_HEADER_CONSTRUCTION: - case EFI_FILE_HEADER_INVALID: - default: - return FALSE; - } -} - - -/** - Check if it's a valid FFS file. - Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first. - - @param ErasePolarity Erase polarity attribute of the firmware volume - @param FfsHeader Points to the FFS file to be checked - - @retval TRUE Valid FFS file - @retval FALSE Invalid FFS file - -**/ -BOOLEAN -IsValidFfsFile ( - IN UINT8 ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -{ - EFI_FFS_FILE_STATE FileState; - UINT8 DataCheckSum; - - FileState = GetFileState (ErasePolarity, FfsHeader); - switch (FileState) { - - case EFI_FILE_DELETED: - case EFI_FILE_DATA_VALID: - case EFI_FILE_MARKED_FOR_UPDATE: - DataCheckSum = FFS_FIXED_CHECKSUM; - if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) { - if (IS_FFS_FILE2 (FfsHeader)) { - DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER2)); - } else { - DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER)); - } - } - if (FfsHeader->IntegrityCheck.Checksum.File == DataCheckSum) { - return TRUE; - } - - default: - return FALSE; - } -} - - diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c b/MdeModulePkg/Core/Dxe/FwVol/FwVol.c deleted file mode 100644 index fe12d6e0ac..0000000000 --- a/MdeModulePkg/Core/Dxe/FwVol/FwVol.c +++ /dev/null @@ -1,775 +0,0 @@ -/** @file - Firmware File System driver that produce Firmware Volume protocol. - Layers on top of Firmware Block protocol to produce a file abstraction - of FV based files. - -Copyright (c) 2006 - 2014, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "FwVolDriver.h" - - -// -// Protocol notify related globals -// -VOID *gEfiFwVolBlockNotifyReg; -EFI_EVENT gEfiFwVolBlockEvent; - -FV_DEVICE mFvDevice = { - FV2_DEVICE_SIGNATURE, - NULL, - NULL, - { - FvGetVolumeAttributes, - FvSetVolumeAttributes, - FvReadFile, - FvReadFileSection, - FvWriteFile, - FvGetNextFile, - sizeof (UINTN), - NULL, - FvGetVolumeInfo, - FvSetVolumeInfo - }, - NULL, - NULL, - NULL, - NULL, - { NULL, NULL }, - 0, - 0, - FALSE, - FALSE -}; - - -// -// FFS helper functions -// -/** - Read data from Firmware Block by FVB protocol Read. - The data may cross the multi block ranges. - - @param Fvb The FW_VOL_BLOCK_PROTOCOL instance from which to read data. - @param StartLba Pointer to StartLba. - On input, the start logical block index from which to read. - On output,the end logical block index after reading. - @param Offset Pointer to Offset - On input, offset into the block at which to begin reading. - On output, offset into the end block after reading. - @param DataSize Size of data to be read. - @param Data Pointer to Buffer that the data will be read into. - - @retval EFI_SUCCESS Successfully read data from firmware block. - @retval others -**/ -EFI_STATUS -ReadFvbData ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb, - IN OUT EFI_LBA *StartLba, - IN OUT UINTN *Offset, - IN UINTN DataSize, - OUT UINT8 *Data - ) -{ - UINTN BlockSize; - UINTN NumberOfBlocks; - UINTN BlockIndex; - UINTN ReadDataSize; - EFI_STATUS Status; - - // - // Try read data in current block - // - BlockIndex = 0; - ReadDataSize = DataSize; - Status = Fvb->Read (Fvb, *StartLba, *Offset, &ReadDataSize, Data); - if (Status == EFI_SUCCESS) { - *Offset += DataSize; - return EFI_SUCCESS; - } else if (Status != EFI_BAD_BUFFER_SIZE) { - // - // other error will direct return - // - return Status; - } - - // - // Data crosses the blocks, read data from next block - // - DataSize -= ReadDataSize; - Data += ReadDataSize; - *StartLba = *StartLba + 1; - while (DataSize > 0) { - Status = Fvb->GetBlockSize (Fvb, *StartLba, &BlockSize, &NumberOfBlocks); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Read data from the crossing blocks - // - BlockIndex = 0; - while (BlockIndex < NumberOfBlocks && DataSize >= BlockSize) { - Status = Fvb->Read (Fvb, *StartLba + BlockIndex, 0, &BlockSize, Data); - if (EFI_ERROR (Status)) { - return Status; - } - Data += BlockSize; - DataSize -= BlockSize; - BlockIndex ++; - } - - // - // Data doesn't exceed the current block range. - // - if (DataSize < BlockSize) { - break; - } - - // - // Data must be got from the next block range. - // - *StartLba += NumberOfBlocks; - } - - // - // read the remaining data - // - if (DataSize > 0) { - Status = Fvb->Read (Fvb, *StartLba + BlockIndex, 0, &DataSize, Data); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Update Lba and Offset used by the following read. - // - *StartLba += BlockIndex; - *Offset = DataSize; - - return EFI_SUCCESS; -} - -/** - Given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and - copy the real length volume header into it. - - @param Fvb The FW_VOL_BLOCK_PROTOCOL instance from which to - read the volume header - @param FwVolHeader Pointer to pointer to allocated buffer in which - the volume header is returned. - - @retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated. - @retval EFI_SUCCESS Successfully read volume header to the allocated - buffer. - @retval EFI_INVALID_PARAMETER The FV Header signature is not as expected or - the file system could not be understood. - -**/ -EFI_STATUS -GetFwVolHeader ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb, - OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader - ) -{ - EFI_STATUS Status; - EFI_FIRMWARE_VOLUME_HEADER TempFvh; - UINTN FvhLength; - EFI_LBA StartLba; - UINTN Offset; - UINT8 *Buffer; - - // - // Read the standard FV header - // - StartLba = 0; - Offset = 0; - FvhLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER); - Status = ReadFvbData (Fvb, &StartLba, &Offset, FvhLength, (UINT8 *)&TempFvh); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Validate FV Header signature, if not as expected, continue. - // - if (TempFvh.Signature != EFI_FVH_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - // - // Check to see that the file system is indeed formatted in a way we can - // understand it... - // - if ((!CompareGuid (&TempFvh.FileSystemGuid, &gEfiFirmwareFileSystem2Guid)) && - (!CompareGuid (&TempFvh.FileSystemGuid, &gEfiFirmwareFileSystem3Guid))) { - return EFI_INVALID_PARAMETER; - } - - // - // Allocate a buffer for the caller - // - *FwVolHeader = AllocatePool (TempFvh.HeaderLength); - if (*FwVolHeader == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Copy the standard header into the buffer - // - CopyMem (*FwVolHeader, &TempFvh, sizeof (EFI_FIRMWARE_VOLUME_HEADER)); - - // - // Read the rest of the header - // - FvhLength = TempFvh.HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER); - Buffer = (UINT8 *)*FwVolHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER); - Status = ReadFvbData (Fvb, &StartLba, &Offset, FvhLength, Buffer); - if (EFI_ERROR (Status)) { - // - // Read failed so free buffer - // - CoreFreePool (*FwVolHeader); - } - - return Status; -} - - - -/** - Free FvDevice resource when error happens - - @param FvDevice pointer to the FvDevice to be freed. - -**/ -VOID -FreeFvDeviceResource ( - IN FV_DEVICE *FvDevice - ) -{ - FFS_FILE_LIST_ENTRY *FfsFileEntry; - LIST_ENTRY *NextEntry; - - // - // Free File List Entry - // - FfsFileEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->FfsFileListHeader.ForwardLink; - while (&FfsFileEntry->Link != &FvDevice->FfsFileListHeader) { - NextEntry = (&FfsFileEntry->Link)->ForwardLink; - - if (FfsFileEntry->StreamHandle != 0) { - // - // Close stream and free resources from SEP - // - CloseSectionStream (FfsFileEntry->StreamHandle, FALSE); - } - - if (FfsFileEntry->FileCached) { - // - // Free the cached file buffer. - // - CoreFreePool (FfsFileEntry->FfsHeader); - } - - CoreFreePool (FfsFileEntry); - - FfsFileEntry = (FFS_FILE_LIST_ENTRY *) NextEntry; - } - - if (!FvDevice->IsMemoryMapped) { - // - // Free the cached FV buffer. - // - CoreFreePool (FvDevice->CachedFv); - } - - // - // Free Volume Header - // - CoreFreePool (FvDevice->FwVolHeader); - - return; -} - - - -/** - Check if an FV is consistent and allocate cache for it. - - @param FvDevice A pointer to the FvDevice to be checked. - - @retval EFI_OUT_OF_RESOURCES No enough buffer could be allocated. - @retval EFI_SUCCESS FV is consistent and cache is allocated. - @retval EFI_VOLUME_CORRUPTED File system is corrupted. - -**/ -EFI_STATUS -FvCheck ( - IN OUT FV_DEVICE *FvDevice - ) -{ - EFI_STATUS Status; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExtHeader; - EFI_FVB_ATTRIBUTES_2 FvbAttributes; - EFI_FV_BLOCK_MAP_ENTRY *BlockMap; - FFS_FILE_LIST_ENTRY *FfsFileEntry; - EFI_FFS_FILE_HEADER *FfsHeader; - UINT8 *CacheLocation; - UINTN LbaOffset; - UINTN HeaderSize; - UINTN Index; - EFI_LBA LbaIndex; - UINTN Size; - EFI_FFS_FILE_STATE FileState; - UINT8 *TopFvAddress; - UINTN TestLength; - EFI_PHYSICAL_ADDRESS PhysicalAddress; - BOOLEAN FileCached; - UINTN WholeFileSize; - EFI_FFS_FILE_HEADER *CacheFfsHeader; - - FileCached = FALSE; - CacheFfsHeader = NULL; - - Fvb = FvDevice->Fvb; - FwVolHeader = FvDevice->FwVolHeader; - - Status = Fvb->GetAttributes (Fvb, &FvbAttributes); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Size is the size of the FV minus the head. We have already allocated - // the header to check to make sure the volume is valid - // - Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength); - if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) { - FvDevice->IsMemoryMapped = TRUE; - - Status = Fvb->GetPhysicalAddress (Fvb, &PhysicalAddress); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Don't cache memory mapped FV really. - // - FvDevice->CachedFv = (UINT8 *) (UINTN) (PhysicalAddress + FwVolHeader->HeaderLength); - } else { - FvDevice->IsMemoryMapped = FALSE; - FvDevice->CachedFv = AllocatePool (Size); - - if (FvDevice->CachedFv == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - // - // Remember a pointer to the end fo the CachedFv - // - FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size; - - if (!FvDevice->IsMemoryMapped) { - // - // Copy FV minus header into memory using the block map we have all ready - // read into memory. - // - BlockMap = FwVolHeader->BlockMap; - CacheLocation = FvDevice->CachedFv; - LbaIndex = 0; - LbaOffset = 0; - HeaderSize = FwVolHeader->HeaderLength; - while ((BlockMap->NumBlocks != 0) || (BlockMap->Length != 0)) { - Index = 0; - Size = BlockMap->Length; - if (HeaderSize > 0) { - // - // Skip header size - // - for (; Index < BlockMap->NumBlocks && HeaderSize >= BlockMap->Length; Index ++) { - HeaderSize -= BlockMap->Length; - LbaIndex ++; - } - - // - // Check whether FvHeader is crossing the multi block range. - // - if (Index >= BlockMap->NumBlocks) { - BlockMap++; - continue; - } else if (HeaderSize > 0) { - LbaOffset = HeaderSize; - Size = BlockMap->Length - HeaderSize; - HeaderSize = 0; - } - } - - // - // read the FV data - // - for (; Index < BlockMap->NumBlocks; Index ++) { - Status = Fvb->Read (Fvb, - LbaIndex, - LbaOffset, - &Size, - CacheLocation - ); - - // - // Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->Length - // - if (EFI_ERROR (Status)) { - goto Done; - } - - LbaIndex++; - CacheLocation += Size; - - // - // After we skip Fv Header always read from start of block - // - LbaOffset = 0; - Size = BlockMap->Length; - } - - BlockMap++; - } - } - - // - // Scan to check the free space & File list - // - if ((FvbAttributes & EFI_FVB2_ERASE_POLARITY) != 0) { - FvDevice->ErasePolarity = 1; - } else { - FvDevice->ErasePolarity = 0; - } - - - // - // go through the whole FV cache, check the consistence of the FV. - // Make a linked list of all the Ffs file headers - // - Status = EFI_SUCCESS; - InitializeListHead (&FvDevice->FfsFileListHeader); - - // - // Build FFS list - // - if (FwVolHeader->ExtHeaderOffset != 0) { - // - // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists. - // - FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) (FvDevice->CachedFv + (FwVolHeader->ExtHeaderOffset - FwVolHeader->HeaderLength)); - FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize); - FfsHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsHeader, 8); - } else { - FfsHeader = (EFI_FFS_FILE_HEADER *) (FvDevice->CachedFv); - } - TopFvAddress = FvDevice->EndOfCachedFv; - while (((UINTN) FfsHeader >= (UINTN) FvDevice->CachedFv) && ((UINTN) FfsHeader <= (UINTN) ((UINTN) TopFvAddress - sizeof (EFI_FFS_FILE_HEADER)))) { - - if (FileCached) { - CoreFreePool (CacheFfsHeader); - FileCached = FALSE; - } - - TestLength = TopFvAddress - ((UINT8 *) FfsHeader); - if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) { - TestLength = sizeof (EFI_FFS_FILE_HEADER); - } - - if (IsBufferErased (FvDevice->ErasePolarity, FfsHeader, TestLength)) { - // - // We have found the free space so we are done! - // - goto Done; - } - - if (!IsValidFfsHeader (FvDevice->ErasePolarity, FfsHeader, &FileState)) { - if ((FileState == EFI_FILE_HEADER_INVALID) || - (FileState == EFI_FILE_HEADER_CONSTRUCTION)) { - if (IS_FFS_FILE2 (FfsHeader)) { - if (!FvDevice->IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsHeader->Name)); - } - FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2)); - } else { - FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER)); - } - continue; - } else { - // - // File system is corrputed - // - Status = EFI_VOLUME_CORRUPTED; - goto Done; - } - } - - CacheFfsHeader = FfsHeader; - if ((CacheFfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) { - if (FvDevice->IsMemoryMapped) { - // - // Memory mapped FV has not been cached. - // Here is to cache FFS file to memory buffer for following checksum calculating. - // And then, the cached file buffer can be also used for FvReadFile. - // - WholeFileSize = IS_FFS_FILE2 (CacheFfsHeader) ? FFS_FILE2_SIZE (CacheFfsHeader): FFS_FILE_SIZE (CacheFfsHeader); - CacheFfsHeader = AllocateCopyPool (WholeFileSize, CacheFfsHeader); - if (CacheFfsHeader == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - FileCached = TRUE; - } - } - - if (!IsValidFfsFile (FvDevice->ErasePolarity, CacheFfsHeader)) { - // - // File system is corrupted - // - Status = EFI_VOLUME_CORRUPTED; - goto Done; - } - - if (IS_FFS_FILE2 (CacheFfsHeader)) { - ASSERT (FFS_FILE2_SIZE (CacheFfsHeader) > 0x00FFFFFF); - if (!FvDevice->IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &CacheFfsHeader->Name)); - FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE2_SIZE (CacheFfsHeader)); - // - // Adjust pointer to the next 8-byte aligned boundary. - // - FfsHeader = (EFI_FFS_FILE_HEADER *) (((UINTN) FfsHeader + 7) & ~0x07); - continue; - } - } - - FileState = GetFileState (FvDevice->ErasePolarity, CacheFfsHeader); - - // - // check for non-deleted file - // - if (FileState != EFI_FILE_DELETED) { - // - // Create a FFS list entry for each non-deleted file - // - FfsFileEntry = AllocateZeroPool (sizeof (FFS_FILE_LIST_ENTRY)); - if (FfsFileEntry == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - FfsFileEntry->FfsHeader = CacheFfsHeader; - FfsFileEntry->FileCached = FileCached; - FileCached = FALSE; - InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link); - } - - if (IS_FFS_FILE2 (CacheFfsHeader)) { - FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE2_SIZE (CacheFfsHeader)); - } else { - FfsHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsHeader + FFS_FILE_SIZE (CacheFfsHeader)); - } - - // - // Adjust pointer to the next 8-byte aligned boundary. - // - FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINTN)FfsHeader + 7) & ~0x07); - - } - -Done: - if (EFI_ERROR (Status)) { - if (FileCached) { - CoreFreePool (CacheFfsHeader); - FileCached = FALSE; - } - FreeFvDeviceResource (FvDevice); - } - - return Status; -} - - - -/** - This notification function is invoked when an instance of the - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL is produced. It layers an instance of the - EFI_FIRMWARE_VOLUME2_PROTOCOL on the same handle. This is the function where - the actual initialization of the EFI_FIRMWARE_VOLUME2_PROTOCOL is done. - - @param Event The event that occured - @param Context For EFI compatiblity. Not used. - -**/ -VOID -EFIAPI -NotifyFwVolBlock ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_HANDLE Handle; - EFI_STATUS Status; - UINTN BufferSize; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - FV_DEVICE *FvDevice; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - // - // Examine all new handles - // - for (;;) { - // - // Get the next handle - // - BufferSize = sizeof (Handle); - Status = CoreLocateHandle ( - ByRegisterNotify, - NULL, - gEfiFwVolBlockNotifyReg, - &BufferSize, - &Handle - ); - - // - // If not found, we're done - // - if (EFI_NOT_FOUND == Status) { - break; - } - - if (EFI_ERROR (Status)) { - continue; - } - - // - // Get the FirmwareVolumeBlock protocol on that handle - // - Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **)&Fvb); - ASSERT_EFI_ERROR (Status); - ASSERT (Fvb != NULL); - - // - // Make sure the Fv Header is O.K. - // - Status = GetFwVolHeader (Fvb, &FwVolHeader); - if (EFI_ERROR (Status)) { - continue; - } - ASSERT (FwVolHeader != NULL); - - if (!VerifyFvHeaderChecksum (FwVolHeader)) { - CoreFreePool (FwVolHeader); - continue; - } - - // - // Check if there is an FV protocol already installed in that handle - // - Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv); - if (!EFI_ERROR (Status)) { - // - // Update Fv to use a new Fvb - // - FvDevice = BASE_CR (Fv, FV_DEVICE, Fv); - if (FvDevice->Signature == FV2_DEVICE_SIGNATURE) { - // - // Only write into our device structure if it's our device structure - // - FvDevice->Fvb = Fvb; - } - - } else { - // - // No FwVol protocol on the handle so create a new one - // - FvDevice = AllocateCopyPool (sizeof (FV_DEVICE), &mFvDevice); - if (FvDevice == NULL) { - return; - } - - FvDevice->Fvb = Fvb; - FvDevice->Handle = Handle; - FvDevice->FwVolHeader = FwVolHeader; - FvDevice->IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid); - FvDevice->Fv.ParentHandle = Fvb->ParentHandle; - - if (Fvb->ParentHandle != NULL) { - // - // Inherit the authentication status from FVB. - // - FvDevice->AuthenticationStatus = GetFvbAuthenticationStatus (Fvb); - } - - if (!EFI_ERROR (FvCheck (FvDevice))) { - // - // Install an New FV protocol on the existing handle - // - Status = CoreInstallProtocolInterface ( - &Handle, - &gEfiFirmwareVolume2ProtocolGuid, - EFI_NATIVE_INTERFACE, - &FvDevice->Fv - ); - ASSERT_EFI_ERROR (Status); - } else { - // - // Free FvDevice Buffer for the corrupt FV image. - // - CoreFreePool (FvDevice); - } - } - } - - return; -} - - - -/** - This routine is the driver initialization entry point. It registers - a notification function. This notification function are responsible - for building the FV stack dynamically. - - @param ImageHandle The image handle. - @param SystemTable The system table. - - @retval EFI_SUCCESS Function successfully returned. - -**/ -EFI_STATUS -EFIAPI -FwVolDriverInit ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - gEfiFwVolBlockEvent = EfiCreateProtocolNotifyEvent ( - &gEfiFirmwareVolumeBlockProtocolGuid, - TPL_CALLBACK, - NotifyFwVolBlock, - NULL, - &gEfiFwVolBlockNotifyReg - ); - return EFI_SUCCESS; -} - - diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c b/MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c deleted file mode 100644 index 0a89e70761..0000000000 --- a/MdeModulePkg/Core/Dxe/FwVol/FwVolAttrib.c +++ /dev/null @@ -1,135 +0,0 @@ -/** @file - Implements get/set firmware volume attributes - -Copyright (c) 2006 - 2012, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "FwVolDriver.h" - - -/** - Retrieves attributes, insures positive polarity of attribute bits, returns - resulting attributes in output parameter. - - @param This Calling context - @param Attributes output buffer which contains attributes - - @retval EFI_SUCCESS Successfully got volume attributes - -**/ -EFI_STATUS -EFIAPI -FvGetVolumeAttributes ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - OUT EFI_FV_ATTRIBUTES *Attributes - ) -{ - EFI_STATUS Status; - FV_DEVICE *FvDevice; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - EFI_FVB_ATTRIBUTES_2 FvbAttributes; - - FvDevice = FV_DEVICE_FROM_THIS (This); - Fvb = FvDevice->Fvb; - - // - // First get the Firmware Volume Block Attributes - // - Status = Fvb->GetAttributes (Fvb, &FvbAttributes); - - // - // Mask out Fvb bits that are not defined in FV - // - FvbAttributes &= 0xfffff0ff; - - *Attributes = (EFI_FV_ATTRIBUTES)FvbAttributes; - - return Status; -} - - - -/** - Sets current attributes for volume - - @param This Calling context - @param Attributes At input, contains attributes to be set. At output - contains new value of FV - - @retval EFI_UNSUPPORTED Could not be set. - -**/ -EFI_STATUS -EFIAPI -FvSetVolumeAttributes ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN OUT EFI_FV_ATTRIBUTES *Attributes - ) -{ - return EFI_UNSUPPORTED; -} - - -/** - Return information of type InformationType for the requested firmware - volume. - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param InformationType InformationType for requested. - @param BufferSize On input, size of Buffer.On output, the amount of data - returned in Buffer. - @param Buffer A poniter to the data buffer to return. - - @retval EFI_SUCCESS Successfully got volume Information. - -**/ -EFI_STATUS -EFIAPI -FvGetVolumeInfo ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN CONST EFI_GUID *InformationType, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - - - -/** - Set information of type InformationType for the requested firmware - volume. - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param InformationType InformationType for requested. - @param BufferSize On input, size of Buffer.On output, the amount of data - returned in Buffer. - @param Buffer A poniter to the data buffer to return. - - @retval EFI_SUCCESS Successfully set volume Information. - -**/ -EFI_STATUS -EFIAPI -FvSetVolumeInfo ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN CONST EFI_GUID *InformationType, - IN UINTN BufferSize, - IN CONST VOID *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - - - diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h b/MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h deleted file mode 100644 index 96cbde37d5..0000000000 --- a/MdeModulePkg/Core/Dxe/FwVol/FwVolDriver.h +++ /dev/null @@ -1,408 +0,0 @@ -/** @file - Firmware File System protocol. Layers on top of Firmware - Block protocol to produce a file abstraction of FV based files. - -Copyright (c) 2006 - 2014, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __FW_VOL_DRIVER_H_ -#define __FW_VOL_DRIVER_H_ - - -#define FV2_DEVICE_SIGNATURE SIGNATURE_32 ('_', 'F', 'V', '2') - -// -// Used to track all non-deleted files -// -typedef struct { - LIST_ENTRY Link; - EFI_FFS_FILE_HEADER *FfsHeader; - UINTN StreamHandle; - BOOLEAN FileCached; -} FFS_FILE_LIST_ENTRY; - -typedef struct { - UINTN Signature; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb; - EFI_HANDLE Handle; - EFI_FIRMWARE_VOLUME2_PROTOCOL Fv; - - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - UINT8 *CachedFv; - UINT8 *EndOfCachedFv; - - FFS_FILE_LIST_ENTRY *LastKey; - - LIST_ENTRY FfsFileListHeader; - - UINT32 AuthenticationStatus; - UINT8 ErasePolarity; - BOOLEAN IsFfs3Fv; - BOOLEAN IsMemoryMapped; -} FV_DEVICE; - -#define FV_DEVICE_FROM_THIS(a) CR(a, FV_DEVICE, Fv, FV2_DEVICE_SIGNATURE) - -/** - Retrieves attributes, insures positive polarity of attribute bits, returns - resulting attributes in output parameter. - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param Attributes output buffer which contains attributes. - - @retval EFI_SUCCESS Successfully got volume attributes. - -**/ -EFI_STATUS -EFIAPI -FvGetVolumeAttributes ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - OUT EFI_FV_ATTRIBUTES *Attributes - ); - - -/** - Sets current attributes for volume - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param Attributes At input, contains attributes to be set. At output - contains new value of FV. - - @retval EFI_UNSUPPORTED Could not be set. - -**/ -EFI_STATUS -EFIAPI -FvSetVolumeAttributes ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN OUT EFI_FV_ATTRIBUTES *Attributes - ); - - -/** - Given the input key, search for the next matching file in the volume. - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param Key Key is a pointer to a caller allocated - buffer that contains implementation specific - data that is used to track where to begin - the search for the next file. The size of - the buffer must be at least This->KeySize - bytes long. To reinitialize the search and - begin from the beginning of the firmware - volume, the entire buffer must be cleared to - zero. Other than clearing the buffer to - initiate a new search, the caller must not - modify the data in the buffer between calls - to GetNextFile(). - @param FileType FileType is a pointer to a caller allocated - EFI_FV_FILETYPE. The GetNextFile() API can - filter it's search for files based on the - value of *FileType input. A *FileType input - of 0 causes GetNextFile() to search for - files of all types. If a file is found, the - file's type is returned in *FileType. - *FileType is not modified if no file is - found. - @param NameGuid NameGuid is a pointer to a caller allocated - EFI_GUID. If a file is found, the file's - name is returned in *NameGuid. *NameGuid is - not modified if no file is found. - @param Attributes Attributes is a pointer to a caller - allocated EFI_FV_FILE_ATTRIBUTES. If a file - is found, the file's attributes are returned - in *Attributes. *Attributes is not modified - if no file is found. - @param Size Size is a pointer to a caller allocated - UINTN. If a file is found, the file's size - is returned in *Size. *Size is not modified - if no file is found. - - @retval EFI_SUCCESS Successfully find the file. - @retval EFI_DEVICE_ERROR Device error. - @retval EFI_ACCESS_DENIED Fv could not read. - @retval EFI_NOT_FOUND No matching file found. - @retval EFI_INVALID_PARAMETER Invalid parameter - -**/ -EFI_STATUS -EFIAPI -FvGetNextFile ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN OUT VOID *Key, - IN OUT EFI_FV_FILETYPE *FileType, - OUT EFI_GUID *NameGuid, - OUT EFI_FV_FILE_ATTRIBUTES *Attributes, - OUT UINTN *Size - ); - - - -/** - Locates a file in the firmware volume and - copies it to the supplied buffer. - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param NameGuid Pointer to an EFI_GUID, which is the - filename. - @param Buffer Buffer is a pointer to pointer to a buffer - in which the file or section contents or are - returned. - @param BufferSize BufferSize is a pointer to caller allocated - UINTN. On input *BufferSize indicates the - size in bytes of the memory region pointed - to by Buffer. On output, *BufferSize - contains the number of bytes required to - read the file. - @param FoundType FoundType is a pointer to a caller allocated - EFI_FV_FILETYPE that on successful return - from Read() contains the type of file read. - This output reflects the file type - irrespective of the value of the SectionType - input. - @param FileAttributes FileAttributes is a pointer to a caller - allocated EFI_FV_FILE_ATTRIBUTES. On - successful return from Read(), - *FileAttributes contains the attributes of - the file read. - @param AuthenticationStatus AuthenticationStatus is a pointer to a - caller allocated UINTN in which the - authentication status is returned. - - @retval EFI_SUCCESS Successfully read to memory buffer. - @retval EFI_WARN_BUFFER_TOO_SMALL Buffer too small. - @retval EFI_NOT_FOUND Not found. - @retval EFI_DEVICE_ERROR Device error. - @retval EFI_ACCESS_DENIED Could not read. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Not enough buffer to be allocated. - -**/ -EFI_STATUS -EFIAPI -FvReadFile ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN CONST EFI_GUID *NameGuid, - IN OUT VOID **Buffer, - IN OUT UINTN *BufferSize, - OUT EFI_FV_FILETYPE *FoundType, - OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes, - OUT UINT32 *AuthenticationStatus - ); - - -/** - Locates a section in a given FFS File and - copies it to the supplied buffer (not including section header). - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param NameGuid Pointer to an EFI_GUID, which is the - filename. - @param SectionType Indicates the section type to return. - @param SectionInstance Indicates which instance of sections with a - type of SectionType to return. - @param Buffer Buffer is a pointer to pointer to a buffer - in which the file or section contents or are - returned. - @param BufferSize BufferSize is a pointer to caller allocated - UINTN. - @param AuthenticationStatus AuthenticationStatus is a pointer to a - caller allocated UINT32 in which the - authentication status is returned. - - @retval EFI_SUCCESS Successfully read the file section into - buffer. - @retval EFI_WARN_BUFFER_TOO_SMALL Buffer too small. - @retval EFI_NOT_FOUND Section not found. - @retval EFI_DEVICE_ERROR Device error. - @retval EFI_ACCESS_DENIED Could not read. - @retval EFI_INVALID_PARAMETER Invalid parameter. - -**/ -EFI_STATUS -EFIAPI -FvReadFileSection ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN CONST EFI_GUID *NameGuid, - IN EFI_SECTION_TYPE SectionType, - IN UINTN SectionInstance, - IN OUT VOID **Buffer, - IN OUT UINTN *BufferSize, - OUT UINT32 *AuthenticationStatus - ); - - -/** - Writes one or more files to the firmware volume. - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param NumberOfFiles Number of files. - @param WritePolicy WritePolicy indicates the level of reliability - for the write in the event of a power failure or - other system failure during the write operation. - @param FileData FileData is an pointer to an array of - EFI_FV_WRITE_DATA. Each element of array - FileData represents a file to be written. - - @retval EFI_SUCCESS Files successfully written to firmware volume - @retval EFI_OUT_OF_RESOURCES Not enough buffer to be allocated. - @retval EFI_DEVICE_ERROR Device error. - @retval EFI_WRITE_PROTECTED Write protected. - @retval EFI_NOT_FOUND Not found. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_UNSUPPORTED This function not supported. - -**/ -EFI_STATUS -EFIAPI -FvWriteFile ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN UINT32 NumberOfFiles, - IN EFI_FV_WRITE_POLICY WritePolicy, - IN EFI_FV_WRITE_FILE_DATA *FileData - ); - - -/** - Return information of type InformationType for the requested firmware - volume. - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param InformationType InformationType for requested. - @param BufferSize On input, size of Buffer.On output, the amount of data - returned in Buffer. - @param Buffer A poniter to the data buffer to return. - - @retval EFI_SUCCESS Successfully got volume Information. - -**/ -EFI_STATUS -EFIAPI -FvGetVolumeInfo ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN CONST EFI_GUID *InformationType, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ); - - - -/** - Set information of type InformationType for the requested firmware - volume. - - @param This Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL. - @param InformationType InformationType for requested. - @param BufferSize On input, size of Buffer.On output, the amount of data - returned in Buffer. - @param Buffer A poniter to the data buffer to return. - - @retval EFI_SUCCESS Successfully set volume Information. - -**/ -EFI_STATUS -EFIAPI -FvSetVolumeInfo ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN CONST EFI_GUID *InformationType, - IN UINTN BufferSize, - IN CONST VOID *Buffer - ); - - - -/** - Check if a block of buffer is erased. - - @param ErasePolarity Erase polarity attribute of the firmware volume - @param InBuffer The buffer to be checked - @param BufferSize Size of the buffer in bytes - - @retval TRUE The block of buffer is erased - @retval FALSE The block of buffer is not erased - -**/ -BOOLEAN -IsBufferErased ( - IN UINT8 ErasePolarity, - IN VOID *InBuffer, - IN UINTN BufferSize - ); - - -/** - Get the FFS file state by checking the highest bit set in the header's state field. - - @param ErasePolarity Erase polarity attribute of the firmware volume - @param FfsHeader Points to the FFS file header - - @return FFS File state - -**/ -EFI_FFS_FILE_STATE -GetFileState ( - IN UINT8 ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader - ); - - -/** - Set the FFS file state. - - @param State The state to be set. - @param FfsHeader Points to the FFS file header - - @return None. - -**/ -VOID -SetFileState ( - IN UINT8 State, - IN EFI_FFS_FILE_HEADER *FfsHeader - ); - -/** - Check if it's a valid FFS file header. - - @param ErasePolarity Erase polarity attribute of the firmware volume - @param FfsHeader Points to the FFS file header to be checked - @param FileState FFS file state to be returned - - @retval TRUE Valid FFS file header - @retval FALSE Invalid FFS file header - -**/ -BOOLEAN -IsValidFfsHeader ( - IN UINT8 ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader, - OUT EFI_FFS_FILE_STATE *FileState - ); - - -/** - Check if it's a valid FFS file. - Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first. - - @param ErasePolarity Erase polarity attribute of the firmware volume - @param FfsHeader Points to the FFS file to be checked - - @retval TRUE Valid FFS file - @retval FALSE Invalid FFS file - -**/ -BOOLEAN -IsValidFfsFile ( - IN UINT8 ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader - ); - -#endif diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c b/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c deleted file mode 100644 index 00e0d7d289..0000000000 --- a/MdeModulePkg/Core/Dxe/FwVol/FwVolRead.c +++ /dev/null @@ -1,529 +0,0 @@ -/** @file - Implements functions to read firmware file - -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "FwVolDriver.h" - -/** -Required Alignment Alignment Value in FFS Alignment Value in -(bytes) Attributes Field Firmware Volume Interfaces -1 0 0 -16 1 4 -128 2 7 -512 3 9 -1 KB 4 10 -4 KB 5 12 -32 KB 6 15 -64 KB 7 16 -**/ -UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16}; - -/** - Convert the FFS File Attributes to FV File Attributes - - @param FfsAttributes The attributes of UINT8 type. - - @return The attributes of EFI_FV_FILE_ATTRIBUTES - -**/ -EFI_FV_FILE_ATTRIBUTES -FfsAttributes2FvFileAttributes ( - IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes - ) -{ - UINT8 DataAlignment; - EFI_FV_FILE_ATTRIBUTES FileAttribute; - - DataAlignment = (UINT8) ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3); - ASSERT (DataAlignment < 8); - - FileAttribute = (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[DataAlignment]; - - if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) { - FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED; - } - - return FileAttribute; -} - -/** - Given the input key, search for the next matching file in the volume. - - @param This Indicates the calling context. - @param Key Key is a pointer to a caller allocated - buffer that contains implementation specific - data that is used to track where to begin - the search for the next file. The size of - the buffer must be at least This->KeySize - bytes long. To reinitialize the search and - begin from the beginning of the firmware - volume, the entire buffer must be cleared to - zero. Other than clearing the buffer to - initiate a new search, the caller must not - modify the data in the buffer between calls - to GetNextFile(). - @param FileType FileType is a pointer to a caller allocated - EFI_FV_FILETYPE. The GetNextFile() API can - filter it's search for files based on the - value of *FileType input. A *FileType input - of 0 causes GetNextFile() to search for - files of all types. If a file is found, the - file's type is returned in *FileType. - *FileType is not modified if no file is - found. - @param NameGuid NameGuid is a pointer to a caller allocated - EFI_GUID. If a file is found, the file's - name is returned in *NameGuid. *NameGuid is - not modified if no file is found. - @param Attributes Attributes is a pointer to a caller - allocated EFI_FV_FILE_ATTRIBUTES. If a file - is found, the file's attributes are returned - in *Attributes. *Attributes is not modified - if no file is found. - @param Size Size is a pointer to a caller allocated - UINTN. If a file is found, the file's size - is returned in *Size. *Size is not modified - if no file is found. - - @retval EFI_SUCCESS Successfully find the file. - @retval EFI_DEVICE_ERROR Device error. - @retval EFI_ACCESS_DENIED Fv could not read. - @retval EFI_NOT_FOUND No matching file found. - @retval EFI_INVALID_PARAMETER Invalid parameter - -**/ -EFI_STATUS -EFIAPI -FvGetNextFile ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN OUT VOID *Key, - IN OUT EFI_FV_FILETYPE *FileType, - OUT EFI_GUID *NameGuid, - OUT EFI_FV_FILE_ATTRIBUTES *Attributes, - OUT UINTN *Size - ) -{ - EFI_STATUS Status; - FV_DEVICE *FvDevice; - EFI_FV_ATTRIBUTES FvAttributes; - EFI_FFS_FILE_HEADER *FfsFileHeader; - UINTN *KeyValue; - LIST_ENTRY *Link; - FFS_FILE_LIST_ENTRY *FfsFileEntry; - - FvDevice = FV_DEVICE_FROM_THIS (This); - - Status = FvGetVolumeAttributes (This, &FvAttributes); - if (EFI_ERROR (Status)){ - return Status; - } - - // - // Check if read operation is enabled - // - if ((FvAttributes & EFI_FV2_READ_STATUS) == 0) { - return EFI_ACCESS_DENIED; - } - - if (*FileType > EFI_FV_FILETYPE_SMM_CORE) { - // - // File type needs to be in 0 - 0x0D - // - return EFI_NOT_FOUND; - } - - KeyValue = (UINTN *)Key; - for (;;) { - if (*KeyValue == 0) { - // - // Search for 1st matching file - // - Link = &FvDevice->FfsFileListHeader; - } else { - // - // Key is pointer to FFsFileEntry, so get next one - // - Link = (LIST_ENTRY *)(*KeyValue); - } - - if (Link->ForwardLink == &FvDevice->FfsFileListHeader) { - // - // Next is end of list so we did not find data - // - return EFI_NOT_FOUND; - } - - FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink; - FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader; - - // - // remember the key - // - *KeyValue = (UINTN)FfsFileEntry; - - if (FfsFileHeader->Type == EFI_FV_FILETYPE_FFS_PAD) { - // - // we ignore pad files - // - continue; - } - - if (*FileType == EFI_FV_FILETYPE_ALL) { - // - // Process all file types so we have a match - // - break; - } - - if (*FileType == FfsFileHeader->Type) { - // - // Found a matching file type - // - break; - } - - } - - // - // Return FileType, NameGuid, and Attributes - // - *FileType = FfsFileHeader->Type; - CopyGuid (NameGuid, &FfsFileHeader->Name); - *Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes); - if ((FvDevice->FwVolHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) { - *Attributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED; - } - - // - // we need to substract the header size - // - if (IS_FFS_FILE2 (FfsFileHeader)) { - *Size = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2); - } else { - *Size = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER); - } - - return EFI_SUCCESS; -} - - - -/** - Locates a file in the firmware volume and - copies it to the supplied buffer. - - @param This Indicates the calling context. - @param NameGuid Pointer to an EFI_GUID, which is the - filename. - @param Buffer Buffer is a pointer to pointer to a buffer - in which the file or section contents or are - returned. - @param BufferSize BufferSize is a pointer to caller allocated - UINTN. On input *BufferSize indicates the - size in bytes of the memory region pointed - to by Buffer. On output, *BufferSize - contains the number of bytes required to - read the file. - @param FoundType FoundType is a pointer to a caller allocated - EFI_FV_FILETYPE that on successful return - from Read() contains the type of file read. - This output reflects the file type - irrespective of the value of the SectionType - input. - @param FileAttributes FileAttributes is a pointer to a caller - allocated EFI_FV_FILE_ATTRIBUTES. On - successful return from Read(), - *FileAttributes contains the attributes of - the file read. - @param AuthenticationStatus AuthenticationStatus is a pointer to a - caller allocated UINTN in which the - authentication status is returned. - - @retval EFI_SUCCESS Successfully read to memory buffer. - @retval EFI_WARN_BUFFER_TOO_SMALL Buffer too small. - @retval EFI_NOT_FOUND Not found. - @retval EFI_DEVICE_ERROR Device error. - @retval EFI_ACCESS_DENIED Could not read. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_OUT_OF_RESOURCES Not enough buffer to be allocated. - -**/ -EFI_STATUS -EFIAPI -FvReadFile ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN CONST EFI_GUID *NameGuid, - IN OUT VOID **Buffer, - IN OUT UINTN *BufferSize, - OUT EFI_FV_FILETYPE *FoundType, - OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes, - OUT UINT32 *AuthenticationStatus - ) -{ - EFI_STATUS Status; - FV_DEVICE *FvDevice; - EFI_GUID SearchNameGuid; - EFI_FV_FILETYPE LocalFoundType; - EFI_FV_FILE_ATTRIBUTES LocalAttributes; - UINTN FileSize; - UINT8 *SrcPtr; - EFI_FFS_FILE_HEADER *FfsHeader; - UINTN InputBufferSize; - UINTN WholeFileSize; - - if (NameGuid == NULL) { - return EFI_INVALID_PARAMETER; - } - - FvDevice = FV_DEVICE_FROM_THIS (This); - - - // - // Keep looking until we find the matching NameGuid. - // The Key is really a FfsFileEntry - // - FvDevice->LastKey = 0; - do { - LocalFoundType = 0; - Status = FvGetNextFile ( - This, - &FvDevice->LastKey, - &LocalFoundType, - &SearchNameGuid, - &LocalAttributes, - &FileSize - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - } while (!CompareGuid (&SearchNameGuid, NameGuid)); - - // - // Get a pointer to the header - // - FfsHeader = FvDevice->LastKey->FfsHeader; - if (FvDevice->IsMemoryMapped) { - // - // Memory mapped FV has not been cached, so here is to cache by file. - // - if (!FvDevice->LastKey->FileCached) { - // - // Cache FFS file to memory buffer. - // - WholeFileSize = IS_FFS_FILE2 (FfsHeader) ? FFS_FILE2_SIZE (FfsHeader): FFS_FILE_SIZE (FfsHeader); - FfsHeader = AllocateCopyPool (WholeFileSize, FfsHeader); - if (FfsHeader == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Let FfsHeader in FfsFileEntry point to the cached file buffer. - // - FvDevice->LastKey->FfsHeader = FfsHeader; - FvDevice->LastKey->FileCached = TRUE; - } - } - - // - // Remember callers buffer size - // - InputBufferSize = *BufferSize; - - // - // Calculate return values - // - *FoundType = FfsHeader->Type; - *FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes); - if ((FvDevice->FwVolHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) { - *FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED; - } - // - // Inherit the authentication status. - // - *AuthenticationStatus = FvDevice->AuthenticationStatus; - *BufferSize = FileSize; - - if (Buffer == NULL) { - // - // If Buffer is NULL, we only want to get the information collected so far - // - return EFI_SUCCESS; - } - - // - // Skip over file header - // - if (IS_FFS_FILE2 (FfsHeader)) { - SrcPtr = ((UINT8 *) FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2); - } else { - SrcPtr = ((UINT8 *) FfsHeader) + sizeof (EFI_FFS_FILE_HEADER); - } - - Status = EFI_SUCCESS; - if (*Buffer == NULL) { - // - // Caller passed in a pointer so allocate buffer for them - // - *Buffer = AllocatePool (FileSize); - if (*Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } else if (FileSize > InputBufferSize) { - // - // Callers buffer was not big enough - // - Status = EFI_WARN_BUFFER_TOO_SMALL; - FileSize = InputBufferSize; - } - - // - // Copy data into callers buffer - // - CopyMem (*Buffer, SrcPtr, FileSize); - - return Status; -} - - - -/** - Locates a section in a given FFS File and - copies it to the supplied buffer (not including section header). - - @param This Indicates the calling context. - @param NameGuid Pointer to an EFI_GUID, which is the - filename. - @param SectionType Indicates the section type to return. - @param SectionInstance Indicates which instance of sections with a - type of SectionType to return. - @param Buffer Buffer is a pointer to pointer to a buffer - in which the file or section contents or are - returned. - @param BufferSize BufferSize is a pointer to caller allocated - UINTN. - @param AuthenticationStatus AuthenticationStatus is a pointer to a - caller allocated UINT32 in which the - authentication status is returned. - - @retval EFI_SUCCESS Successfully read the file section into - buffer. - @retval EFI_WARN_BUFFER_TOO_SMALL Buffer too small. - @retval EFI_NOT_FOUND Section not found. - @retval EFI_DEVICE_ERROR Device error. - @retval EFI_ACCESS_DENIED Could not read. - @retval EFI_INVALID_PARAMETER Invalid parameter. - -**/ -EFI_STATUS -EFIAPI -FvReadFileSection ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN CONST EFI_GUID *NameGuid, - IN EFI_SECTION_TYPE SectionType, - IN UINTN SectionInstance, - IN OUT VOID **Buffer, - IN OUT UINTN *BufferSize, - OUT UINT32 *AuthenticationStatus - ) -{ - EFI_STATUS Status; - FV_DEVICE *FvDevice; - EFI_FV_FILETYPE FileType; - EFI_FV_FILE_ATTRIBUTES FileAttributes; - UINTN FileSize; - UINT8 *FileBuffer; - FFS_FILE_LIST_ENTRY *FfsEntry; - - if (NameGuid == NULL || Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - FvDevice = FV_DEVICE_FROM_THIS (This); - - // - // Read the file - // - Status = FvReadFile ( - This, - NameGuid, - NULL, - &FileSize, - &FileType, - &FileAttributes, - AuthenticationStatus - ); - // - // Get the last key used by our call to FvReadFile as it is the FfsEntry for this file. - // - FfsEntry = (FFS_FILE_LIST_ENTRY *) FvDevice->LastKey; - - if (EFI_ERROR (Status)) { - return Status; - } - if (IS_FFS_FILE2 (FfsEntry->FfsHeader)) { - FileBuffer = ((UINT8 *) FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2); - } else { - FileBuffer = ((UINT8 *) FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER); - } - // - // Check to see that the file actually HAS sections before we go any further. - // - if (FileType == EFI_FV_FILETYPE_RAW) { - Status = EFI_NOT_FOUND; - goto Done; - } - - // - // Use FfsEntry to cache Section Extraction Protocol Information - // - if (FfsEntry->StreamHandle == 0) { - Status = OpenSectionStream ( - FileSize, - FileBuffer, - &FfsEntry->StreamHandle - ); - if (EFI_ERROR (Status)) { - goto Done; - } - } - - // - // If SectionType == 0 We need the whole section stream - // - Status = GetSection ( - FfsEntry->StreamHandle, - (SectionType == 0) ? NULL : &SectionType, - NULL, - (SectionType == 0) ? 0 : SectionInstance, - Buffer, - BufferSize, - AuthenticationStatus, - FvDevice->IsFfs3Fv - ); - - if (!EFI_ERROR (Status)) { - // - // Inherit the authentication status. - // - *AuthenticationStatus |= FvDevice->AuthenticationStatus; - } - - // - // Close of stream defered to close of FfsHeader list to allow SEP to cache data - // - -Done: - return Status; -} - - diff --git a/MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c b/MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c deleted file mode 100644 index 1ec563c865..0000000000 --- a/MdeModulePkg/Core/Dxe/FwVol/FwVolWrite.c +++ /dev/null @@ -1,52 +0,0 @@ -/** @file - Implements functions to write firmware file - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "FwVolDriver.h" - - -/** - Writes one or more files to the firmware volume. - - @param This Indicates the calling context. - @param NumberOfFiles Number of files. - @param WritePolicy WritePolicy indicates the level of reliability - for the write in the event of a power failure or - other system failure during the write operation. - @param FileData FileData is an pointer to an array of - EFI_FV_WRITE_DATA. Each element of array - FileData represents a file to be written. - - @retval EFI_SUCCESS Files successfully written to firmware volume - @retval EFI_OUT_OF_RESOURCES Not enough buffer to be allocated. - @retval EFI_DEVICE_ERROR Device error. - @retval EFI_WRITE_PROTECTED Write protected. - @retval EFI_NOT_FOUND Not found. - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_UNSUPPORTED This function not supported. - -**/ -EFI_STATUS -EFIAPI -FvWriteFile ( - IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This, - IN UINT32 NumberOfFiles, - IN EFI_FV_WRITE_POLICY WritePolicy, - IN EFI_FV_WRITE_FILE_DATA *FileData - ) -{ - return EFI_UNSUPPORTED; -} - - diff --git a/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c b/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c deleted file mode 100644 index bc7b34140f..0000000000 --- a/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.c +++ /dev/null @@ -1,712 +0,0 @@ -/** @file - Implementations for Firmware Volume Block protocol. - - It consumes FV HOBs and creates read-only Firmare Volume Block protocol - instances for each of them. - -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "FwVolBlock.h" - -FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = { - { - { - HARDWARE_DEVICE_PATH, - HW_MEMMAP_DP, - { - (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), - (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) - } - }, - EfiMemoryMappedIO, - (EFI_PHYSICAL_ADDRESS) 0, - (EFI_PHYSICAL_ADDRESS) 0, - }, - { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { - END_DEVICE_PATH_LENGTH, - 0 - } - } -}; - -FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = { - { - { - MEDIA_DEVICE_PATH, - MEDIA_PIWG_FW_VOL_DP, - { - (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), - (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) - } - }, - { 0 } - }, - { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { - END_DEVICE_PATH_LENGTH, - 0 - } - } -}; - -EFI_FW_VOL_BLOCK_DEVICE mFwVolBlock = { - FVB_DEVICE_SIGNATURE, - NULL, - NULL, - { - FwVolBlockGetAttributes, - (EFI_FVB_SET_ATTRIBUTES)FwVolBlockSetAttributes, - FwVolBlockGetPhysicalAddress, - FwVolBlockGetBlockSize, - FwVolBlockReadBlock, - (EFI_FVB_WRITE)FwVolBlockWriteBlock, - (EFI_FVB_ERASE_BLOCKS)FwVolBlockEraseBlock, - NULL - }, - 0, - NULL, - 0, - 0, - 0 -}; - - - -/** - Retrieves Volume attributes. No polarity translations are done. - - @param This Calling context - @param Attributes output buffer which contains attributes - - @retval EFI_SUCCESS The firmware volume attributes were returned. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockGetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - - // - // Since we are read only, it's safe to get attributes data from our in-memory copy. - // - *Attributes = FvbDevice->FvbAttributes & ~EFI_FVB2_WRITE_STATUS; - - return EFI_SUCCESS; -} - - - -/** - Modifies the current settings of the firmware volume according to the input parameter. - - @param This Calling context - @param Attributes input buffer which contains attributes - - @retval EFI_SUCCESS The firmware volume attributes were returned. - @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with - the capabilities as declared in the firmware - volume header. - @retval EFI_UNSUPPORTED Not supported. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockSetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN CONST EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - return EFI_UNSUPPORTED; -} - - - -/** - The EraseBlock() function erases one or more blocks as denoted by the - variable argument list. The entire parameter list of blocks must be verified - prior to erasing any blocks. If a block is requested that does not exist - within the associated firmware volume (it has a larger index than the last - block of the firmware volume), the EraseBlock() function must return - EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. - - @param This Calling context - @param ... Starting LBA followed by Number of Lba to erase. - a -1 to terminate the list. - - @retval EFI_SUCCESS The erase request was successfully completed. - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled - state. - @retval EFI_DEVICE_ERROR The block device is not functioning correctly - and could not be written. The firmware device - may have been partially erased. - @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable - argument list do - @retval EFI_UNSUPPORTED Not supported. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockEraseBlock ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - ... - ) -{ - return EFI_UNSUPPORTED; -} - - - -/** - Read the specified number of bytes from the block to the input buffer. - - @param This Indicates the calling context. - @param Lba The starting logical block index to read. - @param Offset Offset into the block at which to begin reading. - @param NumBytes Pointer to a UINT32. At entry, *NumBytes - contains the total size of the buffer. At exit, - *NumBytes contains the total number of bytes - actually read. - @param Buffer Pinter to a caller-allocated buffer that - contains the destine for the read. - - @retval EFI_SUCCESS The firmware volume was read successfully. - @retval EFI_BAD_BUFFER_SIZE The read was attempted across an LBA boundary. - @retval EFI_ACCESS_DENIED Access denied. - @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not - be read. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockReadBlock ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN CONST EFI_LBA Lba, - IN CONST UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - UINT8 *LbaOffset; - UINTN LbaStart; - UINTN NumOfBytesRead; - UINTN LbaIndex; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - - // - // Check if This FW can be read - // - if ((FvbDevice->FvbAttributes & EFI_FVB2_READ_STATUS) == 0) { - return EFI_ACCESS_DENIED; - } - - LbaIndex = (UINTN) Lba; - if (LbaIndex >= FvbDevice->NumBlocks) { - // - // Invalid Lba, read nothing. - // - *NumBytes = 0; - return EFI_BAD_BUFFER_SIZE; - } - - if (Offset > FvbDevice->LbaCache[LbaIndex].Length) { - // - // all exceed boundary, read nothing. - // - *NumBytes = 0; - return EFI_BAD_BUFFER_SIZE; - } - - NumOfBytesRead = *NumBytes; - if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) { - // - // partial exceed boundary, read data from current postion to end. - // - NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset; - } - - LbaStart = FvbDevice->LbaCache[LbaIndex].Base; - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN) FvbDevice->BaseAddress); - LbaOffset = (UINT8 *) FwVolHeader + LbaStart + Offset; - - // - // Perform read operation - // - CopyMem (Buffer, LbaOffset, NumOfBytesRead); - - if (NumOfBytesRead == *NumBytes) { - return EFI_SUCCESS; - } - - *NumBytes = NumOfBytesRead; - return EFI_BAD_BUFFER_SIZE; -} - - - -/** - Writes the specified number of bytes from the input buffer to the block. - - @param This Indicates the calling context. - @param Lba The starting logical block index to write to. - @param Offset Offset into the block at which to begin writing. - @param NumBytes Pointer to a UINT32. At entry, *NumBytes - contains the total size of the buffer. At exit, - *NumBytes contains the total number of bytes - actually written. - @param Buffer Pinter to a caller-allocated buffer that - contains the source for the write. - - @retval EFI_SUCCESS The firmware volume was written successfully. - @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. - On output, NumBytes contains the total number of - bytes actually written. - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled - state. - @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not - be written. - @retval EFI_UNSUPPORTED Not supported. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockWriteBlock ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - - - -/** - Get Fvb's base address. - - @param This Indicates the calling context. - @param Address Fvb device base address. - - @retval EFI_SUCCESS Successfully got Fvb's base address. - @retval EFI_UNSUPPORTED Not supported. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - - if ((FvbDevice->FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) { - *Address = FvbDevice->BaseAddress; - return EFI_SUCCESS; - } - - return EFI_UNSUPPORTED; -} - - - -/** - Retrieves the size in bytes of a specific block within a firmware volume. - - @param This Indicates the calling context. - @param Lba Indicates the block for which to return the - size. - @param BlockSize Pointer to a caller-allocated UINTN in which the - size of the block is returned. - @param NumberOfBlocks Pointer to a caller-allocated UINTN in which the - number of consecutive blocks starting with Lba - is returned. All blocks in this range have a - size of BlockSize. - - @retval EFI_SUCCESS The firmware volume base address is returned. - @retval EFI_INVALID_PARAMETER The requested LBA is out of range. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN CONST EFI_LBA Lba, - IN OUT UINTN *BlockSize, - IN OUT UINTN *NumberOfBlocks - ) -{ - UINTN TotalBlocks; - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - - FvbDevice = FVB_DEVICE_FROM_THIS (This); - - // - // Do parameter checking - // - if (Lba >= FvbDevice->NumBlocks) { - return EFI_INVALID_PARAMETER; - } - - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress); - - PtrBlockMapEntry = FwVolHeader->BlockMap; - - // - // Search the block map for the given block - // - TotalBlocks = 0; - while ((PtrBlockMapEntry->NumBlocks != 0) || (PtrBlockMapEntry->Length !=0 )) { - TotalBlocks += PtrBlockMapEntry->NumBlocks; - if (Lba < TotalBlocks) { - // - // We find the range - // - break; - } - - PtrBlockMapEntry++; - } - - *BlockSize = PtrBlockMapEntry->Length; - *NumberOfBlocks = TotalBlocks - (UINTN)Lba; - - return EFI_SUCCESS; -} - -/** - - Get FVB authentication status - - @param FvbProtocol FVB protocol. - - @return Authentication status. - -**/ -UINT32 -GetFvbAuthenticationStatus ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol - ) -{ - EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; - UINT32 AuthenticationStatus; - - AuthenticationStatus = 0; - FvbDevice = BASE_CR (FvbProtocol, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance); - if (FvbDevice->Signature == FVB_DEVICE_SIGNATURE) { - AuthenticationStatus = FvbDevice->AuthenticationStatus; - } - - return AuthenticationStatus; -} - -/** - This routine produces a firmware volume block protocol on a given - buffer. - - @param BaseAddress base address of the firmware volume image - @param Length length of the firmware volume image - @param ParentHandle handle of parent firmware volume, if this image - came from an FV image file and section in another firmware - volume (ala capsules) - @param AuthenticationStatus Authentication status inherited, if this image - came from an FV image file and section in another firmware volume. - @param FvProtocol Firmware volume block protocol produced. - - @retval EFI_VOLUME_CORRUPTED Volume corrupted. - @retval EFI_OUT_OF_RESOURCES No enough buffer to be allocated. - @retval EFI_SUCCESS Successfully produced a FVB protocol on given - buffer. - -**/ -EFI_STATUS -ProduceFVBProtocolOnBuffer ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN EFI_HANDLE ParentHandle, - IN UINT32 AuthenticationStatus, - OUT EFI_HANDLE *FvProtocol OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_FW_VOL_BLOCK_DEVICE *FvbDev; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - UINTN BlockIndex; - UINTN BlockIndex2; - UINTN LinearOffset; - UINT32 FvAlignment; - EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; - - FvAlignment = 0; - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN) BaseAddress; - // - // Validate FV Header, if not as expected, return - // - if (FwVolHeader->Signature != EFI_FVH_SIGNATURE) { - return EFI_VOLUME_CORRUPTED; - } - - // - // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume - // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from - // its initial linked location and maintain its alignment. - // - if ((FwVolHeader->Attributes & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) { - // - // Get FvHeader alignment - // - FvAlignment = 1 << ((FwVolHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16); - // - // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value. - // - if (FvAlignment < 8) { - FvAlignment = 8; - } - if ((UINTN)BaseAddress % FvAlignment != 0) { - // - // FvImage buffer is not at its required alignment. - // - DEBUG (( - DEBUG_ERROR, - "Unaligned FvImage found at 0x%lx:0x%lx, the required alignment is 0x%x\n", - BaseAddress, - Length, - FvAlignment - )); - return EFI_VOLUME_CORRUPTED; - } - } - - // - // Allocate EFI_FW_VOL_BLOCK_DEVICE - // - FvbDev = AllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock); - if (FvbDev == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - FvbDev->BaseAddress = BaseAddress; - FvbDev->FvbAttributes = FwVolHeader->Attributes; - FvbDev->FwVolBlockInstance.ParentHandle = ParentHandle; - if (ParentHandle != NULL) { - FvbDev->AuthenticationStatus = AuthenticationStatus; - } - - // - // Init the block caching fields of the device - // First, count the number of blocks - // - FvbDev->NumBlocks = 0; - for (PtrBlockMapEntry = FwVolHeader->BlockMap; - PtrBlockMapEntry->NumBlocks != 0; - PtrBlockMapEntry++) { - FvbDev->NumBlocks += PtrBlockMapEntry->NumBlocks; - } - - // - // Second, allocate the cache - // - if (FvbDev->NumBlocks >= (MAX_ADDRESS / sizeof (LBA_CACHE))) { - CoreFreePool (FvbDev); - return EFI_OUT_OF_RESOURCES; - } - FvbDev->LbaCache = AllocatePool (FvbDev->NumBlocks * sizeof (LBA_CACHE)); - if (FvbDev->LbaCache == NULL) { - CoreFreePool (FvbDev); - return EFI_OUT_OF_RESOURCES; - } - - // - // Last, fill in the cache with the linear address of the blocks - // - BlockIndex = 0; - LinearOffset = 0; - for (PtrBlockMapEntry = FwVolHeader->BlockMap; - PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) { - for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) { - FvbDev->LbaCache[BlockIndex].Base = LinearOffset; - FvbDev->LbaCache[BlockIndex].Length = PtrBlockMapEntry->Length; - LinearOffset += PtrBlockMapEntry->Length; - BlockIndex++; - } - } - - // - // Judget whether FV name guid is produced in Fv extension header - // - if (FwVolHeader->ExtHeaderOffset == 0) { - // - // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH - // - FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); - if (FvbDev->DevicePath == NULL) { - FreePool (FvbDev); - return EFI_OUT_OF_RESOURCES; - } - ((FV_MEMMAP_DEVICE_PATH *) FvbDev->DevicePath)->MemMapDevPath.StartingAddress = BaseAddress; - ((FV_MEMMAP_DEVICE_PATH *) FvbDev->DevicePath)->MemMapDevPath.EndingAddress = BaseAddress + FwVolHeader->FvLength - 1; - } else { - // - // FV contains extension header, then produce MEDIA_FW_VOL_DEVICE_PATH - // - FvbDev->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH), &mFvPIWGDevicePathTemplate); - if (FvbDev->DevicePath == NULL) { - FreePool (FvbDev); - return EFI_OUT_OF_RESOURCES; - } - CopyGuid ( - &((FV_PIWG_DEVICE_PATH *)FvbDev->DevicePath)->FvDevPath.FvName, - (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset) - ); - } - - // - // - // Attach FvVolBlock Protocol to new handle - // - Status = CoreInstallMultipleProtocolInterfaces ( - &FvbDev->Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbDev->FwVolBlockInstance, - &gEfiDevicePathProtocolGuid, FvbDev->DevicePath, - NULL - ); - - // - // If they want the handle back, set it. - // - if (FvProtocol != NULL) { - *FvProtocol = FvbDev->Handle; - } - - return Status; -} - - - -/** - This routine consumes FV hobs and produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate. - - @param ImageHandle The image handle. - @param SystemTable The system table. - - @retval EFI_SUCCESS Successfully initialized firmware volume block - driver. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockDriverInit ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_PEI_HOB_POINTERS FvHob; - - // - // Core Needs Firmware Volumes to function - // - FvHob.Raw = GetHobList (); - while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) { - // - // Produce an FVB protocol for it - // - ProduceFVBProtocolOnBuffer (FvHob.FirmwareVolume->BaseAddress, FvHob.FirmwareVolume->Length, NULL, 0, NULL); - FvHob.Raw = GET_NEXT_HOB (FvHob); - } - - return EFI_SUCCESS; -} - - - -/** - This DXE service routine is used to process a firmware volume. In - particular, it can be called by BDS to process a single firmware - volume found in a capsule. - - Caution: The caller need validate the input firmware volume to follow - PI specification. - DxeCore will trust the input data and process firmware volume directly. - - @param FvHeader pointer to a firmware volume header - @param Size the size of the buffer pointed to by FvHeader - @param FVProtocolHandle the handle on which a firmware volume protocol - was produced for the firmware volume passed in. - - @retval EFI_OUT_OF_RESOURCES if an FVB could not be produced due to lack of - system resources - @retval EFI_VOLUME_CORRUPTED if the volume was corrupted - @retval EFI_SUCCESS a firmware volume protocol was produced for the - firmware volume - -**/ -EFI_STATUS -EFIAPI -CoreProcessFirmwareVolume ( - IN VOID *FvHeader, - IN UINTN Size, - OUT EFI_HANDLE *FVProtocolHandle - ) -{ - VOID *Ptr; - EFI_STATUS Status; - - *FVProtocolHandle = NULL; - Status = ProduceFVBProtocolOnBuffer ( - (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, - (UINT64)Size, - NULL, - 0, - FVProtocolHandle - ); - // - // Since in our implementation we use register-protocol-notify to put a - // FV protocol on the FVB protocol handle, we can't directly verify that - // the FV protocol was produced. Therefore here we will check the handle - // and make sure an FV protocol is on it. This indicates that all went - // well. Otherwise we have to assume that the volume was corrupted - // somehow. - // - if (!EFI_ERROR(Status)) { - ASSERT (*FVProtocolHandle != NULL); - Ptr = NULL; - Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **) &Ptr); - if (EFI_ERROR(Status) || (Ptr == NULL)) { - return EFI_VOLUME_CORRUPTED; - } - return EFI_SUCCESS; - } - return Status; -} - - - diff --git a/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.h b/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.h deleted file mode 100644 index 7ad4e35ecb..0000000000 --- a/MdeModulePkg/Core/Dxe/FwVolBlock/FwVolBlock.h +++ /dev/null @@ -1,244 +0,0 @@ -/** @file - Firmware Volume Block protocol functions. - Consumes FV hobs and creates appropriate block protocols. - -Copyright (c) 2006 - 2012, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _FWVOL_BLOCK_H_ -#define _FWVOL_BLOCK_H_ - - -#define FVB_DEVICE_SIGNATURE SIGNATURE_32('_','F','V','B') - - -typedef struct { - UINTN Base; - UINTN Length; -} LBA_CACHE; - -typedef struct { - MEMMAP_DEVICE_PATH MemMapDevPath; - EFI_DEVICE_PATH_PROTOCOL EndDevPath; -} FV_MEMMAP_DEVICE_PATH; - -// -// UEFI Specification define FV device path format if FV provide name guid in extension header -// -typedef struct { - MEDIA_FW_VOL_DEVICE_PATH FvDevPath; - EFI_DEVICE_PATH_PROTOCOL EndDevPath; -} FV_PIWG_DEVICE_PATH; - -typedef struct { - UINTN Signature; - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance; - UINTN NumBlocks; - LBA_CACHE *LbaCache; - UINT32 FvbAttributes; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINT32 AuthenticationStatus; -} EFI_FW_VOL_BLOCK_DEVICE; - - -#define FVB_DEVICE_FROM_THIS(a) \ - CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE) - - -/** - Retrieves Volume attributes. No polarity translations are done. - - @param This Calling context - @param Attributes output buffer which contains attributes - - @retval EFI_SUCCESS The firmware volume attributes were returned. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockGetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - - - -/** - Modifies the current settings of the firmware volume according to the input parameter. - - @param This Calling context - @param Attributes input buffer which contains attributes - - @retval EFI_SUCCESS The firmware volume attributes were returned. - @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with - the capabilities as declared in the firmware - volume header. - @retval EFI_UNSUPPORTED Not supported. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockSetAttributes ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN CONST EFI_FVB_ATTRIBUTES_2 *Attributes - ); - - - -/** - The EraseBlock() function erases one or more blocks as denoted by the - variable argument list. The entire parameter list of blocks must be verified - prior to erasing any blocks. If a block is requested that does not exist - within the associated firmware volume (it has a larger index than the last - block of the firmware volume), the EraseBlock() function must return - EFI_INVALID_PARAMETER without modifying the contents of the firmware volume. - - @param This Calling context - @param ... Starting LBA followed by Number of Lba to erase. - a -1 to terminate the list. - - @retval EFI_SUCCESS The erase request was successfully completed. - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled - state. - @retval EFI_DEVICE_ERROR The block device is not functioning correctly - and could not be written. The firmware device - may have been partially erased. - @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable - argument list do - @retval EFI_UNSUPPORTED Not supported. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockEraseBlock ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - ... - ); - - - -/** - Read the specified number of bytes from the block to the input buffer. - - @param This Indicates the calling context. - @param Lba The starting logical block index to read. - @param Offset Offset into the block at which to begin reading. - @param NumBytes Pointer to a UINT32. At entry, *NumBytes - contains the total size of the buffer. At exit, - *NumBytes contains the total number of bytes - actually read. - @param Buffer Pinter to a caller-allocated buffer that - contains the destine for the read. - - @retval EFI_SUCCESS The firmware volume was read successfully. - @retval EFI_BAD_BUFFER_SIZE The read was attempted across an LBA boundary. - @retval EFI_ACCESS_DENIED Access denied. - @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not - be read. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockReadBlock ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN CONST EFI_LBA Lba, - IN CONST UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ); - - - -/** - Writes the specified number of bytes from the input buffer to the block. - - @param This Indicates the calling context. - @param Lba The starting logical block index to write to. - @param Offset Offset into the block at which to begin writing. - @param NumBytes Pointer to a UINT32. At entry, *NumBytes - contains the total size of the buffer. At exit, - *NumBytes contains the total number of bytes - actually written. - @param Buffer Pinter to a caller-allocated buffer that - contains the source for the write. - - @retval EFI_SUCCESS The firmware volume was written successfully. - @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. - On output, NumBytes contains the total number of - bytes actually written. - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled - state. - @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not - be written. - @retval EFI_UNSUPPORTED Not supported. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockWriteBlock ( - IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - - - -/** - Get Fvb's base address. - - @param This Indicates the calling context. - @param Address Fvb device base address. - - @retval EFI_SUCCESS Successfully got Fvb's base address. - @retval EFI_UNSUPPORTED Not supported. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - - - -/** - Retrieves the size in bytes of a specific block within a firmware volume. - - @param This Indicates the calling context. - @param Lba Indicates the block for which to return the - size. - @param BlockSize Pointer to a caller-allocated UINTN in which the - size of the block is returned. - @param NumberOfBlocks Pointer to a caller-allocated UINTN in which the - number of consecutive blocks starting with Lba - is returned. All blocks in this range have a - size of BlockSize. - - @retval EFI_SUCCESS The firmware volume base address is returned. - @retval EFI_INVALID_PARAMETER The requested LBA is out of range. - -**/ -EFI_STATUS -EFIAPI -FwVolBlockGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, - IN CONST EFI_LBA Lba, - IN OUT UINTN *BlockSize, - IN OUT UINTN *NumberOfBlocks - ); - - -#endif diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c b/MdeModulePkg/Core/Dxe/Gcd/Gcd.c deleted file mode 100644 index a06f8bb77c..0000000000 --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.c +++ /dev/null @@ -1,2614 +0,0 @@ -/** @file - The file contains the GCD related services in the EFI Boot Services Table. - The GCD services are used to manage the memory and I/O regions that - are accessible to the CPU that is executing the DXE core. - -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Gcd.h" - -#define MINIMUM_INITIAL_MEMORY_SIZE 0x10000 - -#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ - EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ - EFI_RESOURCE_ATTRIBUTE_TESTED | \ - EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | \ - EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \ - EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \ - EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED | \ - EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \ - EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \ - EFI_RESOURCE_ATTRIBUTE_64_BIT_IO | \ - EFI_RESOURCE_ATTRIBUTE_PERSISTENT ) - -#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ - EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ - EFI_RESOURCE_ATTRIBUTE_TESTED ) - -#define INITIALIZED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ - EFI_RESOURCE_ATTRIBUTE_INITIALIZED ) - -#define PRESENT_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT) - -#define INVALID_CPU_ARCH_ATTRIBUTES 0xffffffff - -// -// Module Variables -// -EFI_LOCK mGcdMemorySpaceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); -EFI_LOCK mGcdIoSpaceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); -LIST_ENTRY mGcdMemorySpaceMap = INITIALIZE_LIST_HEAD_VARIABLE (mGcdMemorySpaceMap); -LIST_ENTRY mGcdIoSpaceMap = INITIALIZE_LIST_HEAD_VARIABLE (mGcdIoSpaceMap); - -EFI_GCD_MAP_ENTRY mGcdMemorySpaceMapEntryTemplate = { - EFI_GCD_MAP_SIGNATURE, - { - NULL, - NULL - }, - 0, - 0, - 0, - 0, - EfiGcdMemoryTypeNonExistent, - (EFI_GCD_IO_TYPE) 0, - NULL, - NULL -}; - -EFI_GCD_MAP_ENTRY mGcdIoSpaceMapEntryTemplate = { - EFI_GCD_MAP_SIGNATURE, - { - NULL, - NULL - }, - 0, - 0, - 0, - 0, - (EFI_GCD_MEMORY_TYPE) 0, - EfiGcdIoTypeNonExistent, - NULL, - NULL -}; - -GCD_ATTRIBUTE_CONVERSION_ENTRY mAttributeConversionTable[] = { - { EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE, EFI_MEMORY_UC, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED, EFI_MEMORY_UCE, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE, EFI_MEMORY_WC, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE, EFI_MEMORY_WT, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE, EFI_MEMORY_WB, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE, EFI_MEMORY_RP, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE, EFI_MEMORY_WP, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE, EFI_MEMORY_XP, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE, EFI_MEMORY_RO, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_PRESENT, EFI_MEMORY_PRESENT, FALSE }, - { EFI_RESOURCE_ATTRIBUTE_INITIALIZED, EFI_MEMORY_INITIALIZED, FALSE }, - { EFI_RESOURCE_ATTRIBUTE_TESTED, EFI_MEMORY_TESTED, FALSE }, - { EFI_RESOURCE_ATTRIBUTE_PERSISTABLE, EFI_MEMORY_NV, TRUE }, - { EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE, EFI_MEMORY_MORE_RELIABLE, TRUE }, - { 0, 0, FALSE } -}; - -/// -/// Lookup table used to print GCD Memory Space Map -/// -GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdMemoryTypeNames[] = { - "NonExist ", // EfiGcdMemoryTypeNonExistent - "Reserved ", // EfiGcdMemoryTypeReserved - "SystemMem", // EfiGcdMemoryTypeSystemMemory - "MMIO ", // EfiGcdMemoryTypeMemoryMappedIo - "PersisMem", // EfiGcdMemoryTypePersistentMemory - "MoreRelia", // EfiGcdMemoryTypeMoreReliable - "Unknown " // EfiGcdMemoryTypeMaximum -}; - -/// -/// Lookup table used to print GCD I/O Space Map -/// -GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdIoTypeNames[] = { - "NonExist", // EfiGcdIoTypeNonExistent - "Reserved", // EfiGcdIoTypeReserved - "I/O ", // EfiGcdIoTypeIo - "Unknown " // EfiGcdIoTypeMaximum -}; - -/// -/// Lookup table used to print GCD Allocation Types -/// -GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdAllocationTypeNames[] = { - "AnySearchBottomUp ", // EfiGcdAllocateAnySearchBottomUp - "MaxAddressSearchBottomUp ", // EfiGcdAllocateMaxAddressSearchBottomUp - "AtAddress ", // EfiGcdAllocateAddress - "AnySearchTopDown ", // EfiGcdAllocateAnySearchTopDown - "MaxAddressSearchTopDown ", // EfiGcdAllocateMaxAddressSearchTopDown - "Unknown " // EfiGcdMaxAllocateType -}; - -/** - Dump the entire contents if the GCD Memory Space Map using DEBUG() macros when - PcdDebugPrintErrorLevel has the DEBUG_GCD bit set. - - @param InitialMap TRUE if the initial GCD Memory Map is being dumped. Otherwise, FALSE. - -**/ -VOID -EFIAPI -CoreDumpGcdMemorySpaceMap ( - BOOLEAN InitialMap - ) -{ - DEBUG_CODE ( - EFI_STATUS Status; - UINTN NumberOfDescriptors; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; - UINTN Index; - - Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); - ASSERT (Status == EFI_SUCCESS && MemorySpaceMap != NULL); - - if (InitialMap) { - DEBUG ((DEBUG_GCD, "GCD:Initial GCD Memory Space Map\n")); - } - DEBUG ((DEBUG_GCD, "GCDMemType Range Capabilities Attributes \n")); - DEBUG ((DEBUG_GCD, "========== ================================= ================ ================\n")); - for (Index = 0; Index < NumberOfDescriptors; Index++) { - DEBUG ((DEBUG_GCD, "%a %016lx-%016lx %016lx %016lx%c\n", - mGcdMemoryTypeNames[MIN (MemorySpaceMap[Index].GcdMemoryType, EfiGcdMemoryTypeMaximum)], - MemorySpaceMap[Index].BaseAddress, - MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - 1, - MemorySpaceMap[Index].Capabilities, - MemorySpaceMap[Index].Attributes, - MemorySpaceMap[Index].ImageHandle == NULL ? ' ' : '*' - )); - } - DEBUG ((DEBUG_GCD, "\n")); - FreePool (MemorySpaceMap); - ); -} - -/** - Dump the entire contents if the GCD I/O Space Map using DEBUG() macros when - PcdDebugPrintErrorLevel has the DEBUG_GCD bit set. - - @param InitialMap TRUE if the initial GCD I/O Map is being dumped. Otherwise, FALSE. - -**/ -VOID -EFIAPI -CoreDumpGcdIoSpaceMap ( - BOOLEAN InitialMap - ) -{ - DEBUG_CODE ( - EFI_STATUS Status; - UINTN NumberOfDescriptors; - EFI_GCD_IO_SPACE_DESCRIPTOR *IoSpaceMap; - UINTN Index; - - Status = CoreGetIoSpaceMap (&NumberOfDescriptors, &IoSpaceMap); - ASSERT (Status == EFI_SUCCESS && IoSpaceMap != NULL); - - if (InitialMap) { - DEBUG ((DEBUG_GCD, "GCD:Initial GCD I/O Space Map\n")); - } - - DEBUG ((DEBUG_GCD, "GCDIoType Range \n")); - DEBUG ((DEBUG_GCD, "========== =================================\n")); - for (Index = 0; Index < NumberOfDescriptors; Index++) { - DEBUG ((DEBUG_GCD, "%a %016lx-%016lx%c\n", - mGcdIoTypeNames[MIN (IoSpaceMap[Index].GcdIoType, EfiGcdIoTypeMaximum)], - IoSpaceMap[Index].BaseAddress, - IoSpaceMap[Index].BaseAddress + IoSpaceMap[Index].Length - 1, - IoSpaceMap[Index].ImageHandle == NULL ? ' ' : '*' - )); - } - DEBUG ((DEBUG_GCD, "\n")); - FreePool (IoSpaceMap); - ); -} - -/** - Validate resource descriptor HOB's attributes. - - If Attributes includes some memory resource's settings, it should include - the corresponding capabilites also. - - @param Attributes Resource descriptor HOB attributes. - -**/ -VOID -CoreValidateResourceDescriptorHobAttributes ( - IN UINT64 Attributes - ) -{ - ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED) == 0) || - ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE) != 0)); - ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED) == 0) || - ((Attributes & EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE) != 0)); - ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED) == 0) || - ((Attributes & EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE) != 0)); - ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED) == 0) || - ((Attributes & EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE) != 0)); - ASSERT (((Attributes & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) == 0) || - ((Attributes & EFI_RESOURCE_ATTRIBUTE_PERSISTABLE) != 0)); -} - -/** - Acquire memory lock on mGcdMemorySpaceLock. - -**/ -VOID -CoreAcquireGcdMemoryLock ( - VOID - ) -{ - CoreAcquireLock (&mGcdMemorySpaceLock); -} - - - -/** - Release memory lock on mGcdMemorySpaceLock. - -**/ -VOID -CoreReleaseGcdMemoryLock ( - VOID - ) -{ - CoreReleaseLock (&mGcdMemorySpaceLock); -} - - - -/** - Acquire memory lock on mGcdIoSpaceLock. - -**/ -VOID -CoreAcquireGcdIoLock ( - VOID - ) -{ - CoreAcquireLock (&mGcdIoSpaceLock); -} - - -/** - Release memory lock on mGcdIoSpaceLock. - -**/ -VOID -CoreReleaseGcdIoLock ( - VOID - ) -{ - CoreReleaseLock (&mGcdIoSpaceLock); -} - - - -// -// GCD Initialization Worker Functions -// -/** - Aligns a value to the specified boundary. - - @param Value 64 bit value to align - @param Alignment Log base 2 of the boundary to align Value to - @param RoundUp TRUE if Value is to be rounded up to the nearest - aligned boundary. FALSE is Value is to be - rounded down to the nearest aligned boundary. - - @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment. - -**/ -UINT64 -AlignValue ( - IN UINT64 Value, - IN UINTN Alignment, - IN BOOLEAN RoundUp - ) -{ - UINT64 AlignmentMask; - - AlignmentMask = LShiftU64 (1, Alignment) - 1; - if (RoundUp) { - Value += AlignmentMask; - } - return Value & (~AlignmentMask); -} - - -/** - Aligns address to the page boundary. - - @param Value 64 bit address to align - - @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment. - -**/ -UINT64 -PageAlignAddress ( - IN UINT64 Value - ) -{ - return AlignValue (Value, EFI_PAGE_SHIFT, TRUE); -} - - -/** - Aligns length to the page boundary. - - @param Value 64 bit length to align - - @return A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment. - -**/ -UINT64 -PageAlignLength ( - IN UINT64 Value - ) -{ - return AlignValue (Value, EFI_PAGE_SHIFT, FALSE); -} - -// -// GCD Memory Space Worker Functions -// - -/** - Allocate pool for two entries. - - @param TopEntry An entry of GCD map - @param BottomEntry An entry of GCD map - - @retval EFI_OUT_OF_RESOURCES No enough buffer to be allocated. - @retval EFI_SUCCESS Both entries successfully allocated. - -**/ -EFI_STATUS -CoreAllocateGcdMapEntry ( - IN OUT EFI_GCD_MAP_ENTRY **TopEntry, - IN OUT EFI_GCD_MAP_ENTRY **BottomEntry - ) -{ - *TopEntry = AllocateZeroPool (sizeof (EFI_GCD_MAP_ENTRY)); - if (*TopEntry == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - *BottomEntry = AllocateZeroPool (sizeof (EFI_GCD_MAP_ENTRY)); - if (*BottomEntry == NULL) { - CoreFreePool (*TopEntry); - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} - - -/** - Internal function. Inserts a new descriptor into a sorted list - - @param Link The linked list to insert the range BaseAddress - and Length into - @param Entry A pointer to the entry that is inserted - @param BaseAddress The base address of the new range - @param Length The length of the new range in bytes - @param TopEntry Top pad entry to insert if needed. - @param BottomEntry Bottom pad entry to insert if needed. - - @retval EFI_SUCCESS The new range was inserted into the linked list - -**/ -EFI_STATUS -CoreInsertGcdMapEntry ( - IN LIST_ENTRY *Link, - IN EFI_GCD_MAP_ENTRY *Entry, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN EFI_GCD_MAP_ENTRY *TopEntry, - IN EFI_GCD_MAP_ENTRY *BottomEntry - ) -{ - ASSERT (Length != 0); - - if (BaseAddress > Entry->BaseAddress) { - ASSERT (BottomEntry->Signature == 0); - - CopyMem (BottomEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY)); - Entry->BaseAddress = BaseAddress; - BottomEntry->EndAddress = BaseAddress - 1; - InsertTailList (Link, &BottomEntry->Link); - } - - if ((BaseAddress + Length - 1) < Entry->EndAddress) { - ASSERT (TopEntry->Signature == 0); - - CopyMem (TopEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY)); - TopEntry->BaseAddress = BaseAddress + Length; - Entry->EndAddress = BaseAddress + Length - 1; - InsertHeadList (Link, &TopEntry->Link); - } - - return EFI_SUCCESS; -} - - -/** - Merge the Gcd region specified by Link and its adjacent entry. - - @param Link Specify the entry to be merged (with its - adjacent entry). - @param Forward Direction (forward or backward). - @param Map Boundary. - - @retval EFI_SUCCESS Successfully returned. - @retval EFI_UNSUPPORTED These adjacent regions could not merge. - -**/ -EFI_STATUS -CoreMergeGcdMapEntry ( - IN LIST_ENTRY *Link, - IN BOOLEAN Forward, - IN LIST_ENTRY *Map - ) -{ - LIST_ENTRY *AdjacentLink; - EFI_GCD_MAP_ENTRY *Entry; - EFI_GCD_MAP_ENTRY *AdjacentEntry; - - // - // Get adjacent entry - // - if (Forward) { - AdjacentLink = Link->ForwardLink; - } else { - AdjacentLink = Link->BackLink; - } - - // - // If AdjacentLink is the head of the list, then no merge can be performed - // - if (AdjacentLink == Map) { - return EFI_SUCCESS; - } - - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - AdjacentEntry = CR (AdjacentLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - - if (Entry->Capabilities != AdjacentEntry->Capabilities) { - return EFI_UNSUPPORTED; - } - if (Entry->Attributes != AdjacentEntry->Attributes) { - return EFI_UNSUPPORTED; - } - if (Entry->GcdMemoryType != AdjacentEntry->GcdMemoryType) { - return EFI_UNSUPPORTED; - } - if (Entry->GcdIoType != AdjacentEntry->GcdIoType) { - return EFI_UNSUPPORTED; - } - if (Entry->ImageHandle != AdjacentEntry->ImageHandle) { - return EFI_UNSUPPORTED; - } - if (Entry->DeviceHandle != AdjacentEntry->DeviceHandle) { - return EFI_UNSUPPORTED; - } - - if (Forward) { - Entry->EndAddress = AdjacentEntry->EndAddress; - } else { - Entry->BaseAddress = AdjacentEntry->BaseAddress; - } - RemoveEntryList (AdjacentLink); - CoreFreePool (AdjacentEntry); - - return EFI_SUCCESS; -} - - -/** - Merge adjacent entries on total chain. - - @param TopEntry Top entry of GCD map. - @param BottomEntry Bottom entry of GCD map. - @param StartLink Start link of the list for this loop. - @param EndLink End link of the list for this loop. - @param Map Boundary. - - @retval EFI_SUCCESS GCD map successfully cleaned up. - -**/ -EFI_STATUS -CoreCleanupGcdMapEntry ( - IN EFI_GCD_MAP_ENTRY *TopEntry, - IN EFI_GCD_MAP_ENTRY *BottomEntry, - IN LIST_ENTRY *StartLink, - IN LIST_ENTRY *EndLink, - IN LIST_ENTRY *Map - ) -{ - LIST_ENTRY *Link; - - if (TopEntry->Signature == 0) { - CoreFreePool (TopEntry); - } - if (BottomEntry->Signature == 0) { - CoreFreePool (BottomEntry); - } - - Link = StartLink; - while (Link != EndLink->ForwardLink) { - CoreMergeGcdMapEntry (Link, FALSE, Map); - Link = Link->ForwardLink; - } - CoreMergeGcdMapEntry (EndLink, TRUE, Map); - - return EFI_SUCCESS; -} - - -/** - Search a segment of memory space in GCD map. The result is a range of GCD entry list. - - @param BaseAddress The start address of the segment. - @param Length The length of the segment. - @param StartLink The first GCD entry involves this segment of - memory space. - @param EndLink The first GCD entry involves this segment of - memory space. - @param Map Points to the start entry to search. - - @retval EFI_SUCCESS Successfully found the entry. - @retval EFI_NOT_FOUND Not found. - -**/ -EFI_STATUS -CoreSearchGcdMapEntry ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - OUT LIST_ENTRY **StartLink, - OUT LIST_ENTRY **EndLink, - IN LIST_ENTRY *Map - ) -{ - LIST_ENTRY *Link; - EFI_GCD_MAP_ENTRY *Entry; - - ASSERT (Length != 0); - - *StartLink = NULL; - *EndLink = NULL; - - Link = Map->ForwardLink; - while (Link != Map) { - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - if (BaseAddress >= Entry->BaseAddress && BaseAddress <= Entry->EndAddress) { - *StartLink = Link; - } - if (*StartLink != NULL) { - if ((BaseAddress + Length - 1) >= Entry->BaseAddress && - (BaseAddress + Length - 1) <= Entry->EndAddress ) { - *EndLink = Link; - return EFI_SUCCESS; - } - } - Link = Link->ForwardLink; - } - - return EFI_NOT_FOUND; -} - - -/** - Count the amount of GCD map entries. - - @param Map Points to the start entry to do the count loop. - - @return The count. - -**/ -UINTN -CoreCountGcdMapEntry ( - IN LIST_ENTRY *Map - ) -{ - UINTN Count; - LIST_ENTRY *Link; - - Count = 0; - Link = Map->ForwardLink; - while (Link != Map) { - Count++; - Link = Link->ForwardLink; - } - - return Count; -} - - - -/** - Return the memory attribute specified by Attributes - - @param Attributes A num with some attribute bits on. - - @return The enum value of memory attribute. - -**/ -UINT64 -ConverToCpuArchAttributes ( - UINT64 Attributes - ) -{ - if ( (Attributes & EFI_MEMORY_UC) == EFI_MEMORY_UC) { - return EFI_MEMORY_UC; - } - - if ( (Attributes & EFI_MEMORY_WC ) == EFI_MEMORY_WC) { - return EFI_MEMORY_WC; - } - - if ( (Attributes & EFI_MEMORY_WT ) == EFI_MEMORY_WT) { - return EFI_MEMORY_WT; - } - - if ( (Attributes & EFI_MEMORY_WB) == EFI_MEMORY_WB) { - return EFI_MEMORY_WB; - } - - if ( (Attributes & EFI_MEMORY_WP) == EFI_MEMORY_WP) { - return EFI_MEMORY_WP; - } - - return INVALID_CPU_ARCH_ATTRIBUTES; - -} - - -/** - Do operation on a segment of memory space specified (add, free, remove, change attribute ...). - - @param Operation The type of the operation - @param GcdMemoryType Additional information for the operation - @param GcdIoType Additional information for the operation - @param BaseAddress Start address of the segment - @param Length length of the segment - @param Capabilities The alterable attributes of a newly added entry - @param Attributes The attributes needs to be set - - @retval EFI_INVALID_PARAMETER Length is 0 or address (length) not aligned when - setting attribute. - @retval EFI_SUCCESS Action successfully done. - @retval EFI_UNSUPPORTED Could not find the proper descriptor on this - segment or set an upsupported attribute. - @retval EFI_ACCESS_DENIED Operate on an space non-exist or is used for an - image. - @retval EFI_NOT_FOUND Free a non-using space or remove a non-exist - space, and so on. - @retval EFI_OUT_OF_RESOURCES No buffer could be allocated. - @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU architectural protocol - is not available yet. -**/ -EFI_STATUS -CoreConvertSpace ( - IN UINTN Operation, - IN EFI_GCD_MEMORY_TYPE GcdMemoryType, - IN EFI_GCD_IO_TYPE GcdIoType, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Capabilities, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Map; - LIST_ENTRY *Link; - EFI_GCD_MAP_ENTRY *Entry; - EFI_GCD_MAP_ENTRY *TopEntry; - EFI_GCD_MAP_ENTRY *BottomEntry; - LIST_ENTRY *StartLink; - LIST_ENTRY *EndLink; - UINT64 CpuArchAttributes; - - if (Length == 0) { - DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER)); - return EFI_INVALID_PARAMETER; - } - - Map = NULL; - if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) { - CoreAcquireGcdMemoryLock (); - Map = &mGcdMemorySpaceMap; - } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) { - CoreAcquireGcdIoLock (); - Map = &mGcdIoSpaceMap; - } else { - ASSERT (FALSE); - } - - // - // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length - // - Status = CoreSearchGcdMapEntry (BaseAddress, Length, &StartLink, &EndLink, Map); - if (EFI_ERROR (Status)) { - Status = EFI_UNSUPPORTED; - - goto Done; - } - ASSERT (StartLink != NULL && EndLink != NULL); - - // - // Verify that the list of descriptors are unallocated non-existent memory. - // - Link = StartLink; - while (Link != EndLink->ForwardLink) { - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - switch (Operation) { - // - // Add operations - // - case GCD_ADD_MEMORY_OPERATION: - if (Entry->GcdMemoryType != EfiGcdMemoryTypeNonExistent || - Entry->ImageHandle != NULL ) { - Status = EFI_ACCESS_DENIED; - goto Done; - } - break; - case GCD_ADD_IO_OPERATION: - if (Entry->GcdIoType != EfiGcdIoTypeNonExistent || - Entry->ImageHandle != NULL ) { - Status = EFI_ACCESS_DENIED; - goto Done; - } - break; - // - // Free operations - // - case GCD_FREE_MEMORY_OPERATION: - case GCD_FREE_IO_OPERATION: - if (Entry->ImageHandle == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - break; - // - // Remove operations - // - case GCD_REMOVE_MEMORY_OPERATION: - if (Entry->GcdMemoryType == EfiGcdMemoryTypeNonExistent) { - Status = EFI_NOT_FOUND; - goto Done; - } - if (Entry->ImageHandle != NULL) { - Status = EFI_ACCESS_DENIED; - goto Done; - } - break; - case GCD_REMOVE_IO_OPERATION: - if (Entry->GcdIoType == EfiGcdIoTypeNonExistent) { - Status = EFI_NOT_FOUND; - goto Done; - } - if (Entry->ImageHandle != NULL) { - Status = EFI_ACCESS_DENIED; - goto Done; - } - break; - // - // Set attributes operation - // - case GCD_SET_ATTRIBUTES_MEMORY_OPERATION: - if ((Attributes & EFI_MEMORY_RUNTIME) != 0) { - if ((BaseAddress & EFI_PAGE_MASK) != 0 || (Length & EFI_PAGE_MASK) != 0) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - } - if ((Entry->Capabilities & Attributes) != Attributes) { - Status = EFI_UNSUPPORTED; - goto Done; - } - break; - // - // Set capabilities operation - // - case GCD_SET_CAPABILITIES_MEMORY_OPERATION: - if ((BaseAddress & EFI_PAGE_MASK) != 0 || (Length & EFI_PAGE_MASK) != 0) { - Status = EFI_INVALID_PARAMETER; - - goto Done; - } - // - // Current attributes must still be supported with new capabilities - // - if ((Capabilities & Entry->Attributes) != Entry->Attributes) { - Status = EFI_UNSUPPORTED; - goto Done; - } - break; - } - Link = Link->ForwardLink; - } - - // - // Allocate work space to perform this operation - // - Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry); - if (EFI_ERROR (Status)) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - ASSERT (TopEntry != NULL && BottomEntry != NULL); - - if (Operation == GCD_SET_ATTRIBUTES_MEMORY_OPERATION) { - // - // Call CPU Arch Protocol to attempt to set attributes on the range - // - CpuArchAttributes = ConverToCpuArchAttributes (Attributes); - if (CpuArchAttributes != INVALID_CPU_ARCH_ATTRIBUTES) { - if (gCpu == NULL) { - Status = EFI_NOT_AVAILABLE_YET; - } else { - Status = gCpu->SetMemoryAttributes ( - gCpu, - BaseAddress, - Length, - CpuArchAttributes - ); - } - if (EFI_ERROR (Status)) { - CoreFreePool (TopEntry); - CoreFreePool (BottomEntry); - goto Done; - } - } - } - - // - // Convert/Insert the list of descriptors from StartLink to EndLink - // - Link = StartLink; - while (Link != EndLink->ForwardLink) { - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - CoreInsertGcdMapEntry (Link, Entry, BaseAddress, Length, TopEntry, BottomEntry); - switch (Operation) { - // - // Add operations - // - case GCD_ADD_MEMORY_OPERATION: - Entry->GcdMemoryType = GcdMemoryType; - if (GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { - Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME | EFI_MEMORY_PORT_IO; - } else { - Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME; - } - break; - case GCD_ADD_IO_OPERATION: - Entry->GcdIoType = GcdIoType; - break; - // - // Free operations - // - case GCD_FREE_MEMORY_OPERATION: - case GCD_FREE_IO_OPERATION: - Entry->ImageHandle = NULL; - Entry->DeviceHandle = NULL; - break; - // - // Remove operations - // - case GCD_REMOVE_MEMORY_OPERATION: - Entry->GcdMemoryType = EfiGcdMemoryTypeNonExistent; - Entry->Capabilities = 0; - break; - case GCD_REMOVE_IO_OPERATION: - Entry->GcdIoType = EfiGcdIoTypeNonExistent; - break; - // - // Set attributes operation - // - case GCD_SET_ATTRIBUTES_MEMORY_OPERATION: - Entry->Attributes = Attributes; - break; - // - // Set capabilities operation - // - case GCD_SET_CAPABILITIES_MEMORY_OPERATION: - Entry->Capabilities = Capabilities; - break; - } - Link = Link->ForwardLink; - } - - // - // Cleanup - // - Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map); - -Done: - DEBUG ((DEBUG_GCD, " Status = %r\n", Status)); - - if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) { - CoreReleaseGcdMemoryLock (); - CoreDumpGcdMemorySpaceMap (FALSE); - } - if ((Operation & GCD_IO_SPACE_OPERATION) != 0) { - CoreReleaseGcdIoLock (); - CoreDumpGcdIoSpaceMap (FALSE); - } - - return Status; -} - - -/** - Check whether an entry could be used to allocate space. - - @param Operation Allocate memory or IO - @param Entry The entry to be tested - @param GcdMemoryType The desired memory type - @param GcdIoType The desired IO type - - @retval EFI_NOT_FOUND The memory type does not match or there's an - image handle on the entry. - @retval EFI_UNSUPPORTED The operation unsupported. - @retval EFI_SUCCESS It's ok for this entry to be used to allocate - space. - -**/ -EFI_STATUS -CoreAllocateSpaceCheckEntry ( - IN UINTN Operation, - IN EFI_GCD_MAP_ENTRY *Entry, - IN EFI_GCD_MEMORY_TYPE GcdMemoryType, - IN EFI_GCD_IO_TYPE GcdIoType - ) -{ - if (Entry->ImageHandle != NULL) { - return EFI_NOT_FOUND; - } - switch (Operation) { - case GCD_ALLOCATE_MEMORY_OPERATION: - if (Entry->GcdMemoryType != GcdMemoryType) { - return EFI_NOT_FOUND; - } - break; - case GCD_ALLOCATE_IO_OPERATION: - if (Entry->GcdIoType != GcdIoType) { - return EFI_NOT_FOUND; - } - break; - default: - return EFI_UNSUPPORTED; - } - return EFI_SUCCESS; -} - - -/** - Allocate space on specified address and length. - - @param Operation The type of operation (memory or IO) - @param GcdAllocateType The type of allocate operation - @param GcdMemoryType The desired memory type - @param GcdIoType The desired IO type - @param Alignment Align with 2^Alignment - @param Length Length to allocate - @param BaseAddress Base address to allocate - @param ImageHandle The image handle consume the allocated space. - @param DeviceHandle The device handle consume the allocated space. - - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND No descriptor for the desired space exists. - @retval EFI_SUCCESS Space successfully allocated. - -**/ -EFI_STATUS -CoreAllocateSpace ( - IN UINTN Operation, - IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType, - IN EFI_GCD_MEMORY_TYPE GcdMemoryType, - IN EFI_GCD_IO_TYPE GcdIoType, - IN UINTN Alignment, - IN UINT64 Length, - IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE DeviceHandle OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS AlignmentMask; - EFI_PHYSICAL_ADDRESS MaxAddress; - LIST_ENTRY *Map; - LIST_ENTRY *Link; - LIST_ENTRY *SubLink; - EFI_GCD_MAP_ENTRY *Entry; - EFI_GCD_MAP_ENTRY *TopEntry; - EFI_GCD_MAP_ENTRY *BottomEntry; - LIST_ENTRY *StartLink; - LIST_ENTRY *EndLink; - BOOLEAN Found; - - // - // Make sure parameters are valid - // - if ((UINT32)GcdAllocateType >= EfiGcdMaxAllocateType) { - DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER)); - return EFI_INVALID_PARAMETER; - } - if ((UINT32)GcdMemoryType >= EfiGcdMemoryTypeMaximum) { - DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER)); - return EFI_INVALID_PARAMETER; - } - if ((UINT32)GcdIoType >= EfiGcdIoTypeMaximum) { - DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER)); - return EFI_INVALID_PARAMETER; - } - if (BaseAddress == NULL) { - DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER)); - return EFI_INVALID_PARAMETER; - } - if (ImageHandle == NULL) { - DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER)); - return EFI_INVALID_PARAMETER; - } - if (Alignment >= 64) { - DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_NOT_FOUND)); - return EFI_NOT_FOUND; - } - if (Length == 0) { - DEBUG ((DEBUG_GCD, " Status = %r\n", EFI_INVALID_PARAMETER)); - return EFI_INVALID_PARAMETER; - } - - Map = NULL; - if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) { - CoreAcquireGcdMemoryLock (); - Map = &mGcdMemorySpaceMap; - } else if ((Operation & GCD_IO_SPACE_OPERATION) != 0) { - CoreAcquireGcdIoLock (); - Map = &mGcdIoSpaceMap; - } else { - ASSERT (FALSE); - } - - Found = FALSE; - StartLink = NULL; - EndLink = NULL; - // - // Compute alignment bit mask - // - AlignmentMask = LShiftU64 (1, Alignment) - 1; - - if (GcdAllocateType == EfiGcdAllocateAddress) { - // - // Verify that the BaseAddress passed in is aligned correctly - // - if ((*BaseAddress & AlignmentMask) != 0) { - Status = EFI_NOT_FOUND; - goto Done; - } - - // - // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length - // - Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map); - if (EFI_ERROR (Status)) { - Status = EFI_NOT_FOUND; - goto Done; - } - ASSERT (StartLink != NULL && EndLink != NULL); - - // - // Verify that the list of descriptors are unallocated memory matching GcdMemoryType. - // - Link = StartLink; - while (Link != EndLink->ForwardLink) { - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - Link = Link->ForwardLink; - Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType); - if (EFI_ERROR (Status)) { - goto Done; - } - } - Found = TRUE; - } else { - - Entry = CR (Map->BackLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - - // - // Compute the maximum address to use in the search algorithm - // - if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchBottomUp || - GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown ) { - MaxAddress = *BaseAddress; - } else { - MaxAddress = Entry->EndAddress; - } - - // - // Verify that the list of descriptors are unallocated memory matching GcdMemoryType. - // - if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown || - GcdAllocateType == EfiGcdAllocateAnySearchTopDown ) { - Link = Map->BackLink; - } else { - Link = Map->ForwardLink; - } - while (Link != Map) { - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - - if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown || - GcdAllocateType == EfiGcdAllocateAnySearchTopDown ) { - Link = Link->BackLink; - } else { - Link = Link->ForwardLink; - } - - Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType); - if (EFI_ERROR (Status)) { - continue; - } - - if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown || - GcdAllocateType == EfiGcdAllocateAnySearchTopDown) { - if ((Entry->BaseAddress + Length) > MaxAddress) { - continue; - } - if (Length > (Entry->EndAddress + 1)) { - Status = EFI_NOT_FOUND; - goto Done; - } - if (Entry->EndAddress > MaxAddress) { - *BaseAddress = MaxAddress; - } else { - *BaseAddress = Entry->EndAddress; - } - *BaseAddress = (*BaseAddress + 1 - Length) & (~AlignmentMask); - } else { - *BaseAddress = (Entry->BaseAddress + AlignmentMask) & (~AlignmentMask); - if ((*BaseAddress + Length - 1) > MaxAddress) { - Status = EFI_NOT_FOUND; - goto Done; - } - } - - // - // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length - // - Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map); - if (EFI_ERROR (Status)) { - Status = EFI_NOT_FOUND; - goto Done; - } - ASSERT (StartLink != NULL && EndLink != NULL); - - Link = StartLink; - // - // Verify that the list of descriptors are unallocated memory matching GcdMemoryType. - // - Found = TRUE; - SubLink = StartLink; - while (SubLink != EndLink->ForwardLink) { - Entry = CR (SubLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType); - if (EFI_ERROR (Status)) { - Link = SubLink; - Found = FALSE; - break; - } - SubLink = SubLink->ForwardLink; - } - if (Found) { - break; - } - } - } - if (!Found) { - Status = EFI_NOT_FOUND; - goto Done; - } - - // - // Allocate work space to perform this operation - // - Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry); - if (EFI_ERROR (Status)) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - ASSERT (TopEntry != NULL && BottomEntry != NULL); - - // - // Convert/Insert the list of descriptors from StartLink to EndLink - // - Link = StartLink; - while (Link != EndLink->ForwardLink) { - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - CoreInsertGcdMapEntry (Link, Entry, *BaseAddress, Length, TopEntry, BottomEntry); - Entry->ImageHandle = ImageHandle; - Entry->DeviceHandle = DeviceHandle; - Link = Link->ForwardLink; - } - - // - // Cleanup - // - Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map); - -Done: - DEBUG ((DEBUG_GCD, " Status = %r", Status)); - if (!EFI_ERROR (Status)) { - DEBUG ((DEBUG_GCD, " (BaseAddress = %016lx)", *BaseAddress)); - } - DEBUG ((DEBUG_GCD, "\n")); - - if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) { - CoreReleaseGcdMemoryLock (); - CoreDumpGcdMemorySpaceMap (FALSE); - } - if ((Operation & GCD_IO_SPACE_OPERATION) !=0) { - CoreReleaseGcdIoLock (); - CoreDumpGcdIoSpaceMap (FALSE); - } - - return Status; -} - - -/** - Add a segment of memory to GCD map. - - @param GcdMemoryType Memory type of the segment. - @param BaseAddress Base address of the segment. - @param Length Length of the segment. - @param Capabilities alterable attributes of the segment. - - @retval EFI_INVALID_PARAMETER Invalid parameters. - @retval EFI_SUCCESS Successfully add a segment of memory space. - -**/ -EFI_STATUS -CoreInternalAddMemorySpace ( - IN EFI_GCD_MEMORY_TYPE GcdMemoryType, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Capabilities - ) -{ - DEBUG ((DEBUG_GCD, "GCD:AddMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); - DEBUG ((DEBUG_GCD, " GcdMemoryType = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)])); - DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities)); - - // - // Make sure parameters are valid - // - if (GcdMemoryType <= EfiGcdMemoryTypeNonExistent || GcdMemoryType >= EfiGcdMemoryTypeMaximum) { - return EFI_INVALID_PARAMETER; - } - - return CoreConvertSpace (GCD_ADD_MEMORY_OPERATION, GcdMemoryType, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, Capabilities, 0); -} - -// -// GCD Core Services -// - -/** - Allocates nonexistent memory, reserved memory, system memory, or memorymapped - I/O resources from the global coherency domain of the processor. - - @param GcdAllocateType The type of allocate operation - @param GcdMemoryType The desired memory type - @param Alignment Align with 2^Alignment - @param Length Length to allocate - @param BaseAddress Base address to allocate - @param ImageHandle The image handle consume the allocated space. - @param DeviceHandle The device handle consume the allocated space. - - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND No descriptor contains the desired space. - @retval EFI_SUCCESS Memory space successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocateMemorySpace ( - IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType, - IN EFI_GCD_MEMORY_TYPE GcdMemoryType, - IN UINTN Alignment, - IN UINT64 Length, - IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE DeviceHandle OPTIONAL - ) -{ - if (BaseAddress != NULL) { - DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length)); - } else { - DEBUG ((DEBUG_GCD, "GCD:AllocateMemorySpace(Base=,Length=%016lx)\n", Length)); - } - DEBUG ((DEBUG_GCD, " GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)])); - DEBUG ((DEBUG_GCD, " GcdMemoryType = %a\n", mGcdMemoryTypeNames[MIN (GcdMemoryType, EfiGcdMemoryTypeMaximum)])); - DEBUG ((DEBUG_GCD, " Alignment = %016lx\n", LShiftU64 (1, Alignment))); - DEBUG ((DEBUG_GCD, " ImageHandle = %p\n", ImageHandle)); - DEBUG ((DEBUG_GCD, " DeviceHandle = %p\n", DeviceHandle)); - - return CoreAllocateSpace ( - GCD_ALLOCATE_MEMORY_OPERATION, - GcdAllocateType, - GcdMemoryType, - (EFI_GCD_IO_TYPE) 0, - Alignment, - Length, - BaseAddress, - ImageHandle, - DeviceHandle - ); -} - - -/** - Adds reserved memory, system memory, or memory-mapped I/O resources to the - global coherency domain of the processor. - - @param GcdMemoryType Memory type of the memory space. - @param BaseAddress Base address of the memory space. - @param Length Length of the memory space. - @param Capabilities alterable attributes of the memory space. - - @retval EFI_SUCCESS Merged this memory space into GCD map. - -**/ -EFI_STATUS -EFIAPI -CoreAddMemorySpace ( - IN EFI_GCD_MEMORY_TYPE GcdMemoryType, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Capabilities - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS PageBaseAddress; - UINT64 PageLength; - - Status = CoreInternalAddMemorySpace (GcdMemoryType, BaseAddress, Length, Capabilities); - - if (!EFI_ERROR (Status) && ((GcdMemoryType == EfiGcdMemoryTypeSystemMemory) || (GcdMemoryType == EfiGcdMemoryTypeMoreReliable))) { - - PageBaseAddress = PageAlignAddress (BaseAddress); - PageLength = PageAlignLength (BaseAddress + Length - PageBaseAddress); - - Status = CoreAllocateMemorySpace ( - EfiGcdAllocateAddress, - GcdMemoryType, - EFI_PAGE_SHIFT, - PageLength, - &PageBaseAddress, - gDxeCoreImageHandle, - NULL - ); - - if (!EFI_ERROR (Status)) { - CoreAddMemoryDescriptor ( - EfiConventionalMemory, - PageBaseAddress, - RShiftU64 (PageLength, EFI_PAGE_SHIFT), - Capabilities - ); - } else { - for (; PageLength != 0; PageLength -= EFI_PAGE_SIZE, PageBaseAddress += EFI_PAGE_SIZE) { - Status = CoreAllocateMemorySpace ( - EfiGcdAllocateAddress, - GcdMemoryType, - EFI_PAGE_SHIFT, - EFI_PAGE_SIZE, - &PageBaseAddress, - gDxeCoreImageHandle, - NULL - ); - - if (!EFI_ERROR (Status)) { - CoreAddMemoryDescriptor ( - EfiConventionalMemory, - PageBaseAddress, - 1, - Capabilities - ); - } - } - } - } - return Status; -} - - -/** - Frees nonexistent memory, reserved memory, system memory, or memory-mapped - I/O resources from the global coherency domain of the processor. - - @param BaseAddress Base address of the memory space. - @param Length Length of the memory space. - - @retval EFI_SUCCESS Space successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreeMemorySpace ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ) -{ - DEBUG ((DEBUG_GCD, "GCD:FreeMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); - - return CoreConvertSpace (GCD_FREE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0); -} - - -/** - Removes reserved memory, system memory, or memory-mapped I/O resources from - the global coherency domain of the processor. - - @param BaseAddress Base address of the memory space. - @param Length Length of the memory space. - - @retval EFI_SUCCESS Successfully remove a segment of memory space. - -**/ -EFI_STATUS -EFIAPI -CoreRemoveMemorySpace ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ) -{ - DEBUG ((DEBUG_GCD, "GCD:RemoveMemorySpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); - - return CoreConvertSpace (GCD_REMOVE_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0); -} - - -/** - Build a memory descriptor according to an entry. - - @param Descriptor The descriptor to be built - @param Entry According to this entry - -**/ -VOID -BuildMemoryDescriptor ( - IN OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor, - IN EFI_GCD_MAP_ENTRY *Entry - ) -{ - Descriptor->BaseAddress = Entry->BaseAddress; - Descriptor->Length = Entry->EndAddress - Entry->BaseAddress + 1; - Descriptor->Capabilities = Entry->Capabilities; - Descriptor->Attributes = Entry->Attributes; - Descriptor->GcdMemoryType = Entry->GcdMemoryType; - Descriptor->ImageHandle = Entry->ImageHandle; - Descriptor->DeviceHandle = Entry->DeviceHandle; -} - - -/** - Retrieves the descriptor for a memory region containing a specified address. - - @param BaseAddress Specified start address - @param Descriptor Specified length - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully get memory space descriptor. - -**/ -EFI_STATUS -EFIAPI -CoreGetMemorySpaceDescriptor ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor - ) -{ - EFI_STATUS Status; - LIST_ENTRY *StartLink; - LIST_ENTRY *EndLink; - EFI_GCD_MAP_ENTRY *Entry; - - // - // Make sure parameters are valid - // - if (Descriptor == NULL) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireGcdMemoryLock (); - - // - // Search for the list of descriptors that contain BaseAddress - // - Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdMemorySpaceMap); - if (EFI_ERROR (Status)) { - Status = EFI_NOT_FOUND; - } else { - ASSERT (StartLink != NULL && EndLink != NULL); - // - // Copy the contents of the found descriptor into Descriptor - // - Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - BuildMemoryDescriptor (Descriptor, Entry); - } - - CoreReleaseGcdMemoryLock (); - - return Status; -} - - -/** - Modifies the attributes for a memory region in the global coherency domain of the - processor. - - @param BaseAddress Specified start address - @param Length Specified length - @param Attributes Specified attributes - - @retval EFI_SUCCESS The attributes were set for the memory region. - @retval EFI_INVALID_PARAMETER Length is zero. - @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory - resource range specified by BaseAddress and Length. - @retval EFI_UNSUPPORTED The bit mask of attributes is not support for the memory resource - range specified by BaseAddress and Length. - @retval EFI_ACCESS_DEFINED The attributes for the memory resource range specified by - BaseAddress and Length cannot be modified. - @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of - the memory resource range. - @retval EFI_NOT_AVAILABLE_YET The attributes cannot be set because CPU architectural protocol is - not available yet. - -**/ -EFI_STATUS -EFIAPI -CoreSetMemorySpaceAttributes ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes - ) -{ - DEBUG ((DEBUG_GCD, "GCD:SetMemorySpaceAttributes(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); - DEBUG ((DEBUG_GCD, " Attributes = %016lx\n", Attributes)); - - return CoreConvertSpace (GCD_SET_ATTRIBUTES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, Attributes); -} - - -/** - Modifies the capabilities for a memory region in the global coherency domain of the - processor. - - @param BaseAddress The physical address that is the start address of a memory region. - @param Length The size in bytes of the memory region. - @param Capabilities The bit mask of capabilities that the memory region supports. - - @retval EFI_SUCCESS The capabilities were set for the memory region. - @retval EFI_INVALID_PARAMETER Length is zero. - @retval EFI_UNSUPPORTED The capabilities specified by Capabilities do not include the - memory region attributes currently in use. - @retval EFI_ACCESS_DENIED The capabilities for the memory resource range specified by - BaseAddress and Length cannot be modified. - @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the capabilities - of the memory resource range. -**/ -EFI_STATUS -EFIAPI -CoreSetMemorySpaceCapabilities ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN UINT64 Capabilities - ) -{ - EFI_STATUS Status; - - DEBUG ((DEBUG_GCD, "GCD:CoreSetMemorySpaceCapabilities(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); - DEBUG ((DEBUG_GCD, " Capabilities = %016lx\n", Capabilities)); - - Status = CoreConvertSpace (GCD_SET_CAPABILITIES_MEMORY_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, Capabilities, 0); - if (!EFI_ERROR(Status)) { - CoreUpdateMemoryAttributes(BaseAddress, RShiftU64(Length, EFI_PAGE_SHIFT), Capabilities & (~EFI_MEMORY_RUNTIME)); - } - - return Status; -} - - -/** - Returns a map of the memory resources in the global coherency domain of the - processor. - - @param NumberOfDescriptors Number of descriptors. - @param MemorySpaceMap Descriptor array - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SUCCESS Successfully get memory space map. - -**/ -EFI_STATUS -EFIAPI -CoreGetMemorySpaceMap ( - OUT UINTN *NumberOfDescriptors, - OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **MemorySpaceMap - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - EFI_GCD_MAP_ENTRY *Entry; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor; - - // - // Make sure parameters are valid - // - if (NumberOfDescriptors == NULL) { - return EFI_INVALID_PARAMETER; - } - if (MemorySpaceMap == NULL) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireGcdMemoryLock (); - - // - // Count the number of descriptors - // - *NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdMemorySpaceMap); - - // - // Allocate the MemorySpaceMap - // - *MemorySpaceMap = AllocatePool (*NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR)); - if (*MemorySpaceMap == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - // - // Fill in the MemorySpaceMap - // - Descriptor = *MemorySpaceMap; - Link = mGcdMemorySpaceMap.ForwardLink; - while (Link != &mGcdMemorySpaceMap) { - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - BuildMemoryDescriptor (Descriptor, Entry); - Descriptor++; - Link = Link->ForwardLink; - } - Status = EFI_SUCCESS; - -Done: - CoreReleaseGcdMemoryLock (); - return Status; -} - - -/** - Adds reserved I/O or I/O resources to the global coherency domain of the processor. - - @param GcdIoType IO type of the segment. - @param BaseAddress Base address of the segment. - @param Length Length of the segment. - - @retval EFI_SUCCESS Merged this segment into GCD map. - @retval EFI_INVALID_PARAMETER Parameter not valid - -**/ -EFI_STATUS -EFIAPI -CoreAddIoSpace ( - IN EFI_GCD_IO_TYPE GcdIoType, - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ) -{ - DEBUG ((DEBUG_GCD, "GCD:AddIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); - DEBUG ((DEBUG_GCD, " GcdIoType = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)])); - - // - // Make sure parameters are valid - // - if (GcdIoType <= EfiGcdIoTypeNonExistent || GcdIoType >= EfiGcdIoTypeMaximum) { - return EFI_INVALID_PARAMETER; - } - return CoreConvertSpace (GCD_ADD_IO_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, GcdIoType, BaseAddress, Length, 0, 0); -} - - -/** - Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency - domain of the processor. - - @param GcdAllocateType The type of allocate operation - @param GcdIoType The desired IO type - @param Alignment Align with 2^Alignment - @param Length Length to allocate - @param BaseAddress Base address to allocate - @param ImageHandle The image handle consume the allocated space. - @param DeviceHandle The device handle consume the allocated space. - - @retval EFI_INVALID_PARAMETER Invalid parameter. - @retval EFI_NOT_FOUND No descriptor contains the desired space. - @retval EFI_SUCCESS IO space successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocateIoSpace ( - IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType, - IN EFI_GCD_IO_TYPE GcdIoType, - IN UINTN Alignment, - IN UINT64 Length, - IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE DeviceHandle OPTIONAL - ) -{ - if (BaseAddress != NULL) { - DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=%016lx,Length=%016lx)\n", *BaseAddress, Length)); - } else { - DEBUG ((DEBUG_GCD, "GCD:AllocateIoSpace(Base=,Length=%016lx)\n", Length)); - } - DEBUG ((DEBUG_GCD, " GcdAllocateType = %a\n", mGcdAllocationTypeNames[MIN (GcdAllocateType, EfiGcdMaxAllocateType)])); - DEBUG ((DEBUG_GCD, " GcdIoType = %a\n", mGcdIoTypeNames[MIN (GcdIoType, EfiGcdIoTypeMaximum)])); - DEBUG ((DEBUG_GCD, " Alignment = %016lx\n", LShiftU64 (1, Alignment))); - DEBUG ((DEBUG_GCD, " ImageHandle = %p\n", ImageHandle)); - DEBUG ((DEBUG_GCD, " DeviceHandle = %p\n", DeviceHandle)); - - return CoreAllocateSpace ( - GCD_ALLOCATE_IO_OPERATION, - GcdAllocateType, - (EFI_GCD_MEMORY_TYPE) 0, - GcdIoType, - Alignment, - Length, - BaseAddress, - ImageHandle, - DeviceHandle - ); -} - - -/** - Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency - domain of the processor. - - @param BaseAddress Base address of the segment. - @param Length Length of the segment. - - @retval EFI_SUCCESS Space successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreeIoSpace ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ) -{ - DEBUG ((DEBUG_GCD, "GCD:FreeIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); - - return CoreConvertSpace (GCD_FREE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0); -} - - -/** - Removes reserved I/O or I/O resources from the global coherency domain of the - processor. - - @param BaseAddress Base address of the segment. - @param Length Length of the segment. - - @retval EFI_SUCCESS Successfully removed a segment of IO space. - -**/ -EFI_STATUS -EFIAPI -CoreRemoveIoSpace ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ) -{ - DEBUG ((DEBUG_GCD, "GCD:RemoveIoSpace(Base=%016lx,Length=%016lx)\n", BaseAddress, Length)); - - return CoreConvertSpace (GCD_REMOVE_IO_OPERATION, (EFI_GCD_MEMORY_TYPE) 0, (EFI_GCD_IO_TYPE) 0, BaseAddress, Length, 0, 0); -} - - -/** - Build a IO descriptor according to an entry. - - @param Descriptor The descriptor to be built - @param Entry According to this entry - -**/ -VOID -BuildIoDescriptor ( - IN EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor, - IN EFI_GCD_MAP_ENTRY *Entry - ) -{ - Descriptor->BaseAddress = Entry->BaseAddress; - Descriptor->Length = Entry->EndAddress - Entry->BaseAddress + 1; - Descriptor->GcdIoType = Entry->GcdIoType; - Descriptor->ImageHandle = Entry->ImageHandle; - Descriptor->DeviceHandle = Entry->DeviceHandle; -} - - -/** - Retrieves the descriptor for an I/O region containing a specified address. - - @param BaseAddress Specified start address - @param Descriptor Specified length - - @retval EFI_INVALID_PARAMETER Descriptor is NULL. - @retval EFI_SUCCESS Successfully get the IO space descriptor. - -**/ -EFI_STATUS -EFIAPI -CoreGetIoSpaceDescriptor ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - OUT EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor - ) -{ - EFI_STATUS Status; - LIST_ENTRY *StartLink; - LIST_ENTRY *EndLink; - EFI_GCD_MAP_ENTRY *Entry; - - // - // Make sure parameters are valid - // - if (Descriptor == NULL) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireGcdIoLock (); - - // - // Search for the list of descriptors that contain BaseAddress - // - Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdIoSpaceMap); - if (EFI_ERROR (Status)) { - Status = EFI_NOT_FOUND; - } else { - ASSERT (StartLink != NULL && EndLink != NULL); - // - // Copy the contents of the found descriptor into Descriptor - // - Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - BuildIoDescriptor (Descriptor, Entry); - } - - CoreReleaseGcdIoLock (); - - return Status; -} - - -/** - Returns a map of the I/O resources in the global coherency domain of the processor. - - @param NumberOfDescriptors Number of descriptors. - @param IoSpaceMap Descriptor array - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SUCCESS Successfully get IO space map. - -**/ -EFI_STATUS -EFIAPI -CoreGetIoSpaceMap ( - OUT UINTN *NumberOfDescriptors, - OUT EFI_GCD_IO_SPACE_DESCRIPTOR **IoSpaceMap - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - EFI_GCD_MAP_ENTRY *Entry; - EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor; - - // - // Make sure parameters are valid - // - if (NumberOfDescriptors == NULL) { - return EFI_INVALID_PARAMETER; - } - if (IoSpaceMap == NULL) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireGcdIoLock (); - - // - // Count the number of descriptors - // - *NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdIoSpaceMap); - - // - // Allocate the IoSpaceMap - // - *IoSpaceMap = AllocatePool (*NumberOfDescriptors * sizeof (EFI_GCD_IO_SPACE_DESCRIPTOR)); - if (*IoSpaceMap == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - // - // Fill in the IoSpaceMap - // - Descriptor = *IoSpaceMap; - Link = mGcdIoSpaceMap.ForwardLink; - while (Link != &mGcdIoSpaceMap) { - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - BuildIoDescriptor (Descriptor, Entry); - Descriptor++; - Link = Link->ForwardLink; - } - Status = EFI_SUCCESS; - -Done: - CoreReleaseGcdIoLock (); - return Status; -} - - -/** - Converts a Resource Descriptor HOB attributes mask to an EFI Memory Descriptor - capabilities mask - - @param GcdMemoryType Type of resource in the GCD memory map. - @param Attributes The attribute mask in the Resource Descriptor - HOB. - - @return The capabilities mask for an EFI Memory Descriptor. - -**/ -UINT64 -CoreConvertResourceDescriptorHobAttributesToCapabilities ( - EFI_GCD_MEMORY_TYPE GcdMemoryType, - UINT64 Attributes - ) -{ - UINT64 Capabilities; - GCD_ATTRIBUTE_CONVERSION_ENTRY *Conversion; - - // - // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask - // - for (Capabilities = 0, Conversion = mAttributeConversionTable; Conversion->Attribute != 0; Conversion++) { - if (Conversion->Memory || ((GcdMemoryType != EfiGcdMemoryTypeSystemMemory) && (GcdMemoryType != EfiGcdMemoryTypeMoreReliable))) { - if (Attributes & Conversion->Attribute) { - Capabilities |= Conversion->Capability; - } - } - } - - return Capabilities; -} - -/** - Calculate total memory bin size neeeded. - - @return The total memory bin size neeeded. - -**/ -UINT64 -CalculateTotalMemoryBinSizeNeeded ( - VOID - ) -{ - UINTN Index; - UINT64 TotalSize; - - // - // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array - // - TotalSize = 0; - for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { - TotalSize += LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, EFI_PAGE_SHIFT); - } - - return TotalSize; -} - -/** - External function. Initializes memory services based on the memory - descriptor HOBs. This function is responsible for priming the memory - map, so memory allocations and resource allocations can be made. - The first part of this function can not depend on any memory services - until at least one memory descriptor is provided to the memory services. - - @param HobStart The start address of the HOB. - @param MemoryBaseAddress Start address of memory region found to init DXE - core. - @param MemoryLength Length of memory region found to init DXE core. - - @retval EFI_SUCCESS Memory services successfully initialized. - -**/ -EFI_STATUS -CoreInitializeMemoryServices ( - IN VOID **HobStart, - OUT EFI_PHYSICAL_ADDRESS *MemoryBaseAddress, - OUT UINT64 *MemoryLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; - EFI_MEMORY_TYPE_INFORMATION *EfiMemoryTypeInformation; - UINTN DataSize; - BOOLEAN Found; - EFI_HOB_HANDOFF_INFO_TABLE *PhitHob; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINT64 Length; - UINT64 Attributes; - UINT64 Capabilities; - EFI_PHYSICAL_ADDRESS TestedMemoryBaseAddress; - UINT64 TestedMemoryLength; - EFI_PHYSICAL_ADDRESS HighAddress; - EFI_HOB_GUID_TYPE *GuidHob; - UINT32 ReservedCodePageNumber; - UINT64 MinimalMemorySizeNeeded; - - // - // Point at the first HOB. This must be the PHIT HOB. - // - Hob.Raw = *HobStart; - ASSERT (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_HANDOFF); - - // - // Initialize the spin locks and maps in the memory services. - // Also fill in the memory services into the EFI Boot Services Table - // - CoreInitializePool (); - - // - // Initialize Local Variables - // - PhitResourceHob = NULL; - ResourceHob = NULL; - BaseAddress = 0; - Length = 0; - Attributes = 0; - - // - // Cache the PHIT HOB for later use - // - PhitHob = Hob.HandoffInformationTable; - - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { - ReservedCodePageNumber = PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber); - ReservedCodePageNumber += PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber); - - // - // cache the Top address for loading modules at Fixed Address - // - gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress = PhitHob->EfiMemoryTop - + EFI_PAGES_TO_SIZE(ReservedCodePageNumber); - } - // - // See if a Memory Type Information HOB is available - // - GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); - if (GuidHob != NULL) { - EfiMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob); - DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); - if (EfiMemoryTypeInformation != NULL && DataSize > 0 && DataSize <= (EfiMaxMemoryType + 1) * sizeof (EFI_MEMORY_TYPE_INFORMATION)) { - CopyMem (&gMemoryTypeInformation, EfiMemoryTypeInformation, DataSize); - } - } - - // - // Include the total memory bin size needed to make sure memory bin could be allocated successfully. - // - MinimalMemorySizeNeeded = MINIMUM_INITIAL_MEMORY_SIZE + CalculateTotalMemoryBinSizeNeeded (); - - // - // Find the Resource Descriptor HOB that contains PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop - // - Found = FALSE; - for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - // - // Skip all HOBs except Resource Descriptor HOBs - // - if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - continue; - } - - // - // Skip Resource Descriptor HOBs that do not describe tested system memory - // - ResourceHob = Hob.ResourceDescriptor; - if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { - continue; - } - if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) { - continue; - } - - // - // Skip Resource Descriptor HOBs that do not contain the PHIT range EfiFreeMemoryBottom..EfiFreeMemoryTop - // - if (PhitHob->EfiFreeMemoryBottom < ResourceHob->PhysicalStart) { - continue; - } - if (PhitHob->EfiFreeMemoryTop > (ResourceHob->PhysicalStart + ResourceHob->ResourceLength)) { - continue; - } - - // - // Cache the resource descriptor HOB for the memory region described by the PHIT HOB - // - PhitResourceHob = ResourceHob; - Found = TRUE; - - // - // Compute range between PHIT EfiMemoryTop and the end of the Resource Descriptor HOB - // - Attributes = PhitResourceHob->ResourceAttribute; - BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop); - Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress); - if (Length < MinimalMemorySizeNeeded) { - // - // If that range is not large enough to intialize the DXE Core, then - // Compute range between PHIT EfiFreeMemoryBottom and PHIT EfiFreeMemoryTop - // - BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom); - Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress); - if (Length < MinimalMemorySizeNeeded) { - // - // If that range is not large enough to intialize the DXE Core, then - // Compute range between the start of the Resource Descriptor HOB and the start of the HOB List - // - BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart); - Length = PageAlignLength ((UINT64)((UINTN)*HobStart - BaseAddress)); - } - } - break; - } - - // - // Assert if a resource descriptor HOB for the memory region described by the PHIT was not found - // - ASSERT (Found); - - // - // Take the range in the resource descriptor HOB for the memory region described - // by the PHIT as higher priority if it is big enough. It can make the memory bin - // allocated to be at the same memory region with PHIT that has more better compatibility - // to avoid memory fragmentation for some code practices assume and allocate <4G ACPI memory. - // - if (Length < MinimalMemorySizeNeeded) { - // - // Search all the resource descriptor HOBs from the highest possible addresses down for a memory - // region that is big enough to initialize the DXE core. Always skip the PHIT Resource HOB. - // The max address must be within the physically addressible range for the processor. - // - HighAddress = MAX_ADDRESS; - for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - // - // Skip the Resource Descriptor HOB that contains the PHIT - // - if (Hob.ResourceDescriptor == PhitResourceHob) { - continue; - } - // - // Skip all HOBs except Resource Descriptor HOBs - // - if (GET_HOB_TYPE (Hob) != EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - continue; - } - - // - // Skip Resource Descriptor HOBs that do not describe tested system memory below MAX_ADDRESS - // - ResourceHob = Hob.ResourceDescriptor; - if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) { - continue; - } - if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) != TESTED_MEMORY_ATTRIBUTES) { - continue; - } - if ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS) { - continue; - } - - // - // Skip Resource Descriptor HOBs that are below a previously found Resource Descriptor HOB - // - if (HighAddress != (EFI_PHYSICAL_ADDRESS)MAX_ADDRESS && ResourceHob->PhysicalStart <= HighAddress) { - continue; - } - - // - // Skip Resource Descriptor HOBs that are not large enough to initilize the DXE Core - // - TestedMemoryBaseAddress = PageAlignAddress (ResourceHob->PhysicalStart); - TestedMemoryLength = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - TestedMemoryBaseAddress); - if (TestedMemoryLength < MinimalMemorySizeNeeded) { - continue; - } - - // - // Save the range described by the Resource Descriptor that is large enough to initilize the DXE Core - // - BaseAddress = TestedMemoryBaseAddress; - Length = TestedMemoryLength; - Attributes = ResourceHob->ResourceAttribute; - HighAddress = ResourceHob->PhysicalStart; - } - } - - DEBUG ((EFI_D_INFO, "CoreInitializeMemoryServices:\n")); - DEBUG ((EFI_D_INFO, " BaseAddress - 0x%lx Length - 0x%lx MinimalMemorySizeNeeded - 0x%lx\n", BaseAddress, Length, MinimalMemorySizeNeeded)); - - // - // If no memory regions are found that are big enough to initialize the DXE core, then ASSERT(). - // - ASSERT (Length >= MinimalMemorySizeNeeded); - - // - // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask - // - if ((Attributes & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) == EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) { - Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeMoreReliable, Attributes); - } else { - Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeSystemMemory, Attributes); - } - - // - // Declare the very first memory region, so the EFI Memory Services are available. - // - CoreAddMemoryDescriptor ( - EfiConventionalMemory, - BaseAddress, - RShiftU64 (Length, EFI_PAGE_SHIFT), - Capabilities - ); - - *MemoryBaseAddress = BaseAddress; - *MemoryLength = Length; - - return EFI_SUCCESS; -} - - -/** - External function. Initializes the GCD and memory services based on the memory - descriptor HOBs. This function is responsible for priming the GCD map and the - memory map, so memory allocations and resource allocations can be made. The - HobStart will be relocated to a pool buffer. - - @param HobStart The start address of the HOB - @param MemoryBaseAddress Start address of memory region found to init DXE - core. - @param MemoryLength Length of memory region found to init DXE core. - - @retval EFI_SUCCESS GCD services successfully initialized. - -**/ -EFI_STATUS -CoreInitializeGcdServices ( - IN OUT VOID **HobStart, - IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress, - IN UINT64 MemoryLength - ) -{ - EFI_PEI_HOB_POINTERS Hob; - VOID *NewHobList; - EFI_HOB_HANDOFF_INFO_TABLE *PhitHob; - UINT8 SizeOfMemorySpace; - UINT8 SizeOfIoSpace; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - EFI_PHYSICAL_ADDRESS BaseAddress; - UINT64 Length; - EFI_STATUS Status; - EFI_GCD_MAP_ENTRY *Entry; - EFI_GCD_MEMORY_TYPE GcdMemoryType; - EFI_GCD_IO_TYPE GcdIoType; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; - EFI_HOB_MEMORY_ALLOCATION *MemoryHob; - EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob; - UINTN NumberOfDescriptors; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; - UINTN Index; - UINT64 Capabilities; - EFI_HOB_CPU * CpuHob; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMapHobList; - - // - // Cache the PHIT HOB for later use - // - PhitHob = (EFI_HOB_HANDOFF_INFO_TABLE *)(*HobStart); - - // - // Get the number of address lines in the I/O and Memory space for the CPU - // - CpuHob = GetFirstHob (EFI_HOB_TYPE_CPU); - ASSERT (CpuHob != NULL); - SizeOfMemorySpace = CpuHob->SizeOfMemorySpace; - SizeOfIoSpace = CpuHob->SizeOfIoSpace; - - // - // Initialize the GCD Memory Space Map - // - Entry = AllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdMemorySpaceMapEntryTemplate); - ASSERT (Entry != NULL); - - Entry->EndAddress = LShiftU64 (1, SizeOfMemorySpace) - 1; - - InsertHeadList (&mGcdMemorySpaceMap, &Entry->Link); - - CoreDumpGcdMemorySpaceMap (TRUE); - - // - // Initialize the GCD I/O Space Map - // - Entry = AllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdIoSpaceMapEntryTemplate); - ASSERT (Entry != NULL); - - Entry->EndAddress = LShiftU64 (1, SizeOfIoSpace) - 1; - - InsertHeadList (&mGcdIoSpaceMap, &Entry->Link); - - CoreDumpGcdIoSpaceMap (TRUE); - - // - // Walk the HOB list and add all resource descriptors to the GCD - // - for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - - GcdMemoryType = EfiGcdMemoryTypeNonExistent; - GcdIoType = EfiGcdIoTypeNonExistent; - - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - - ResourceHob = Hob.ResourceDescriptor; - - switch (ResourceHob->ResourceType) { - case EFI_RESOURCE_SYSTEM_MEMORY: - if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) { - if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) == EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE) { - GcdMemoryType = EfiGcdMemoryTypeMoreReliable; - } else { - GcdMemoryType = EfiGcdMemoryTypeSystemMemory; - } - } - if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) { - GcdMemoryType = EfiGcdMemoryTypeReserved; - } - if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) { - GcdMemoryType = EfiGcdMemoryTypeReserved; - } - if ((ResourceHob->ResourceAttribute & EFI_RESOURCE_ATTRIBUTE_PERSISTENT) == EFI_RESOURCE_ATTRIBUTE_PERSISTENT) { - GcdMemoryType = EfiGcdMemoryTypePersistentMemory; - } - break; - case EFI_RESOURCE_MEMORY_MAPPED_IO: - case EFI_RESOURCE_FIRMWARE_DEVICE: - GcdMemoryType = EfiGcdMemoryTypeMemoryMappedIo; - break; - case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT: - case EFI_RESOURCE_MEMORY_RESERVED: - GcdMemoryType = EfiGcdMemoryTypeReserved; - break; - case EFI_RESOURCE_IO: - GcdIoType = EfiGcdIoTypeIo; - break; - case EFI_RESOURCE_IO_RESERVED: - GcdIoType = EfiGcdIoTypeReserved; - break; - } - - if (GcdMemoryType != EfiGcdMemoryTypeNonExistent) { - // - // Validate the Resource HOB Attributes - // - CoreValidateResourceDescriptorHobAttributes (ResourceHob->ResourceAttribute); - - // - // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask - // - Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities ( - GcdMemoryType, - ResourceHob->ResourceAttribute - ); - - Status = CoreInternalAddMemorySpace ( - GcdMemoryType, - ResourceHob->PhysicalStart, - ResourceHob->ResourceLength, - Capabilities - ); - } - - if (GcdIoType != EfiGcdIoTypeNonExistent) { - Status = CoreAddIoSpace ( - GcdIoType, - ResourceHob->PhysicalStart, - ResourceHob->ResourceLength - ); - } - } - } - - // - // Allocate first memory region from the GCD by the DXE core - // - Status = CoreGetMemorySpaceDescriptor (MemoryBaseAddress, &Descriptor); - if (!EFI_ERROR (Status)) { - ASSERT ((Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) || - (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMoreReliable)); - Status = CoreAllocateMemorySpace ( - EfiGcdAllocateAddress, - Descriptor.GcdMemoryType, - 0, - MemoryLength, - &MemoryBaseAddress, - gDxeCoreImageHandle, - NULL - ); - } - - // - // Walk the HOB list and allocate all memory space that is consumed by memory allocation HOBs, - // and Firmware Volume HOBs. Also update the EFI Memory Map with the memory allocation HOBs. - // - for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) { - MemoryHob = Hob.MemoryAllocation; - BaseAddress = MemoryHob->AllocDescriptor.MemoryBaseAddress; - Status = CoreGetMemorySpaceDescriptor (BaseAddress, &Descriptor); - if (!EFI_ERROR (Status)) { - Status = CoreAllocateMemorySpace ( - EfiGcdAllocateAddress, - Descriptor.GcdMemoryType, - 0, - MemoryHob->AllocDescriptor.MemoryLength, - &BaseAddress, - gDxeCoreImageHandle, - NULL - ); - if (!EFI_ERROR (Status) && - ((Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) || - (Descriptor.GcdMemoryType == EfiGcdMemoryTypeMoreReliable))) { - CoreAddMemoryDescriptor ( - MemoryHob->AllocDescriptor.MemoryType, - MemoryHob->AllocDescriptor.MemoryBaseAddress, - RShiftU64 (MemoryHob->AllocDescriptor.MemoryLength, EFI_PAGE_SHIFT), - Descriptor.Capabilities & (~EFI_MEMORY_RUNTIME) - ); - } - } - } - - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) { - FirmwareVolumeHob = Hob.FirmwareVolume; - BaseAddress = FirmwareVolumeHob->BaseAddress; - Status = CoreAllocateMemorySpace ( - EfiGcdAllocateAddress, - EfiGcdMemoryTypeMemoryMappedIo, - 0, - FirmwareVolumeHob->Length, - &BaseAddress, - gDxeCoreImageHandle, - NULL - ); - } - } - - // - // Add and allocate the remaining unallocated system memory to the memory services. - // - Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap); - ASSERT (Status == EFI_SUCCESS); - - MemorySpaceMapHobList = NULL; - for (Index = 0; Index < NumberOfDescriptors; Index++) { - if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) || - (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMoreReliable)) { - if (MemorySpaceMap[Index].ImageHandle == NULL) { - BaseAddress = PageAlignAddress (MemorySpaceMap[Index].BaseAddress); - Length = PageAlignLength (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - BaseAddress); - if (Length == 0 || MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length < BaseAddress) { - continue; - } - if (((UINTN) MemorySpaceMap[Index].BaseAddress <= (UINTN) (*HobStart)) && - ((UINTN) (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) >= (UINTN) PhitHob->EfiFreeMemoryBottom)) { - // - // Skip the memory space that covers HOB List, it should be processed - // after HOB List relocation to avoid the resources allocated by others - // to corrupt HOB List before its relocation. - // - MemorySpaceMapHobList = &MemorySpaceMap[Index]; - continue; - } - CoreAddMemoryDescriptor ( - EfiConventionalMemory, - BaseAddress, - RShiftU64 (Length, EFI_PAGE_SHIFT), - MemorySpaceMap[Index].Capabilities & (~EFI_MEMORY_RUNTIME) - ); - Status = CoreAllocateMemorySpace ( - EfiGcdAllocateAddress, - MemorySpaceMap[Index].GcdMemoryType, - 0, - Length, - &BaseAddress, - gDxeCoreImageHandle, - NULL - ); - } - } - } - - // - // Relocate HOB List to an allocated pool buffer. - // The relocation should be at after all the tested memory resources added - // (except the memory space that covers HOB List) to the memory services, - // because the memory resource found in CoreInitializeMemoryServices() - // may have not enough remaining resource for HOB List. - // - NewHobList = AllocateCopyPool ( - (UINTN) PhitHob->EfiFreeMemoryBottom - (UINTN) (*HobStart), - *HobStart - ); - ASSERT (NewHobList != NULL); - - *HobStart = NewHobList; - gHobList = NewHobList; - - if (MemorySpaceMapHobList != NULL) { - // - // Add and allocate the memory space that covers HOB List to the memory services - // after HOB List relocation. - // - BaseAddress = PageAlignAddress (MemorySpaceMapHobList->BaseAddress); - Length = PageAlignLength (MemorySpaceMapHobList->BaseAddress + MemorySpaceMapHobList->Length - BaseAddress); - CoreAddMemoryDescriptor ( - EfiConventionalMemory, - BaseAddress, - RShiftU64 (Length, EFI_PAGE_SHIFT), - MemorySpaceMapHobList->Capabilities & (~EFI_MEMORY_RUNTIME) - ); - Status = CoreAllocateMemorySpace ( - EfiGcdAllocateAddress, - MemorySpaceMapHobList->GcdMemoryType, - 0, - Length, - &BaseAddress, - gDxeCoreImageHandle, - NULL - ); - } - - CoreFreePool (MemorySpaceMap); - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/Dxe/Gcd/Gcd.h b/MdeModulePkg/Core/Dxe/Gcd/Gcd.h deleted file mode 100644 index 1d5fb61092..0000000000 --- a/MdeModulePkg/Core/Dxe/Gcd/Gcd.h +++ /dev/null @@ -1,46 +0,0 @@ -/** @file - GCD Operations and data structure used to - convert from GCD attributes to EFI Memory Map attributes. - -Copyright (c) 2006 - 2014, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _GCD_H_ -#define _GCD_H_ - -// -// GCD Operations -// -#define GCD_MEMORY_SPACE_OPERATION 0x20 -#define GCD_IO_SPACE_OPERATION 0x40 - -#define GCD_ADD_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 0) -#define GCD_ALLOCATE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 1) -#define GCD_FREE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 2) -#define GCD_REMOVE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 3) -#define GCD_SET_ATTRIBUTES_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 4) -#define GCD_SET_CAPABILITIES_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 5) - -#define GCD_ADD_IO_OPERATION (GCD_IO_SPACE_OPERATION | 0) -#define GCD_ALLOCATE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 1) -#define GCD_FREE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 2) -#define GCD_REMOVE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 3) - -// -// The data structure used to convert from GCD attributes to EFI Memory Map attributes -// -typedef struct { - UINT64 Attribute; - UINT64 Capability; - BOOLEAN Memory; -} GCD_ATTRIBUTE_CONVERSION_ENTRY; - -#endif diff --git a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c deleted file mode 100644 index 33dd0bd0b7..0000000000 --- a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c +++ /dev/null @@ -1,964 +0,0 @@ -/** @file - Support functions to connect/disconnect UEFI Driver model Protocol - -Copyright (c) 2006 - 2014, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Handle.h" - - -// -// Driver Support Functions -// -/** - Connects one or more drivers to a controller. - - @param ControllerHandle The handle of the controller to which driver(s) are to be connected. - @param DriverImageHandle A pointer to an ordered list handles that support the - EFI_DRIVER_BINDING_PROTOCOL. - @param RemainingDevicePath A pointer to the device path that specifies a child of the - controller specified by ControllerHandle. - @param Recursive If TRUE, then ConnectController() is called recursively - until the entire tree of controllers below the controller specified - by ControllerHandle have been created. If FALSE, then - the tree of controllers is only expanded one level. - - @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. - 2) No drivers were connected to ControllerHandle, but - RemainingDevicePath is not NULL, and it is an End Device - Path Node. - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances - present in the system. - 2) No drivers were connected to ControllerHandle. - @retval EFI_SECURITY_VIOLATION - The user has no permission to start UEFI device drivers on the device path - associated with the ControllerHandle or specified by the RemainingDevicePath. - -**/ -EFI_STATUS -EFIAPI -CoreConnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *DriverImageHandle OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, - IN BOOLEAN Recursive - ) -{ - EFI_STATUS Status; - EFI_STATUS ReturnStatus; - IHANDLE *Handle; - PROTOCOL_INTERFACE *Prot; - LIST_ENTRY *Link; - LIST_ENTRY *ProtLink; - OPEN_PROTOCOL_DATA *OpenData; - EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath; - EFI_HANDLE *ChildHandleBuffer; - UINTN ChildHandleCount; - UINTN Index; - UINTN HandleFilePathSize; - UINTN RemainingDevicePathSize; - EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; - EFI_DEVICE_PATH_PROTOCOL *FilePath; - EFI_DEVICE_PATH_PROTOCOL *TempFilePath; - - // - // Make sure ControllerHandle is valid - // - Status = CoreValidateHandle (ControllerHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - if (gSecurity2 != NULL) { - // - // Check whether the user has permission to start UEFI device drivers. - // - Status = CoreHandleProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath); - if (!EFI_ERROR (Status)) { - ASSERT (HandleFilePath != NULL); - FilePath = HandleFilePath; - TempFilePath = NULL; - if (RemainingDevicePath != NULL && !Recursive) { - HandleFilePathSize = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); - RemainingDevicePathSize = GetDevicePathSize (RemainingDevicePath); - TempFilePath = AllocateZeroPool (HandleFilePathSize + RemainingDevicePathSize); - ASSERT (TempFilePath != NULL); - CopyMem (TempFilePath, HandleFilePath, HandleFilePathSize); - CopyMem ((UINT8 *) TempFilePath + HandleFilePathSize, RemainingDevicePath, RemainingDevicePathSize); - FilePath = TempFilePath; - } - Status = gSecurity2->FileAuthentication ( - gSecurity2, - FilePath, - NULL, - 0, - FALSE - ); - if (TempFilePath != NULL) { - FreePool (TempFilePath); - } - if (EFI_ERROR (Status)) { - return Status; - } - } - } - - Handle = ControllerHandle; - - // - // Make a copy of RemainingDevicePath to guanatee it is aligned - // - AlignedRemainingDevicePath = NULL; - if (RemainingDevicePath != NULL) { - AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath); - - if (AlignedRemainingDevicePath == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - // - // Connect all drivers to ControllerHandle - // If CoreConnectSingleController returns EFI_NOT_READY, then the number of - // Driver Binding Protocols in the handle database has increased during the call - // so the connect operation must be restarted - // - do { - ReturnStatus = CoreConnectSingleController ( - ControllerHandle, - DriverImageHandle, - AlignedRemainingDevicePath - ); - } while (ReturnStatus == EFI_NOT_READY); - - // - // Free the aligned copy of RemainingDevicePath - // - if (AlignedRemainingDevicePath != NULL) { - CoreFreePool (AlignedRemainingDevicePath); - } - - // - // If recursive, then connect all drivers to all of ControllerHandle's children - // - if (Recursive) { - // - // Acquire the protocol lock on the handle database so the child handles can be collected - // - CoreAcquireProtocolLock (); - - // - // Make sure the DriverBindingHandle is valid - // - Status = CoreValidateHandle (ControllerHandle); - if (EFI_ERROR (Status)) { - // - // Release the protocol lock on the handle database - // - CoreReleaseProtocolLock (); - - return ReturnStatus; - } - - - // - // Count ControllerHandle's children - // - for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - for (ProtLink = Prot->OpenList.ForwardLink; - ProtLink != &Prot->OpenList; - ProtLink = ProtLink->ForwardLink) { - OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { - ChildHandleCount++; - } - } - } - - // - // Allocate a handle buffer for ControllerHandle's children - // - ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof(EFI_HANDLE)); - if (ChildHandleBuffer == NULL) { - CoreReleaseProtocolLock (); - return EFI_OUT_OF_RESOURCES; - } - - // - // Fill in a handle buffer with ControllerHandle's children - // - for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - for (ProtLink = Prot->OpenList.ForwardLink; - ProtLink != &Prot->OpenList; - ProtLink = ProtLink->ForwardLink) { - OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { - ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle; - ChildHandleCount++; - } - } - } - - // - // Release the protocol lock on the handle database - // - CoreReleaseProtocolLock (); - - // - // Recursively connect each child handle - // - for (Index = 0; Index < ChildHandleCount; Index++) { - CoreConnectController ( - ChildHandleBuffer[Index], - NULL, - NULL, - TRUE - ); - } - - // - // Free the handle buffer of ControllerHandle's children - // - CoreFreePool (ChildHandleBuffer); - } - - return ReturnStatus; -} - - -/** - Add Driver Binding Protocols from Context Driver Image Handles to sorted - Driver Binding Protocol list. - - @param DriverBindingHandle Handle of the driver binding - protocol. - @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding - protocols - @param SortedDriverBindingProtocols The sorted protocol list. - @param DriverBindingHandleCount Driver Binding Handle Count. - @param DriverBindingHandleBuffer The buffer of driver binding - protocol to be modified. - @param IsImageHandle Indicate whether - DriverBindingHandle is an image - handle - - @return None. - -**/ -VOID -AddSortedDriverBindingProtocol ( - IN EFI_HANDLE DriverBindingHandle, - IN OUT UINTN *NumberOfSortedDriverBindingProtocols, - IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols, - IN UINTN DriverBindingHandleCount, - IN OUT EFI_HANDLE *DriverBindingHandleBuffer, - IN BOOLEAN IsImageHandle - ) -{ - EFI_STATUS Status; - EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; - UINTN Index; - - // - // Make sure the DriverBindingHandle is valid - // - Status = CoreValidateHandle (DriverBindingHandle); - if (EFI_ERROR (Status)) { - return; - } - - // - // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle - // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list - // - if (IsImageHandle) { - // - // Loop through all the Driver Binding Handles - // - for (Index = 0; Index < DriverBindingHandleCount; Index++) { - // - // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle - // - Status = CoreHandleProtocol ( - DriverBindingHandleBuffer[Index], - &gEfiDriverBindingProtocolGuid, - (VOID **) &DriverBinding - ); - if (EFI_ERROR (Status) || DriverBinding == NULL) { - continue; - } - - // - // If the ImageHandle associated with DriverBinding matches DriverBindingHandle, - // then add the DriverBindingProtocol[Index] to the sorted list - // - if (DriverBinding->ImageHandle == DriverBindingHandle) { - AddSortedDriverBindingProtocol ( - DriverBindingHandleBuffer[Index], - NumberOfSortedDriverBindingProtocols, - SortedDriverBindingProtocols, - DriverBindingHandleCount, - DriverBindingHandleBuffer, - FALSE - ); - } - } - return; - } - - // - // Retrieve the Driver Binding Protocol from DriverBindingHandle - // - Status = CoreHandleProtocol( - DriverBindingHandle, - &gEfiDriverBindingProtocolGuid, - (VOID **) &DriverBinding - ); - // - // If DriverBindingHandle does not support the Driver Binding Protocol then return - // - if (EFI_ERROR (Status) || DriverBinding == NULL) { - return; - } - - // - // See if DriverBinding is already in the sorted list - // - for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) { - if (DriverBinding == SortedDriverBindingProtocols[Index]) { - return; - } - } - - // - // Add DriverBinding to the end of the list - // - if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) { - SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding; - } - *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1; - - // - // Mark the cooresponding handle in DriverBindingHandleBuffer as used - // - for (Index = 0; Index < DriverBindingHandleCount; Index++) { - if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) { - DriverBindingHandleBuffer[Index] = NULL; - } - } -} - - -/** - Connects a controller to a driver. - - @param ControllerHandle Handle of the controller to be - connected. - @param ContextDriverImageHandles DriverImageHandle A pointer to an - ordered list of driver image - handles. - @param RemainingDevicePath RemainingDevicePath A pointer to - the device path that specifies a - child of the controller - specified by ControllerHandle. - - @retval EFI_SUCCESS One or more drivers were - connected to ControllerHandle. - @retval EFI_OUT_OF_RESOURCES No enough system resources to - complete the request. - @retval EFI_NOT_FOUND No drivers were connected to - ControllerHandle. - -**/ -EFI_STATUS -CoreConnectSingleController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - EFI_STATUS Status; - UINTN Index; - EFI_HANDLE DriverImageHandle; - EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride; - EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; - UINTN DriverBindingHandleCount; - EFI_HANDLE *DriverBindingHandleBuffer; - UINTN NewDriverBindingHandleCount; - EFI_HANDLE *NewDriverBindingHandleBuffer; - EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; - EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *DriverFamilyOverride; - UINTN NumberOfSortedDriverBindingProtocols; - EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols; - UINT32 DriverFamilyOverrideVersion; - UINT32 HighestVersion; - UINTN HighestIndex; - UINTN SortIndex; - BOOLEAN OneStarted; - BOOLEAN DriverFound; - - // - // Initialize local variables - // - DriverBindingHandleCount = 0; - DriverBindingHandleBuffer = NULL; - NumberOfSortedDriverBindingProtocols = 0; - SortedDriverBindingProtocols = NULL; - PlatformDriverOverride = NULL; - NewDriverBindingHandleBuffer = NULL; - - // - // Get list of all Driver Binding Protocol Instances - // - Status = CoreLocateHandleBuffer ( - ByProtocol, - &gEfiDriverBindingProtocolGuid, - NULL, - &DriverBindingHandleCount, - &DriverBindingHandleBuffer - ); - if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) { - return EFI_NOT_FOUND; - } - - // - // Allocate a duplicate array for the sorted Driver Binding Protocol Instances - // - SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount); - if (SortedDriverBindingProtocols == NULL) { - CoreFreePool (DriverBindingHandleBuffer); - return EFI_OUT_OF_RESOURCES; - } - - // - // Add Driver Binding Protocols from Context Driver Image Handles first - // - if (ContextDriverImageHandles != NULL) { - for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) { - AddSortedDriverBindingProtocol ( - ContextDriverImageHandles[Index], - &NumberOfSortedDriverBindingProtocols, - SortedDriverBindingProtocols, - DriverBindingHandleCount, - DriverBindingHandleBuffer, - FALSE - ); - } - } - - // - // Add the Platform Driver Override Protocol drivers for ControllerHandle next - // - Status = CoreLocateProtocol ( - &gEfiPlatformDriverOverrideProtocolGuid, - NULL, - (VOID **) &PlatformDriverOverride - ); - if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) { - DriverImageHandle = NULL; - do { - Status = PlatformDriverOverride->GetDriver ( - PlatformDriverOverride, - ControllerHandle, - &DriverImageHandle - ); - if (!EFI_ERROR (Status)) { - AddSortedDriverBindingProtocol ( - DriverImageHandle, - &NumberOfSortedDriverBindingProtocols, - SortedDriverBindingProtocols, - DriverBindingHandleCount, - DriverBindingHandleBuffer, - TRUE - ); - } - } while (!EFI_ERROR (Status)); - } - - // - // Add the Driver Family Override Protocol drivers for ControllerHandle - // - while (TRUE) { - HighestIndex = DriverBindingHandleCount; - HighestVersion = 0; - for (Index = 0; Index < DriverBindingHandleCount; Index++) { - Status = CoreHandleProtocol ( - DriverBindingHandleBuffer[Index], - &gEfiDriverFamilyOverrideProtocolGuid, - (VOID **) &DriverFamilyOverride - ); - if (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) { - DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion (DriverFamilyOverride); - if ((HighestIndex == DriverBindingHandleCount) || (DriverFamilyOverrideVersion > HighestVersion)) { - HighestVersion = DriverFamilyOverrideVersion; - HighestIndex = Index; - } - } - } - - if (HighestIndex == DriverBindingHandleCount) { - break; - } - - AddSortedDriverBindingProtocol ( - DriverBindingHandleBuffer[HighestIndex], - &NumberOfSortedDriverBindingProtocols, - SortedDriverBindingProtocols, - DriverBindingHandleCount, - DriverBindingHandleBuffer, - FALSE - ); - } - - // - // Get the Bus Specific Driver Override Protocol instance on the Controller Handle - // - Status = CoreHandleProtocol ( - ControllerHandle, - &gEfiBusSpecificDriverOverrideProtocolGuid, - (VOID **) &BusSpecificDriverOverride - ); - if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) { - DriverImageHandle = NULL; - do { - Status = BusSpecificDriverOverride->GetDriver ( - BusSpecificDriverOverride, - &DriverImageHandle - ); - if (!EFI_ERROR (Status)) { - AddSortedDriverBindingProtocol ( - DriverImageHandle, - &NumberOfSortedDriverBindingProtocols, - SortedDriverBindingProtocols, - DriverBindingHandleCount, - DriverBindingHandleBuffer, - TRUE - ); - } - } while (!EFI_ERROR (Status)); - } - - // - // Then add all the remaining Driver Binding Protocols - // - SortIndex = NumberOfSortedDriverBindingProtocols; - for (Index = 0; Index < DriverBindingHandleCount; Index++) { - AddSortedDriverBindingProtocol ( - DriverBindingHandleBuffer[Index], - &NumberOfSortedDriverBindingProtocols, - SortedDriverBindingProtocols, - DriverBindingHandleCount, - DriverBindingHandleBuffer, - FALSE - ); - } - - // - // Free the Driver Binding Handle Buffer - // - CoreFreePool (DriverBindingHandleBuffer); - - // - // If the number of Driver Binding Protocols has increased since this function started, then return - // EFI_NOT_READY, so it will be restarted - // - Status = CoreLocateHandleBuffer ( - ByProtocol, - &gEfiDriverBindingProtocolGuid, - NULL, - &NewDriverBindingHandleCount, - &NewDriverBindingHandleBuffer - ); - CoreFreePool (NewDriverBindingHandleBuffer); - if (NewDriverBindingHandleCount > DriverBindingHandleCount) { - // - // Free any buffers that were allocated with AllocatePool() - // - CoreFreePool (SortedDriverBindingProtocols); - - return EFI_NOT_READY; - } - - // - // Sort the remaining DriverBinding Protocol based on their Version field from - // highest to lowest. - // - for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) { - HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version; - HighestIndex = SortIndex; - for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) { - if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) { - HighestVersion = SortedDriverBindingProtocols[Index]->Version; - HighestIndex = Index; - } - } - if (SortIndex != HighestIndex) { - DriverBinding = SortedDriverBindingProtocols[SortIndex]; - SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex]; - SortedDriverBindingProtocols[HighestIndex] = DriverBinding; - } - } - - // - // Loop until no more drivers can be started on ControllerHandle - // - OneStarted = FALSE; - do { - - // - // Loop through the sorted Driver Binding Protocol Instances in order, and see if - // any of the Driver Binding Protocols support the controller specified by - // ControllerHandle. - // - DriverBinding = NULL; - DriverFound = FALSE; - for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) { - if (SortedDriverBindingProtocols[Index] != NULL) { - DriverBinding = SortedDriverBindingProtocols[Index]; - PERF_START (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0); - Status = DriverBinding->Supported( - DriverBinding, - ControllerHandle, - RemainingDevicePath - ); - PERF_END (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0); - if (!EFI_ERROR (Status)) { - SortedDriverBindingProtocols[Index] = NULL; - DriverFound = TRUE; - - // - // A driver was found that supports ControllerHandle, so attempt to start the driver - // on ControllerHandle. - // - PERF_START (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0); - Status = DriverBinding->Start ( - DriverBinding, - ControllerHandle, - RemainingDevicePath - ); - PERF_END (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0); - - if (!EFI_ERROR (Status)) { - // - // The driver was successfully started on ControllerHandle, so set a flag - // - OneStarted = TRUE; - } - } - } - } - } while (DriverFound); - - // - // Free any buffers that were allocated with AllocatePool() - // - CoreFreePool (SortedDriverBindingProtocols); - - // - // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS. - // - if (OneStarted) { - return EFI_SUCCESS; - } - - // - // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS - // - if (RemainingDevicePath != NULL) { - if (IsDevicePathEnd (RemainingDevicePath)) { - return EFI_SUCCESS; - } - } - - // - // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND - // - return EFI_NOT_FOUND; -} - - - -/** - Disonnects a controller from a driver - - @param ControllerHandle ControllerHandle The handle of - the controller from which - driver(s) are to be - disconnected. - @param DriverImageHandle DriverImageHandle The driver to - disconnect from ControllerHandle. - @param ChildHandle ChildHandle The handle of the - child to destroy. - - @retval EFI_SUCCESS One or more drivers were - disconnected from the controller. - @retval EFI_SUCCESS On entry, no drivers are managing - ControllerHandle. - @retval EFI_SUCCESS DriverImageHandle is not NULL, - and on entry DriverImageHandle is - not managing ControllerHandle. - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, - and it is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it - is not a valid EFI_HANDLE. - @retval EFI_OUT_OF_RESOURCES There are not enough resources - available to disconnect any - drivers from ControllerHandle. - @retval EFI_DEVICE_ERROR The controller could not be - disconnected because of a device - error. - -**/ -EFI_STATUS -EFIAPI -CoreDisconnectController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE DriverImageHandle OPTIONAL, - IN EFI_HANDLE ChildHandle OPTIONAL - ) -{ - EFI_STATUS Status; - IHANDLE *Handle; - EFI_HANDLE *DriverImageHandleBuffer; - EFI_HANDLE *ChildBuffer; - UINTN Index; - UINTN HandleIndex; - UINTN DriverImageHandleCount; - UINTN ChildrenToStop; - UINTN ChildBufferCount; - UINTN StopCount; - BOOLEAN Duplicate; - BOOLEAN ChildHandleValid; - BOOLEAN DriverImageHandleValid; - LIST_ENTRY *Link; - LIST_ENTRY *ProtLink; - OPEN_PROTOCOL_DATA *OpenData; - PROTOCOL_INTERFACE *Prot; - EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; - - // - // Make sure ControllerHandle is valid - // - Status = CoreValidateHandle (ControllerHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Make sure ChildHandle is valid if it is not NULL - // - if (ChildHandle != NULL) { - Status = CoreValidateHandle (ChildHandle); - if (EFI_ERROR (Status)) { - return Status; - } - } - - Handle = ControllerHandle; - - // - // Get list of drivers that are currently managing ControllerHandle - // - DriverImageHandleBuffer = NULL; - DriverImageHandleCount = 1; - - if (DriverImageHandle == NULL) { - // - // Look at each protocol interface for a match - // - DriverImageHandleCount = 0; - - CoreAcquireProtocolLock (); - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - for (ProtLink = Prot->OpenList.ForwardLink; - ProtLink != &Prot->OpenList; - ProtLink = ProtLink->ForwardLink) { - OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - DriverImageHandleCount++; - } - } - } - CoreReleaseProtocolLock (); - - // - // If there are no drivers managing this controller, then return EFI_SUCCESS - // - if (DriverImageHandleCount == 0) { - Status = EFI_SUCCESS; - goto Done; - } - - DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount); - if (DriverImageHandleBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - DriverImageHandleCount = 0; - - CoreAcquireProtocolLock (); - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - for (ProtLink = Prot->OpenList.ForwardLink; - ProtLink != &Prot->OpenList; - ProtLink = ProtLink->ForwardLink) { - OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - Duplicate = FALSE; - for (Index = 0; Index< DriverImageHandleCount; Index++) { - if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) { - Duplicate = TRUE; - break; - } - } - if (!Duplicate) { - DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle; - DriverImageHandleCount++; - } - } - } - } - CoreReleaseProtocolLock (); - } - - StopCount = 0; - for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) { - - if (DriverImageHandleBuffer != NULL) { - DriverImageHandle = DriverImageHandleBuffer[HandleIndex]; - } - - // - // Get the Driver Binding Protocol of the driver that is managing this controller - // - Status = CoreHandleProtocol ( - DriverImageHandle, - &gEfiDriverBindingProtocolGuid, - (VOID **)&DriverBinding - ); - if (EFI_ERROR (Status) || DriverBinding == NULL) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - // - // Look at each protocol interface for a match - // - DriverImageHandleValid = FALSE; - ChildBufferCount = 0; - - CoreAcquireProtocolLock (); - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - for (ProtLink = Prot->OpenList.ForwardLink; - ProtLink != &Prot->OpenList; - ProtLink = ProtLink->ForwardLink) { - OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if (OpenData->AgentHandle == DriverImageHandle) { - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { - ChildBufferCount++; - } - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - DriverImageHandleValid = TRUE; - } - } - } - } - CoreReleaseProtocolLock (); - - if (DriverImageHandleValid) { - ChildHandleValid = FALSE; - ChildBuffer = NULL; - if (ChildBufferCount != 0) { - ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount); - if (ChildBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - ChildBufferCount = 0; - - CoreAcquireProtocolLock (); - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - for (ProtLink = Prot->OpenList.ForwardLink; - ProtLink != &Prot->OpenList; - ProtLink = ProtLink->ForwardLink) { - OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if ((OpenData->AgentHandle == DriverImageHandle) && - ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) { - Duplicate = FALSE; - for (Index = 0; Index < ChildBufferCount; Index++) { - if (ChildBuffer[Index] == OpenData->ControllerHandle) { - Duplicate = TRUE; - break; - } - } - if (!Duplicate) { - ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle; - if (ChildHandle == ChildBuffer[ChildBufferCount]) { - ChildHandleValid = TRUE; - } - ChildBufferCount++; - } - } - } - } - CoreReleaseProtocolLock (); - } - - if (ChildHandle == NULL || ChildHandleValid) { - ChildrenToStop = 0; - Status = EFI_SUCCESS; - if (ChildBufferCount > 0) { - if (ChildHandle != NULL) { - ChildrenToStop = 1; - Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle); - } else { - ChildrenToStop = ChildBufferCount; - Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer); - } - } - if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) { - Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL); - } - if (!EFI_ERROR (Status)) { - StopCount++; - } - } - - if (ChildBuffer != NULL) { - CoreFreePool (ChildBuffer); - } - } - } - - if (StopCount > 0) { - Status = EFI_SUCCESS; - } else { - Status = EFI_NOT_FOUND; - } - -Done: - - if (DriverImageHandleBuffer != NULL) { - CoreFreePool (DriverImageHandleBuffer); - } - - return Status; -} diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.c b/MdeModulePkg/Core/Dxe/Hand/Handle.c deleted file mode 100644 index 1c25521672..0000000000 --- a/MdeModulePkg/Core/Dxe/Hand/Handle.c +++ /dev/null @@ -1,1553 +0,0 @@ -/** @file - UEFI handle & protocol handling. - -Copyright (c) 2006 - 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Handle.h" - - -// -// mProtocolDatabase - A list of all protocols in the system. (simple list for now) -// gHandleList - A list of all the handles in the system -// gProtocolDatabaseLock - Lock to protect the mProtocolDatabase -// gHandleDatabaseKey - The Key to show that the handle has been created/modified -// -LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase); -LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList); -EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); -UINT64 gHandleDatabaseKey = 0; - - - -/** - Acquire lock on gProtocolDatabaseLock. - -**/ -VOID -CoreAcquireProtocolLock ( - VOID - ) -{ - CoreAcquireLock (&gProtocolDatabaseLock); -} - - - -/** - Release lock on gProtocolDatabaseLock. - -**/ -VOID -CoreReleaseProtocolLock ( - VOID - ) -{ - CoreReleaseLock (&gProtocolDatabaseLock); -} - - - -/** - Check whether a handle is a valid EFI_HANDLE - - @param UserHandle The handle to check - - @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE. - @retval EFI_SUCCESS The handle is valid EFI_HANDLE. - -**/ -EFI_STATUS -CoreValidateHandle ( - IN EFI_HANDLE UserHandle - ) -{ - IHANDLE *Handle; - - Handle = (IHANDLE *)UserHandle; - if (Handle == NULL) { - return EFI_INVALID_PARAMETER; - } - if (Handle->Signature != EFI_HANDLE_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - return EFI_SUCCESS; -} - - - -/** - Finds the protocol entry for the requested protocol. - The gProtocolDatabaseLock must be owned - - @param Protocol The ID of the protocol - @param Create Create a new entry if not found - - @return Protocol entry - -**/ -PROTOCOL_ENTRY * -CoreFindProtocolEntry ( - IN EFI_GUID *Protocol, - IN BOOLEAN Create - ) -{ - LIST_ENTRY *Link; - PROTOCOL_ENTRY *Item; - PROTOCOL_ENTRY *ProtEntry; - - ASSERT_LOCKED(&gProtocolDatabaseLock); - - // - // Search the database for the matching GUID - // - - ProtEntry = NULL; - for (Link = mProtocolDatabase.ForwardLink; - Link != &mProtocolDatabase; - Link = Link->ForwardLink) { - - Item = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE); - if (CompareGuid (&Item->ProtocolID, Protocol)) { - - // - // This is the protocol entry - // - - ProtEntry = Item; - break; - } - } - - // - // If the protocol entry was not found and Create is TRUE, then - // allocate a new entry - // - if ((ProtEntry == NULL) && Create) { - ProtEntry = AllocatePool (sizeof(PROTOCOL_ENTRY)); - - if (ProtEntry != NULL) { - // - // Initialize new protocol entry structure - // - ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE; - CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol); - InitializeListHead (&ProtEntry->Protocols); - InitializeListHead (&ProtEntry->Notify); - - // - // Add it to protocol database - // - InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries); - } - } - - return ProtEntry; -} - - - -/** - Finds the protocol instance for the requested handle and protocol. - Note: This function doesn't do parameters checking, it's caller's responsibility - to pass in valid parameters. - - @param Handle The handle to search the protocol on - @param Protocol GUID of the protocol - @param Interface The interface for the protocol being searched - - @return Protocol instance (NULL: Not found) - -**/ -PROTOCOL_INTERFACE * -CoreFindProtocolInterface ( - IN IHANDLE *Handle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ) -{ - PROTOCOL_INTERFACE *Prot; - PROTOCOL_ENTRY *ProtEntry; - LIST_ENTRY *Link; - - ASSERT_LOCKED(&gProtocolDatabaseLock); - Prot = NULL; - - // - // Lookup the protocol entry for this protocol ID - // - - ProtEntry = CoreFindProtocolEntry (Protocol, FALSE); - if (ProtEntry != NULL) { - - // - // Look at each protocol interface for any matches - // - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link=Link->ForwardLink) { - - // - // If this protocol interface matches, remove it - // - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - if (Prot->Interface == Interface && Prot->Protocol == ProtEntry) { - break; - } - - Prot = NULL; - } - } - - return Prot; -} - - -/** - Removes an event from a register protocol notify list on a protocol. - - @param Event The event to search for in the protocol - database. - - @return EFI_SUCCESS if the event was found and removed. - @return EFI_NOT_FOUND if the event was not found in the protocl database. - -**/ -EFI_STATUS -CoreUnregisterProtocolNotifyEvent ( - IN EFI_EVENT Event - ) -{ - LIST_ENTRY *Link; - PROTOCOL_ENTRY *ProtEntry; - LIST_ENTRY *NotifyLink; - PROTOCOL_NOTIFY *ProtNotify; - - CoreAcquireProtocolLock (); - - for ( Link = mProtocolDatabase.ForwardLink; - Link != &mProtocolDatabase; - Link = Link->ForwardLink) { - - ProtEntry = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE); - - for ( NotifyLink = ProtEntry->Notify.ForwardLink; - NotifyLink != &ProtEntry->Notify; - NotifyLink = NotifyLink->ForwardLink) { - - ProtNotify = CR(NotifyLink, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); - - if (ProtNotify->Event == Event) { - RemoveEntryList(&ProtNotify->Link); - CoreFreePool(ProtNotify); - CoreReleaseProtocolLock (); - return EFI_SUCCESS; - } - } - } - - CoreReleaseProtocolLock (); - return EFI_NOT_FOUND; -} - - - -/** - Removes all the events in the protocol database that match Event. - - @param Event The event to search for in the protocol - database. - - @return EFI_SUCCESS when done searching the entire database. - -**/ -EFI_STATUS -CoreUnregisterProtocolNotify ( - IN EFI_EVENT Event - ) -{ - EFI_STATUS Status; - - do { - Status = CoreUnregisterProtocolNotifyEvent (Event); - } while (!EFI_ERROR (Status)); - - return EFI_SUCCESS; -} - - - - -/** - Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which - Calls the private one which contains a BOOLEAN parameter for notifications - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - - @return Status code - -**/ -EFI_STATUS -EFIAPI -CoreInstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface - ) -{ - return CoreInstallProtocolInterfaceNotify ( - UserHandle, - Protocol, - InterfaceType, - Interface, - TRUE - ); -} - - -/** - Installs a protocol interface into the boot services environment. - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - @param Notify indicates whether notify the notification list - for this protocol - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SUCCESS Protocol interface successfully installed - -**/ -EFI_STATUS -CoreInstallProtocolInterfaceNotify ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface, - IN BOOLEAN Notify - ) -{ - PROTOCOL_INTERFACE *Prot; - PROTOCOL_ENTRY *ProtEntry; - IHANDLE *Handle; - EFI_STATUS Status; - VOID *ExistingInterface; - - // - // returns EFI_INVALID_PARAMETER if InterfaceType is invalid. - // Also added check for invalid UserHandle and Protocol pointers. - // - if (UserHandle == NULL || Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (InterfaceType != EFI_NATIVE_INTERFACE) { - return EFI_INVALID_PARAMETER; - } - - // - // Print debug message - // - DEBUG((DEBUG_INFO, "InstallProtocolInterface: %g %p\n", Protocol, Interface)); - - Status = EFI_OUT_OF_RESOURCES; - Prot = NULL; - Handle = NULL; - - if (*UserHandle != NULL) { - Status = CoreHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface); - if (!EFI_ERROR (Status)) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - // - // Lookup the Protocol Entry for the requested protocol - // - ProtEntry = CoreFindProtocolEntry (Protocol, TRUE); - if (ProtEntry == NULL) { - goto Done; - } - - // - // Allocate a new protocol interface structure - // - Prot = AllocateZeroPool (sizeof(PROTOCOL_INTERFACE)); - if (Prot == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - // - // If caller didn't supply a handle, allocate a new one - // - Handle = (IHANDLE *)*UserHandle; - if (Handle == NULL) { - Handle = AllocateZeroPool (sizeof(IHANDLE)); - if (Handle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - // - // Initialize new handler structure - // - Handle->Signature = EFI_HANDLE_SIGNATURE; - InitializeListHead (&Handle->Protocols); - - // - // Initialize the Key to show that the handle has been created/modified - // - gHandleDatabaseKey++; - Handle->Key = gHandleDatabaseKey; - - // - // Add this handle to the list global list of all handles - // in the system - // - InsertTailList (&gHandleList, &Handle->AllHandles); - } - - Status = CoreValidateHandle (Handle); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Each interface that is added must be unique - // - ASSERT (CoreFindProtocolInterface (Handle, Protocol, Interface) == NULL); - - // - // Initialize the protocol interface structure - // - Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE; - Prot->Handle = Handle; - Prot->Protocol = ProtEntry; - Prot->Interface = Interface; - - // - // Initalize OpenProtocol Data base - // - InitializeListHead (&Prot->OpenList); - Prot->OpenListCount = 0; - - // - // Add this protocol interface to the head of the supported - // protocol list for this handle - // - InsertHeadList (&Handle->Protocols, &Prot->Link); - - // - // Add this protocol interface to the tail of the - // protocol entry - // - InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol); - - // - // Notify the notification list for this protocol - // - if (Notify) { - CoreNotifyProtocolEntry (ProtEntry); - } - Status = EFI_SUCCESS; - -Done: - // - // Done, unlock the database and return - // - CoreReleaseProtocolLock (); - if (!EFI_ERROR (Status)) { - // - // Return the new handle back to the caller - // - *UserHandle = Handle; - } else { - // - // There was an error, clean up - // - if (Prot != NULL) { - CoreFreePool (Prot); - } - } - - return Status; -} - - - - -/** - Installs a list of protocol interface into the boot services environment. - This function calls InstallProtocolInterface() in a loop. If any error - occures all the protocols added by this function are removed. This is - basically a lib function to save space. - - @param Handle The pointer to a handle to install the new - protocol interfaces on, or a pointer to NULL - if a new handle is to be allocated. - @param ... EFI_GUID followed by protocol instance. A NULL - terminates the list. The pairs are the - arguments to InstallProtocolInterface(). All the - protocols are added to Handle. - - @retval EFI_SUCCESS All the protocol interface was installed. - @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. - @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in - the handle database. - @retval EFI_INVALID_PARAMETER Handle is NULL. - @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. - -**/ -EFI_STATUS -EFIAPI -CoreInstallMultipleProtocolInterfaces ( - IN OUT EFI_HANDLE *Handle, - ... - ) -{ - VA_LIST Args; - EFI_STATUS Status; - EFI_GUID *Protocol; - VOID *Interface; - EFI_TPL OldTpl; - UINTN Index; - EFI_HANDLE OldHandle; - EFI_HANDLE DeviceHandle; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - if (Handle == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Syncronize with notifcations. - // - OldTpl = CoreRaiseTpl (TPL_NOTIFY); - OldHandle = *Handle; - - // - // Check for duplicate device path and install the protocol interfaces - // - VA_START (Args, Handle); - for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { - // - // If protocol is NULL, then it's the end of the list - // - Protocol = VA_ARG (Args, EFI_GUID *); - if (Protocol == NULL) { - break; - } - - Interface = VA_ARG (Args, VOID *); - - // - // Make sure you are installing on top a device path that has already been added. - // - if (CompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) { - DeviceHandle = NULL; - DevicePath = Interface; - Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle); - if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(DevicePath)) { - Status = EFI_ALREADY_STARTED; - continue; - } - } - - // - // Install it - // - Status = CoreInstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface); - } - VA_END (Args); - - // - // If there was an error, remove all the interfaces that were installed without any errors - // - if (EFI_ERROR (Status)) { - // - // Reset the va_arg back to the first argument. - // - VA_START (Args, Handle); - for (; Index > 1; Index--) { - Protocol = VA_ARG (Args, EFI_GUID *); - Interface = VA_ARG (Args, VOID *); - CoreUninstallProtocolInterface (*Handle, Protocol, Interface); - } - VA_END (Args); - - *Handle = OldHandle; - } - - // - // Done - // - CoreRestoreTpl (OldTpl); - return Status; -} - - -/** - Attempts to disconnect all drivers that are using the protocol interface being queried. - If failed, reconnect all drivers disconnected. - Note: This function doesn't do parameters checking, it's caller's responsibility - to pass in valid parameters. - - @param UserHandle The handle on which the protocol is installed - @param Prot The protocol to disconnect drivers from - - @retval EFI_SUCCESS Drivers using the protocol interface are all - disconnected - @retval EFI_ACCESS_DENIED Failed to disconnect one or all of the drivers - -**/ -EFI_STATUS -CoreDisconnectControllersUsingProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN PROTOCOL_INTERFACE *Prot - ) -{ - EFI_STATUS Status; - BOOLEAN ItemFound; - LIST_ENTRY *Link; - OPEN_PROTOCOL_DATA *OpenData; - - Status = EFI_SUCCESS; - - // - // Attempt to disconnect all drivers from this protocol interface - // - do { - ItemFound = FALSE; - for ( Link = Prot->OpenList.ForwardLink; - (Link != &Prot->OpenList) && !ItemFound; - Link = Link->ForwardLink ) { - OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - ItemFound = TRUE; - CoreReleaseProtocolLock (); - Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL); - CoreAcquireProtocolLock (); - if (EFI_ERROR (Status)) { - ItemFound = FALSE; - break; - } - } - } - } while (ItemFound); - - if (!EFI_ERROR (Status)) { - // - // Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items - // - do { - ItemFound = FALSE; - for ( Link = Prot->OpenList.ForwardLink; - (Link != &Prot->OpenList) && !ItemFound; - Link = Link->ForwardLink ) { - OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if ((OpenData->Attributes & - (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0) { - ItemFound = TRUE; - RemoveEntryList (&OpenData->Link); - Prot->OpenListCount--; - CoreFreePool (OpenData); - } - } - } while (ItemFound); - } - - // - // If there are errors or still has open items in the list, then reconnect all the drivers and return an error - // - if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) { - CoreReleaseProtocolLock (); - CoreConnectController (UserHandle, NULL, NULL, TRUE); - CoreAcquireProtocolLock (); - Status = EFI_ACCESS_DENIED; - } - - return Status; -} - - - -/** - Uninstalls all instances of a protocol:interfacer from a handle. - If the last protocol interface is remove from the handle, the - handle is freed. - - @param UserHandle The handle to remove the protocol handler from - @param Protocol The protocol, of protocol:interface, to remove - @param Interface The interface, of protocol:interface, to remove - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Protocol interface successfully uninstalled. - -**/ -EFI_STATUS -EFIAPI -CoreUninstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ) -{ - EFI_STATUS Status; - IHANDLE *Handle; - PROTOCOL_INTERFACE *Prot; - - // - // Check that Protocol is valid - // - if (Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check that UserHandle is a valid handle - // - Status = CoreValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - // - // Check that Protocol exists on UserHandle, and Interface matches the interface in the database - // - Prot = CoreFindProtocolInterface (UserHandle, Protocol, Interface); - if (Prot == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - // - // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed - // - Status = CoreDisconnectControllersUsingProtocolInterface ( - UserHandle, - Prot - ); - if (EFI_ERROR (Status)) { - // - // One or more drivers refused to release, so return the error - // - goto Done; - } - - // - // Remove the protocol interface from the protocol - // - Status = EFI_NOT_FOUND; - Handle = (IHANDLE *)UserHandle; - Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, Interface); - - if (Prot != NULL) { - // - // Update the Key to show that the handle has been created/modified - // - gHandleDatabaseKey++; - Handle->Key = gHandleDatabaseKey; - - // - // Remove the protocol interface from the handle - // - RemoveEntryList (&Prot->Link); - - // - // Free the memory - // - Prot->Signature = 0; - CoreFreePool (Prot); - Status = EFI_SUCCESS; - } - - // - // If there are no more handlers for the handle, free the handle - // - if (IsListEmpty (&Handle->Protocols)) { - Handle->Signature = 0; - RemoveEntryList (&Handle->AllHandles); - CoreFreePool (Handle); - } - -Done: - // - // Done, unlock the database and return - // - CoreReleaseProtocolLock (); - return Status; -} - - - - -/** - Uninstalls a list of protocol interface in the boot services environment. - This function calls UnisatllProtocolInterface() in a loop. This is - basically a lib function to save space. - - @param Handle The handle to uninstall the protocol - @param ... EFI_GUID followed by protocol instance. A NULL - terminates the list. The pairs are the - arguments to UninstallProtocolInterface(). All - the protocols are added to Handle. - - @return Status code - -**/ -EFI_STATUS -EFIAPI -CoreUninstallMultipleProtocolInterfaces ( - IN EFI_HANDLE Handle, - ... - ) -{ - EFI_STATUS Status; - VA_LIST Args; - EFI_GUID *Protocol; - VOID *Interface; - UINTN Index; - - VA_START (Args, Handle); - for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { - // - // If protocol is NULL, then it's the end of the list - // - Protocol = VA_ARG (Args, EFI_GUID *); - if (Protocol == NULL) { - break; - } - - Interface = VA_ARG (Args, VOID *); - - // - // Uninstall it - // - Status = CoreUninstallProtocolInterface (Handle, Protocol, Interface); - } - VA_END (Args); - - // - // If there was an error, add all the interfaces that were - // uninstalled without any errors - // - if (EFI_ERROR (Status)) { - // - // Reset the va_arg back to the first argument. - // - VA_START (Args, Handle); - for (; Index > 1; Index--) { - Protocol = VA_ARG(Args, EFI_GUID *); - Interface = VA_ARG(Args, VOID *); - CoreInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface); - } - VA_END (Args); - } - - return Status; -} - - -/** - Locate a certain GUID protocol interface in a Handle's protocols. - - @param UserHandle The handle to obtain the protocol interface on - @param Protocol The GUID of the protocol - - @return The requested protocol interface for the handle - -**/ -PROTOCOL_INTERFACE * -CoreGetProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol - ) -{ - EFI_STATUS Status; - PROTOCOL_ENTRY *ProtEntry; - PROTOCOL_INTERFACE *Prot; - IHANDLE *Handle; - LIST_ENTRY *Link; - - Status = CoreValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return NULL; - } - - Handle = (IHANDLE *)UserHandle; - - // - // Look at each protocol interface for a match - // - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - ProtEntry = Prot->Protocol; - if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) { - return Prot; - } - } - return NULL; -} - - - -/** - Queries a handle to determine if it supports a specified protocol. - - @param UserHandle The handle being queried. - @param Protocol The published unique identifier of the protocol. - @param Interface Supplies the address where a pointer to the - corresponding Protocol Interface is returned. - - @retval EFI_SUCCESS The interface information for the specified protocol was returned. - @retval EFI_UNSUPPORTED The device does not support the specified protocol. - @retval EFI_INVALID_PARAMETER Handle is NULL.. - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_INVALID_PARAMETER Interface is NULL. - -**/ -EFI_STATUS -EFIAPI -CoreHandleProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ) -{ - return CoreOpenProtocol ( - UserHandle, - Protocol, - Interface, - gDxeCoreImageHandle, - NULL, - EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - ); -} - - - -/** - Locates the installed protocol handler for the handle, and - invokes it to obtain the protocol interface. Usage information - is registered in the protocol data base. - - @param UserHandle The handle to obtain the protocol interface on - @param Protocol The ID of the protocol - @param Interface The location to return the protocol interface - @param ImageHandle The handle of the Image that is opening the - protocol interface specified by Protocol and - Interface. - @param ControllerHandle The controller handle that is requiring this - interface. - @param Attributes The open mode of the protocol interface - specified by Handle and Protocol. - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Get the protocol interface. - -**/ -EFI_STATUS -EFIAPI -CoreOpenProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface OPTIONAL, - IN EFI_HANDLE ImageHandle, - IN EFI_HANDLE ControllerHandle, - IN UINT32 Attributes - ) -{ - EFI_STATUS Status; - PROTOCOL_INTERFACE *Prot; - LIST_ENTRY *Link; - OPEN_PROTOCOL_DATA *OpenData; - BOOLEAN ByDriver; - BOOLEAN Exclusive; - BOOLEAN Disconnect; - BOOLEAN ExactMatch; - - // - // Check for invalid Protocol - // - if (Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check for invalid Interface - // - if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) { - if (Interface == NULL) { - return EFI_INVALID_PARAMETER; - } else { - *Interface = NULL; - } - } - - // - // Check for invalid UserHandle - // - Status = CoreValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Check for invalid Attributes - // - switch (Attributes) { - case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER : - Status = CoreValidateHandle (ImageHandle); - if (EFI_ERROR (Status)) { - return Status; - } - Status = CoreValidateHandle (ControllerHandle); - if (EFI_ERROR (Status)) { - return Status; - } - if (UserHandle == ControllerHandle) { - return EFI_INVALID_PARAMETER; - } - break; - case EFI_OPEN_PROTOCOL_BY_DRIVER : - case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE : - Status = CoreValidateHandle (ImageHandle); - if (EFI_ERROR (Status)) { - return Status; - } - Status = CoreValidateHandle (ControllerHandle); - if (EFI_ERROR (Status)) { - return Status; - } - break; - case EFI_OPEN_PROTOCOL_EXCLUSIVE : - Status = CoreValidateHandle (ImageHandle); - if (EFI_ERROR (Status)) { - return Status; - } - break; - case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL : - case EFI_OPEN_PROTOCOL_GET_PROTOCOL : - case EFI_OPEN_PROTOCOL_TEST_PROTOCOL : - break; - default: - return EFI_INVALID_PARAMETER; - } - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - // - // Look at each protocol interface for a match - // - Prot = CoreGetProtocolInterface (UserHandle, Protocol); - if (Prot == NULL) { - Status = EFI_UNSUPPORTED; - goto Done; - } - - // - // This is the protocol interface entry for this protocol - // - if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) { - *Interface = Prot->Interface; - } - Status = EFI_SUCCESS; - - ByDriver = FALSE; - Exclusive = FALSE; - for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) { - OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) && - (OpenData->Attributes == Attributes) && - (OpenData->ControllerHandle == ControllerHandle)); - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - ByDriver = TRUE; - if (ExactMatch) { - Status = EFI_ALREADY_STARTED; - goto Done; - } - } - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) { - Exclusive = TRUE; - } else if (ExactMatch) { - OpenData->OpenCount++; - Status = EFI_SUCCESS; - goto Done; - } - } - - // - // ByDriver TRUE -> A driver is managing (UserHandle, Protocol) - // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol) - // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol) - // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol) - // - - switch (Attributes) { - case EFI_OPEN_PROTOCOL_BY_DRIVER : - if (Exclusive || ByDriver) { - Status = EFI_ACCESS_DENIED; - goto Done; - } - break; - case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE : - case EFI_OPEN_PROTOCOL_EXCLUSIVE : - if (Exclusive) { - Status = EFI_ACCESS_DENIED; - goto Done; - } - if (ByDriver) { - do { - Disconnect = FALSE; - for ( Link = Prot->OpenList.ForwardLink; (Link != &Prot->OpenList) && (!Disconnect); Link = Link->ForwardLink) { - OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { - Disconnect = TRUE; - CoreReleaseProtocolLock (); - Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL); - CoreAcquireProtocolLock (); - if (EFI_ERROR (Status)) { - Status = EFI_ACCESS_DENIED; - goto Done; - } - } - } - } while (Disconnect); - } - break; - case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER : - case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL : - case EFI_OPEN_PROTOCOL_GET_PROTOCOL : - case EFI_OPEN_PROTOCOL_TEST_PROTOCOL : - break; - } - - if (ImageHandle == NULL) { - Status = EFI_SUCCESS; - goto Done; - } - // - // Create new entry - // - OpenData = AllocatePool (sizeof(OPEN_PROTOCOL_DATA)); - if (OpenData == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } else { - OpenData->Signature = OPEN_PROTOCOL_DATA_SIGNATURE; - OpenData->AgentHandle = ImageHandle; - OpenData->ControllerHandle = ControllerHandle; - OpenData->Attributes = Attributes; - OpenData->OpenCount = 1; - InsertTailList (&Prot->OpenList, &OpenData->Link); - Prot->OpenListCount++; - Status = EFI_SUCCESS; - } - -Done: - // - // Done. Release the database lock are return - // - CoreReleaseProtocolLock (); - return Status; -} - - - -/** - Closes a protocol on a handle that was opened using OpenProtocol(). - - @param UserHandle The handle for the protocol interface that was - previously opened with OpenProtocol(), and is - now being closed. - @param Protocol The published unique identifier of the protocol. - It is the caller's responsibility to pass in a - valid GUID. - @param AgentHandle The handle of the agent that is closing the - protocol interface. - @param ControllerHandle If the agent that opened a protocol is a driver - that follows the EFI Driver Model, then this - parameter is the controller handle that required - the protocol interface. If the agent does not - follow the EFI Driver Model, then this parameter - is optional and may be NULL. - - @retval EFI_SUCCESS The protocol instance was closed. - @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a - valid EFI_HANDLE. - @retval EFI_NOT_FOUND Can not find the specified protocol or - AgentHandle. - -**/ -EFI_STATUS -EFIAPI -CoreCloseProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN EFI_HANDLE AgentHandle, - IN EFI_HANDLE ControllerHandle - ) -{ - EFI_STATUS Status; - PROTOCOL_INTERFACE *ProtocolInterface; - LIST_ENTRY *Link; - OPEN_PROTOCOL_DATA *OpenData; - - // - // Check for invalid parameters - // - Status = CoreValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return Status; - } - Status = CoreValidateHandle (AgentHandle); - if (EFI_ERROR (Status)) { - return Status; - } - if (ControllerHandle != NULL) { - Status = CoreValidateHandle (ControllerHandle); - if (EFI_ERROR (Status)) { - return Status; - } - } - if (Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - // - // Look at each protocol interface for a match - // - Status = EFI_NOT_FOUND; - ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol); - if (ProtocolInterface == NULL) { - goto Done; - } - - // - // Walk the Open data base looking for AgentHandle - // - Link = ProtocolInterface->OpenList.ForwardLink; - while (Link != &ProtocolInterface->OpenList) { - OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - Link = Link->ForwardLink; - if ((OpenData->AgentHandle == AgentHandle) && (OpenData->ControllerHandle == ControllerHandle)) { - RemoveEntryList (&OpenData->Link); - ProtocolInterface->OpenListCount--; - CoreFreePool (OpenData); - Status = EFI_SUCCESS; - } - } - -Done: - // - // Done. Release the database lock and return. - // - CoreReleaseProtocolLock (); - return Status; -} - - - - -/** - Return information about Opened protocols in the system - - @param UserHandle The handle to close the protocol interface on - @param Protocol The ID of the protocol - @param EntryBuffer A pointer to a buffer of open protocol information in the - form of EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. - @param EntryCount Number of EntryBuffer entries - - @retval EFI_SUCCESS The open protocol information was returned in EntryBuffer, - and the number of entries was returned EntryCount. - @retval EFI_NOT_FOUND Handle does not support the protocol specified by Protocol. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to allocate EntryBuffer. - -**/ -EFI_STATUS -EFIAPI -CoreOpenProtocolInformation ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, - OUT UINTN *EntryCount - ) -{ - EFI_STATUS Status; - PROTOCOL_INTERFACE *ProtocolInterface; - LIST_ENTRY *Link; - OPEN_PROTOCOL_DATA *OpenData; - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Buffer; - UINTN Count; - UINTN Size; - - *EntryBuffer = NULL; - *EntryCount = 0; - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - // - // Look at each protocol interface for a match - // - Status = EFI_NOT_FOUND; - ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol); - if (ProtocolInterface == NULL) { - goto Done; - } - - // - // Count the number of Open Entries - // - for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0; - (Link != &ProtocolInterface->OpenList) ; - Link = Link->ForwardLink ) { - Count++; - } - - ASSERT (Count == ProtocolInterface->OpenListCount); - - if (Count == 0) { - Size = sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY); - } else { - Size = Count * sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY); - } - - Buffer = AllocatePool (Size); - if (Buffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - Status = EFI_SUCCESS; - for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0; - (Link != &ProtocolInterface->OpenList); - Link = Link->ForwardLink, Count++ ) { - OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); - - Buffer[Count].AgentHandle = OpenData->AgentHandle; - Buffer[Count].ControllerHandle = OpenData->ControllerHandle; - Buffer[Count].Attributes = OpenData->Attributes; - Buffer[Count].OpenCount = OpenData->OpenCount; - } - - *EntryBuffer = Buffer; - *EntryCount = Count; - -Done: - // - // Done. Release the database lock. - // - CoreReleaseProtocolLock (); - return Status; -} - - - - -/** - Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated - from pool. - - @param UserHandle The handle from which to retrieve the list of - protocol interface GUIDs. - @param ProtocolBuffer A pointer to the list of protocol interface GUID - pointers that are installed on Handle. - @param ProtocolBufferCount A pointer to the number of GUID pointers present - in ProtocolBuffer. - - @retval EFI_SUCCESS The list of protocol interface GUIDs installed - on Handle was returned in ProtocolBuffer. The - number of protocol interface GUIDs was returned - in ProtocolBufferCount. - @retval EFI_INVALID_PARAMETER Handle is NULL. - @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. - @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. - @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - results. - -**/ -EFI_STATUS -EFIAPI -CoreProtocolsPerHandle ( - IN EFI_HANDLE UserHandle, - OUT EFI_GUID ***ProtocolBuffer, - OUT UINTN *ProtocolBufferCount - ) -{ - EFI_STATUS Status; - IHANDLE *Handle; - PROTOCOL_INTERFACE *Prot; - LIST_ENTRY *Link; - UINTN ProtocolCount; - EFI_GUID **Buffer; - - Status = CoreValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - Handle = (IHANDLE *)UserHandle; - - if (ProtocolBuffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (ProtocolBufferCount == NULL) { - return EFI_INVALID_PARAMETER; - } - - *ProtocolBufferCount = 0; - - ProtocolCount = 0; - - CoreAcquireProtocolLock (); - - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { - ProtocolCount++; - } - - // - // If there are no protocol interfaces installed on Handle, then Handle is not a valid EFI_HANDLE - // - if (ProtocolCount == 0) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - Buffer = AllocatePool (sizeof (EFI_GUID *) * ProtocolCount); - if (Buffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - *ProtocolBuffer = Buffer; - *ProtocolBufferCount = ProtocolCount; - - for ( Link = Handle->Protocols.ForwardLink, ProtocolCount = 0; - Link != &Handle->Protocols; - Link = Link->ForwardLink, ProtocolCount++) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - Buffer[ProtocolCount] = &(Prot->Protocol->ProtocolID); - } - Status = EFI_SUCCESS; - -Done: - CoreReleaseProtocolLock (); - return Status; -} - - - -/** - return handle database key. - - - @return Handle database key. - -**/ -UINT64 -CoreGetHandleDatabaseKey ( - VOID - ) -{ - return gHandleDatabaseKey; -} - - - -/** - Go connect any handles that were created or modified while a image executed. - - @param Key The Key to show that the handle has been - created/modified - -**/ -VOID -CoreConnectHandlesByKey ( - UINT64 Key - ) -{ - UINTN Count; - LIST_ENTRY *Link; - EFI_HANDLE *HandleBuffer; - IHANDLE *Handle; - UINTN Index; - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) { - Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); - if (Handle->Key > Key) { - Count++; - } - } - - HandleBuffer = AllocatePool (Count * sizeof (EFI_HANDLE)); - if (HandleBuffer == NULL) { - CoreReleaseProtocolLock (); - return; - } - - for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) { - Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); - if (Handle->Key > Key) { - HandleBuffer[Count++] = Handle; - } - } - - // - // Unlock the protocol database - // - CoreReleaseProtocolLock (); - - // - // Connect all handles whose Key value is greater than Key - // - for (Index = 0; Index < Count; Index++) { - CoreConnectController (HandleBuffer[Index], NULL, NULL, TRUE); - } - - CoreFreePool(HandleBuffer); -} diff --git a/MdeModulePkg/Core/Dxe/Hand/Handle.h b/MdeModulePkg/Core/Dxe/Hand/Handle.h deleted file mode 100644 index 28f762265a..0000000000 --- a/MdeModulePkg/Core/Dxe/Hand/Handle.h +++ /dev/null @@ -1,270 +0,0 @@ -/** @file - Support functions for managing protocol. - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _HAND_H_ -#define _HAND_H_ - - -#define EFI_HANDLE_SIGNATURE SIGNATURE_32('h','n','d','l') - -/// -/// IHANDLE - contains a list of protocol handles -/// -typedef struct { - UINTN Signature; - /// All handles list of IHANDLE - LIST_ENTRY AllHandles; - /// List of PROTOCOL_INTERFACE's for this handle - LIST_ENTRY Protocols; - UINTN LocateRequest; - /// The Handle Database Key value when this handle was last created or modified - UINT64 Key; -} IHANDLE; - -#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE) - -#define PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('p','r','t','e') - -/// -/// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol -/// database. Each handler that supports this protocol is listed, along -/// with a list of registered notifies. -/// -typedef struct { - UINTN Signature; - /// Link Entry inserted to mProtocolDatabase - LIST_ENTRY AllEntries; - /// ID of the protocol - EFI_GUID ProtocolID; - /// All protocol interfaces - LIST_ENTRY Protocols; - /// Registerd notification handlers - LIST_ENTRY Notify; -} PROTOCOL_ENTRY; - - -#define PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('p','i','f','c') - -/// -/// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked -/// with a protocol interface structure -/// -typedef struct { - UINTN Signature; - /// Link on IHANDLE.Protocols - LIST_ENTRY Link; - /// Back pointer - IHANDLE *Handle; - /// Link on PROTOCOL_ENTRY.Protocols - LIST_ENTRY ByProtocol; - /// The protocol ID - PROTOCOL_ENTRY *Protocol; - /// The interface value - VOID *Interface; - /// OPEN_PROTOCOL_DATA list - LIST_ENTRY OpenList; - UINTN OpenListCount; - -} PROTOCOL_INTERFACE; - -#define OPEN_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('p','o','d','l') - -typedef struct { - UINTN Signature; - ///Link on PROTOCOL_INTERFACE.OpenList - LIST_ENTRY Link; - - EFI_HANDLE AgentHandle; - EFI_HANDLE ControllerHandle; - UINT32 Attributes; - UINT32 OpenCount; -} OPEN_PROTOCOL_DATA; - - -#define PROTOCOL_NOTIFY_SIGNATURE SIGNATURE_32('p','r','t','n') - -/// -/// PROTOCOL_NOTIFY - used for each register notification for a protocol -/// -typedef struct { - UINTN Signature; - PROTOCOL_ENTRY *Protocol; - /// All notifications for this protocol - LIST_ENTRY Link; - /// Event to notify - EFI_EVENT Event; - /// Last position notified - LIST_ENTRY *Position; -} PROTOCOL_NOTIFY; - - - -/** - Finds the protocol entry for the requested protocol. - The gProtocolDatabaseLock must be owned - - @param Protocol The ID of the protocol - @param Create Create a new entry if not found - - @return Protocol entry - -**/ -PROTOCOL_ENTRY * -CoreFindProtocolEntry ( - IN EFI_GUID *Protocol, - IN BOOLEAN Create - ); - - -/** - Signal event for every protocol in protocol entry. - - @param ProtEntry Protocol entry - -**/ -VOID -CoreNotifyProtocolEntry ( - IN PROTOCOL_ENTRY *ProtEntry - ); - - -/** - Finds the protocol instance for the requested handle and protocol. - Note: This function doesn't do parameters checking, it's caller's responsibility - to pass in valid parameters. - - @param Handle The handle to search the protocol on - @param Protocol GUID of the protocol - @param Interface The interface for the protocol being searched - - @return Protocol instance (NULL: Not found) - -**/ -PROTOCOL_INTERFACE * -CoreFindProtocolInterface ( - IN IHANDLE *Handle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ); - - -/** - Removes Protocol from the protocol list (but not the handle list). - - @param Handle The handle to remove protocol on. - @param Protocol GUID of the protocol to be moved - @param Interface The interface of the protocol - - @return Protocol Entry - -**/ -PROTOCOL_INTERFACE * -CoreRemoveInterfaceFromProtocol ( - IN IHANDLE *Handle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ); - - -/** - Connects a controller to a driver. - - @param ControllerHandle Handle of the controller to be - connected. - @param ContextDriverImageHandles DriverImageHandle A pointer to an - ordered list of driver image - handles. - @param RemainingDevicePath RemainingDevicePath A pointer to - the device path that specifies a - child of the controller - specified by ControllerHandle. - - @retval EFI_SUCCESS One or more drivers were - connected to ControllerHandle. - @retval EFI_OUT_OF_RESOURCES No enough system resources to - complete the request. - @retval EFI_NOT_FOUND No drivers were connected to - ControllerHandle. - -**/ -EFI_STATUS -CoreConnectSingleController ( - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ); - -/** - Attempts to disconnect all drivers that are using the protocol interface being queried. - If failed, reconnect all drivers disconnected. - Note: This function doesn't do parameters checking, it's caller's responsibility - to pass in valid parameters. - - @param UserHandle The handle on which the protocol is installed - @param Prot The protocol to disconnect drivers from - - @retval EFI_SUCCESS Drivers using the protocol interface are all - disconnected - @retval EFI_ACCESS_DENIED Failed to disconnect one or all of the drivers - -**/ -EFI_STATUS -CoreDisconnectControllersUsingProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN PROTOCOL_INTERFACE *Prot - ); - - -/** - Acquire lock on gProtocolDatabaseLock. - -**/ -VOID -CoreAcquireProtocolLock ( - VOID - ); - - -/** - Release lock on gProtocolDatabaseLock. - -**/ -VOID -CoreReleaseProtocolLock ( - VOID - ); - - -/** - Check whether a handle is a valid EFI_HANDLE - - @param UserHandle The handle to check - - @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE. - @retval EFI_SUCCESS The handle is valid EFI_HANDLE. - -**/ -EFI_STATUS -CoreValidateHandle ( - IN EFI_HANDLE UserHandle - ); - -// -// Externs -// -extern EFI_LOCK gProtocolDatabaseLock; -extern LIST_ENTRY gHandleList; -extern UINT64 gHandleDatabaseKey; - -#endif diff --git a/MdeModulePkg/Core/Dxe/Hand/Locate.c b/MdeModulePkg/Core/Dxe/Hand/Locate.c deleted file mode 100644 index 80df0d4a6c..0000000000 --- a/MdeModulePkg/Core/Dxe/Hand/Locate.c +++ /dev/null @@ -1,712 +0,0 @@ -/** @file - Locate handle functions - -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Handle.h" - -// -// ProtocolRequest - Last LocateHandle request ID -// -UINTN mEfiLocateHandleRequest = 0; - -// -// Internal prototypes -// - -typedef struct { - EFI_GUID *Protocol; - VOID *SearchKey; - LIST_ENTRY *Position; - PROTOCOL_ENTRY *ProtEntry; -} LOCATE_POSITION; - -typedef -IHANDLE * -(* CORE_GET_NEXT) ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - -/** - Routine to get the next Handle, when you are searching for all handles. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -CoreGetNextLocateAllHandles ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - -/** - Routine to get the next Handle, when you are searching for register protocol - notifies. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -CoreGetNextLocateByRegisterNotify ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - -/** - Routine to get the next Handle, when you are searching for a given protocol. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -CoreGetNextLocateByProtocol ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - - -/** - Locates the requested handle(s) and returns them in Buffer. - - @param SearchType The type of search to perform to locate the - handles - @param Protocol The protocol to search for - @param SearchKey Dependant on SearchType - @param BufferSize On input the size of Buffer. On output the - size of data returned. - @param Buffer The buffer to return the results in - - @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is - returned in BufferSize. - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully found the requested handle(s) and - returns them in Buffer. - -**/ -EFI_STATUS -EFIAPI -CoreLocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ) -{ - EFI_STATUS Status; - LOCATE_POSITION Position; - PROTOCOL_NOTIFY *ProtNotify; - CORE_GET_NEXT GetNext; - UINTN ResultSize; - IHANDLE *Handle; - IHANDLE **ResultBuffer; - VOID *Interface; - - if (BufferSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((*BufferSize > 0) && (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - GetNext = NULL; - - // - // Set initial position - // - Position.Protocol = Protocol; - Position.SearchKey = SearchKey; - Position.Position = &gHandleList; - - ResultSize = 0; - ResultBuffer = (IHANDLE **) Buffer; - Status = EFI_SUCCESS; - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - // - // Get the search function based on type - // - switch (SearchType) { - case AllHandles: - GetNext = CoreGetNextLocateAllHandles; - break; - - case ByRegisterNotify: - // - // Must have SearchKey for locate ByRegisterNotify - // - if (SearchKey == NULL) { - Status = EFI_INVALID_PARAMETER; - break; - } - GetNext = CoreGetNextLocateByRegisterNotify; - break; - - case ByProtocol: - GetNext = CoreGetNextLocateByProtocol; - if (Protocol == NULL) { - Status = EFI_INVALID_PARAMETER; - break; - } - // - // Look up the protocol entry and set the head pointer - // - Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE); - if (Position.ProtEntry == NULL) { - Status = EFI_NOT_FOUND; - break; - } - Position.Position = &Position.ProtEntry->Protocols; - break; - - default: - Status = EFI_INVALID_PARAMETER; - break; - } - - if (EFI_ERROR(Status)) { - CoreReleaseProtocolLock (); - return Status; - } - - ASSERT (GetNext != NULL); - // - // Enumerate out the matching handles - // - mEfiLocateHandleRequest += 1; - for (; ;) { - // - // Get the next handle. If no more handles, stop - // - Handle = GetNext (&Position, &Interface); - if (NULL == Handle) { - break; - } - - // - // Increase the resulting buffer size, and if this handle - // fits return it - // - ResultSize += sizeof(Handle); - if (ResultSize <= *BufferSize) { - *ResultBuffer = Handle; - ResultBuffer += 1; - } - } - - // - // If the result is a zero length buffer, then there were no - // matching handles - // - if (ResultSize == 0) { - Status = EFI_NOT_FOUND; - } else { - // - // Return the resulting buffer size. If it's larger than what - // was passed, then set the error code - // - if (ResultSize > *BufferSize) { - Status = EFI_BUFFER_TOO_SMALL; - } - - *BufferSize = ResultSize; - - if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) { - // - // If this is a search by register notify and a handle was - // returned, update the register notification position - // - ASSERT (SearchKey != NULL); - ProtNotify = SearchKey; - ProtNotify->Position = ProtNotify->Position->ForwardLink; - } - } - - CoreReleaseProtocolLock (); - return Status; -} - - - -/** - Routine to get the next Handle, when you are searching for all handles. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -CoreGetNextLocateAllHandles ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - - // - // Next handle - // - Position->Position = Position->Position->ForwardLink; - - // - // If not at the end of the list, get the handle - // - Handle = NULL; - *Interface = NULL; - if (Position->Position != &gHandleList) { - Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); - } - - return Handle; -} - - - -/** - Routine to get the next Handle, when you are searching for register protocol - notifies. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -CoreGetNextLocateByRegisterNotify ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - PROTOCOL_NOTIFY *ProtNotify; - PROTOCOL_INTERFACE *Prot; - LIST_ENTRY *Link; - - Handle = NULL; - *Interface = NULL; - ProtNotify = Position->SearchKey; - - // - // If this is the first request, get the next handle - // - if (ProtNotify != NULL) { - ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE); - Position->SearchKey = NULL; - - // - // If not at the end of the list, get the next handle - // - Link = ProtNotify->Position->ForwardLink; - if (Link != &ProtNotify->Protocol->Protocols) { - Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); - Handle = Prot->Handle; - *Interface = Prot->Interface; - } - } - - return Handle; -} - - -/** - Routine to get the next Handle, when you are searching for a given protocol. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -CoreGetNextLocateByProtocol ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - LIST_ENTRY *Link; - PROTOCOL_INTERFACE *Prot; - - Handle = NULL; - *Interface = NULL; - for (; ;) { - // - // Next entry - // - Link = Position->Position->ForwardLink; - Position->Position = Link; - - // - // If not at the end, return the handle - // - if (Link == &Position->ProtEntry->Protocols) { - Handle = NULL; - break; - } - - // - // Get the handle - // - Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); - Handle = Prot->Handle; - *Interface = Prot->Interface; - - // - // If this handle has not been returned this request, then - // return it now - // - if (Handle->LocateRequest != mEfiLocateHandleRequest) { - Handle->LocateRequest = mEfiLocateHandleRequest; - break; - } - } - - return Handle; -} - - -/** - Locates the handle to a device on the device path that supports the specified protocol. - - @param Protocol Specifies the protocol to search for. - @param DevicePath On input, a pointer to a pointer to the device path. On output, the device - path pointer is modified to point to the remaining part of the device - path. - @param Device A pointer to the returned device handle. - - @retval EFI_SUCCESS The resulting handle was returned. - @retval EFI_NOT_FOUND No handles match the search. - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_INVALID_PARAMETER DevicePath is NULL. - @retval EFI_INVALID_PARAMETER A handle matched the search and Device is NULL. - -**/ -EFI_STATUS -EFIAPI -CoreLocateDevicePath ( - IN EFI_GUID *Protocol, - IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, - OUT EFI_HANDLE *Device - ) -{ - INTN SourceSize; - INTN Size; - INTN BestMatch; - UINTN HandleCount; - UINTN Index; - EFI_STATUS Status; - EFI_HANDLE *Handles; - EFI_HANDLE Handle; - EFI_HANDLE BestDevice; - EFI_DEVICE_PATH_PROTOCOL *SourcePath; - EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; - - if (Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((DevicePath == NULL) || (*DevicePath == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Handles = NULL; - BestDevice = NULL; - SourcePath = *DevicePath; - TmpDevicePath = SourcePath; - while (!IsDevicePathEnd (TmpDevicePath)) { - if (IsDevicePathEndInstance (TmpDevicePath)) { - // - // If DevicePath is a multi-instance device path, - // the function will operate on the first instance - // - break; - } - TmpDevicePath = NextDevicePathNode (TmpDevicePath); - } - - SourceSize = (UINTN) TmpDevicePath - (UINTN) SourcePath; - - // - // Get a list of all handles that support the requested protocol - // - Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles); - if (EFI_ERROR (Status) || HandleCount == 0) { - return EFI_NOT_FOUND; - } - - BestMatch = -1; - for(Index = 0; Index < HandleCount; Index += 1) { - Handle = Handles[Index]; - Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&TmpDevicePath); - if (EFI_ERROR (Status)) { - // - // If this handle doesn't support device path, then skip it - // - continue; - } - - // - // Check if DevicePath is first part of SourcePath - // - Size = GetDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); - ASSERT (Size >= 0); - if ((Size <= SourceSize) && CompareMem (SourcePath, TmpDevicePath, (UINTN) Size) == 0) { - // - // If the size is equal to the best match, then we - // have a duplicate device path for 2 different device - // handles - // - ASSERT (Size != BestMatch); - - // - // We've got a match, see if it's the best match so far - // - if (Size > BestMatch) { - BestMatch = Size; - BestDevice = Handle; - } - } - } - - CoreFreePool (Handles); - - // - // If there wasn't any match, then no parts of the device path was found. - // Which is strange since there is likely a "root level" device path in the system. - // - if (BestMatch == -1) { - return EFI_NOT_FOUND; - } - - if (Device == NULL) { - return EFI_INVALID_PARAMETER; - } - *Device = BestDevice; - - // - // Return the remaining part of the device path - // - *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch); - return EFI_SUCCESS; -} - - -/** - Return the first Protocol Interface that matches the Protocol GUID. If - Registration is passed in, return a Protocol Instance that was just add - to the system. If Registration is NULL return the first Protocol Interface - you find. - - @param Protocol The protocol to search for - @param Registration Optional Registration Key returned from - RegisterProtocolNotify() - @param Interface Return the Protocol interface (instance). - - @retval EFI_SUCCESS If a valid Interface is returned - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Protocol interface not found - -**/ -EFI_STATUS -EFIAPI -CoreLocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *Registration OPTIONAL, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - LOCATE_POSITION Position; - PROTOCOL_NOTIFY *ProtNotify; - IHANDLE *Handle; - - if (Interface == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Protocol == NULL) { - return EFI_NOT_FOUND; - } - - *Interface = NULL; - Status = EFI_SUCCESS; - - // - // Set initial position - // - Position.Protocol = Protocol; - Position.SearchKey = Registration; - Position.Position = &gHandleList; - - // - // Lock the protocol database - // - Status = CoreAcquireLockOrFail (&gProtocolDatabaseLock); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - mEfiLocateHandleRequest += 1; - - if (Registration == NULL) { - // - // Look up the protocol entry and set the head pointer - // - Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE); - if (Position.ProtEntry == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - Position.Position = &Position.ProtEntry->Protocols; - - Handle = CoreGetNextLocateByProtocol (&Position, Interface); - } else { - Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface); - } - - if (Handle == NULL) { - Status = EFI_NOT_FOUND; - } else if (Registration != NULL) { - // - // If this is a search by register notify and a handle was - // returned, update the register notification position - // - ProtNotify = Registration; - ProtNotify->Position = ProtNotify->Position->ForwardLink; - } - -Done: - CoreReleaseProtocolLock (); - return Status; -} - - -/** - Function returns an array of handles that support the requested protocol - in a buffer allocated from pool. This is a version of CoreLocateHandle() - that allocates a buffer for the caller. - - @param SearchType Specifies which handle(s) are to be returned. - @param Protocol Provides the protocol to search by. This - parameter is only valid for SearchType - ByProtocol. - @param SearchKey Supplies the search key depending on the - SearchType. - @param NumberHandles The number of handles returned in Buffer. - @param Buffer A pointer to the buffer to return the requested - array of handles that support Protocol. - - @retval EFI_SUCCESS The result array of handles was returned. - @retval EFI_NOT_FOUND No handles match the search. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - matching results. - @retval EFI_INVALID_PARAMETER One or more parameters are not valid. - -**/ -EFI_STATUS -EFIAPI -CoreLocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ) -{ - EFI_STATUS Status; - UINTN BufferSize; - - if (NumberHandles == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - BufferSize = 0; - *NumberHandles = 0; - *Buffer = NULL; - Status = CoreLocateHandle ( - SearchType, - Protocol, - SearchKey, - &BufferSize, - *Buffer - ); - // - // LocateHandleBuffer() returns incorrect status code if SearchType is - // invalid. - // - // Add code to correctly handle expected errors from CoreLocateHandle(). - // - if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { - if (Status != EFI_INVALID_PARAMETER) { - Status = EFI_NOT_FOUND; - } - return Status; - } - - *Buffer = AllocatePool (BufferSize); - if (*Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = CoreLocateHandle ( - SearchType, - Protocol, - SearchKey, - &BufferSize, - *Buffer - ); - - *NumberHandles = BufferSize / sizeof(EFI_HANDLE); - if (EFI_ERROR(Status)) { - *NumberHandles = 0; - } - - return Status; -} - - - diff --git a/MdeModulePkg/Core/Dxe/Hand/Notify.c b/MdeModulePkg/Core/Dxe/Hand/Notify.c deleted file mode 100644 index f0837c403f..0000000000 --- a/MdeModulePkg/Core/Dxe/Hand/Notify.c +++ /dev/null @@ -1,291 +0,0 @@ -/** @file - Support functions for UEFI protocol notification infrastructure. - -Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
-(C) Copyright 2015 Hewlett Packard Enterprise Development LP
-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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Handle.h" -#include "Event.h" - -/** - Signal event for every protocol in protocol entry. - - @param ProtEntry Protocol entry - -**/ -VOID -CoreNotifyProtocolEntry ( - IN PROTOCOL_ENTRY *ProtEntry - ) -{ - PROTOCOL_NOTIFY *ProtNotify; - LIST_ENTRY *Link; - - ASSERT_LOCKED (&gProtocolDatabaseLock); - - for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) { - ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); - CoreSignalEvent (ProtNotify->Event); - } -} - - - -/** - Removes Protocol from the protocol list (but not the handle list). - - @param Handle The handle to remove protocol on. - @param Protocol GUID of the protocol to be moved - @param Interface The interface of the protocol - - @return Protocol Entry - -**/ -PROTOCOL_INTERFACE * -CoreRemoveInterfaceFromProtocol ( - IN IHANDLE *Handle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ) -{ - PROTOCOL_INTERFACE *Prot; - PROTOCOL_NOTIFY *ProtNotify; - PROTOCOL_ENTRY *ProtEntry; - LIST_ENTRY *Link; - - ASSERT_LOCKED (&gProtocolDatabaseLock); - - Prot = CoreFindProtocolInterface (Handle, Protocol, Interface); - if (Prot != NULL) { - - ProtEntry = Prot->Protocol; - - // - // If there's a protocol notify location pointing to this entry, back it up one - // - for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) { - ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); - - if (ProtNotify->Position == &Prot->ByProtocol) { - ProtNotify->Position = Prot->ByProtocol.BackLink; - } - } - - // - // Remove the protocol interface entry - // - RemoveEntryList (&Prot->ByProtocol); - } - - return Prot; -} - - -/** - Add a new protocol notification record for the request protocol. - - @param Protocol The requested protocol to add the notify - registration - @param Event The event to signal - @param Registration Returns the registration record - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully returned the registration record - that has been added - -**/ -EFI_STATUS -EFIAPI -CoreRegisterProtocolNotify ( - IN EFI_GUID *Protocol, - IN EFI_EVENT Event, - OUT VOID **Registration - ) -{ - PROTOCOL_ENTRY *ProtEntry; - PROTOCOL_NOTIFY *ProtNotify; - EFI_STATUS Status; - - if ((Protocol == NULL) || (Event == NULL) || (Registration == NULL)) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireProtocolLock (); - - ProtNotify = NULL; - - // - // Get the protocol entry to add the notification too - // - - ProtEntry = CoreFindProtocolEntry (Protocol, TRUE); - if (ProtEntry != NULL) { - - // - // Allocate a new notification record - // - ProtNotify = AllocatePool (sizeof(PROTOCOL_NOTIFY)); - if (ProtNotify != NULL) { - ((IEVENT *)Event)->ExFlag |= EVT_EXFLAG_EVENT_PROTOCOL_NOTIFICATION; - ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE; - ProtNotify->Protocol = ProtEntry; - ProtNotify->Event = Event; - // - // start at the begining - // - ProtNotify->Position = &ProtEntry->Protocols; - - InsertTailList (&ProtEntry->Notify, &ProtNotify->Link); - } - } - - CoreReleaseProtocolLock (); - - // - // Done. If we have a protocol notify entry, then return it. - // Otherwise, we must have run out of resources trying to add one - // - - Status = EFI_OUT_OF_RESOURCES; - if (ProtNotify != NULL) { - *Registration = ProtNotify; - Status = EFI_SUCCESS; - } - - return Status; -} - - -/** - Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. - - @param UserHandle Handle on which the interface is to be - reinstalled - @param Protocol The numeric ID of the interface - @param OldInterface A pointer to the old interface - @param NewInterface A pointer to the new interface - - @retval EFI_SUCCESS The protocol interface was installed - @retval EFI_NOT_FOUND The OldInterface on the handle was not found - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value - -**/ -EFI_STATUS -EFIAPI -CoreReinstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *OldInterface, - IN VOID *NewInterface - ) -{ - EFI_STATUS Status; - IHANDLE *Handle; - PROTOCOL_INTERFACE *Prot; - PROTOCOL_ENTRY *ProtEntry; - - Status = CoreValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - if (Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - Handle = (IHANDLE *) UserHandle; - - // - // Lock the protocol database - // - CoreAcquireProtocolLock (); - - // - // Check that Protocol exists on UserHandle, and Interface matches the interface in the database - // - Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface); - if (Prot == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - // - // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled - // - Status = CoreDisconnectControllersUsingProtocolInterface ( - UserHandle, - Prot - ); - if (EFI_ERROR (Status)) { - // - // One or more drivers refused to release, so return the error - // - goto Done; - } - - // - // Remove the protocol interface from the protocol - // - Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface); - - if (Prot == NULL) { - Status = EFI_NOT_FOUND; - goto Done; - } - - ProtEntry = Prot->Protocol; - - // - // Update the interface on the protocol - // - Prot->Interface = NewInterface; - - // - // Add this protocol interface to the tail of the - // protocol entry - // - InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol); - - // - // Update the Key to show that the handle has been created/modified - // - gHandleDatabaseKey++; - Handle->Key = gHandleDatabaseKey; - - // - // Release the lock and connect all drivers to UserHandle - // - CoreReleaseProtocolLock (); - // - // Return code is ignored on purpose. - // - CoreConnectController ( - UserHandle, - NULL, - NULL, - TRUE - ); - CoreAcquireProtocolLock (); - - // - // Notify the notification list for this protocol - // - CoreNotifyProtocolEntry (ProtEntry); - - Status = EFI_SUCCESS; - -Done: - CoreReleaseProtocolLock (); - - return Status; -} diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c deleted file mode 100644 index 03e979a604..0000000000 --- a/MdeModulePkg/Core/Dxe/Image/Image.c +++ /dev/null @@ -1,1942 +0,0 @@ -/** @file - Core image handling services to load and unload PeImage. - -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Image.h" - -// -// Module Globals -// -LOADED_IMAGE_PRIVATE_DATA *mCurrentImage = NULL; - -LOAD_PE32_IMAGE_PRIVATE_DATA mLoadPe32PrivateData = { - LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE, - NULL, - { - CoreLoadImageEx, - CoreUnloadImageEx - } -}; - - -// -// This code is needed to build the Image handle for the DXE Core -// -LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = { - LOADED_IMAGE_PRIVATE_DATA_SIGNATURE, // Signature - NULL, // Image handle - EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, // Image type - TRUE, // If entrypoint has been called - NULL, // EntryPoint - { - EFI_LOADED_IMAGE_INFORMATION_REVISION, // Revision - NULL, // Parent handle - NULL, // System handle - - NULL, // Device handle - NULL, // File path - NULL, // Reserved - - 0, // LoadOptionsSize - NULL, // LoadOptions - - NULL, // ImageBase - 0, // ImageSize - EfiBootServicesCode, // ImageCodeType - EfiBootServicesData // ImageDataType - }, - (EFI_PHYSICAL_ADDRESS)0, // ImageBasePage - 0, // NumberOfPages - NULL, // FixupData - 0, // Tpl - EFI_SUCCESS, // Status - 0, // ExitDataSize - NULL, // ExitData - NULL, // JumpBuffer - NULL, // JumpContext - 0, // Machine - NULL, // Ebc - NULL, // RuntimeData - NULL // LoadedImageDevicePath -}; -// -// The field is define for Loading modules at fixed address feature to tracker the PEI code -// memory range usage. It is a bit mapped array in which every bit indicates the correspoding memory page -// available or not. -// -GLOBAL_REMOVE_IF_UNREFERENCED UINT64 *mDxeCodeMemoryRangeUsageBitMap=NULL; - -typedef struct { - UINT16 MachineType; - CHAR16 *MachineTypeName; -} MACHINE_TYPE_INFO; - -// -// EBC machine is not listed in this table, because EBC is in the default supported scopes of other machine type. -// -GLOBAL_REMOVE_IF_UNREFERENCED MACHINE_TYPE_INFO mMachineTypeInfo[] = { - {EFI_IMAGE_MACHINE_IA32, L"IA32"}, - {EFI_IMAGE_MACHINE_IA64, L"IA64"}, - {EFI_IMAGE_MACHINE_X64, L"X64"}, - {EFI_IMAGE_MACHINE_ARMTHUMB_MIXED, L"ARM"}, - {EFI_IMAGE_MACHINE_AARCH64, L"AARCH64"} -}; - -UINT16 mDxeCoreImageMachineType = 0; - -/** - Return machine type name. - - @param MachineType The machine type - - @return machine type name -**/ -CHAR16 * -GetMachineTypeName ( - UINT16 MachineType - ) -{ - UINTN Index; - - for (Index = 0; Index < sizeof(mMachineTypeInfo)/sizeof(mMachineTypeInfo[0]); Index++) { - if (mMachineTypeInfo[Index].MachineType == MachineType) { - return mMachineTypeInfo[Index].MachineTypeName; - } - } - - return L""; -} - -/** - Add the Image Services to EFI Boot Services Table and install the protocol - interfaces for this image. - - @param HobStart The HOB to initialize - - @return Status code. - -**/ -EFI_STATUS -CoreInitializeImageServices ( - IN VOID *HobStart - ) -{ - EFI_STATUS Status; - LOADED_IMAGE_PRIVATE_DATA *Image; - EFI_PHYSICAL_ADDRESS DxeCoreImageBaseAddress; - UINT64 DxeCoreImageLength; - VOID *DxeCoreEntryPoint; - EFI_PEI_HOB_POINTERS DxeCoreHob; - - // - // Searching for image hob - // - DxeCoreHob.Raw = HobStart; - while ((DxeCoreHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw)) != NULL) { - if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) { - // - // Find Dxe Core HOB - // - break; - } - DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob); - } - ASSERT (DxeCoreHob.Raw != NULL); - - DxeCoreImageBaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress; - DxeCoreImageLength = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength; - DxeCoreEntryPoint = (VOID *) (UINTN) DxeCoreHob.MemoryAllocationModule->EntryPoint; - gDxeCoreFileName = &DxeCoreHob.MemoryAllocationModule->ModuleName; - - // - // Initialize the fields for an internal driver - // - Image = &mCorePrivateImage; - - Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)DxeCoreEntryPoint; - Image->ImageBasePage = DxeCoreImageBaseAddress; - Image->NumberOfPages = (UINTN)(EFI_SIZE_TO_PAGES((UINTN)(DxeCoreImageLength))); - Image->Tpl = gEfiCurrentTpl; - Image->Info.SystemTable = gDxeCoreST; - Image->Info.ImageBase = (VOID *)(UINTN)DxeCoreImageBaseAddress; - Image->Info.ImageSize = DxeCoreImageLength; - - // - // Install the protocol interfaces for this image - // - Status = CoreInstallProtocolInterface ( - &Image->Handle, - &gEfiLoadedImageProtocolGuid, - EFI_NATIVE_INTERFACE, - &Image->Info - ); - ASSERT_EFI_ERROR (Status); - - mCurrentImage = Image; - - // - // Fill in DXE globals - // - mDxeCoreImageMachineType = PeCoffLoaderGetMachineType (Image->Info.ImageBase); - gDxeCoreImageHandle = Image->Handle; - gDxeCoreLoadedImage = &Image->Info; - - if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) { - // - // Export DXE Core PE Loader functionality for backward compatibility. - // - Status = CoreInstallProtocolInterface ( - &mLoadPe32PrivateData.Handle, - &gEfiLoadPeImageProtocolGuid, - EFI_NATIVE_INTERFACE, - &mLoadPe32PrivateData.Pe32Image - ); - } - - ProtectUefiImage (&Image->Info, Image->LoadedImageDevicePath); - - return Status; -} - -/** - Read image file (specified by UserHandle) into user specified buffer with specified offset - and length. - - @param UserHandle Image file handle - @param Offset Offset to the source file - @param ReadSize For input, pointer of size to read; For output, - pointer of size actually read. - @param Buffer Buffer to write into - - @retval EFI_SUCCESS Successfully read the specified part of file - into buffer. - -**/ -EFI_STATUS -EFIAPI -CoreReadImageFile ( - IN VOID *UserHandle, - IN UINTN Offset, - IN OUT UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - UINTN EndPosition; - IMAGE_FILE_HANDLE *FHand; - - if (UserHandle == NULL || ReadSize == NULL || Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (MAX_ADDRESS - Offset < *ReadSize) { - return EFI_INVALID_PARAMETER; - } - - FHand = (IMAGE_FILE_HANDLE *)UserHandle; - ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE); - - // - // Move data from our local copy of the file - // - EndPosition = Offset + *ReadSize; - if (EndPosition > FHand->SourceSize) { - *ReadSize = (UINT32)(FHand->SourceSize - Offset); - } - if (Offset >= FHand->SourceSize) { - *ReadSize = 0; - } - - CopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize); - return EFI_SUCCESS; -} -/** - To check memory usage bit map array to figure out if the memory range the image will be loaded in is available or not. If - memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used. - The function is only invoked when load modules at fixed address feature is enabled. - - @param ImageBase The base address the image will be loaded at. - @param ImageSize The size of the image - - @retval EFI_SUCCESS The memory range the image will be loaded in is available - @retval EFI_NOT_FOUND The memory range the image will be loaded in is not available -**/ -EFI_STATUS -CheckAndMarkFixLoadingMemoryUsageBitMap ( - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINTN ImageSize - ) -{ - UINT32 DxeCodePageNumber; - UINT64 DxeCodeSize; - EFI_PHYSICAL_ADDRESS DxeCodeBase; - UINTN BaseOffsetPageNumber; - UINTN TopOffsetPageNumber; - UINTN Index; - // - // The DXE code range includes RuntimeCodePage range and Boot time code range. - // - DxeCodePageNumber = PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber); - DxeCodePageNumber += PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber); - DxeCodeSize = EFI_PAGES_TO_SIZE(DxeCodePageNumber); - DxeCodeBase = gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress - DxeCodeSize; - - // - // If the memory usage bit map is not initialized, do it. Every bit in the array - // indicate the status of the corresponding memory page, available or not - // - if (mDxeCodeMemoryRangeUsageBitMap == NULL) { - mDxeCodeMemoryRangeUsageBitMap = AllocateZeroPool(((DxeCodePageNumber/64) + 1)*sizeof(UINT64)); - } - // - // If the Dxe code memory range is not allocated or the bit map array allocation failed, return EFI_NOT_FOUND - // - if (!gLoadFixedAddressCodeMemoryReady || mDxeCodeMemoryRangeUsageBitMap == NULL) { - return EFI_NOT_FOUND; - } - // - // Test the memory range for loading the image in the DXE code range. - // - if (gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress < ImageBase + ImageSize || - DxeCodeBase > ImageBase) { - return EFI_NOT_FOUND; - } - // - // Test if the memory is avalaible or not. - // - BaseOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase - DxeCodeBase)); - TopOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - DxeCodeBase)); - for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) { - if ((mDxeCodeMemoryRangeUsageBitMap[Index / 64] & LShiftU64(1, (Index % 64))) != 0) { - // - // This page is already used. - // - return EFI_NOT_FOUND; - } - } - - // - // Being here means the memory range is available. So mark the bits for the memory range - // - for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) { - mDxeCodeMemoryRangeUsageBitMap[Index / 64] |= LShiftU64(1, (Index % 64)); - } - return EFI_SUCCESS; -} -/** - - Get the fixed loading address from image header assigned by build tool. This function only be called - when Loading module at Fixed address feature enabled. - - @param ImageContext Pointer to the image context structure that describes the PE/COFF - image that needs to be examined by this function. - @retval EFI_SUCCESS An fixed loading address is assigned to this image by build tools . - @retval EFI_NOT_FOUND The image has no assigned fixed loading address. - -**/ -EFI_STATUS -GetPeCoffImageFixLoadingAssignedAddress( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - UINTN SectionHeaderOffset; - EFI_STATUS Status; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - UINT16 Index; - UINTN Size; - UINT16 NumberOfSections; - IMAGE_FILE_HANDLE *Handle; - UINT64 ValueInSectionHeader; - - - Status = EFI_NOT_FOUND; - - // - // Get PeHeader pointer - // - Handle = (IMAGE_FILE_HANDLE*)ImageContext->Handle; - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )Handle->Source + ImageContext->PeCoffHeaderOffset); - SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; - NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; - - // - // Get base address from the first section header that doesn't point to code section. - // - for (Index = 0; Index < NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (EFI_ERROR (Status)) { - return Status; - } - if (Size != sizeof (EFI_IMAGE_SECTION_HEADER)) { - return EFI_NOT_FOUND; - } - - Status = EFI_NOT_FOUND; - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - // - // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header - // that doesn't point to code section in image header, as well as ImageBase field of image header. And there is an - // assumption that when the feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations - // & PointerToLineNumbers fields should NOT be Zero, or else, these 2 fields should be set to Zero - // - ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations); - if (ValueInSectionHeader != 0) { - // - // When the feature is configured as load module at fixed absolute address, the ImageAddress field of ImageContext - // hold the spcified address. If the feature is configured as load module at fixed offset, ImageAddress hold an offset - // relative to top address - // - if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) < 0) { - ImageContext->ImageAddress = gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress + (INT64)(INTN)ImageContext->ImageAddress; - } - // - // Check if the memory range is available. - // - Status = CheckAndMarkFixLoadingMemoryUsageBitMap (ImageContext->ImageAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment)); - } - break; - } - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status = %r \n", (VOID *)(UINTN)(ImageContext->ImageAddress), Status)); - return Status; -} -/** - Loads, relocates, and invokes a PE/COFF image - - @param BootPolicy If TRUE, indicates that the request originates - from the boot manager, and that the boot - manager is attempting to load FilePath as a - boot selection. - @param Pe32Handle The handle of PE32 image - @param Image PE image to be loaded - @param DstBuffer The buffer to store the image - @param EntryPoint A pointer to the entry point - @param Attribute The bit mask of attributes to set for the load - PE image - - @retval EFI_SUCCESS The file was loaded, relocated, and invoked - @retval EFI_OUT_OF_RESOURCES There was not enough memory to load and - relocate the PE/COFF file - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_BUFFER_TOO_SMALL Buffer for image is too small - -**/ -EFI_STATUS -CoreLoadPeImage ( - IN BOOLEAN BootPolicy, - IN VOID *Pe32Handle, - IN LOADED_IMAGE_PRIVATE_DATA *Image, - IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, - IN UINT32 Attribute - ) -{ - EFI_STATUS Status; - BOOLEAN DstBufAlocated; - UINTN Size; - - ZeroMem (&Image->ImageContext, sizeof (Image->ImageContext)); - - Image->ImageContext.Handle = Pe32Handle; - Image->ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)CoreReadImageFile; - - // - // Get information about the image being loaded - // - Status = PeCoffLoaderGetImageInfo (&Image->ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine)) { - if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Image->ImageContext.Machine)) { - // - // The PE/COFF loader can support loading image types that can be executed. - // If we loaded an image type that we can not execute return EFI_UNSUPORTED. - // - DEBUG ((EFI_D_ERROR, "Image type %s can't be loaded ", GetMachineTypeName(Image->ImageContext.Machine))); - DEBUG ((EFI_D_ERROR, "on %s UEFI system.\n", GetMachineTypeName(mDxeCoreImageMachineType))); - return EFI_UNSUPPORTED; - } - } - - // - // Set EFI memory type based on ImageType - // - switch (Image->ImageContext.ImageType) { - case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION: - Image->ImageContext.ImageCodeMemoryType = EfiLoaderCode; - Image->ImageContext.ImageDataMemoryType = EfiLoaderData; - break; - case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER: - Image->ImageContext.ImageCodeMemoryType = EfiBootServicesCode; - Image->ImageContext.ImageDataMemoryType = EfiBootServicesData; - break; - case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER: - case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER: - Image->ImageContext.ImageCodeMemoryType = EfiRuntimeServicesCode; - Image->ImageContext.ImageDataMemoryType = EfiRuntimeServicesData; - break; - default: - Image->ImageContext.ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM; - return EFI_UNSUPPORTED; - } - - // - // Allocate memory of the correct memory type aligned on the required image boundary - // - DstBufAlocated = FALSE; - if (DstBuffer == 0) { - // - // Allocate Destination Buffer as caller did not pass it in - // - - if (Image->ImageContext.SectionAlignment > EFI_PAGE_SIZE) { - Size = (UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment; - } else { - Size = (UINTN)Image->ImageContext.ImageSize; - } - - Image->NumberOfPages = EFI_SIZE_TO_PAGES (Size); - - // - // If the image relocations have not been stripped, then load at any address. - // Otherwise load at the address at which it was linked. - // - // Memory below 1MB should be treated reserved for CSM and there should be - // no modules whose preferred load addresses are below 1MB. - // - Status = EFI_OUT_OF_RESOURCES; - // - // If Loading Module At Fixed Address feature is enabled, the module should be loaded to - // a specified address. - // - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 ) { - Status = GetPeCoffImageFixLoadingAssignedAddress (&(Image->ImageContext)); - - if (EFI_ERROR (Status)) { - // - // If the code memory is not ready, invoke CoreAllocatePage with AllocateAnyPages to load the driver. - // - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Loading module at fixed address failed since specified memory is not available.\n")); - - Status = CoreAllocatePages ( - AllocateAnyPages, - (EFI_MEMORY_TYPE) (Image->ImageContext.ImageCodeMemoryType), - Image->NumberOfPages, - &Image->ImageContext.ImageAddress - ); - } - } else { - if (Image->ImageContext.ImageAddress >= 0x100000 || Image->ImageContext.RelocationsStripped) { - Status = CoreAllocatePages ( - AllocateAddress, - (EFI_MEMORY_TYPE) (Image->ImageContext.ImageCodeMemoryType), - Image->NumberOfPages, - &Image->ImageContext.ImageAddress - ); - } - if (EFI_ERROR (Status) && !Image->ImageContext.RelocationsStripped) { - Status = CoreAllocatePages ( - AllocateAnyPages, - (EFI_MEMORY_TYPE) (Image->ImageContext.ImageCodeMemoryType), - Image->NumberOfPages, - &Image->ImageContext.ImageAddress - ); - } - } - if (EFI_ERROR (Status)) { - return Status; - } - DstBufAlocated = TRUE; - } else { - // - // Caller provided the destination buffer - // - - if (Image->ImageContext.RelocationsStripped && (Image->ImageContext.ImageAddress != DstBuffer)) { - // - // If the image relocations were stripped, and the caller provided a - // destination buffer address that does not match the address that the - // image is linked at, then the image cannot be loaded. - // - return EFI_INVALID_PARAMETER; - } - - if (Image->NumberOfPages != 0 && - Image->NumberOfPages < - (EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment))) { - Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment); - return EFI_BUFFER_TOO_SMALL; - } - - Image->NumberOfPages = EFI_SIZE_TO_PAGES ((UINTN)Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment); - Image->ImageContext.ImageAddress = DstBuffer; - } - - Image->ImageBasePage = Image->ImageContext.ImageAddress; - if (!Image->ImageContext.IsTeImage) { - Image->ImageContext.ImageAddress = - (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) & - ~((UINTN)Image->ImageContext.SectionAlignment - 1); - } - - // - // Load the image from the file into the allocated memory - // - Status = PeCoffLoaderLoadImage (&Image->ImageContext); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // If this is a Runtime Driver, then allocate memory for the FixupData that - // is used to relocate the image when SetVirtualAddressMap() is called. The - // relocation is done by the Runtime AP. - // - if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) != 0) { - if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { - Image->ImageContext.FixupData = AllocateRuntimePool ((UINTN)(Image->ImageContext.FixupDataSize)); - if (Image->ImageContext.FixupData == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - } - } - - // - // Relocate the image in memory - // - Status = PeCoffLoaderRelocateImage (&Image->ImageContext); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Flush the Instruction Cache - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)Image->ImageContext.ImageAddress, (UINTN)Image->ImageContext.ImageSize); - - // - // Copy the machine type from the context to the image private data. This - // is needed during image unload to know if we should call an EBC protocol - // to unload the image. - // - Image->Machine = Image->ImageContext.Machine; - - // - // Get the image entry point. If it's an EBC image, then call into the - // interpreter to create a thunk for the entry point and use the returned - // value for the entry point. - // - Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)Image->ImageContext.EntryPoint; - if (Image->ImageContext.Machine == EFI_IMAGE_MACHINE_EBC) { - // - // Locate the EBC interpreter protocol - // - Status = CoreLocateProtocol (&gEfiEbcProtocolGuid, NULL, (VOID **)&Image->Ebc); - if (EFI_ERROR(Status) || Image->Ebc == NULL) { - DEBUG ((DEBUG_LOAD | DEBUG_ERROR, "CoreLoadPeImage: There is no EBC interpreter for an EBC image.\n")); - goto Done; - } - - // - // Register a callback for flushing the instruction cache so that created - // thunks can be flushed. - // - Status = Image->Ebc->RegisterICacheFlush (Image->Ebc, (EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange); - if (EFI_ERROR(Status)) { - goto Done; - } - - // - // Create a thunk for the image's entry point. This will be the new - // entry point for the image. - // - Status = Image->Ebc->CreateThunk ( - Image->Ebc, - Image->Handle, - (VOID *)(UINTN) Image->ImageContext.EntryPoint, - (VOID **) &Image->EntryPoint - ); - if (EFI_ERROR(Status)) { - goto Done; - } - } - - // - // Fill in the image information for the Loaded Image Protocol - // - Image->Type = Image->ImageContext.ImageType; - Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageContext.ImageAddress; - Image->Info.ImageSize = Image->ImageContext.ImageSize; - Image->Info.ImageCodeType = (EFI_MEMORY_TYPE) (Image->ImageContext.ImageCodeMemoryType); - Image->Info.ImageDataType = (EFI_MEMORY_TYPE) (Image->ImageContext.ImageDataMemoryType); - if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) != 0) { - if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { - // - // Make a list off all the RT images so we can let the RT AP know about them. - // - Image->RuntimeData = AllocateRuntimePool (sizeof(EFI_RUNTIME_IMAGE_ENTRY)); - if (Image->RuntimeData == NULL) { - goto Done; - } - Image->RuntimeData->ImageBase = Image->Info.ImageBase; - Image->RuntimeData->ImageSize = (UINT64) (Image->Info.ImageSize); - Image->RuntimeData->RelocationData = Image->ImageContext.FixupData; - Image->RuntimeData->Handle = Image->Handle; - InsertTailList (&gRuntime->ImageHead, &Image->RuntimeData->Link); - InsertImageRecord (Image->RuntimeData); - } - } - - // - // Fill in the entry point of the image if it is available - // - if (EntryPoint != NULL) { - *EntryPoint = Image->ImageContext.EntryPoint; - } - - // - // Print the load address and the PDB file name if it is available - // - - DEBUG_CODE_BEGIN (); - - UINTN Index; - UINTN StartIndex; - CHAR8 EfiFileName[256]; - - - DEBUG ((DEBUG_INFO | DEBUG_LOAD, - "Loading driver at 0x%11p EntryPoint=0x%11p ", - (VOID *)(UINTN) Image->ImageContext.ImageAddress, - FUNCTION_ENTRY_POINT (Image->ImageContext.EntryPoint))); - - - // - // Print Module Name by Pdb file path. - // Windows and Unix style file path are all trimmed correctly. - // - if (Image->ImageContext.PdbPointer != NULL) { - StartIndex = 0; - for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) { - if ((Image->ImageContext.PdbPointer[Index] == '\\') || (Image->ImageContext.PdbPointer[Index] == '/')) { - StartIndex = Index + 1; - } - } - // - // Copy the PDB file name to our temporary string, and replace .pdb with .efi - // The PDB file name is limited in the range of 0~255. - // If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary. - // - for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) { - EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex]; - if (EfiFileName[Index] == 0) { - EfiFileName[Index] = '.'; - } - if (EfiFileName[Index] == '.') { - EfiFileName[Index + 1] = 'e'; - EfiFileName[Index + 2] = 'f'; - EfiFileName[Index + 3] = 'i'; - EfiFileName[Index + 4] = 0; - break; - } - } - - if (Index == sizeof (EfiFileName) - 4) { - EfiFileName[Index] = 0; - } - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex])); - } - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n")); - - DEBUG_CODE_END (); - - return EFI_SUCCESS; - -Done: - - // - // Free memory. - // - - if (DstBufAlocated) { - CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages); - } - - if (Image->ImageContext.FixupData != NULL) { - CoreFreePool (Image->ImageContext.FixupData); - } - - return Status; -} - - - -/** - Get the image's private data from its handle. - - @param ImageHandle The image handle - - @return Return the image private data associated with ImageHandle. - -**/ -LOADED_IMAGE_PRIVATE_DATA * -CoreLoadedImageInfo ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - LOADED_IMAGE_PRIVATE_DATA *Image; - - Status = CoreHandleProtocol ( - ImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID **)&LoadedImage - ); - if (!EFI_ERROR (Status)) { - Image = LOADED_IMAGE_PRIVATE_DATA_FROM_THIS (LoadedImage); - } else { - DEBUG ((DEBUG_LOAD, "CoreLoadedImageInfo: Not an ImageHandle %p\n", ImageHandle)); - Image = NULL; - } - - return Image; -} - - -/** - Unloads EFI image from memory. - - @param Image EFI image - @param FreePage Free allocated pages - -**/ -VOID -CoreUnloadAndCloseImage ( - IN LOADED_IMAGE_PRIVATE_DATA *Image, - IN BOOLEAN FreePage - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN HandleIndex; - EFI_GUID **ProtocolGuidArray; - UINTN ArrayCount; - UINTN ProtocolIndex; - EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo; - UINTN OpenInfoCount; - UINTN OpenInfoIndex; - - HandleBuffer = NULL; - ProtocolGuidArray = NULL; - - if (Image->Started) { - UnregisterMemoryProfileImage (Image); - } - - UnprotectUefiImage (&Image->Info, Image->LoadedImageDevicePath); - - if (Image->Ebc != NULL) { - // - // If EBC protocol exists we must perform cleanups for this image. - // - Image->Ebc->UnloadImage (Image->Ebc, Image->Handle); - } - - // - // Unload image, free Image->ImageContext->ModHandle - // - PeCoffLoaderUnloadImage (&Image->ImageContext); - - // - // Free our references to the image handle - // - if (Image->Handle != NULL) { - - Status = CoreLocateHandleBuffer ( - AllHandles, - NULL, - NULL, - &HandleCount, - &HandleBuffer - ); - if (!EFI_ERROR (Status)) { - for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { - Status = CoreProtocolsPerHandle ( - HandleBuffer[HandleIndex], - &ProtocolGuidArray, - &ArrayCount - ); - if (!EFI_ERROR (Status)) { - for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) { - Status = CoreOpenProtocolInformation ( - HandleBuffer[HandleIndex], - ProtocolGuidArray[ProtocolIndex], - &OpenInfo, - &OpenInfoCount - ); - if (!EFI_ERROR (Status)) { - for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) { - if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) { - Status = CoreCloseProtocol ( - HandleBuffer[HandleIndex], - ProtocolGuidArray[ProtocolIndex], - Image->Handle, - OpenInfo[OpenInfoIndex].ControllerHandle - ); - } - } - if (OpenInfo != NULL) { - CoreFreePool(OpenInfo); - } - } - } - if (ProtocolGuidArray != NULL) { - CoreFreePool(ProtocolGuidArray); - } - } - } - if (HandleBuffer != NULL) { - CoreFreePool (HandleBuffer); - } - } - - CoreRemoveDebugImageInfoEntry (Image->Handle); - - Status = CoreUninstallProtocolInterface ( - Image->Handle, - &gEfiLoadedImageDevicePathProtocolGuid, - Image->LoadedImageDevicePath - ); - - Status = CoreUninstallProtocolInterface ( - Image->Handle, - &gEfiLoadedImageProtocolGuid, - &Image->Info - ); - - if (Image->ImageContext.HiiResourceData != 0) { - Status = CoreUninstallProtocolInterface ( - Image->Handle, - &gEfiHiiPackageListProtocolGuid, - (VOID *) (UINTN) Image->ImageContext.HiiResourceData - ); - } - - } - - if (Image->RuntimeData != NULL) { - if (Image->RuntimeData->Link.ForwardLink != NULL) { - // - // Remove the Image from the Runtime Image list as we are about to Free it! - // - RemoveEntryList (&Image->RuntimeData->Link); - RemoveImageRecord (Image->RuntimeData); - } - CoreFreePool (Image->RuntimeData); - } - - // - // Free the Image from memory - // - if ((Image->ImageBasePage != 0) && FreePage) { - CoreFreePages (Image->ImageBasePage, Image->NumberOfPages); - } - - // - // Done with the Image structure - // - if (Image->Info.FilePath != NULL) { - CoreFreePool (Image->Info.FilePath); - } - - if (Image->LoadedImageDevicePath != NULL) { - CoreFreePool (Image->LoadedImageDevicePath); - } - - if (Image->FixupData != NULL) { - CoreFreePool (Image->FixupData); - } - - CoreFreePool (Image); -} - - -/** - Loads an EFI image into memory and returns a handle to the image. - - @param BootPolicy If TRUE, indicates that the request originates - from the boot manager, and that the boot - manager is attempting to load FilePath as a - boot selection. - @param ParentImageHandle The caller's image handle. - @param FilePath The specific file path from which the image is - loaded. - @param SourceBuffer If not NULL, a pointer to the memory location - containing a copy of the image to be loaded. - @param SourceSize The size in bytes of SourceBuffer. - @param DstBuffer The buffer to store the image - @param NumberOfPages If not NULL, it inputs a pointer to the page - number of DstBuffer and outputs a pointer to - the page number of the image. If this number is - not enough, return EFI_BUFFER_TOO_SMALL and - this parameter contains the required number. - @param ImageHandle Pointer to the returned image handle that is - created when the image is successfully loaded. - @param EntryPoint A pointer to the entry point - @param Attribute The bit mask of attributes to set for the load - PE image - - @retval EFI_SUCCESS The image was loaded into memory. - @retval EFI_NOT_FOUND The FilePath was not found. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - @retval EFI_BUFFER_TOO_SMALL The buffer is too small - @retval EFI_UNSUPPORTED The image type is not supported, or the device - path cannot be parsed to locate the proper - protocol for loading the file. - @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient - resources. - @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not - understood. - @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. - @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the - image from being loaded. NULL is returned in *ImageHandle. - @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a - valid EFI_LOADED_IMAGE_PROTOCOL. However, the current - platform policy specifies that the image should not be started. - -**/ -EFI_STATUS -CoreLoadImageCommon ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL, - IN OUT UINTN *NumberOfPages OPTIONAL, - OUT EFI_HANDLE *ImageHandle, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, - IN UINT32 Attribute - ) -{ - LOADED_IMAGE_PRIVATE_DATA *Image; - LOADED_IMAGE_PRIVATE_DATA *ParentImage; - IMAGE_FILE_HANDLE FHand; - EFI_STATUS Status; - EFI_STATUS SecurityStatus; - EFI_HANDLE DeviceHandle; - UINT32 AuthenticationStatus; - EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath; - EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; - EFI_DEVICE_PATH_PROTOCOL *InputFilePath; - EFI_DEVICE_PATH_PROTOCOL *Node; - UINTN FilePathSize; - BOOLEAN ImageIsFromFv; - BOOLEAN ImageIsFromLoadFile; - - SecurityStatus = EFI_SUCCESS; - - ASSERT (gEfiCurrentTpl < TPL_NOTIFY); - ParentImage = NULL; - - // - // The caller must pass in a valid ParentImageHandle - // - if (ImageHandle == NULL || ParentImageHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - ParentImage = CoreLoadedImageInfo (ParentImageHandle); - if (ParentImage == NULL) { - DEBUG((DEBUG_LOAD|DEBUG_ERROR, "LoadImageEx: Parent handle not an image handle\n")); - return EFI_INVALID_PARAMETER; - } - - ZeroMem (&FHand, sizeof (IMAGE_FILE_HANDLE)); - FHand.Signature = IMAGE_FILE_HANDLE_SIGNATURE; - OriginalFilePath = FilePath; - InputFilePath = FilePath; - HandleFilePath = FilePath; - DeviceHandle = NULL; - Status = EFI_SUCCESS; - AuthenticationStatus = 0; - ImageIsFromFv = FALSE; - ImageIsFromLoadFile = FALSE; - - // - // If the caller passed a copy of the file, then just use it - // - if (SourceBuffer != NULL) { - FHand.Source = SourceBuffer; - FHand.SourceSize = SourceSize; - Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &HandleFilePath, &DeviceHandle); - if (EFI_ERROR (Status)) { - DeviceHandle = NULL; - } - if (SourceSize > 0) { - Status = EFI_SUCCESS; - } else { - Status = EFI_LOAD_ERROR; - } - } else { - if (FilePath == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Try to get the image device handle by checking the match protocol. - // - Node = NULL; - Status = CoreLocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle); - if (!EFI_ERROR (Status)) { - ImageIsFromFv = TRUE; - } else { - HandleFilePath = FilePath; - Status = CoreLocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &HandleFilePath, &DeviceHandle); - if (EFI_ERROR (Status)) { - if (!BootPolicy) { - HandleFilePath = FilePath; - Status = CoreLocateDevicePath (&gEfiLoadFile2ProtocolGuid, &HandleFilePath, &DeviceHandle); - } - if (EFI_ERROR (Status)) { - HandleFilePath = FilePath; - Status = CoreLocateDevicePath (&gEfiLoadFileProtocolGuid, &HandleFilePath, &DeviceHandle); - if (!EFI_ERROR (Status)) { - ImageIsFromLoadFile = TRUE; - Node = HandleFilePath; - } - } - } - } - - // - // Get the source file buffer by its device path. - // - FHand.Source = GetFileBufferByFilePath ( - BootPolicy, - FilePath, - &FHand.SourceSize, - &AuthenticationStatus - ); - if (FHand.Source == NULL) { - Status = EFI_NOT_FOUND; - } else { - FHand.FreeBuffer = TRUE; - if (ImageIsFromLoadFile) { - // - // LoadFile () may cause the device path of the Handle be updated. - // - OriginalFilePath = AppendDevicePath (DevicePathFromHandle (DeviceHandle), Node); - } - } - } - - if (EFI_ERROR (Status)) { - Image = NULL; - goto Done; - } - - if (gSecurity2 != NULL) { - // - // Verify File Authentication through the Security2 Architectural Protocol - // - SecurityStatus = gSecurity2->FileAuthentication ( - gSecurity2, - OriginalFilePath, - FHand.Source, - FHand.SourceSize, - BootPolicy - ); - if (!EFI_ERROR (SecurityStatus) && ImageIsFromFv) { - // - // When Security2 is installed, Security Architectural Protocol must be published. - // - ASSERT (gSecurity != NULL); - - // - // Verify the Authentication Status through the Security Architectural Protocol - // Only on images that have been read using Firmware Volume protocol. - // - SecurityStatus = gSecurity->FileAuthenticationState ( - gSecurity, - AuthenticationStatus, - OriginalFilePath - ); - } - } else if ((gSecurity != NULL) && (OriginalFilePath != NULL)) { - // - // Verify the Authentication Status through the Security Architectural Protocol - // - SecurityStatus = gSecurity->FileAuthenticationState ( - gSecurity, - AuthenticationStatus, - OriginalFilePath - ); - } - - // - // Check Security Status. - // - if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) { - if (SecurityStatus == EFI_ACCESS_DENIED) { - // - // Image was not loaded because the platform policy prohibits the image from being loaded. - // It's the only place we could meet EFI_ACCESS_DENIED. - // - *ImageHandle = NULL; - } - Status = SecurityStatus; - Image = NULL; - goto Done; - } - - // - // Allocate a new image structure - // - Image = AllocateZeroPool (sizeof(LOADED_IMAGE_PRIVATE_DATA)); - if (Image == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - // - // Pull out just the file portion of the DevicePath for the LoadedImage FilePath - // - FilePath = OriginalFilePath; - if (DeviceHandle != NULL) { - Status = CoreHandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath); - if (!EFI_ERROR (Status)) { - FilePathSize = GetDevicePathSize (HandleFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); - FilePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *)FilePath) + FilePathSize ); - } - } - // - // Initialize the fields for an internal driver - // - Image->Signature = LOADED_IMAGE_PRIVATE_DATA_SIGNATURE; - Image->Info.SystemTable = gDxeCoreST; - Image->Info.DeviceHandle = DeviceHandle; - Image->Info.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; - Image->Info.FilePath = DuplicateDevicePath (FilePath); - Image->Info.ParentHandle = ParentImageHandle; - - - if (NumberOfPages != NULL) { - Image->NumberOfPages = *NumberOfPages ; - } else { - Image->NumberOfPages = 0 ; - } - - // - // Install the protocol interfaces for this image - // don't fire notifications yet - // - Status = CoreInstallProtocolInterfaceNotify ( - &Image->Handle, - &gEfiLoadedImageProtocolGuid, - EFI_NATIVE_INTERFACE, - &Image->Info, - FALSE - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Load the image. If EntryPoint is Null, it will not be set. - // - Status = CoreLoadPeImage (BootPolicy, &FHand, Image, DstBuffer, EntryPoint, Attribute); - if (EFI_ERROR (Status)) { - if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_OUT_OF_RESOURCES)) { - if (NumberOfPages != NULL) { - *NumberOfPages = Image->NumberOfPages; - } - } - goto Done; - } - - if (NumberOfPages != NULL) { - *NumberOfPages = Image->NumberOfPages; - } - - // - // Register the image in the Debug Image Info Table if the attribute is set - // - if ((Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION) != 0) { - CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle); - } - - // - //Reinstall loaded image protocol to fire any notifications - // - Status = CoreReinstallProtocolInterface ( - Image->Handle, - &gEfiLoadedImageProtocolGuid, - &Image->Info, - &Image->Info - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // If DevicePath parameter to the LoadImage() is not NULL, then make a copy of DevicePath, - // otherwise Loaded Image Device Path Protocol is installed with a NULL interface pointer. - // - if (OriginalFilePath != NULL) { - Image->LoadedImageDevicePath = DuplicateDevicePath (OriginalFilePath); - } - - // - // Install Loaded Image Device Path Protocol onto the image handle of a PE/COFE image - // - Status = CoreInstallProtocolInterface ( - &Image->Handle, - &gEfiLoadedImageDevicePathProtocolGuid, - EFI_NATIVE_INTERFACE, - Image->LoadedImageDevicePath - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Install HII Package List Protocol onto the image handle - // - if (Image->ImageContext.HiiResourceData != 0) { - Status = CoreInstallProtocolInterface ( - &Image->Handle, - &gEfiHiiPackageListProtocolGuid, - EFI_NATIVE_INTERFACE, - (VOID *) (UINTN) Image->ImageContext.HiiResourceData - ); - if (EFI_ERROR (Status)) { - goto Done; - } - } - ProtectUefiImage (&Image->Info, Image->LoadedImageDevicePath); - - // - // Success. Return the image handle - // - *ImageHandle = Image->Handle; - -Done: - // - // All done accessing the source file - // If we allocated the Source buffer, free it - // - if (FHand.FreeBuffer) { - CoreFreePool (FHand.Source); - } - if (OriginalFilePath != InputFilePath) { - CoreFreePool (OriginalFilePath); - } - - // - // There was an error. If there's an Image structure, free it - // - if (EFI_ERROR (Status)) { - if (Image != NULL) { - CoreUnloadAndCloseImage (Image, (BOOLEAN)(DstBuffer == 0)); - Image = NULL; - } - } else if (EFI_ERROR (SecurityStatus)) { - Status = SecurityStatus; - } - - // - // Track the return status from LoadImage. - // - if (Image != NULL) { - Image->LoadImageStatus = Status; - } - - return Status; -} - - - - -/** - Loads an EFI image into memory and returns a handle to the image. - - @param BootPolicy If TRUE, indicates that the request originates - from the boot manager, and that the boot - manager is attempting to load FilePath as a - boot selection. - @param ParentImageHandle The caller's image handle. - @param FilePath The specific file path from which the image is - loaded. - @param SourceBuffer If not NULL, a pointer to the memory location - containing a copy of the image to be loaded. - @param SourceSize The size in bytes of SourceBuffer. - @param ImageHandle Pointer to the returned image handle that is - created when the image is successfully loaded. - - @retval EFI_SUCCESS The image was loaded into memory. - @retval EFI_NOT_FOUND The FilePath was not found. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - @retval EFI_UNSUPPORTED The image type is not supported, or the device - path cannot be parsed to locate the proper - protocol for loading the file. - @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient - resources. - @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not - understood. - @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. - @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the - image from being loaded. NULL is returned in *ImageHandle. - @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a - valid EFI_LOADED_IMAGE_PROTOCOL. However, the current - platform policy specifies that the image should not be started. - -**/ -EFI_STATUS -EFIAPI -CoreLoadImage ( - IN BOOLEAN BootPolicy, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - OUT EFI_HANDLE *ImageHandle - ) -{ - EFI_STATUS Status; - UINT64 Tick; - EFI_HANDLE Handle; - - Tick = 0; - PERF_CODE ( - Tick = GetPerformanceCounter (); - ); - - Status = CoreLoadImageCommon ( - BootPolicy, - ParentImageHandle, - FilePath, - SourceBuffer, - SourceSize, - (EFI_PHYSICAL_ADDRESS) (UINTN) NULL, - NULL, - ImageHandle, - NULL, - EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION - ); - - Handle = NULL; - if (!EFI_ERROR (Status)) { - // - // ImageHandle will be valid only Status is success. - // - Handle = *ImageHandle; - } - - PERF_START (Handle, "LoadImage:", NULL, Tick); - PERF_END (Handle, "LoadImage:", NULL, 0); - - return Status; -} - - - -/** - Loads an EFI image into memory and returns a handle to the image with extended parameters. - - @param This Calling context - @param ParentImageHandle The caller's image handle. - @param FilePath The specific file path from which the image is - loaded. - @param SourceBuffer If not NULL, a pointer to the memory location - containing a copy of the image to be loaded. - @param SourceSize The size in bytes of SourceBuffer. - @param DstBuffer The buffer to store the image. - @param NumberOfPages For input, specifies the space size of the - image by caller if not NULL. For output, - specifies the actual space size needed. - @param ImageHandle Image handle for output. - @param EntryPoint Image entry point for output. - @param Attribute The bit mask of attributes to set for the load - PE image. - - @retval EFI_SUCCESS The image was loaded into memory. - @retval EFI_NOT_FOUND The FilePath was not found. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - @retval EFI_UNSUPPORTED The image type is not supported, or the device - path cannot be parsed to locate the proper - protocol for loading the file. - @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient - resources. - @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not - understood. - @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. - @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the - image from being loaded. NULL is returned in *ImageHandle. - @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a - valid EFI_LOADED_IMAGE_PROTOCOL. However, the current - platform policy specifies that the image should not be started. - -**/ -EFI_STATUS -EFIAPI -CoreLoadImageEx ( - IN EFI_PE32_IMAGE_PROTOCOL *This, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL, - OUT UINTN *NumberOfPages OPTIONAL, - OUT EFI_HANDLE *ImageHandle, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, - IN UINT32 Attribute - ) -{ - EFI_STATUS Status; - UINT64 Tick; - EFI_HANDLE Handle; - - Tick = 0; - PERF_CODE ( - Tick = GetPerformanceCounter (); - ); - - Status = CoreLoadImageCommon ( - TRUE, - ParentImageHandle, - FilePath, - SourceBuffer, - SourceSize, - DstBuffer, - NumberOfPages, - ImageHandle, - EntryPoint, - Attribute - ); - - Handle = NULL; - if (!EFI_ERROR (Status)) { - // - // ImageHandle will be valid only Status is success. - // - Handle = *ImageHandle; - } - - PERF_START (Handle, "LoadImage:", NULL, Tick); - PERF_END (Handle, "LoadImage:", NULL, 0); - - return Status; -} - - -/** - Transfer control to a loaded image's entry point. - - @param ImageHandle Handle of image to be started. - @param ExitDataSize Pointer of the size to ExitData - @param ExitData Pointer to a pointer to a data buffer that - includes a Null-terminated string, - optionally followed by additional binary data. - The string is a description that the caller may - use to further indicate the reason for the - image's exit. - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. - @retval EFI_SUCCESS Successfully transfer control to the image's - entry point. - -**/ -EFI_STATUS -EFIAPI -CoreStartImage ( - IN EFI_HANDLE ImageHandle, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ) -{ - EFI_STATUS Status; - LOADED_IMAGE_PRIVATE_DATA *Image; - LOADED_IMAGE_PRIVATE_DATA *LastImage; - UINT64 HandleDatabaseKey; - UINTN SetJumpFlag; - UINT64 Tick; - EFI_HANDLE Handle; - - Tick = 0; - Handle = ImageHandle; - - Image = CoreLoadedImageInfo (ImageHandle); - if (Image == NULL || Image->Started) { - return EFI_INVALID_PARAMETER; - } - if (EFI_ERROR (Image->LoadImageStatus)) { - return Image->LoadImageStatus; - } - - // - // The image to be started must have the machine type supported by DxeCore. - // - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->Machine)) { - // - // Do not ASSERT here, because image might be loaded via EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED - // But it can not be started. - // - DEBUG ((EFI_D_ERROR, "Image type %s can't be started ", GetMachineTypeName(Image->Machine))); - DEBUG ((EFI_D_ERROR, "on %s UEFI system.\n", GetMachineTypeName(mDxeCoreImageMachineType))); - return EFI_UNSUPPORTED; - } - - PERF_CODE ( - Tick = GetPerformanceCounter (); - ); - - - // - // Push the current start image context, and - // link the current image to the head. This is the - // only image that can call Exit() - // - HandleDatabaseKey = CoreGetHandleDatabaseKey (); - LastImage = mCurrentImage; - mCurrentImage = Image; - Image->Tpl = gEfiCurrentTpl; - - // - // Set long jump for Exit() support - // JumpContext must be aligned on a CPU specific boundary. - // Overallocate the buffer and force the required alignment - // - Image->JumpBuffer = AllocatePool (sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT); - if (Image->JumpBuffer == NULL) { - // - // Image may be unloaded after return with failure, - // then ImageHandle may be invalid, so use NULL handle to record perf log. - // - PERF_START (NULL, "StartImage:", NULL, Tick); - PERF_END (NULL, "StartImage:", NULL, 0); - - // - // Pop the current start image context - // - mCurrentImage = LastImage; - - return EFI_OUT_OF_RESOURCES; - } - Image->JumpContext = ALIGN_POINTER (Image->JumpBuffer, BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT); - - SetJumpFlag = SetJump (Image->JumpContext); - // - // The initial call to SetJump() must always return 0. - // Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump(). - // - if (SetJumpFlag == 0) { - RegisterMemoryProfileImage (Image, (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER)); - // - // Call the image's entry point - // - Image->Started = TRUE; - Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable); - - // - // Add some debug information if the image returned with error. - // This make the user aware and check if the driver image have already released - // all the resource in this situation. - // - DEBUG_CODE_BEGIN (); - if (EFI_ERROR (Image->Status)) { - DEBUG ((DEBUG_ERROR, "Error: Image at %11p start failed: %r\n", Image->Info.ImageBase, Image->Status)); - } - DEBUG_CODE_END (); - - // - // If the image returns, exit it through Exit() - // - CoreExit (ImageHandle, Image->Status, 0, NULL); - } - - // - // Image has completed. Verify the tpl is the same - // - ASSERT (Image->Tpl == gEfiCurrentTpl); - CoreRestoreTpl (Image->Tpl); - - CoreFreePool (Image->JumpBuffer); - - // - // Pop the current start image context - // - mCurrentImage = LastImage; - - // - // Go connect any handles that were created or modified while the image executed. - // - CoreConnectHandlesByKey (HandleDatabaseKey); - - // - // Handle the image's returned ExitData - // - DEBUG_CODE_BEGIN (); - if (Image->ExitDataSize != 0 || Image->ExitData != NULL) { - - DEBUG ((DEBUG_LOAD, "StartImage: ExitDataSize %d, ExitData %p", (UINT32)Image->ExitDataSize, Image->ExitData)); - if (Image->ExitData != NULL) { - DEBUG ((DEBUG_LOAD, " (%hs)", Image->ExitData)); - } - DEBUG ((DEBUG_LOAD, "\n")); - } - DEBUG_CODE_END (); - - // - // Return the exit data to the caller - // - if (ExitData != NULL && ExitDataSize != NULL) { - *ExitDataSize = Image->ExitDataSize; - *ExitData = Image->ExitData; - } else { - // - // Caller doesn't want the exit data, free it - // - CoreFreePool (Image->ExitData); - Image->ExitData = NULL; - } - - // - // Save the Status because Image will get destroyed if it is unloaded. - // - Status = Image->Status; - - // - // If the image returned an error, or if the image is an application - // unload it - // - if (EFI_ERROR (Image->Status) || Image->Type == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) { - CoreUnloadAndCloseImage (Image, TRUE); - // - // ImageHandle may be invalid after the image is unloaded, so use NULL handle to record perf log. - // - Handle = NULL; - } - - // - // Done - // - PERF_START (Handle, "StartImage:", NULL, Tick); - PERF_END (Handle, "StartImage:", NULL, 0); - return Status; -} - -/** - Terminates the currently loaded EFI image and returns control to boot services. - - @param ImageHandle Handle that identifies the image. This - parameter is passed to the image on entry. - @param Status The image's exit code. - @param ExitDataSize The size, in bytes, of ExitData. Ignored if - ExitStatus is EFI_SUCCESS. - @param ExitData Pointer to a data buffer that includes a - Null-terminated Unicode string, optionally - followed by additional binary data. The string - is a description that the caller may use to - further indicate the reason for the image's - exit. - - @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current - image. - @retval EFI_SUCCESS Successfully terminates the currently loaded - EFI image. - @retval EFI_ACCESS_DENIED Should never reach there. - @retval EFI_OUT_OF_RESOURCES Could not allocate pool - -**/ -EFI_STATUS -EFIAPI -CoreExit ( - IN EFI_HANDLE ImageHandle, - IN EFI_STATUS Status, - IN UINTN ExitDataSize, - IN CHAR16 *ExitData OPTIONAL - ) -{ - LOADED_IMAGE_PRIVATE_DATA *Image; - EFI_TPL OldTpl; - - // - // Prevent possible reentrance to this function - // for the same ImageHandle - // - OldTpl = CoreRaiseTpl (TPL_NOTIFY); - - Image = CoreLoadedImageInfo (ImageHandle); - if (Image == NULL) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - if (!Image->Started) { - // - // The image has not been started so just free its resources - // - CoreUnloadAndCloseImage (Image, TRUE); - Status = EFI_SUCCESS; - goto Done; - } - - // - // Image has been started, verify this image can exit - // - if (Image != mCurrentImage) { - DEBUG ((DEBUG_LOAD|DEBUG_ERROR, "Exit: Image is not exitable image\n")); - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - // - // Set status - // - Image->Status = Status; - - // - // If there's ExitData info, move it - // - if (ExitData != NULL) { - Image->ExitDataSize = ExitDataSize; - Image->ExitData = AllocatePool (Image->ExitDataSize); - if (Image->ExitData == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - CopyMem (Image->ExitData, ExitData, Image->ExitDataSize); - } - - CoreRestoreTpl (OldTpl); - // - // return to StartImage - // - LongJump (Image->JumpContext, (UINTN)-1); - - // - // If we return from LongJump, then it is an error - // - ASSERT (FALSE); - Status = EFI_ACCESS_DENIED; -Done: - CoreRestoreTpl (OldTpl); - return Status; -} - - - - -/** - Unloads an image. - - @param ImageHandle Handle that identifies the image to be - unloaded. - - @retval EFI_SUCCESS The image has been unloaded. - @retval EFI_UNSUPPORTED The image has been started, and does not support - unload. - @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. - -**/ -EFI_STATUS -EFIAPI -CoreUnloadImage ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_STATUS Status; - LOADED_IMAGE_PRIVATE_DATA *Image; - - Image = CoreLoadedImageInfo (ImageHandle); - if (Image == NULL ) { - // - // The image handle is not valid - // - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - if (Image->Started) { - // - // The image has been started, request it to unload. - // - Status = EFI_UNSUPPORTED; - if (Image->Info.Unload != NULL) { - Status = Image->Info.Unload (ImageHandle); - } - - } else { - // - // This Image hasn't been started, thus it can be unloaded - // - Status = EFI_SUCCESS; - } - - - if (!EFI_ERROR (Status)) { - // - // if the Image was not started or Unloaded O.K. then clean up - // - CoreUnloadAndCloseImage (Image, TRUE); - } - -Done: - return Status; -} - - - -/** - Unload the specified image. - - @param This Indicates the calling context. - @param ImageHandle The specified image handle. - - @retval EFI_INVALID_PARAMETER Image handle is NULL. - @retval EFI_UNSUPPORTED Attempt to unload an unsupported image. - @retval EFI_SUCCESS Image successfully unloaded. - -**/ -EFI_STATUS -EFIAPI -CoreUnloadImageEx ( - IN EFI_PE32_IMAGE_PROTOCOL *This, - IN EFI_HANDLE ImageHandle - ) -{ - return CoreUnloadImage (ImageHandle); -} diff --git a/MdeModulePkg/Core/Dxe/Image/Image.h b/MdeModulePkg/Core/Dxe/Image/Image.h deleted file mode 100644 index 7fb8c9368e..0000000000 --- a/MdeModulePkg/Core/Dxe/Image/Image.h +++ /dev/null @@ -1,113 +0,0 @@ -/** @file - Data structure and functions to load and unload PeImage. - -Copyright (c) 2006 - 2011, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#ifndef _IMAGE_H_ -#define _IMAGE_H_ - -#define LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE SIGNATURE_32('l','p','e','i') - -typedef struct { - UINTN Signature; - /// Image handle - EFI_HANDLE Handle; - EFI_PE32_IMAGE_PROTOCOL Pe32Image; -} LOAD_PE32_IMAGE_PRIVATE_DATA; - -#define LOAD_PE32_IMAGE_PRIVATE_DATA_FROM_THIS(a) \ - CR(a, LOAD_PE32_IMAGE_PRIVATE_DATA, Pe32Image, LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE) - - -// -// Private Data Types -// -#define IMAGE_FILE_HANDLE_SIGNATURE SIGNATURE_32('i','m','g','f') -typedef struct { - UINTN Signature; - BOOLEAN FreeBuffer; - VOID *Source; - UINTN SourceSize; -} IMAGE_FILE_HANDLE; - -/** - Loads an EFI image into memory and returns a handle to the image with extended parameters. - - @param This Calling context - @param ParentImageHandle The caller's image handle. - @param FilePath The specific file path from which the image is - loaded. - @param SourceBuffer If not NULL, a pointer to the memory location - containing a copy of the image to be loaded. - @param SourceSize The size in bytes of SourceBuffer. - @param DstBuffer The buffer to store the image. - @param NumberOfPages For input, specifies the space size of the - image by caller if not NULL. For output, - specifies the actual space size needed. - @param ImageHandle Image handle for output. - @param EntryPoint Image entry point for output. - @param Attribute The bit mask of attributes to set for the load - PE image. - - @retval EFI_SUCCESS The image was loaded into memory. - @retval EFI_NOT_FOUND The FilePath was not found. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - @retval EFI_UNSUPPORTED The image type is not supported, or the device - path cannot be parsed to locate the proper - protocol for loading the file. - @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient - resources. - @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not - understood. - @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. - @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the - image from being loaded. NULL is returned in *ImageHandle. - @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a - valid EFI_LOADED_IMAGE_PROTOCOL. However, the current - platform policy specifies that the image should not be started. - -**/ -EFI_STATUS -EFIAPI -CoreLoadImageEx ( - IN EFI_PE32_IMAGE_PROTOCOL *This, - IN EFI_HANDLE ParentImageHandle, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN VOID *SourceBuffer OPTIONAL, - IN UINTN SourceSize, - IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL, - OUT UINTN *NumberOfPages OPTIONAL, - OUT EFI_HANDLE *ImageHandle, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL, - IN UINT32 Attribute - ); - - -/** - Unload the specified image. - - @param This Indicates the calling context. - @param ImageHandle The specified image handle. - - @retval EFI_INVALID_PARAMETER Image handle is NULL. - @retval EFI_UNSUPPORTED Attempt to unload an unsupported image. - @retval EFI_SUCCESS Image successfully unloaded. - -**/ -EFI_STATUS -EFIAPI -CoreUnloadImageEx ( - IN EFI_PE32_IMAGE_PROTOCOL *This, - IN EFI_HANDLE ImageHandle - ); -#endif diff --git a/MdeModulePkg/Core/Dxe/Library/Library.c b/MdeModulePkg/Core/Dxe/Library/Library.c deleted file mode 100644 index ad46c27fa2..0000000000 --- a/MdeModulePkg/Core/Dxe/Library/Library.c +++ /dev/null @@ -1,106 +0,0 @@ -/** @file - DXE Core library services. - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - -// -// Lock Stuff -// -/** - Initialize a basic mutual exclusion lock. Each lock - provides mutual exclusion access at it's task priority - level. Since there is no-premption (at any TPL) or - multiprocessor support, acquiring the lock only consists - of raising to the locks TPL. - - @param Lock The EFI_LOCK structure to initialize - - @retval EFI_SUCCESS Lock Owned. - @retval EFI_ACCESS_DENIED Reentrant Lock Acquisition, Lock not Owned. - -**/ -EFI_STATUS -CoreAcquireLockOrFail ( - IN EFI_LOCK *Lock - ) -{ - ASSERT (Lock != NULL); - ASSERT (Lock->Lock != EfiLockUninitialized); - - if (Lock->Lock == EfiLockAcquired) { - // - // Lock is already owned, so bail out - // - return EFI_ACCESS_DENIED; - } - - Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl); - - Lock->Lock = EfiLockAcquired; - return EFI_SUCCESS; -} - - - -/** - Raising to the task priority level of the mutual exclusion - lock, and then acquires ownership of the lock. - - @param Lock The lock to acquire - - @return Lock owned - -**/ -VOID -CoreAcquireLock ( - IN EFI_LOCK *Lock - ) -{ - ASSERT (Lock != NULL); - ASSERT (Lock->Lock == EfiLockReleased); - - Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl); - Lock->Lock = EfiLockAcquired; -} - - - -/** - Releases ownership of the mutual exclusion lock, and - restores the previous task priority level. - - @param Lock The lock to release - - @return Lock unowned - -**/ -VOID -CoreReleaseLock ( - IN EFI_LOCK *Lock - ) -{ - EFI_TPL Tpl; - - ASSERT (Lock != NULL); - ASSERT (Lock->Lock == EfiLockAcquired); - - Tpl = Lock->OwnerTpl; - - Lock->Lock = EfiLockReleased; - - CoreRestoreTpl (Tpl); -} - - - diff --git a/MdeModulePkg/Core/Dxe/Mem/Imem.h b/MdeModulePkg/Core/Dxe/Mem/Imem.h deleted file mode 100644 index fb53f95575..0000000000 --- a/MdeModulePkg/Core/Dxe/Mem/Imem.h +++ /dev/null @@ -1,156 +0,0 @@ -/** @file - Data structure and functions to allocate and free memory space. - -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _IMEM_H_ -#define _IMEM_H_ - -// -// +---------------------------------------------------+ -// | 0..(EfiMaxMemoryType - 1) - Normal memory type | -// +---------------------------------------------------+ -// | EfiMaxMemoryType..0x6FFFFFFF - Invalid | -// +---------------------------------------------------+ -// | 0x70000000..0x7FFFFFFF - OEM reserved | -// +---------------------------------------------------+ -// | 0x80000000..0xFFFFFFFF - OS reserved | -// +---------------------------------------------------+ -// -#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 -#define MEMORY_TYPE_OS_RESERVED_MAX 0xFFFFFFFF -#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 -#define MEMORY_TYPE_OEM_RESERVED_MAX 0x7FFFFFFF - -// -// MEMORY_MAP_ENTRY -// - -#define MEMORY_MAP_SIGNATURE SIGNATURE_32('m','m','a','p') -typedef struct { - UINTN Signature; - LIST_ENTRY Link; - BOOLEAN FromPages; - - EFI_MEMORY_TYPE Type; - UINT64 Start; - UINT64 End; - - UINT64 VirtualStart; - UINT64 Attribute; -} MEMORY_MAP; - -// -// Internal prototypes -// - - -/** - Internal function. Used by the pool functions to allocate pages - to back pool allocation requests. - - @param PoolType The type of memory for the new pool pages - @param NumberOfPages No of pages to allocate - @param Alignment Bits to align. - - @return The allocated memory, or NULL - -**/ -VOID * -CoreAllocatePoolPages ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NumberOfPages, - IN UINTN Alignment - ); - - - -/** - Internal function. Frees pool pages allocated via AllocatePoolPages () - - @param Memory The base address to free - @param NumberOfPages The number of pages to free - -**/ -VOID -CoreFreePoolPages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - - - -/** - Internal function to allocate pool of a particular type. - Caller must have the memory lock held - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - - @return The allocate pool, or NULL - -**/ -VOID * -CoreAllocatePoolI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size - ); - - - -/** - Internal function to free a pool entry. - Caller must have the memory lock held - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer not valid - @retval EFI_SUCCESS Buffer successfully freed. - -**/ -EFI_STATUS -CoreFreePoolI ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ); - - - -/** - Enter critical section by gaining lock on gMemoryLock. - -**/ -VOID -CoreAcquireMemoryLock ( - VOID - ); - - -/** - Exit critical section by releasing lock on gMemoryLock. - -**/ -VOID -CoreReleaseMemoryLock ( - VOID - ); - - -// -// Internal Global data -// - -extern EFI_LOCK gMemoryLock; -extern LIST_ENTRY gMemoryMap; -extern LIST_ENTRY mGcdMemorySpaceMap; -#endif diff --git a/MdeModulePkg/Core/Dxe/Mem/MemData.c b/MdeModulePkg/Core/Dxe/Mem/MemData.c deleted file mode 100644 index e51b894433..0000000000 --- a/MdeModulePkg/Core/Dxe/Mem/MemData.c +++ /dev/null @@ -1,26 +0,0 @@ -/** @file - Global data used in memory service - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - - -// -// MemoryLock - synchronizes access to the memory map and pool lists -// -EFI_LOCK gMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); - -// -// MemoryMap - the current memory map -// -LIST_ENTRY gMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (gMemoryMap); diff --git a/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c b/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c deleted file mode 100644 index a91a719b4d..0000000000 --- a/MdeModulePkg/Core/Dxe/Mem/MemoryProfileRecord.c +++ /dev/null @@ -1,1794 +0,0 @@ -/** @file - Support routines for UEFI memory profile. - - Copyright (c) 2014 - 2016, 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 - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Imem.h" - -#define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0) - -#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \ - ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))) - -typedef struct { - UINT32 Signature; - MEMORY_PROFILE_CONTEXT Context; - LIST_ENTRY *DriverInfoList; -} MEMORY_PROFILE_CONTEXT_DATA; - -typedef struct { - UINT32 Signature; - MEMORY_PROFILE_DRIVER_INFO DriverInfo; - LIST_ENTRY *AllocInfoList; - CHAR8 *PdbString; - LIST_ENTRY Link; -} MEMORY_PROFILE_DRIVER_INFO_DATA; - -typedef struct { - UINT32 Signature; - MEMORY_PROFILE_ALLOC_INFO AllocInfo; - CHAR8 *ActionString; - LIST_ENTRY Link; -} MEMORY_PROFILE_ALLOC_INFO_DATA; - - -GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mImageQueue = INITIALIZE_LIST_HEAD_VARIABLE (mImageQueue); -GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA mMemoryProfileContext = { - MEMORY_PROFILE_CONTEXT_SIGNATURE, - { - { - MEMORY_PROFILE_CONTEXT_SIGNATURE, - sizeof (MEMORY_PROFILE_CONTEXT), - MEMORY_PROFILE_CONTEXT_REVISION - }, - 0, - 0, - {0}, - {0}, - 0, - 0, - 0 - }, - &mImageQueue, -}; -GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA *mMemoryProfileContextPtr = NULL; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_LOCK mMemoryProfileLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); -GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mMemoryProfileGettingStatus = FALSE; -GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mMemoryProfileRecordingEnable = MEMORY_PROFILE_RECORDING_DISABLE; -GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_PROTOCOL *mMemoryProfileDriverPath; -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mMemoryProfileDriverPathSize; - -/** - Get memory profile data. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer. - On return, points to the size of the data returned in ProfileBuffer. - @param[out] ProfileBuffer Profile buffer. - - @return EFI_SUCCESS Get the memory profile data successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data. - ProfileSize is updated with the size required. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolGetData ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN OUT UINT64 *ProfileSize, - OUT VOID *ProfileBuffer - ); - -/** - Register image to memory profile. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in] FilePath File path of the image. - @param[in] ImageBase Image base address. - @param[in] ImageSize Image size. - @param[in] FileType File type of the image. - - @return EFI_SUCCESS Register successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCE No enough resource for this register. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolRegisterImage ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN EFI_FV_FILETYPE FileType - ); - -/** - Unregister image from memory profile. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in] FilePath File path of the image. - @param[in] ImageBase Image base address. - @param[in] ImageSize Image size. - - @return EFI_SUCCESS Unregister successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_NOT_FOUND The image is not found. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolUnregisterImage ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize - ); - -/** - Get memory profile recording state. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[out] RecordingState Recording state. - - @return EFI_SUCCESS Memory profile recording state is returned. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_INVALID_PARAMETER RecordingState is NULL. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolGetRecordingState ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - OUT BOOLEAN *RecordingState - ); - -/** - Set memory profile recording state. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in] RecordingState Recording state. - - @return EFI_SUCCESS Set memory profile recording state successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolSetRecordingState ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN BOOLEAN RecordingState - ); - -/** - Record memory profile of multilevel caller. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in] CallerAddress Address of caller. - @param[in] Action Memory profile action. - @param[in] MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param[in] Buffer Buffer address. - @param[in] Size Buffer size. - @param[in] ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolRecord ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN VOID *Buffer, - IN UINTN Size, - IN CHAR8 *ActionString OPTIONAL - ); - -GLOBAL_REMOVE_IF_UNREFERENCED EDKII_MEMORY_PROFILE_PROTOCOL mProfileProtocol = { - ProfileProtocolGetData, - ProfileProtocolRegisterImage, - ProfileProtocolUnregisterImage, - ProfileProtocolGetRecordingState, - ProfileProtocolSetRecordingState, - ProfileProtocolRecord, -}; - -/** - Acquire lock on mMemoryProfileLock. -**/ -VOID -CoreAcquireMemoryProfileLock ( - VOID - ) -{ - CoreAcquireLock (&mMemoryProfileLock); -} - -/** - Release lock on mMemoryProfileLock. -**/ -VOID -CoreReleaseMemoryProfileLock ( - VOID - ) -{ - CoreReleaseLock (&mMemoryProfileLock); -} - -/** - Return memory profile context. - - @return Memory profile context. - -**/ -MEMORY_PROFILE_CONTEXT_DATA * -GetMemoryProfileContext ( - VOID - ) -{ - return mMemoryProfileContextPtr; -} - -/** - Retrieves the magic value from the PE/COFF header. - - @param Hdr The buffer in which to return the PE32, PE32+, or TE header. - - @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32 - @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+ - -**/ -UINT16 -InternalPeCoffGetPeHeaderMagicValue ( - IN EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr - ) -{ - // - // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value - // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the - // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - // then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - // - if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - } - // - // Return the magic value from the PC/COFF Optional Header - // - return Hdr.Pe32->OptionalHeader.Magic; -} - -/** - Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory. - If Pe32Data is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - - @return The Subsystem of the PE/COFF image. - -**/ -UINT16 -InternalPeCoffGetSubsystem ( - IN VOID *Pe32Data - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT16 Magic; - - ASSERT (Pe32Data != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data; - } - - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - return Hdr.Te->Subsystem; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - Magic = InternalPeCoffGetPeHeaderMagicValue (Hdr); - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - return Hdr.Pe32->OptionalHeader.Subsystem; - } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - return Hdr.Pe32Plus->OptionalHeader.Subsystem; - } - } - - return 0x0000; -} - -/** - Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded - into system memory with the PE/COFF Loader Library functions. - - Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry - point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then - return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. - If Pe32Data is NULL, then ASSERT(). - If EntryPoint is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - @param EntryPoint The pointer to entry point to the PE/COFF image to return. - - @retval RETURN_SUCCESS EntryPoint was returned. - @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. - -**/ -RETURN_STATUS -InternalPeCoffGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - - ASSERT (Pe32Data != NULL); - ASSERT (EntryPoint != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data; - } - - // - // Calculate the entry point relative to the start of the image. - // AddressOfEntryPoint is common for PE32 & PE32+ - // - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); - return RETURN_SUCCESS; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff)); - return RETURN_SUCCESS; - } - - return RETURN_UNSUPPORTED; -} - -/** - Build driver info. - - @param ContextData Memory profile context. - @param FileName File name of the image. - @param ImageBase Image base address. - @param ImageSize Image size. - @param EntryPoint Entry point of the image. - @param ImageSubsystem Image subsystem of the image. - @param FileType File type of the image. - - @return Pointer to memory profile driver info. - -**/ -MEMORY_PROFILE_DRIVER_INFO_DATA * -BuildDriverInfo ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, - IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN PHYSICAL_ADDRESS EntryPoint, - IN UINT16 ImageSubsystem, - IN EFI_FV_FILETYPE FileType - ) -{ - EFI_STATUS Status; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - VOID *EntryPointInImage; - CHAR8 *PdbString; - UINTN PdbSize; - UINTN PdbOccupiedSize; - - PdbSize = 0; - PdbOccupiedSize = 0; - PdbString = NULL; - if (ImageBase != 0) { - PdbString = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageBase); - if (PdbString != NULL) { - PdbSize = AsciiStrSize (PdbString); - PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64)); - } - } - - // - // Use CoreInternalAllocatePool() that will not update profile for this AllocatePool action. - // - Status = CoreInternalAllocatePool ( - EfiBootServicesData, - sizeof (*DriverInfoData) + sizeof (LIST_ENTRY) + PdbSize, - (VOID **) &DriverInfoData - ); - if (EFI_ERROR (Status)) { - return NULL; - } - ASSERT (DriverInfoData != NULL); - - ZeroMem (DriverInfoData, sizeof (*DriverInfoData)); - - DriverInfo = &DriverInfoData->DriverInfo; - DriverInfoData->Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE; - DriverInfo->Header.Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE; - DriverInfo->Header.Length = (UINT16) (sizeof (MEMORY_PROFILE_DRIVER_INFO) + PdbOccupiedSize); - DriverInfo->Header.Revision = MEMORY_PROFILE_DRIVER_INFO_REVISION; - if (FileName != NULL) { - CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID)); - } - DriverInfo->ImageBase = ImageBase; - DriverInfo->ImageSize = ImageSize; - DriverInfo->EntryPoint = EntryPoint; - DriverInfo->ImageSubsystem = ImageSubsystem; - if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageBuffer here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage; - } - DriverInfo->FileType = FileType; - DriverInfoData->AllocInfoList = (LIST_ENTRY *) (DriverInfoData + 1); - InitializeListHead (DriverInfoData->AllocInfoList); - DriverInfo->CurrentUsage = 0; - DriverInfo->PeakUsage = 0; - DriverInfo->AllocRecordCount = 0; - if (PdbSize != 0) { - DriverInfo->PdbStringOffset = (UINT16) sizeof (MEMORY_PROFILE_DRIVER_INFO); - DriverInfoData->PdbString = (CHAR8 *) (DriverInfoData->AllocInfoList + 1); - CopyMem (DriverInfoData->PdbString, PdbString, PdbSize); - } else { - DriverInfo->PdbStringOffset = 0; - DriverInfoData->PdbString = NULL; - } - - InsertTailList (ContextData->DriverInfoList, &DriverInfoData->Link); - ContextData->Context.ImageCount ++; - ContextData->Context.TotalImageSize += DriverInfo->ImageSize; - - return DriverInfoData; -} - -/** - Return if record for this driver is needed.. - - @param DriverFilePath Driver file path. - - @retval TRUE Record for this driver is needed. - @retval FALSE Record for this driver is not needed. - -**/ -BOOLEAN -NeedRecordThisDriver ( - IN EFI_DEVICE_PATH_PROTOCOL *DriverFilePath - ) -{ - EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance; - UINTN DevicePathSize; - UINTN FilePathSize; - - if (!IsDevicePathValid (mMemoryProfileDriverPath, mMemoryProfileDriverPathSize)) { - // - // Invalid Device Path means record all. - // - return TRUE; - } - - // - // Record FilePath without END node. - // - FilePathSize = GetDevicePathSize (DriverFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); - - DevicePathInstance = mMemoryProfileDriverPath; - do { - // - // Find END node (it might be END_ENTIRE or END_INSTANCE). - // - TmpDevicePath = DevicePathInstance; - while (!IsDevicePathEndType (TmpDevicePath)) { - TmpDevicePath = NextDevicePathNode (TmpDevicePath); - } - - // - // Do not compare END node. - // - DevicePathSize = (UINTN)TmpDevicePath - (UINTN)DevicePathInstance; - if ((FilePathSize == DevicePathSize) && - (CompareMem (DriverFilePath, DevicePathInstance, DevicePathSize) == 0)) { - return TRUE; - } - - // - // Get next instance. - // - DevicePathInstance = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)DevicePathInstance + DevicePathSize + DevicePathNodeLength(TmpDevicePath)); - } while (DevicePathSubType (TmpDevicePath) != END_ENTIRE_DEVICE_PATH_SUBTYPE); - - return FALSE; -} - -/** - Register DXE Core to memory profile. - - @param HobStart The start address of the HOB. - @param ContextData Memory profile context. - - @retval TRUE Register success. - @retval FALSE Register fail. - -**/ -BOOLEAN -RegisterDxeCore ( - IN VOID *HobStart, - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData - ) -{ - EFI_PEI_HOB_POINTERS DxeCoreHob; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - PHYSICAL_ADDRESS ImageBase; - UINT8 TempBuffer[sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH_PROTOCOL)]; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; - - ASSERT (ContextData != NULL); - - // - // Searching for image hob - // - DxeCoreHob.Raw = HobStart; - while ((DxeCoreHob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw)) != NULL) { - if (CompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemoryAllocModuleGuid)) { - // - // Find Dxe Core HOB - // - break; - } - DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob); - } - ASSERT (DxeCoreHob.Raw != NULL); - - FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempBuffer; - EfiInitializeFwVolDevicepathNode (FilePath, &DxeCoreHob.MemoryAllocationModule->ModuleName); - SetDevicePathEndNode (FilePath + 1); - - if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *) FilePath)) { - return FALSE; - } - - ImageBase = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress; - DriverInfoData = BuildDriverInfo ( - ContextData, - &DxeCoreHob.MemoryAllocationModule->ModuleName, - ImageBase, - DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength, - DxeCoreHob.MemoryAllocationModule->EntryPoint, - InternalPeCoffGetSubsystem ((VOID *) (UINTN) ImageBase), - EFI_FV_FILETYPE_DXE_CORE - ); - if (DriverInfoData == NULL) { - return FALSE; - } - - return TRUE; -} - -/** - Initialize memory profile. - - @param HobStart The start address of the HOB. - -**/ -VOID -MemoryProfileInit ( - IN VOID *HobStart - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - - if (!IS_UEFI_MEMORY_PROFILE_ENABLED) { - return; - } - - ContextData = GetMemoryProfileContext (); - if (ContextData != NULL) { - return; - } - - mMemoryProfileGettingStatus = FALSE; - if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT7) != 0) { - mMemoryProfileRecordingEnable = MEMORY_PROFILE_RECORDING_DISABLE; - } else { - mMemoryProfileRecordingEnable = MEMORY_PROFILE_RECORDING_ENABLE; - } - mMemoryProfileDriverPathSize = PcdGetSize (PcdMemoryProfileDriverPath); - mMemoryProfileDriverPath = AllocateCopyPool (mMemoryProfileDriverPathSize, PcdGetPtr (PcdMemoryProfileDriverPath)); - mMemoryProfileContextPtr = &mMemoryProfileContext; - - RegisterDxeCore (HobStart, &mMemoryProfileContext); - - DEBUG ((EFI_D_INFO, "MemoryProfileInit MemoryProfileContext - 0x%x\n", &mMemoryProfileContext)); -} - -/** - Install memory profile protocol. - -**/ -VOID -MemoryProfileInstallProtocol ( - VOID - ) -{ - EFI_HANDLE Handle; - EFI_STATUS Status; - - if (!IS_UEFI_MEMORY_PROFILE_ENABLED) { - return; - } - - Handle = NULL; - Status = CoreInstallMultipleProtocolInterfaces ( - &Handle, - &gEdkiiMemoryProfileGuid, - &mProfileProtocol, - NULL - ); - ASSERT_EFI_ERROR (Status); -} - -/** - Get the GUID file name from the file path. - - @param FilePath File path. - - @return The GUID file name from the file path. - -**/ -EFI_GUID * -GetFileNameFromFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath - ) -{ - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *ThisFilePath; - EFI_GUID *FileName; - - FileName = NULL; - if (FilePath != NULL) { - ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) FilePath; - while (!IsDevicePathEnd (ThisFilePath)) { - FileName = EfiGetNameGuidFromFwVolDevicePathNode (ThisFilePath); - if (FileName != NULL) { - break; - } - ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) NextDevicePathNode (ThisFilePath); - } - } - - return FileName; -} - -/** - Register image to memory profile. - - @param DriverEntry Image info. - @param FileType Image file type. - - @return EFI_SUCCESS Register successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCES No enough resource for this register. - -**/ -EFI_STATUS -RegisterMemoryProfileImage ( - IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry, - IN EFI_FV_FILETYPE FileType - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - - if (!IS_UEFI_MEMORY_PROFILE_ENABLED) { - return EFI_UNSUPPORTED; - } - - if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) { - return EFI_UNSUPPORTED; - } - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - DriverInfoData = BuildDriverInfo ( - ContextData, - GetFileNameFromFilePath (DriverEntry->Info.FilePath), - DriverEntry->ImageContext.ImageAddress, - DriverEntry->ImageContext.ImageSize, - DriverEntry->ImageContext.EntryPoint, - DriverEntry->ImageContext.ImageType, - FileType - ); - if (DriverInfoData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} - -/** - Search image from memory profile. - - @param ContextData Memory profile context. - @param FileName Image file name. - @param Address Image Address. - - @return Pointer to memory profile driver info. - -**/ -MEMORY_PROFILE_DRIVER_INFO_DATA * -GetMemoryProfileDriverInfoByFileNameAndAddress ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, - IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS Address - ) -{ - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - LIST_ENTRY *DriverLink; - LIST_ENTRY *DriverInfoList; - - DriverInfoList = ContextData->DriverInfoList; - - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - DriverInfo = &DriverInfoData->DriverInfo; - if ((CompareGuid (&DriverInfo->FileName, FileName)) && - (Address >= DriverInfo->ImageBase) && - (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) { - return DriverInfoData; - } - } - - return NULL; -} - -/** - Search image from memory profile. - It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize). - - @param ContextData Memory profile context. - @param Address Image or Function address. - - @return Pointer to memory profile driver info. - -**/ -MEMORY_PROFILE_DRIVER_INFO_DATA * -GetMemoryProfileDriverInfoFromAddress ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, - IN PHYSICAL_ADDRESS Address - ) -{ - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - LIST_ENTRY *DriverLink; - LIST_ENTRY *DriverInfoList; - - DriverInfoList = ContextData->DriverInfoList; - - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - DriverInfo = &DriverInfoData->DriverInfo; - if ((Address >= DriverInfo->ImageBase) && - (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) { - return DriverInfoData; - } - } - - return NULL; -} - -/** - Unregister image from memory profile. - - @param DriverEntry Image info. - - @return EFI_SUCCESS Unregister successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_NOT_FOUND The image is not found. - -**/ -EFI_STATUS -UnregisterMemoryProfileImage ( - IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry - ) -{ - EFI_STATUS Status; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - EFI_GUID *FileName; - PHYSICAL_ADDRESS ImageAddress; - VOID *EntryPointInImage; - - if (!IS_UEFI_MEMORY_PROFILE_ENABLED) { - return EFI_UNSUPPORTED; - } - - if (!NeedRecordThisDriver (DriverEntry->Info.FilePath)) { - return EFI_UNSUPPORTED; - } - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - DriverInfoData = NULL; - FileName = GetFileNameFromFilePath (DriverEntry->Info.FilePath); - ImageAddress = DriverEntry->ImageContext.ImageAddress; - if ((DriverEntry->ImageContext.EntryPoint < ImageAddress) || (DriverEntry->ImageContext.EntryPoint >= (ImageAddress + DriverEntry->ImageContext.ImageSize))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageAddress here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageAddress, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - ImageAddress = ImageAddress + (UINTN) DriverEntry->ImageContext.EntryPoint - (UINTN) EntryPointInImage; - } - if (FileName != NULL) { - DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress); - } - if (DriverInfoData == NULL) { - DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageAddress); - } - if (DriverInfoData == NULL) { - return EFI_NOT_FOUND; - } - - ContextData->Context.TotalImageSize -= DriverInfoData->DriverInfo.ImageSize; - - // Keep the ImageBase for RVA calculation in Application. - //DriverInfoData->DriverInfo.ImageBase = 0; - DriverInfoData->DriverInfo.ImageSize = 0; - - if (DriverInfoData->DriverInfo.PeakUsage == 0) { - ContextData->Context.ImageCount --; - RemoveEntryList (&DriverInfoData->Link); - // - // Use CoreInternalFreePool() that will not update profile for this FreePool action. - // - CoreInternalFreePool (DriverInfoData, NULL); - } - - return EFI_SUCCESS; -} - -/** - Return if this memory type needs to be recorded into memory profile. - If BIOS memory type (0 ~ EfiMaxMemoryType - 1), it checks bit (1 << MemoryType). - If OS memory type (0x80000000 ~ 0xFFFFFFFF), it checks bit63 - 0x8000000000000000. - If OEM memory type (0x70000000 ~ 0x7FFFFFFF), it checks bit62 - 0x4000000000000000. - - @param MemoryType Memory type. - - @retval TRUE This memory type need to be recorded. - @retval FALSE This memory type need not to be recorded. - -**/ -BOOLEAN -CoreNeedRecordProfile ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - UINT64 TestBit; - - if ((UINT32) MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { - TestBit = BIT63; - } else if ((UINT32) MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { - TestBit = BIT62; - } else { - TestBit = LShiftU64 (1, MemoryType); - } - - if ((PcdGet64 (PcdMemoryProfileMemoryType) & TestBit) != 0) { - return TRUE; - } else { - return FALSE; - } -} - -/** - Convert EFI memory type to profile memory index. The rule is: - If BIOS memory type (0 ~ EfiMaxMemoryType - 1), ProfileMemoryIndex = MemoryType. - If OS memory type (0x80000000 ~ 0xFFFFFFFF), ProfileMemoryIndex = EfiMaxMemoryType. - If OEM memory type (0x70000000 ~ 0x7FFFFFFF), ProfileMemoryIndex = EfiMaxMemoryType + 1. - - @param MemoryType Memory type. - - @return Profile memory index. - -**/ -UINTN -GetProfileMemoryIndex ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - if ((UINT32) MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { - return EfiMaxMemoryType; - } else if ((UINT32) MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { - return EfiMaxMemoryType + 1; - } else { - return MemoryType; - } -} - -/** - Update memory profile Allocate information. - - @param CallerAddress Address of caller who call Allocate. - @param Action This Allocate action. - @param MemoryType Memory type. - @param Size Buffer size. - @param Buffer Buffer address. - @param ActionString String for memory profile action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - -**/ -EFI_STATUS -CoreUpdateProfileAllocate ( - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Size, - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ) -{ - EFI_STATUS Status; - MEMORY_PROFILE_CONTEXT *Context; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - UINTN ProfileMemoryIndex; - MEMORY_PROFILE_ACTION BasicAction; - UINTN ActionStringSize; - UINTN ActionStringOccupiedSize; - - BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK; - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress); - if (DriverInfoData == NULL) { - return EFI_UNSUPPORTED; - } - - ActionStringSize = 0; - ActionStringOccupiedSize = 0; - if (ActionString != NULL) { - ActionStringSize = AsciiStrSize (ActionString); - ActionStringOccupiedSize = GET_OCCUPIED_SIZE (ActionStringSize, sizeof (UINT64)); - } - - // - // Use CoreInternalAllocatePool() that will not update profile for this AllocatePool action. - // - AllocInfoData = NULL; - Status = CoreInternalAllocatePool ( - EfiBootServicesData, - sizeof (*AllocInfoData) + ActionStringSize, - (VOID **) &AllocInfoData - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - ASSERT (AllocInfoData != NULL); - - // - // Only update SequenceCount if and only if it is basic action. - // - if (Action == BasicAction) { - ContextData->Context.SequenceCount ++; - } - - AllocInfo = &AllocInfoData->AllocInfo; - AllocInfoData->Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE; - AllocInfo->Header.Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE; - AllocInfo->Header.Length = (UINT16) (sizeof (MEMORY_PROFILE_ALLOC_INFO) + ActionStringOccupiedSize); - AllocInfo->Header.Revision = MEMORY_PROFILE_ALLOC_INFO_REVISION; - AllocInfo->CallerAddress = CallerAddress; - AllocInfo->SequenceId = ContextData->Context.SequenceCount; - AllocInfo->Action = Action; - AllocInfo->MemoryType = MemoryType; - AllocInfo->Buffer = (PHYSICAL_ADDRESS) (UINTN) Buffer; - AllocInfo->Size = Size; - if (ActionString != NULL) { - AllocInfo->ActionStringOffset = (UINT16) sizeof (MEMORY_PROFILE_ALLOC_INFO); - AllocInfoData->ActionString = (CHAR8 *) (AllocInfoData + 1); - CopyMem (AllocInfoData->ActionString, ActionString, ActionStringSize); - } else { - AllocInfo->ActionStringOffset = 0; - AllocInfoData->ActionString = NULL; - } - - InsertTailList (DriverInfoData->AllocInfoList, &AllocInfoData->Link); - - Context = &ContextData->Context; - DriverInfo = &DriverInfoData->DriverInfo; - DriverInfo->AllocRecordCount ++; - - // - // Update summary if and only if it is basic action. - // - if (Action == BasicAction) { - ProfileMemoryIndex = GetProfileMemoryIndex (MemoryType); - - DriverInfo->CurrentUsage += Size; - if (DriverInfo->PeakUsage < DriverInfo->CurrentUsage) { - DriverInfo->PeakUsage = DriverInfo->CurrentUsage; - } - DriverInfo->CurrentUsageByType[ProfileMemoryIndex] += Size; - if (DriverInfo->PeakUsageByType[ProfileMemoryIndex] < DriverInfo->CurrentUsageByType[ProfileMemoryIndex]) { - DriverInfo->PeakUsageByType[ProfileMemoryIndex] = DriverInfo->CurrentUsageByType[ProfileMemoryIndex]; - } - - Context->CurrentTotalUsage += Size; - if (Context->PeakTotalUsage < Context->CurrentTotalUsage) { - Context->PeakTotalUsage = Context->CurrentTotalUsage; - } - Context->CurrentTotalUsageByType[ProfileMemoryIndex] += Size; - if (Context->PeakTotalUsageByType[ProfileMemoryIndex] < Context->CurrentTotalUsageByType[ProfileMemoryIndex]) { - Context->PeakTotalUsageByType[ProfileMemoryIndex] = Context->CurrentTotalUsageByType[ProfileMemoryIndex]; - } - } - - return EFI_SUCCESS; -} - -/** - Get memory profile alloc info from memory profile. - - @param DriverInfoData Driver info. - @param BasicAction This Free basic action. - @param Size Buffer size. - @param Buffer Buffer address. - - @return Pointer to memory profile alloc info. - -**/ -MEMORY_PROFILE_ALLOC_INFO_DATA * -GetMemoryProfileAllocInfoFromAddress ( - IN MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData, - IN MEMORY_PROFILE_ACTION BasicAction, - IN UINTN Size, - IN VOID *Buffer - ) -{ - LIST_ENTRY *AllocInfoList; - LIST_ENTRY *AllocLink; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - - AllocInfoList = DriverInfoData->AllocInfoList; - - for (AllocLink = AllocInfoList->ForwardLink; - AllocLink != AllocInfoList; - AllocLink = AllocLink->ForwardLink) { - AllocInfoData = CR ( - AllocLink, - MEMORY_PROFILE_ALLOC_INFO_DATA, - Link, - MEMORY_PROFILE_ALLOC_INFO_SIGNATURE - ); - AllocInfo = &AllocInfoData->AllocInfo; - if ((AllocInfo->Action & MEMORY_PROFILE_ACTION_BASIC_MASK) != BasicAction) { - continue; - } - switch (BasicAction) { - case MemoryProfileActionAllocatePages: - if ((AllocInfo->Buffer <= (PHYSICAL_ADDRESS) (UINTN) Buffer) && - ((AllocInfo->Buffer + AllocInfo->Size) >= ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size))) { - return AllocInfoData; - } - break; - case MemoryProfileActionAllocatePool: - if (AllocInfo->Buffer == (PHYSICAL_ADDRESS) (UINTN) Buffer) { - return AllocInfoData; - } - break; - default: - ASSERT (FALSE); - break; - } - } - - return NULL; -} - -/** - Update memory profile Free information. - - @param CallerAddress Address of caller who call Free. - @param Action This Free action. - @param Size Buffer size. - @param Buffer Buffer address. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -CoreUpdateProfileFree ( - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN UINTN Size, - IN VOID *Buffer - ) -{ - MEMORY_PROFILE_CONTEXT *Context; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - LIST_ENTRY *DriverLink; - LIST_ENTRY *DriverInfoList; - MEMORY_PROFILE_DRIVER_INFO_DATA *ThisDriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - UINTN ProfileMemoryIndex; - MEMORY_PROFILE_ACTION BasicAction; - BOOLEAN Found; - - BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK; - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress); - - // - // Do not return if DriverInfoData == NULL here, - // because driver A might free memory allocated by driver B. - // - - // - // Need use do-while loop to find all possible records, - // because one address might be recorded multiple times. - // - Found = FALSE; - AllocInfoData = NULL; - do { - if (DriverInfoData != NULL) { - switch (BasicAction) { - case MemoryProfileActionFreePages: - AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer); - break; - case MemoryProfileActionFreePool: - AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer); - break; - default: - ASSERT (FALSE); - AllocInfoData = NULL; - break; - } - } - if (AllocInfoData == NULL) { - // - // Legal case, because driver A might free memory allocated by driver B, by some protocol. - // - DriverInfoList = ContextData->DriverInfoList; - - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - ThisDriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - switch (BasicAction) { - case MemoryProfileActionFreePages: - AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer); - break; - case MemoryProfileActionFreePool: - AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer); - break; - default: - ASSERT (FALSE); - AllocInfoData = NULL; - break; - } - if (AllocInfoData != NULL) { - DriverInfoData = ThisDriverInfoData; - break; - } - } - - if (AllocInfoData == NULL) { - // - // If (!Found), no matched allocate info is found for this free action. - // It is because the specified memory type allocate actions have been filtered by - // CoreNeedRecordProfile(), but free actions may have no memory type information, - // they can not be filtered by CoreNeedRecordProfile(). Then, they will be - // filtered here. - // - // If (Found), it is normal exit path. - return (Found ? EFI_SUCCESS : EFI_NOT_FOUND); - } - } - - ASSERT (DriverInfoData != NULL); - ASSERT (AllocInfoData != NULL); - - Found = TRUE; - - Context = &ContextData->Context; - DriverInfo = &DriverInfoData->DriverInfo; - AllocInfo = &AllocInfoData->AllocInfo; - - DriverInfo->AllocRecordCount --; - // - // Update summary if and only if it is basic action. - // - if (AllocInfo->Action == (AllocInfo->Action & MEMORY_PROFILE_ACTION_BASIC_MASK)) { - ProfileMemoryIndex = GetProfileMemoryIndex (AllocInfo->MemoryType); - - Context->CurrentTotalUsage -= AllocInfo->Size; - Context->CurrentTotalUsageByType[ProfileMemoryIndex] -= AllocInfo->Size; - - DriverInfo->CurrentUsage -= AllocInfo->Size; - DriverInfo->CurrentUsageByType[ProfileMemoryIndex] -= AllocInfo->Size; - } - - RemoveEntryList (&AllocInfoData->Link); - - if (BasicAction == MemoryProfileActionFreePages) { - if (AllocInfo->Buffer != (PHYSICAL_ADDRESS) (UINTN) Buffer) { - CoreUpdateProfileAllocate ( - AllocInfo->CallerAddress, - AllocInfo->Action, - AllocInfo->MemoryType, - (UINTN) ((PHYSICAL_ADDRESS) (UINTN) Buffer - AllocInfo->Buffer), - (VOID *) (UINTN) AllocInfo->Buffer, - AllocInfoData->ActionString - ); - } - if (AllocInfo->Buffer + AllocInfo->Size != ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)) { - CoreUpdateProfileAllocate ( - AllocInfo->CallerAddress, - AllocInfo->Action, - AllocInfo->MemoryType, - (UINTN) ((AllocInfo->Buffer + AllocInfo->Size) - ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)), - (VOID *) ((UINTN) Buffer + Size), - AllocInfoData->ActionString - ); - } - } - - // - // Use CoreInternalFreePool() that will not update profile for this FreePool action. - // - CoreInternalFreePool (AllocInfoData, NULL); - } while (TRUE); -} - -/** - Update memory profile information. - - @param CallerAddress Address of caller who call Allocate or Free. - @param Action This Allocate or Free action. - @param MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param Size Buffer size. - @param Buffer Buffer address. - @param ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -CoreUpdateProfile ( - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ) -{ - EFI_STATUS Status; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_ACTION BasicAction; - - if (!IS_UEFI_MEMORY_PROFILE_ENABLED) { - return EFI_UNSUPPORTED; - } - - if (mMemoryProfileGettingStatus) { - return EFI_ACCESS_DENIED; - } - - if (!mMemoryProfileRecordingEnable) { - return EFI_ABORTED; - } - - // - // Get the basic action to know how to process the record - // - BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK; - - // - // EfiMaxMemoryType means the MemoryType is unknown. - // - if (MemoryType != EfiMaxMemoryType) { - // - // Only record limited MemoryType. - // - if (!CoreNeedRecordProfile (MemoryType)) { - return EFI_UNSUPPORTED; - } - } - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - CoreAcquireMemoryProfileLock (); - switch (BasicAction) { - case MemoryProfileActionAllocatePages: - Status = CoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer, ActionString); - break; - case MemoryProfileActionFreePages: - Status = CoreUpdateProfileFree (CallerAddress, Action, Size, Buffer); - break; - case MemoryProfileActionAllocatePool: - Status = CoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer, ActionString); - break; - case MemoryProfileActionFreePool: - Status = CoreUpdateProfileFree (CallerAddress, Action, 0, Buffer); - break; - default: - ASSERT (FALSE); - Status = EFI_UNSUPPORTED; - break; - } - CoreReleaseMemoryProfileLock (); - - return Status; -} - -//////////////////// - -/** - Get memory profile data size. - - @return Memory profile data size. - -**/ -UINTN -MemoryProfileGetDataSize ( - VOID - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - LIST_ENTRY *DriverInfoList; - LIST_ENTRY *DriverLink; - LIST_ENTRY *AllocInfoList; - LIST_ENTRY *AllocLink; - UINTN TotalSize; - - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return 0; - } - - TotalSize = sizeof (MEMORY_PROFILE_CONTEXT); - - DriverInfoList = ContextData->DriverInfoList; - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - TotalSize += DriverInfoData->DriverInfo.Header.Length; - - AllocInfoList = DriverInfoData->AllocInfoList; - for (AllocLink = AllocInfoList->ForwardLink; - AllocLink != AllocInfoList; - AllocLink = AllocLink->ForwardLink) { - AllocInfoData = CR ( - AllocLink, - MEMORY_PROFILE_ALLOC_INFO_DATA, - Link, - MEMORY_PROFILE_ALLOC_INFO_SIGNATURE - ); - TotalSize += AllocInfoData->AllocInfo.Header.Length; - } - } - - return TotalSize; -} - -/** - Copy memory profile data. - - @param ProfileBuffer The buffer to hold memory profile data. - -**/ -VOID -MemoryProfileCopyData ( - IN VOID *ProfileBuffer - ) -{ - MEMORY_PROFILE_CONTEXT *Context; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - LIST_ENTRY *DriverInfoList; - LIST_ENTRY *DriverLink; - LIST_ENTRY *AllocInfoList; - LIST_ENTRY *AllocLink; - UINTN PdbSize; - UINTN ActionStringSize; - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return ; - } - - Context = ProfileBuffer; - CopyMem (Context, &ContextData->Context, sizeof (MEMORY_PROFILE_CONTEXT)); - DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) (Context + 1); - - DriverInfoList = ContextData->DriverInfoList; - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - CopyMem (DriverInfo, &DriverInfoData->DriverInfo, sizeof (MEMORY_PROFILE_DRIVER_INFO)); - if (DriverInfo->PdbStringOffset != 0) { - PdbSize = AsciiStrSize (DriverInfoData->PdbString); - CopyMem ((VOID *) ((UINTN) DriverInfo + DriverInfo->PdbStringOffset), DriverInfoData->PdbString, PdbSize); - } - AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) DriverInfo + DriverInfo->Header.Length); - - AllocInfoList = DriverInfoData->AllocInfoList; - for (AllocLink = AllocInfoList->ForwardLink; - AllocLink != AllocInfoList; - AllocLink = AllocLink->ForwardLink) { - AllocInfoData = CR ( - AllocLink, - MEMORY_PROFILE_ALLOC_INFO_DATA, - Link, - MEMORY_PROFILE_ALLOC_INFO_SIGNATURE - ); - CopyMem (AllocInfo, &AllocInfoData->AllocInfo, sizeof (MEMORY_PROFILE_ALLOC_INFO)); - if (AllocInfo->ActionStringOffset != 0) { - ActionStringSize = AsciiStrSize (AllocInfoData->ActionString); - CopyMem ((VOID *) ((UINTN) AllocInfo + AllocInfo->ActionStringOffset), AllocInfoData->ActionString, ActionStringSize); - } - AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *) ((UINTN) AllocInfo + AllocInfo->Header.Length); - } - - DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) AllocInfo; - } -} - -/** - Get memory profile data. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer. - On return, points to the size of the data returned in ProfileBuffer. - @param[out] ProfileBuffer Profile buffer. - - @return EFI_SUCCESS Get the memory profile data successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data. - ProfileSize is updated with the size required. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolGetData ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN OUT UINT64 *ProfileSize, - OUT VOID *ProfileBuffer - ) -{ - UINTN Size; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - BOOLEAN MemoryProfileGettingStatus; - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - MemoryProfileGettingStatus = mMemoryProfileGettingStatus; - mMemoryProfileGettingStatus = TRUE; - - Size = MemoryProfileGetDataSize (); - - if (*ProfileSize < Size) { - *ProfileSize = Size; - mMemoryProfileGettingStatus = MemoryProfileGettingStatus; - return EFI_BUFFER_TOO_SMALL; - } - - *ProfileSize = Size; - MemoryProfileCopyData (ProfileBuffer); - - mMemoryProfileGettingStatus = MemoryProfileGettingStatus; - return EFI_SUCCESS; -} - -/** - Register image to memory profile. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in] FilePath File path of the image. - @param[in] ImageBase Image base address. - @param[in] ImageSize Image size. - @param[in] FileType File type of the image. - - @return EFI_SUCCESS Register successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCES No enough resource for this register. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolRegisterImage ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN EFI_FV_FILETYPE FileType - ) -{ - EFI_STATUS Status; - LOADED_IMAGE_PRIVATE_DATA DriverEntry; - VOID *EntryPointInImage; - - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - DriverEntry.Info.FilePath = FilePath; - DriverEntry.ImageContext.ImageAddress = ImageBase; - DriverEntry.ImageContext.ImageSize = ImageSize; - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageContext.EntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage; - DriverEntry.ImageContext.ImageType = InternalPeCoffGetSubsystem ((VOID *) (UINTN) ImageBase); - - return RegisterMemoryProfileImage (&DriverEntry, FileType); -} - -/** - Unregister image from memory profile. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in] FilePath File path of the image. - @param[in] ImageBase Image base address. - @param[in] ImageSize Image size. - - @return EFI_SUCCESS Unregister successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_NOT_FOUND The image is not found. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolUnregisterImage ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize - ) -{ - EFI_STATUS Status; - LOADED_IMAGE_PRIVATE_DATA DriverEntry; - VOID *EntryPointInImage; - - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - DriverEntry.Info.FilePath = FilePath; - DriverEntry.ImageContext.ImageAddress = ImageBase; - DriverEntry.ImageContext.ImageSize = ImageSize; - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageContext.EntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage; - - return UnregisterMemoryProfileImage (&DriverEntry); -} - -/** - Get memory profile recording state. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[out] RecordingState Recording state. - - @return EFI_SUCCESS Memory profile recording state is returned. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_INVALID_PARAMETER RecordingState is NULL. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolGetRecordingState ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - OUT BOOLEAN *RecordingState - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - if (RecordingState == NULL) { - return EFI_INVALID_PARAMETER; - } - *RecordingState = mMemoryProfileRecordingEnable; - return EFI_SUCCESS; -} - -/** - Set memory profile recording state. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in] RecordingState Recording state. - - @return EFI_SUCCESS Set memory profile recording state successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolSetRecordingState ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN BOOLEAN RecordingState - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - - ContextData = GetMemoryProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - mMemoryProfileRecordingEnable = RecordingState; - return EFI_SUCCESS; -} - -/** - Record memory profile of multilevel caller. - - @param[in] This The EDKII_MEMORY_PROFILE_PROTOCOL instance. - @param[in] CallerAddress Address of caller. - @param[in] Action Memory profile action. - @param[in] MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param[in] Buffer Buffer address. - @param[in] Size Buffer size. - @param[in] ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -ProfileProtocolRecord ( - IN EDKII_MEMORY_PROFILE_PROTOCOL *This, - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN VOID *Buffer, - IN UINTN Size, - IN CHAR8 *ActionString OPTIONAL - ) -{ - return CoreUpdateProfile (CallerAddress, Action, MemoryType, Size, Buffer, ActionString); -} - -//////////////////// diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c deleted file mode 100644 index 3b3b9a8131..0000000000 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ /dev/null @@ -1,1977 +0,0 @@ -/** @file - UEFI Memory page management functions. - -Copyright (c) 2007 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Imem.h" - -// -// Entry for tracking the memory regions for each memory type to coalesce similar memory types -// -typedef struct { - EFI_PHYSICAL_ADDRESS BaseAddress; - EFI_PHYSICAL_ADDRESS MaximumAddress; - UINT64 CurrentNumberOfPages; - UINT64 NumberOfPages; - UINTN InformationIndex; - BOOLEAN Special; - BOOLEAN Runtime; -} EFI_MEMORY_TYPE_STATISTICS; - -// -// MemoryMap - The current memory map -// -UINTN mMemoryMapKey = 0; - -#define MAX_MAP_DEPTH 6 - -/// -/// mMapDepth - depth of new descriptor stack -/// -UINTN mMapDepth = 0; -/// -/// mMapStack - space to use as temp storage to build new map descriptors -/// -MEMORY_MAP mMapStack[MAX_MAP_DEPTH]; -UINTN mFreeMapStack = 0; -/// -/// This list maintain the free memory map list -/// -LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemoryMapEntryList); -BOOLEAN mMemoryTypeInformationInitialized = FALSE; - -EFI_MEMORY_TYPE_STATISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = { - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiReservedMemoryType - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiLoaderCode - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiLoaderData - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiBootServicesCode - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiBootServicesData - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiRuntimeServicesCode - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiRuntimeServicesData - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiConventionalMemory - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiUnusableMemory - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiACPIReclaimMemory - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiACPIMemoryNVS - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIO - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIOPortSpace - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiPalCode - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiPersistentMemory - { 0, MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE } // EfiMaxMemoryType -}; - -EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = MAX_ADDRESS; -EFI_PHYSICAL_ADDRESS mDefaultBaseAddress = MAX_ADDRESS; - -EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = { - { EfiReservedMemoryType, 0 }, - { EfiLoaderCode, 0 }, - { EfiLoaderData, 0 }, - { EfiBootServicesCode, 0 }, - { EfiBootServicesData, 0 }, - { EfiRuntimeServicesCode, 0 }, - { EfiRuntimeServicesData, 0 }, - { EfiConventionalMemory, 0 }, - { EfiUnusableMemory, 0 }, - { EfiACPIReclaimMemory, 0 }, - { EfiACPIMemoryNVS, 0 }, - { EfiMemoryMappedIO, 0 }, - { EfiMemoryMappedIOPortSpace, 0 }, - { EfiPalCode, 0 }, - { EfiPersistentMemory, 0 }, - { EfiMaxMemoryType, 0 } -}; -// -// Only used when load module at fixed address feature is enabled. True means the memory is alreay successfully allocated -// and ready to load the module in to specified address.or else, the memory is not ready and module will be loaded at a -// address assigned by DXE core. -// -GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN gLoadFixedAddressCodeMemoryReady = FALSE; - -/** - Enter critical section by gaining lock on gMemoryLock. - -**/ -VOID -CoreAcquireMemoryLock ( - VOID - ) -{ - CoreAcquireLock (&gMemoryLock); -} - - - -/** - Exit critical section by releasing lock on gMemoryLock. - -**/ -VOID -CoreReleaseMemoryLock ( - VOID - ) -{ - CoreReleaseLock (&gMemoryLock); -} - - - - -/** - Internal function. Removes a descriptor entry. - - @param Entry The entry to remove - -**/ -VOID -RemoveMemoryMapEntry ( - IN OUT MEMORY_MAP *Entry - ) -{ - RemoveEntryList (&Entry->Link); - Entry->Link.ForwardLink = NULL; - - if (Entry->FromPages) { - // - // Insert the free memory map descriptor to the end of mFreeMemoryMapEntryList - // - InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link); - } -} - -/** - Internal function. Adds a ranges to the memory map. - The range must not already exist in the map. - - @param Type The type of memory range to add - @param Start The starting address in the memory range Must be - paged aligned - @param End The last address in the range Must be the last - byte of a page - @param Attribute The attributes of the memory range to add - -**/ -VOID -CoreAddRange ( - IN EFI_MEMORY_TYPE Type, - IN EFI_PHYSICAL_ADDRESS Start, - IN EFI_PHYSICAL_ADDRESS End, - IN UINT64 Attribute - ) -{ - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - - ASSERT ((Start & EFI_PAGE_MASK) == 0); - ASSERT (End > Start) ; - - ASSERT_LOCKED (&gMemoryLock); - - DEBUG ((DEBUG_PAGE, "AddRange: %lx-%lx to %d\n", Start, End, Type)); - - // - // If memory of type EfiConventionalMemory is being added that includes the page - // starting at address 0, then zero the page starting at address 0. This has - // two benifits. It helps find NULL pointer bugs and it also maximizes - // compatibility with operating systems that may evaluate memory in this page - // for legacy data structures. If memory of any other type is added starting - // at address 0, then do not zero the page at address 0 because the page is being - // used for other purposes. - // - if (Type == EfiConventionalMemory && Start == 0 && (End >= EFI_PAGE_SIZE - 1)) { - SetMem ((VOID *)(UINTN)Start, EFI_PAGE_SIZE, 0); - } - - // - // Memory map being altered so updated key - // - mMemoryMapKey += 1; - - // - // UEFI 2.0 added an event group for notificaiton on memory map changes. - // So we need to signal this Event Group every time the memory map changes. - // If we are in EFI 1.10 compatability mode no event groups will be - // found and nothing will happen we we call this function. These events - // will get signaled but since a lock is held around the call to this - // function the notificaiton events will only be called after this function - // returns and the lock is released. - // - CoreNotifySignalList (&gEfiEventMemoryMapChangeGuid); - - // - // Look for adjoining memory descriptor - // - - // Two memory descriptors can only be merged if they have the same Type - // and the same Attribute - // - - Link = gMemoryMap.ForwardLink; - while (Link != &gMemoryMap) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - Link = Link->ForwardLink; - - if (Entry->Type != Type) { - continue; - } - - if (Entry->Attribute != Attribute) { - continue; - } - - if (Entry->End + 1 == Start) { - - Start = Entry->Start; - RemoveMemoryMapEntry (Entry); - - } else if (Entry->Start == End + 1) { - - End = Entry->End; - RemoveMemoryMapEntry (Entry); - } - } - - // - // Add descriptor - // - - mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE; - mMapStack[mMapDepth].FromPages = FALSE; - mMapStack[mMapDepth].Type = Type; - mMapStack[mMapDepth].Start = Start; - mMapStack[mMapDepth].End = End; - mMapStack[mMapDepth].VirtualStart = 0; - mMapStack[mMapDepth].Attribute = Attribute; - InsertTailList (&gMemoryMap, &mMapStack[mMapDepth].Link); - - mMapDepth += 1; - ASSERT (mMapDepth < MAX_MAP_DEPTH); - - return ; -} - -/** - Internal function. Deque a descriptor entry from the mFreeMemoryMapEntryList. - If the list is emtry, then allocate a new page to refuel the list. - Please Note this algorithm to allocate the memory map descriptor has a property - that the memory allocated for memory entries always grows, and will never really be freed - For example, if the current boot uses 2000 memory map entries at the maximum point, but - ends up with only 50 at the time the OS is booted, then the memory associated with the 1950 - memory map entries is still allocated from EfiBootServicesMemory. - - - @return The Memory map descriptor dequed from the mFreeMemoryMapEntryList - -**/ -MEMORY_MAP * -AllocateMemoryMapEntry ( - VOID - ) -{ - MEMORY_MAP* FreeDescriptorEntries; - MEMORY_MAP* Entry; - UINTN Index; - - if (IsListEmpty (&mFreeMemoryMapEntryList)) { - // - // The list is empty, to allocate one page to refuel the list - // - FreeDescriptorEntries = CoreAllocatePoolPages (EfiBootServicesData, - EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION_GRANULARITY), - DEFAULT_PAGE_ALLOCATION_GRANULARITY); - if (FreeDescriptorEntries != NULL) { - // - // Enque the free memmory map entries into the list - // - for (Index = 0; Index < DEFAULT_PAGE_ALLOCATION_GRANULARITY / sizeof(MEMORY_MAP); Index++) { - FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE; - InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link); - } - } else { - return NULL; - } - } - // - // dequeue the first descriptor from the list - // - Entry = CR (mFreeMemoryMapEntryList.ForwardLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - RemoveEntryList (&Entry->Link); - - return Entry; -} - - -/** - Internal function. Moves any memory descriptors that are on the - temporary descriptor stack to heap. - -**/ -VOID -CoreFreeMemoryMapStack ( - VOID - ) -{ - MEMORY_MAP *Entry; - MEMORY_MAP *Entry2; - LIST_ENTRY *Link2; - - ASSERT_LOCKED (&gMemoryLock); - - // - // If already freeing the map stack, then return - // - if (mFreeMapStack != 0) { - return ; - } - - // - // Move the temporary memory descriptor stack into pool - // - mFreeMapStack += 1; - - while (mMapDepth != 0) { - // - // Deque an memory map entry from mFreeMemoryMapEntryList - // - Entry = AllocateMemoryMapEntry (); - - ASSERT (Entry); - - // - // Update to proper entry - // - mMapDepth -= 1; - - if (mMapStack[mMapDepth].Link.ForwardLink != NULL) { - - // - // Move this entry to general memory - // - RemoveEntryList (&mMapStack[mMapDepth].Link); - mMapStack[mMapDepth].Link.ForwardLink = NULL; - - CopyMem (Entry , &mMapStack[mMapDepth], sizeof (MEMORY_MAP)); - Entry->FromPages = TRUE; - - // - // Find insertion location - // - for (Link2 = gMemoryMap.ForwardLink; Link2 != &gMemoryMap; Link2 = Link2->ForwardLink) { - Entry2 = CR (Link2, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - if (Entry2->FromPages && Entry2->Start > Entry->Start) { - break; - } - } - - InsertTailList (Link2, &Entry->Link); - - } else { - // - // This item of mMapStack[mMapDepth] has already been dequeued from gMemoryMap list, - // so here no need to move it to memory. - // - InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link); - } - } - - mFreeMapStack -= 1; -} - -/** - Find untested but initialized memory regions in GCD map and convert them to be DXE allocatable. - -**/ -BOOLEAN -PromoteMemoryResource ( - VOID - ) -{ - LIST_ENTRY *Link; - EFI_GCD_MAP_ENTRY *Entry; - BOOLEAN Promoted; - - DEBUG ((DEBUG_PAGE, "Promote the memory resource\n")); - - CoreAcquireGcdMemoryLock (); - - Promoted = FALSE; - Link = mGcdMemorySpaceMap.ForwardLink; - while (Link != &mGcdMemorySpaceMap) { - - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - - if (Entry->GcdMemoryType == EfiGcdMemoryTypeReserved && - Entry->EndAddress < MAX_ADDRESS && - (Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == - (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) { - // - // Update the GCD map - // - if ((Entry->Capabilities & EFI_MEMORY_MORE_RELIABLE) == EFI_MEMORY_MORE_RELIABLE) { - Entry->GcdMemoryType = EfiGcdMemoryTypeMoreReliable; - } else { - Entry->GcdMemoryType = EfiGcdMemoryTypeSystemMemory; - } - Entry->Capabilities |= EFI_MEMORY_TESTED; - Entry->ImageHandle = gDxeCoreImageHandle; - Entry->DeviceHandle = NULL; - - // - // Add to allocable system memory resource - // - - CoreAddRange ( - EfiConventionalMemory, - Entry->BaseAddress, - Entry->EndAddress, - Entry->Capabilities & ~(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME) - ); - CoreFreeMemoryMapStack (); - - Promoted = TRUE; - } - - Link = Link->ForwardLink; - } - - CoreReleaseGcdMemoryLock (); - - return Promoted; -} -/** - This function try to allocate Runtime code & Boot time code memory range. If LMFA enabled, 2 patchable PCD - PcdLoadFixAddressRuntimeCodePageNumber & PcdLoadFixAddressBootTimeCodePageNumber which are set by tools will record the - size of boot time and runtime code. - -**/ -VOID -CoreLoadingFixedAddressHook ( - VOID - ) -{ - UINT32 RuntimeCodePageNumber; - UINT32 BootTimeCodePageNumber; - EFI_PHYSICAL_ADDRESS RuntimeCodeBase; - EFI_PHYSICAL_ADDRESS BootTimeCodeBase; - EFI_STATUS Status; - - // - // Make sure these 2 areas are not initialzied. - // - if (!gLoadFixedAddressCodeMemoryReady) { - RuntimeCodePageNumber = PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber); - BootTimeCodePageNumber= PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber); - RuntimeCodeBase = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressConfigurationTable.DxeCodeTopAddress - EFI_PAGES_TO_SIZE (RuntimeCodePageNumber)); - BootTimeCodeBase = (EFI_PHYSICAL_ADDRESS)(RuntimeCodeBase - EFI_PAGES_TO_SIZE (BootTimeCodePageNumber)); - // - // Try to allocate runtime memory. - // - Status = CoreAllocatePages ( - AllocateAddress, - EfiRuntimeServicesCode, - RuntimeCodePageNumber, - &RuntimeCodeBase - ); - if (EFI_ERROR(Status)) { - // - // Runtime memory allocation failed - // - return; - } - // - // Try to allocate boot memory. - // - Status = CoreAllocatePages ( - AllocateAddress, - EfiBootServicesCode, - BootTimeCodePageNumber, - &BootTimeCodeBase - ); - if (EFI_ERROR(Status)) { - // - // boot memory allocation failed. Free Runtime code range and will try the allocation again when - // new memory range is installed. - // - CoreFreePages ( - RuntimeCodeBase, - RuntimeCodePageNumber - ); - return; - } - gLoadFixedAddressCodeMemoryReady = TRUE; - } - return; -} - -/** - Called to initialize the memory map and add descriptors to - the current descriptor list. - The first descriptor that is added must be general usable - memory as the addition allocates heap. - - @param Type The type of memory to add - @param Start The starting address in the memory range Must be - page aligned - @param NumberOfPages The number of pages in the range - @param Attribute Attributes of the memory to add - - @return None. The range is added to the memory map - -**/ -VOID -CoreAddMemoryDescriptor ( - IN EFI_MEMORY_TYPE Type, - IN EFI_PHYSICAL_ADDRESS Start, - IN UINT64 NumberOfPages, - IN UINT64 Attribute - ) -{ - EFI_PHYSICAL_ADDRESS End; - EFI_STATUS Status; - UINTN Index; - UINTN FreeIndex; - - if ((Start & EFI_PAGE_MASK) != 0) { - return; - } - - if (Type >= EfiMaxMemoryType && Type < MEMORY_TYPE_OEM_RESERVED_MIN) { - return; - } - CoreAcquireMemoryLock (); - End = Start + LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT) - 1; - CoreAddRange (Type, Start, End, Attribute); - CoreFreeMemoryMapStack (); - CoreReleaseMemoryLock (); - - ApplyMemoryProtectionPolicy (EfiMaxMemoryType, Type, Start, - LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT)); - - // - // If Loading Module At Fixed Address feature is enabled. try to allocate memory with Runtime code & Boot time code type - // - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { - CoreLoadingFixedAddressHook(); - } - - // - // Check to see if the statistics for the different memory types have already been established - // - if (mMemoryTypeInformationInitialized) { - return; - } - - - // - // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array - // - for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { - // - // Make sure the memory type in the gMemoryTypeInformation[] array is valid - // - Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[Index].Type); - if ((UINT32)Type > EfiMaxMemoryType) { - continue; - } - if (gMemoryTypeInformation[Index].NumberOfPages != 0) { - // - // Allocate pages for the current memory type from the top of available memory - // - Status = CoreAllocatePages ( - AllocateAnyPages, - Type, - gMemoryTypeInformation[Index].NumberOfPages, - &mMemoryTypeStatistics[Type].BaseAddress - ); - if (EFI_ERROR (Status)) { - // - // If an error occurs allocating the pages for the current memory type, then - // free all the pages allocates for the previous memory types and return. This - // operation with be retied when/if more memory is added to the system - // - for (FreeIndex = 0; FreeIndex < Index; FreeIndex++) { - // - // Make sure the memory type in the gMemoryTypeInformation[] array is valid - // - Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[FreeIndex].Type); - if ((UINT32)Type > EfiMaxMemoryType) { - continue; - } - - if (gMemoryTypeInformation[FreeIndex].NumberOfPages != 0) { - CoreFreePages ( - mMemoryTypeStatistics[Type].BaseAddress, - gMemoryTypeInformation[FreeIndex].NumberOfPages - ); - mMemoryTypeStatistics[Type].BaseAddress = 0; - mMemoryTypeStatistics[Type].MaximumAddress = MAX_ADDRESS; - } - } - return; - } - - // - // Compute the address at the top of the current statistics - // - mMemoryTypeStatistics[Type].MaximumAddress = - mMemoryTypeStatistics[Type].BaseAddress + - LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, EFI_PAGE_SHIFT) - 1; - - // - // If the current base address is the lowest address so far, then update the default - // maximum address - // - if (mMemoryTypeStatistics[Type].BaseAddress < mDefaultMaximumAddress) { - mDefaultMaximumAddress = mMemoryTypeStatistics[Type].BaseAddress - 1; - } - } - } - - // - // There was enough system memory for all the the memory types were allocated. So, - // those memory areas can be freed for future allocations, and all future memory - // allocations can occur within their respective bins - // - for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { - // - // Make sure the memory type in the gMemoryTypeInformation[] array is valid - // - Type = (EFI_MEMORY_TYPE) (gMemoryTypeInformation[Index].Type); - if ((UINT32)Type > EfiMaxMemoryType) { - continue; - } - if (gMemoryTypeInformation[Index].NumberOfPages != 0) { - CoreFreePages ( - mMemoryTypeStatistics[Type].BaseAddress, - gMemoryTypeInformation[Index].NumberOfPages - ); - mMemoryTypeStatistics[Type].NumberOfPages = gMemoryTypeInformation[Index].NumberOfPages; - gMemoryTypeInformation[Index].NumberOfPages = 0; - } - } - - // - // If the number of pages reserved for a memory type is 0, then all allocations for that type - // should be in the default range. - // - for (Type = (EFI_MEMORY_TYPE) 0; Type < EfiMaxMemoryType; Type++) { - for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { - if (Type == (EFI_MEMORY_TYPE)gMemoryTypeInformation[Index].Type) { - mMemoryTypeStatistics[Type].InformationIndex = Index; - } - } - mMemoryTypeStatistics[Type].CurrentNumberOfPages = 0; - if (mMemoryTypeStatistics[Type].MaximumAddress == MAX_ADDRESS) { - mMemoryTypeStatistics[Type].MaximumAddress = mDefaultMaximumAddress; - } - } - - mMemoryTypeInformationInitialized = TRUE; -} - - -/** - Internal function. Converts a memory range to the specified type or attributes. - The range must exist in the memory map. Either ChangingType or - ChangingAttributes must be set, but not both. - - @param Start The first address of the range Must be page - aligned - @param NumberOfPages The number of pages to convert - @param ChangingType Boolean indicating that type value should be changed - @param NewType The new type for the memory range - @param ChangingAttributes Boolean indicating that attributes value should be changed - @param NewAttributes The new attributes for the memory range - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Could not find a descriptor cover the specified - range or convertion not allowed. - @retval EFI_SUCCESS Successfully converts the memory range to the - specified type. - -**/ -EFI_STATUS -CoreConvertPagesEx ( - IN UINT64 Start, - IN UINT64 NumberOfPages, - IN BOOLEAN ChangingType, - IN EFI_MEMORY_TYPE NewType, - IN BOOLEAN ChangingAttributes, - IN UINT64 NewAttributes - ) -{ - - UINT64 NumberOfBytes; - UINT64 End; - UINT64 RangeEnd; - UINT64 Attribute; - EFI_MEMORY_TYPE MemType; - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - - Entry = NULL; - NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT); - End = Start + NumberOfBytes - 1; - - ASSERT (NumberOfPages); - ASSERT ((Start & EFI_PAGE_MASK) == 0); - ASSERT (End > Start) ; - ASSERT_LOCKED (&gMemoryLock); - ASSERT ( (ChangingType == FALSE) || (ChangingAttributes == FALSE) ); - - if (NumberOfPages == 0 || ((Start & EFI_PAGE_MASK) != 0) || (Start >= End)) { - return EFI_INVALID_PARAMETER; - } - - // - // Convert the entire range - // - - while (Start < End) { - - // - // Find the entry that the covers the range - // - for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - - if (Entry->Start <= Start && Entry->End > Start) { - break; - } - } - - if (Link == &gMemoryMap) { - DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "ConvertPages: failed to find range %lx - %lx\n", Start, End)); - return EFI_NOT_FOUND; - } - - // - // If we are converting the type of the range from EfiConventionalMemory to - // another type, we have to ensure that the entire range is covered by a - // single entry. - // - if (ChangingType && (NewType != EfiConventionalMemory)) { - if (Entry->End < End) { - DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "ConvertPages: range %lx - %lx covers multiple entries\n", Start, End)); - return EFI_NOT_FOUND; - } - } - // - // Convert range to the end, or to the end of the descriptor - // if that's all we've got - // - RangeEnd = End; - - ASSERT (Entry != NULL); - if (Entry->End < End) { - RangeEnd = Entry->End; - } - - if (ChangingType) { - DEBUG ((DEBUG_PAGE, "ConvertRange: %lx-%lx to type %d\n", Start, RangeEnd, NewType)); - } - if (ChangingAttributes) { - DEBUG ((DEBUG_PAGE, "ConvertRange: %lx-%lx to attr %lx\n", Start, RangeEnd, NewAttributes)); - } - - if (ChangingType) { - // - // Debug code - verify conversion is allowed - // - if (!(NewType == EfiConventionalMemory ? 1 : 0) ^ (Entry->Type == EfiConventionalMemory ? 1 : 0)) { - DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "ConvertPages: Incompatible memory types\n")); - return EFI_NOT_FOUND; - } - - // - // Update counters for the number of pages allocated to each memory type - // - if ((UINT32)Entry->Type < EfiMaxMemoryType) { - if ((Start >= mMemoryTypeStatistics[Entry->Type].BaseAddress && Start <= mMemoryTypeStatistics[Entry->Type].MaximumAddress) || - (Start >= mDefaultBaseAddress && Start <= mDefaultMaximumAddress) ) { - if (NumberOfPages > mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages) { - mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages = 0; - } else { - mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages -= NumberOfPages; - } - } - } - - if ((UINT32)NewType < EfiMaxMemoryType) { - if ((Start >= mMemoryTypeStatistics[NewType].BaseAddress && Start <= mMemoryTypeStatistics[NewType].MaximumAddress) || - (Start >= mDefaultBaseAddress && Start <= mDefaultMaximumAddress) ) { - mMemoryTypeStatistics[NewType].CurrentNumberOfPages += NumberOfPages; - if (mMemoryTypeStatistics[NewType].CurrentNumberOfPages > gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages) { - gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages = (UINT32)mMemoryTypeStatistics[NewType].CurrentNumberOfPages; - } - } - } - } - - // - // Pull range out of descriptor - // - if (Entry->Start == Start) { - - // - // Clip start - // - Entry->Start = RangeEnd + 1; - - } else if (Entry->End == RangeEnd) { - - // - // Clip end - // - Entry->End = Start - 1; - - } else { - - // - // Pull it out of the center, clip current - // - - // - // Add a new one - // - mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE; - mMapStack[mMapDepth].FromPages = FALSE; - mMapStack[mMapDepth].Type = Entry->Type; - mMapStack[mMapDepth].Start = RangeEnd+1; - mMapStack[mMapDepth].End = Entry->End; - - // - // Inherit Attribute from the Memory Descriptor that is being clipped - // - mMapStack[mMapDepth].Attribute = Entry->Attribute; - - Entry->End = Start - 1; - ASSERT (Entry->Start < Entry->End); - - Entry = &mMapStack[mMapDepth]; - InsertTailList (&gMemoryMap, &Entry->Link); - - mMapDepth += 1; - ASSERT (mMapDepth < MAX_MAP_DEPTH); - } - - // - // The new range inherits the same Attribute as the Entry - // it is being cut out of unless attributes are being changed - // - if (ChangingType) { - Attribute = Entry->Attribute; - MemType = NewType; - } else { - Attribute = NewAttributes; - MemType = Entry->Type; - } - - // - // If the descriptor is empty, then remove it from the map - // - if (Entry->Start == Entry->End + 1) { - RemoveMemoryMapEntry (Entry); - Entry = NULL; - } - - // - // Add our new range in - // - CoreAddRange (MemType, Start, RangeEnd, Attribute); - if (ChangingType && (MemType == EfiConventionalMemory)) { - // - // Avoid calling DEBUG_CLEAR_MEMORY() for an address of 0 because this - // macro will ASSERT() if address is 0. Instead, CoreAddRange() guarantees - // that the page starting at address 0 is always filled with zeros. - // - if (Start == 0) { - if (RangeEnd > EFI_PAGE_SIZE) { - DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) EFI_PAGE_SIZE, (UINTN) (RangeEnd - EFI_PAGE_SIZE + 1)); - } - } else { - DEBUG_CLEAR_MEMORY ((VOID *)(UINTN) Start, (UINTN) (RangeEnd - Start + 1)); - } - } - - // - // Move any map descriptor stack to general pool - // - CoreFreeMemoryMapStack (); - - // - // Bump the starting address, and convert the next range - // - Start = RangeEnd + 1; - } - - // - // Converted the whole range, done - // - - return EFI_SUCCESS; -} - - -/** - Internal function. Converts a memory range to the specified type. - The range must exist in the memory map. - - @param Start The first address of the range Must be page - aligned - @param NumberOfPages The number of pages to convert - @param NewType The new type for the memory range - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Could not find a descriptor cover the specified - range or convertion not allowed. - @retval EFI_SUCCESS Successfully converts the memory range to the - specified type. - -**/ -EFI_STATUS -CoreConvertPages ( - IN UINT64 Start, - IN UINT64 NumberOfPages, - IN EFI_MEMORY_TYPE NewType - ) -{ - return CoreConvertPagesEx(Start, NumberOfPages, TRUE, NewType, FALSE, 0); -} - - -/** - Internal function. Converts a memory range to use new attributes. - - @param Start The first address of the range Must be page - aligned - @param NumberOfPages The number of pages to convert - @param NewAttributes The new attributes value for the range. - -**/ -VOID -CoreUpdateMemoryAttributes ( - IN EFI_PHYSICAL_ADDRESS Start, - IN UINT64 NumberOfPages, - IN UINT64 NewAttributes - ) -{ - CoreAcquireMemoryLock (); - - // - // Update the attributes to the new value - // - CoreConvertPagesEx(Start, NumberOfPages, FALSE, (EFI_MEMORY_TYPE)0, TRUE, NewAttributes); - - CoreReleaseMemoryLock (); -} - - -/** - Internal function. Finds a consecutive free page range below - the requested address. - - @param MaxAddress The address that the range must be below - @param MinAddress The address that the range must be above - @param NumberOfPages Number of pages needed - @param NewType The type of memory the range is going to be - turned into - @param Alignment Bits to align with - - @return The base address of the range, or 0 if the range was not found - -**/ -UINT64 -CoreFindFreePagesI ( - IN UINT64 MaxAddress, - IN UINT64 MinAddress, - IN UINT64 NumberOfPages, - IN EFI_MEMORY_TYPE NewType, - IN UINTN Alignment - ) -{ - UINT64 NumberOfBytes; - UINT64 Target; - UINT64 DescStart; - UINT64 DescEnd; - UINT64 DescNumberOfBytes; - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - - if ((MaxAddress < EFI_PAGE_MASK) ||(NumberOfPages == 0)) { - return 0; - } - - if ((MaxAddress & EFI_PAGE_MASK) != EFI_PAGE_MASK) { - - // - // If MaxAddress is not aligned to the end of a page - // - - // - // Change MaxAddress to be 1 page lower - // - MaxAddress -= (EFI_PAGE_MASK + 1); - - // - // Set MaxAddress to a page boundary - // - MaxAddress &= ~(UINT64)EFI_PAGE_MASK; - - // - // Set MaxAddress to end of the page - // - MaxAddress |= EFI_PAGE_MASK; - } - - NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT); - Target = 0; - - for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - - // - // If it's not a free entry, don't bother with it - // - if (Entry->Type != EfiConventionalMemory) { - continue; - } - - DescStart = Entry->Start; - DescEnd = Entry->End; - - // - // If desc is past max allowed address or below min allowed address, skip it - // - if ((DescStart >= MaxAddress) || (DescEnd < MinAddress)) { - continue; - } - - // - // If desc ends past max allowed address, clip the end - // - if (DescEnd >= MaxAddress) { - DescEnd = MaxAddress; - } - - DescEnd = ((DescEnd + 1) & (~(Alignment - 1))) - 1; - - // Skip if DescEnd is less than DescStart after alignment clipping - if (DescEnd < DescStart) { - continue; - } - - // - // Compute the number of bytes we can used from this - // descriptor, and see it's enough to satisfy the request - // - DescNumberOfBytes = DescEnd - DescStart + 1; - - if (DescNumberOfBytes >= NumberOfBytes) { - // - // If the start of the allocated range is below the min address allowed, skip it - // - if ((DescEnd - NumberOfBytes + 1) < MinAddress) { - continue; - } - - // - // If this is the best match so far remember it - // - if (DescEnd > Target) { - Target = DescEnd; - } - } - } - - // - // If this is a grow down, adjust target to be the allocation base - // - Target -= NumberOfBytes - 1; - - // - // If we didn't find a match, return 0 - // - if ((Target & EFI_PAGE_MASK) != 0) { - return 0; - } - - return Target; -} - - -/** - Internal function. Finds a consecutive free page range below - the requested address - - @param MaxAddress The address that the range must be below - @param NoPages Number of pages needed - @param NewType The type of memory the range is going to be - turned into - @param Alignment Bits to align with - - @return The base address of the range, or 0 if the range was not found. - -**/ -UINT64 -FindFreePages ( - IN UINT64 MaxAddress, - IN UINT64 NoPages, - IN EFI_MEMORY_TYPE NewType, - IN UINTN Alignment - ) -{ - UINT64 Start; - - // - // Attempt to find free pages in the preferred bin based on the requested memory type - // - if ((UINT32)NewType < EfiMaxMemoryType && MaxAddress >= mMemoryTypeStatistics[NewType].MaximumAddress) { - Start = CoreFindFreePagesI ( - mMemoryTypeStatistics[NewType].MaximumAddress, - mMemoryTypeStatistics[NewType].BaseAddress, - NoPages, - NewType, - Alignment - ); - if (Start != 0) { - return Start; - } - } - - // - // Attempt to find free pages in the default allocation bin - // - if (MaxAddress >= mDefaultMaximumAddress) { - Start = CoreFindFreePagesI (mDefaultMaximumAddress, 0, NoPages, NewType, Alignment); - if (Start != 0) { - if (Start < mDefaultBaseAddress) { - mDefaultBaseAddress = Start; - } - return Start; - } - } - - // - // The allocation did not succeed in any of the prefered bins even after - // promoting resources. Attempt to find free pages anywhere is the requested - // address range. If this allocation fails, then there are not enough - // resources anywhere to satisfy the request. - // - Start = CoreFindFreePagesI (MaxAddress, 0, NoPages, NewType, Alignment); - if (Start != 0) { - return Start; - } - - // - // If allocations from the preferred bins fail, then attempt to promote memory resources. - // - if (!PromoteMemoryResource ()) { - return 0; - } - - // - // If any memory resources were promoted, then re-attempt the allocation - // - return FindFreePages (MaxAddress, NoPages, NewType, Alignment); -} - - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform - @param MemoryType The type of memory to turn the allocated pages - into - @param NumberOfPages The number of pages to allocate - @param Memory A pointer to receive the base allocated memory - address - - @return Status. On success, Memory is filled in with the base address allocated - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in - spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreInternalAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - IN OUT EFI_PHYSICAL_ADDRESS *Memory - ) -{ - EFI_STATUS Status; - UINT64 Start; - UINT64 NumberOfBytes; - UINT64 End; - UINT64 MaxAddress; - UINTN Alignment; - - if ((UINT32)Type >= MaxAllocateType) { - return EFI_INVALID_PARAMETER; - } - - if ((MemoryType >= EfiMaxMemoryType && MemoryType < MEMORY_TYPE_OEM_RESERVED_MIN) || - (MemoryType == EfiConventionalMemory) || (MemoryType == EfiPersistentMemory)) { - return EFI_INVALID_PARAMETER; - } - - if (Memory == NULL) { - return EFI_INVALID_PARAMETER; - } - - Alignment = DEFAULT_PAGE_ALLOCATION_GRANULARITY; - - if (MemoryType == EfiACPIReclaimMemory || - MemoryType == EfiACPIMemoryNVS || - MemoryType == EfiRuntimeServicesCode || - MemoryType == EfiRuntimeServicesData) { - - Alignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - } - - if (Type == AllocateAddress) { - if ((*Memory & (Alignment - 1)) != 0) { - return EFI_NOT_FOUND; - } - } - - NumberOfPages += EFI_SIZE_TO_PAGES (Alignment) - 1; - NumberOfPages &= ~(EFI_SIZE_TO_PAGES (Alignment) - 1); - - // - // If this is for below a particular address, then - // - Start = *Memory; - - // - // The max address is the max natively addressable address for the processor - // - MaxAddress = MAX_ADDRESS; - - // - // Check for Type AllocateAddress, - // if NumberOfPages is 0 or - // if (NumberOfPages << EFI_PAGE_SHIFT) is above MAX_ADDRESS or - // if (Start + NumberOfBytes) rolls over 0 or - // if Start is above MAX_ADDRESS or - // if End is above MAX_ADDRESS, - // return EFI_NOT_FOUND. - // - if (Type == AllocateAddress) { - if ((NumberOfPages == 0) || - (NumberOfPages > RShiftU64 (MaxAddress, EFI_PAGE_SHIFT))) { - return EFI_NOT_FOUND; - } - NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT); - End = Start + NumberOfBytes - 1; - - if ((Start >= End) || - (Start > MaxAddress) || - (End > MaxAddress)) { - return EFI_NOT_FOUND; - } - } - - if (Type == AllocateMaxAddress) { - MaxAddress = Start; - } - - CoreAcquireMemoryLock (); - - // - // If not a specific address, then find an address to allocate - // - if (Type != AllocateAddress) { - Start = FindFreePages (MaxAddress, NumberOfPages, MemoryType, Alignment); - if (Start == 0) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - } - - // - // Convert pages from FreeMemory to the requested type - // - Status = CoreConvertPages (Start, NumberOfPages, MemoryType); - -Done: - CoreReleaseMemoryLock (); - - if (!EFI_ERROR (Status)) { - *Memory = Start; - } - - return Status; -} - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform - @param MemoryType The type of memory to turn the allocated pages - into - @param NumberOfPages The number of pages to allocate - @param Memory A pointer to receive the base allocated memory - address - - @return Status. On success, Memory is filled in with the base address allocated - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in - spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory - ) -{ - EFI_STATUS Status; - - Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory); - if (!EFI_ERROR (Status)) { - CoreUpdateProfile ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), - MemoryProfileActionAllocatePages, - MemoryType, - EFI_PAGES_TO_SIZE (NumberOfPages), - (VOID *) (UINTN) *Memory, - NULL - ); - InstallMemoryAttributesTableOnMemoryAllocation (MemoryType); - ApplyMemoryProtectionPolicy (EfiConventionalMemory, MemoryType, *Memory, - EFI_PAGES_TO_SIZE (NumberOfPages)); - } - return Status; -} - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed - @param NumberOfPages The number of pages to free - @param MemoryType Pointer to memory type - - @retval EFI_NOT_FOUND Could not find the entry that covers the range - @retval EFI_INVALID_PARAMETER Address not aligned - @return EFI_SUCCESS -Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreInternalFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages, - OUT EFI_MEMORY_TYPE *MemoryType OPTIONAL - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - UINTN Alignment; - - // - // Free the range - // - CoreAcquireMemoryLock (); - - // - // Find the entry that the covers the range - // - Entry = NULL; - for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) { - Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - if (Entry->Start <= Memory && Entry->End > Memory) { - break; - } - } - if (Link == &gMemoryMap) { - Status = EFI_NOT_FOUND; - goto Done; - } - - Alignment = DEFAULT_PAGE_ALLOCATION_GRANULARITY; - - ASSERT (Entry != NULL); - if (Entry->Type == EfiACPIReclaimMemory || - Entry->Type == EfiACPIMemoryNVS || - Entry->Type == EfiRuntimeServicesCode || - Entry->Type == EfiRuntimeServicesData) { - - Alignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - - } - - if ((Memory & (Alignment - 1)) != 0) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - NumberOfPages += EFI_SIZE_TO_PAGES (Alignment) - 1; - NumberOfPages &= ~(EFI_SIZE_TO_PAGES (Alignment) - 1); - - if (MemoryType != NULL) { - *MemoryType = Entry->Type; - } - - Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory); - - if (EFI_ERROR (Status)) { - goto Done; - } - -Done: - CoreReleaseMemoryLock (); - return Status; -} - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed - @param NumberOfPages The number of pages to free - - @retval EFI_NOT_FOUND Could not find the entry that covers the range - @retval EFI_INVALID_PARAMETER Address not aligned - @return EFI_SUCCESS -Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ) -{ - EFI_STATUS Status; - EFI_MEMORY_TYPE MemoryType; - - Status = CoreInternalFreePages (Memory, NumberOfPages, &MemoryType); - if (!EFI_ERROR (Status)) { - CoreUpdateProfile ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), - MemoryProfileActionFreePages, - MemoryType, - EFI_PAGES_TO_SIZE (NumberOfPages), - (VOID *) (UINTN) Memory, - NULL - ); - InstallMemoryAttributesTableOnMemoryAllocation (MemoryType); - ApplyMemoryProtectionPolicy (MemoryType, EfiConventionalMemory, Memory, - EFI_PAGES_TO_SIZE (NumberOfPages)); - } - return Status; -} - -/** - This function checks to see if the last memory map descriptor in a memory map - can be merged with any of the other memory map descriptors in a memorymap. - Memory descriptors may be merged if they are adjacent and have the same type - and attributes. - - @param MemoryMap A pointer to the start of the memory map. - @param MemoryMapDescriptor A pointer to the last descriptor in MemoryMap. - @param DescriptorSize The size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - - @return A pointer to the next available descriptor in MemoryMap - -**/ -EFI_MEMORY_DESCRIPTOR * -MergeMemoryMapDescriptor ( - IN EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN EFI_MEMORY_DESCRIPTOR *MemoryMapDescriptor, - IN UINTN DescriptorSize - ) -{ - // - // Traverse the array of descriptors in MemoryMap - // - for (; MemoryMap != MemoryMapDescriptor; MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize)) { - // - // Check to see if the Type fields are identical. - // - if (MemoryMap->Type != MemoryMapDescriptor->Type) { - continue; - } - - // - // Check to see if the Attribute fields are identical. - // - if (MemoryMap->Attribute != MemoryMapDescriptor->Attribute) { - continue; - } - - // - // Check to see if MemoryMapDescriptor is immediately above MemoryMap - // - if (MemoryMap->PhysicalStart + EFI_PAGES_TO_SIZE ((UINTN)MemoryMap->NumberOfPages) == MemoryMapDescriptor->PhysicalStart) { - // - // Merge MemoryMapDescriptor into MemoryMap - // - MemoryMap->NumberOfPages += MemoryMapDescriptor->NumberOfPages; - - // - // Return MemoryMapDescriptor as the next available slot int he MemoryMap array - // - return MemoryMapDescriptor; - } - - // - // Check to see if MemoryMapDescriptor is immediately below MemoryMap - // - if (MemoryMap->PhysicalStart - EFI_PAGES_TO_SIZE ((UINTN)MemoryMapDescriptor->NumberOfPages) == MemoryMapDescriptor->PhysicalStart) { - // - // Merge MemoryMapDescriptor into MemoryMap - // - MemoryMap->PhysicalStart = MemoryMapDescriptor->PhysicalStart; - MemoryMap->VirtualStart = MemoryMapDescriptor->VirtualStart; - MemoryMap->NumberOfPages += MemoryMapDescriptor->NumberOfPages; - - // - // Return MemoryMapDescriptor as the next available slot int he MemoryMap array - // - return MemoryMapDescriptor; - } - } - - // - // MemoryMapDescrtiptor could not be merged with any descriptors in MemoryMap. - // - // Return the slot immediately after MemoryMapDescriptor as the next available - // slot in the MemoryMap array - // - return NEXT_MEMORY_DESCRIPTOR (MemoryMapDescriptor, DescriptorSize); -} - -/** - This function returns a copy of the current memory map. The map is an array of - memory descriptors, each of which describes a contiguous block of memory. - - @param MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -CoreGetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ) -{ - EFI_STATUS Status; - UINTN Size; - UINTN BufferSize; - UINTN NumberOfEntries; - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - EFI_GCD_MAP_ENTRY *GcdMapEntry; - EFI_GCD_MAP_ENTRY MergeGcdMapEntry; - EFI_MEMORY_TYPE Type; - EFI_MEMORY_DESCRIPTOR *MemoryMapStart; - - // - // Make sure the parameters are valid - // - if (MemoryMapSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireGcdMemoryLock (); - - // - // Count the number of Reserved and runtime MMIO entries - // And, count the number of Persistent entries. - // - NumberOfEntries = 0; - for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) { - GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistentMemory) || - (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) || - ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && - ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) { - NumberOfEntries ++; - } - } - - Size = sizeof (EFI_MEMORY_DESCRIPTOR); - - // - // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will - // prevent people from having pointer math bugs in their code. - // now you have to use *DescriptorSize to make things work. - // - Size += sizeof(UINT64) - (Size % sizeof (UINT64)); - - if (DescriptorSize != NULL) { - *DescriptorSize = Size; - } - - if (DescriptorVersion != NULL) { - *DescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION; - } - - CoreAcquireMemoryLock (); - - // - // Compute the buffer size needed to fit the entire map - // - BufferSize = Size * NumberOfEntries; - for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) { - BufferSize += Size; - } - - if (*MemoryMapSize < BufferSize) { - Status = EFI_BUFFER_TOO_SMALL; - goto Done; - } - - if (MemoryMap == NULL) { - Status = EFI_INVALID_PARAMETER; - goto Done; - } - - // - // Build the map - // - ZeroMem (MemoryMap, BufferSize); - MemoryMapStart = MemoryMap; - for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - ASSERT (Entry->VirtualStart == 0); - - // - // Convert internal map into an EFI_MEMORY_DESCRIPTOR - // - MemoryMap->Type = Entry->Type; - MemoryMap->PhysicalStart = Entry->Start; - MemoryMap->VirtualStart = Entry->VirtualStart; - MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT); - // - // If the memory type is EfiConventionalMemory, then determine if the range is part of a - // memory type bin and needs to be converted to the same memory type as the rest of the - // memory type bin in order to minimize EFI Memory Map changes across reboots. This - // improves the chances for a successful S4 resume in the presence of minor page allocation - // differences across reboots. - // - if (MemoryMap->Type == EfiConventionalMemory) { - for (Type = (EFI_MEMORY_TYPE) 0; Type < EfiMaxMemoryType; Type++) { - if (mMemoryTypeStatistics[Type].Special && - mMemoryTypeStatistics[Type].NumberOfPages > 0 && - Entry->Start >= mMemoryTypeStatistics[Type].BaseAddress && - Entry->End <= mMemoryTypeStatistics[Type].MaximumAddress) { - MemoryMap->Type = Type; - } - } - } - MemoryMap->Attribute = Entry->Attribute; - if (MemoryMap->Type < EfiMaxMemoryType) { - if (mMemoryTypeStatistics[MemoryMap->Type].Runtime) { - MemoryMap->Attribute |= EFI_MEMORY_RUNTIME; - } - } - - // - // Check to see if the new Memory Map Descriptor can be merged with an - // existing descriptor if they are adjacent and have the same attributes - // - MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size); - } - - - ZeroMem (&MergeGcdMapEntry, sizeof (MergeGcdMapEntry)); - GcdMapEntry = NULL; - for (Link = mGcdMemorySpaceMap.ForwardLink; ; Link = Link->ForwardLink) { - if (Link != &mGcdMemorySpaceMap) { - // - // Merge adjacent same type and attribute GCD memory range - // - GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - - if ((MergeGcdMapEntry.Capabilities == GcdMapEntry->Capabilities) && - (MergeGcdMapEntry.Attributes == GcdMapEntry->Attributes) && - (MergeGcdMapEntry.GcdMemoryType == GcdMapEntry->GcdMemoryType) && - (MergeGcdMapEntry.GcdIoType == GcdMapEntry->GcdIoType)) { - MergeGcdMapEntry.EndAddress = GcdMapEntry->EndAddress; - continue; - } - } - - if ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) || - ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) && - ((MergeGcdMapEntry.Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) { - // - // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, - // it will be recorded as page PhysicalStart and NumberOfPages. - // - ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0); - ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0); - - // - // Create EFI_MEMORY_DESCRIPTOR for every Reserved and runtime MMIO GCD entries - // - MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress; - MemoryMap->VirtualStart = 0; - MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT); - MemoryMap->Attribute = (MergeGcdMapEntry.Attributes & ~EFI_MEMORY_PORT_IO) | - (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO | - EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB)); - - if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) { - MemoryMap->Type = EfiReservedMemoryType; - } else if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { - if ((MergeGcdMapEntry.Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) { - MemoryMap->Type = EfiMemoryMappedIOPortSpace; - } else { - MemoryMap->Type = EfiMemoryMappedIO; - } - } - - // - // Check to see if the new Memory Map Descriptor can be merged with an - // existing descriptor if they are adjacent and have the same attributes - // - MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size); - } - - if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypePersistentMemory) { - // - // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, - // it will be recorded as page PhysicalStart and NumberOfPages. - // - ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0); - ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0); - - // - // Create EFI_MEMORY_DESCRIPTOR for every Persistent GCD entries - // - MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress; - MemoryMap->VirtualStart = 0; - MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT); - MemoryMap->Attribute = MergeGcdMapEntry.Attributes | EFI_MEMORY_NV | - (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO | - EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB)); - MemoryMap->Type = EfiPersistentMemory; - - // - // Check to see if the new Memory Map Descriptor can be merged with an - // existing descriptor if they are adjacent and have the same attributes - // - MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size); - } - if (Link == &mGcdMemorySpaceMap) { - // - // break loop when arrive at head. - // - break; - } - if (GcdMapEntry != NULL) { - // - // Copy new GCD map entry for the following GCD range merge - // - CopyMem (&MergeGcdMapEntry, GcdMapEntry, sizeof (MergeGcdMapEntry)); - } - } - - // - // Compute the size of the buffer actually used after all memory map descriptor merge operations - // - BufferSize = ((UINT8 *)MemoryMap - (UINT8 *)MemoryMapStart); - - Status = EFI_SUCCESS; - -Done: - // - // Update the map key finally - // - if (MapKey != NULL) { - *MapKey = mMemoryMapKey; - } - - CoreReleaseMemoryLock (); - - CoreReleaseGcdMemoryLock (); - - *MemoryMapSize = BufferSize; - - return Status; -} - - -/** - Internal function. Used by the pool functions to allocate pages - to back pool allocation requests. - - @param PoolType The type of memory for the new pool pages - @param NumberOfPages No of pages to allocate - @param Alignment Bits to align. - - @return The allocated memory, or NULL - -**/ -VOID * -CoreAllocatePoolPages ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NumberOfPages, - IN UINTN Alignment - ) -{ - UINT64 Start; - - // - // Find the pages to convert - // - Start = FindFreePages (MAX_ADDRESS, NumberOfPages, PoolType, Alignment); - - // - // Convert it to boot services data - // - if (Start == 0) { - DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "AllocatePoolPages: failed to allocate %d pages\n", (UINT32)NumberOfPages)); - } else { - CoreConvertPages (Start, NumberOfPages, PoolType); - } - - return (VOID *)(UINTN) Start; -} - - -/** - Internal function. Frees pool pages allocated via AllocatePoolPages () - - @param Memory The base address to free - @param NumberOfPages The number of pages to free - -**/ -VOID -CoreFreePoolPages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ) -{ - CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory); -} - - - -/** - Make sure the memory map is following all the construction rules, - it is the last time to check memory map error before exit boot services. - - @param MapKey Memory map key - - @retval EFI_INVALID_PARAMETER Memory map not consistent with construction - rules. - @retval EFI_SUCCESS Valid memory map. - -**/ -EFI_STATUS -CoreTerminateMemoryMap ( - IN UINTN MapKey - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - - Status = EFI_SUCCESS; - - CoreAcquireMemoryLock (); - - if (MapKey == mMemoryMapKey) { - - // - // Make sure the memory map is following all the construction rules - // This is the last chance we will be able to display any messages on - // the console devices. - // - - for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) { - Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - if (Entry->Type < EfiMaxMemoryType) { - if (mMemoryTypeStatistics[Entry->Type].Runtime) { - ASSERT (Entry->Type != EfiACPIReclaimMemory); - ASSERT (Entry->Type != EfiACPIMemoryNVS); - if ((Entry->Start & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) { - DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n")); - Status = EFI_INVALID_PARAMETER; - goto Done; - } - if (((Entry->End + 1) & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) { - DEBUG((DEBUG_ERROR | DEBUG_PAGE, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n")); - Status = EFI_INVALID_PARAMETER; - goto Done; - } - } - } - } - - // - // The map key they gave us matches what we expect. Fall through and - // return success. In an ideal world we would clear out all of - // EfiBootServicesCode and EfiBootServicesData. However this function - // is not the last one called by ExitBootServices(), so we have to - // preserve the memory contents. - // - } else { - Status = EFI_INVALID_PARAMETER; - } - -Done: - CoreReleaseMemoryLock (); - - return Status; -} - - - - - - - - - diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c deleted file mode 100644 index dd165fea75..0000000000 --- a/MdeModulePkg/Core/Dxe/Mem/Pool.c +++ /dev/null @@ -1,764 +0,0 @@ -/** @file - UEFI Memory pool management functions. - -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" -#include "Imem.h" - -STATIC EFI_LOCK mPoolMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); - -#define POOL_FREE_SIGNATURE SIGNATURE_32('p','f','r','0') -typedef struct { - UINT32 Signature; - UINT32 Index; - LIST_ENTRY Link; -} POOL_FREE; - - -#define POOL_HEAD_SIGNATURE SIGNATURE_32('p','h','d','0') -typedef struct { - UINT32 Signature; - UINT32 Reserved; - EFI_MEMORY_TYPE Type; - UINTN Size; - CHAR8 Data[1]; -} POOL_HEAD; - -#define SIZE_OF_POOL_HEAD OFFSET_OF(POOL_HEAD,Data) - -#define POOL_TAIL_SIGNATURE SIGNATURE_32('p','t','a','l') -typedef struct { - UINT32 Signature; - UINT32 Reserved; - UINTN Size; -} POOL_TAIL; - -#define POOL_OVERHEAD (SIZE_OF_POOL_HEAD + sizeof(POOL_TAIL)) - -#define HEAD_TO_TAIL(a) \ - ((POOL_TAIL *) (((CHAR8 *) (a)) + (a)->Size - sizeof(POOL_TAIL))); - -// -// Each element is the sum of the 2 previous ones: this allows us to migrate -// blocks between bins by splitting them up, while not wasting too much memory -// as we would in a strict power-of-2 sequence -// -STATIC CONST UINT16 mPoolSizeTable[] = { - 128, 256, 384, 640, 1024, 1664, 2688, 4352, 7040, 11392, 18432, 29824 -}; - -#define SIZE_TO_LIST(a) (GetPoolIndexFromSize (a)) -#define LIST_TO_SIZE(a) (mPoolSizeTable [a]) - -#define MAX_POOL_LIST (ARRAY_SIZE (mPoolSizeTable)) - -#define MAX_POOL_SIZE (MAX_ADDRESS - POOL_OVERHEAD) - -// -// Globals -// - -#define POOL_SIGNATURE SIGNATURE_32('p','l','s','t') -typedef struct { - INTN Signature; - UINTN Used; - EFI_MEMORY_TYPE MemoryType; - LIST_ENTRY FreeList[MAX_POOL_LIST]; - LIST_ENTRY Link; -} POOL; - -// -// Pool header for each memory type. -// -POOL mPoolHead[EfiMaxMemoryType]; - -// -// List of pool header to search for the appropriate memory type. -// -LIST_ENTRY mPoolHeadList = INITIALIZE_LIST_HEAD_VARIABLE (mPoolHeadList); - -/** - Get pool size table index from the specified size. - - @param Size The specified size to get index from pool table. - - @return The index of pool size table. - -**/ -STATIC -UINTN -GetPoolIndexFromSize ( - UINTN Size - ) -{ - UINTN Index; - - for (Index = 0; Index < MAX_POOL_LIST; Index++) { - if (mPoolSizeTable [Index] >= Size) { - return Index; - } - } - return MAX_POOL_LIST; -} - -/** - Called to initialize the pool. - -**/ -VOID -CoreInitializePool ( - VOID - ) -{ - UINTN Type; - UINTN Index; - - for (Type=0; Type < EfiMaxMemoryType; Type++) { - mPoolHead[Type].Signature = 0; - mPoolHead[Type].Used = 0; - mPoolHead[Type].MemoryType = (EFI_MEMORY_TYPE) Type; - for (Index=0; Index < MAX_POOL_LIST; Index++) { - InitializeListHead (&mPoolHead[Type].FreeList[Index]); - } - } -} - - -/** - Look up pool head for specified memory type. - - @param MemoryType Memory type of which pool head is looked for - - @return Pointer of Corresponding pool head. - -**/ -POOL * -LookupPoolHead ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - LIST_ENTRY *Link; - POOL *Pool; - UINTN Index; - - if ((UINT32)MemoryType < EfiMaxMemoryType) { - return &mPoolHead[MemoryType]; - } - - // - // MemoryType values in the range 0x80000000..0xFFFFFFFF are reserved for use by UEFI - // OS loaders that are provided by operating system vendors. - // MemoryType values in the range 0x70000000..0x7FFFFFFF are reserved for OEM use. - // - if ((UINT32) MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { - - for (Link = mPoolHeadList.ForwardLink; Link != &mPoolHeadList; Link = Link->ForwardLink) { - Pool = CR(Link, POOL, Link, POOL_SIGNATURE); - if (Pool->MemoryType == MemoryType) { - return Pool; - } - } - - Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL)); - if (Pool == NULL) { - return NULL; - } - - Pool->Signature = POOL_SIGNATURE; - Pool->Used = 0; - Pool->MemoryType = MemoryType; - for (Index=0; Index < MAX_POOL_LIST; Index++) { - InitializeListHead (&Pool->FreeList[Index]); - } - - InsertHeadList (&mPoolHeadList, &Pool->Link); - - return Pool; - } - - return NULL; -} - - - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER Buffer is NULL. - PoolType is in the range EfiMaxMemoryType..0x6FFFFFFF. - PoolType is EfiPersistentMemory. - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreInternalAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ) -{ - EFI_STATUS Status; - - // - // If it's not a valid type, fail it - // - if ((PoolType >= EfiMaxMemoryType && PoolType < MEMORY_TYPE_OEM_RESERVED_MIN) || - (PoolType == EfiConventionalMemory) || (PoolType == EfiPersistentMemory)) { - return EFI_INVALID_PARAMETER; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Buffer = NULL; - - // - // If size is too large, fail it - // Base on the EFI spec, return status of EFI_OUT_OF_RESOURCES - // - if (Size > MAX_POOL_SIZE) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Acquire the memory lock and make the allocation - // - Status = CoreAcquireLockOrFail (&mPoolMemoryLock); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - - *Buffer = CoreAllocatePoolI (PoolType, Size); - CoreReleaseLock (&mPoolMemoryLock); - return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES; -} - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER Buffer is NULL. - PoolType is in the range EfiMaxMemoryType..0x6FFFFFFF. - PoolType is EfiPersistentMemory. - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -CoreAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ) -{ - EFI_STATUS Status; - - Status = CoreInternalAllocatePool (PoolType, Size, Buffer); - if (!EFI_ERROR (Status)) { - CoreUpdateProfile ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), - MemoryProfileActionAllocatePool, - PoolType, - Size, - *Buffer, - NULL - ); - InstallMemoryAttributesTableOnMemoryAllocation (PoolType); - } - return Status; -} - -/** - Internal function. Used by the pool functions to allocate pages - to back pool allocation requests. - - @param PoolType The type of memory for the new pool pages - @param NoPages No of pages to allocate - @param Granularity Bits to align. - - @return The allocated memory, or NULL - -**/ -STATIC -VOID * -CoreAllocatePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN NoPages, - IN UINTN Granularity - ) -{ - VOID *Buffer; - EFI_STATUS Status; - - Status = CoreAcquireLockOrFail (&gMemoryLock); - if (EFI_ERROR (Status)) { - return NULL; - } - - Buffer = CoreAllocatePoolPages (PoolType, NoPages, Granularity); - CoreReleaseMemoryLock (); - - if (Buffer != NULL) { - ApplyMemoryProtectionPolicy (EfiConventionalMemory, PoolType, - (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, EFI_PAGES_TO_SIZE (NoPages)); - } - return Buffer; -} - -/** - Internal function to allocate pool of a particular type. - Caller must have the memory lock held - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - - @return The allocate pool, or NULL - -**/ -VOID * -CoreAllocatePoolI ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size - ) -{ - POOL *Pool; - POOL_FREE *Free; - POOL_HEAD *Head; - POOL_TAIL *Tail; - CHAR8 *NewPage; - VOID *Buffer; - UINTN Index; - UINTN FSize; - UINTN Offset, MaxOffset; - UINTN NoPages; - UINTN Granularity; - - ASSERT_LOCKED (&mPoolMemoryLock); - - if (PoolType == EfiACPIReclaimMemory || - PoolType == EfiACPIMemoryNVS || - PoolType == EfiRuntimeServicesCode || - PoolType == EfiRuntimeServicesData) { - - Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - } else { - Granularity = DEFAULT_PAGE_ALLOCATION_GRANULARITY; - } - - // - // Adjust the size by the pool header & tail overhead - // - - // - // Adjusting the Size to be of proper alignment so that - // we don't get an unaligned access fault later when - // pool_Tail is being initialized - // - Size = ALIGN_VARIABLE (Size); - - Size += POOL_OVERHEAD; - Index = SIZE_TO_LIST(Size); - Pool = LookupPoolHead (PoolType); - if (Pool== NULL) { - return NULL; - } - Head = NULL; - - // - // If allocation is over max size, just allocate pages for the request - // (slow) - // - if (Index >= SIZE_TO_LIST (Granularity)) { - NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (Granularity) - 1; - NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1); - Head = CoreAllocatePoolPagesI (PoolType, NoPages, Granularity); - goto Done; - } - - // - // If there's no free pool in the proper list size, go get some more pages - // - if (IsListEmpty (&Pool->FreeList[Index])) { - - Offset = LIST_TO_SIZE (Index); - MaxOffset = Granularity; - - // - // Check the bins holding larger blocks, and carve one up if needed - // - while (++Index < SIZE_TO_LIST (Granularity)) { - if (!IsListEmpty (&Pool->FreeList[Index])) { - Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE); - RemoveEntryList (&Free->Link); - NewPage = (VOID *) Free; - MaxOffset = LIST_TO_SIZE (Index); - goto Carve; - } - } - - // - // Get another page - // - NewPage = CoreAllocatePoolPagesI (PoolType, EFI_SIZE_TO_PAGES (Granularity), Granularity); - if (NewPage == NULL) { - goto Done; - } - - // - // Serve the allocation request from the head of the allocated block - // -Carve: - Head = (POOL_HEAD *) NewPage; - - // - // Carve up remaining space into free pool blocks - // - Index--; - while (Offset < MaxOffset) { - ASSERT (Index < MAX_POOL_LIST); - FSize = LIST_TO_SIZE(Index); - - while (Offset + FSize <= MaxOffset) { - Free = (POOL_FREE *) &NewPage[Offset]; - Free->Signature = POOL_FREE_SIGNATURE; - Free->Index = (UINT32)Index; - InsertHeadList (&Pool->FreeList[Index], &Free->Link); - Offset += FSize; - } - Index -= 1; - } - - ASSERT (Offset == MaxOffset); - goto Done; - } - - // - // Remove entry from free pool list - // - Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE); - RemoveEntryList (&Free->Link); - - Head = (POOL_HEAD *) Free; - -Done: - Buffer = NULL; - - if (Head != NULL) { - - // - // If we have a pool buffer, fill in the header & tail info - // - Head->Signature = POOL_HEAD_SIGNATURE; - Head->Size = Size; - Head->Type = (EFI_MEMORY_TYPE) PoolType; - Tail = HEAD_TO_TAIL (Head); - Tail->Signature = POOL_TAIL_SIGNATURE; - Tail->Size = Size; - Buffer = Head->Data; - DEBUG_CLEAR_MEMORY (Buffer, Size - POOL_OVERHEAD); - - DEBUG (( - DEBUG_POOL, - "AllocatePoolI: Type %x, Addr %p (len %lx) %,ld\n", PoolType, - Buffer, - (UINT64)(Size - POOL_OVERHEAD), - (UINT64) Pool->Used - )); - - // - // Account the allocation - // - Pool->Used += Size; - - } else { - DEBUG ((DEBUG_ERROR | DEBUG_POOL, "AllocatePool: failed to allocate %ld bytes\n", (UINT64) Size)); - } - - return Buffer; -} - - - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreInternalFreePool ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ) -{ - EFI_STATUS Status; - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquireLock (&mPoolMemoryLock); - Status = CoreFreePoolI (Buffer, PoolType); - CoreReleaseLock (&mPoolMemoryLock); - return Status; -} - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -CoreFreePool ( - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - EFI_MEMORY_TYPE PoolType; - - Status = CoreInternalFreePool (Buffer, &PoolType); - if (!EFI_ERROR (Status)) { - CoreUpdateProfile ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), - MemoryProfileActionFreePool, - PoolType, - 0, - Buffer, - NULL - ); - InstallMemoryAttributesTableOnMemoryAllocation (PoolType); - } - return Status; -} - -/** - Internal function. Frees pool pages allocated via CoreAllocatePoolPagesI(). - - @param PoolType The type of memory for the pool pages - @param Memory The base address to free - @param NoPages The number of pages to free - -**/ -STATIC -VOID -CoreFreePoolPagesI ( - IN EFI_MEMORY_TYPE PoolType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NoPages - ) -{ - CoreAcquireMemoryLock (); - CoreFreePoolPages (Memory, NoPages); - CoreReleaseMemoryLock (); - - ApplyMemoryProtectionPolicy (PoolType, EfiConventionalMemory, - (EFI_PHYSICAL_ADDRESS)(UINTN)Memory, EFI_PAGES_TO_SIZE (NoPages)); -} - -/** - Internal function to free a pool entry. - Caller must have the memory lock held - - @param Buffer The allocated pool entry to free - @param PoolType Pointer to pool type - - @retval EFI_INVALID_PARAMETER Buffer not valid - @retval EFI_SUCCESS Buffer successfully freed. - -**/ -EFI_STATUS -CoreFreePoolI ( - IN VOID *Buffer, - OUT EFI_MEMORY_TYPE *PoolType OPTIONAL - ) -{ - POOL *Pool; - POOL_HEAD *Head; - POOL_TAIL *Tail; - POOL_FREE *Free; - UINTN Index; - UINTN NoPages; - UINTN Size; - CHAR8 *NewPage; - UINTN Offset; - BOOLEAN AllFree; - UINTN Granularity; - - ASSERT(Buffer != NULL); - // - // Get the head & tail of the pool entry - // - Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE); - ASSERT(Head != NULL); - - if (Head->Signature != POOL_HEAD_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - Tail = HEAD_TO_TAIL (Head); - ASSERT(Tail != NULL); - - // - // Debug - // - ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE); - ASSERT (Head->Size == Tail->Size); - ASSERT_LOCKED (&mPoolMemoryLock); - - if (Tail->Signature != POOL_TAIL_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - if (Head->Size != Tail->Size) { - return EFI_INVALID_PARAMETER; - } - - // - // Determine the pool type and account for it - // - Size = Head->Size; - Pool = LookupPoolHead (Head->Type); - if (Pool == NULL) { - return EFI_INVALID_PARAMETER; - } - Pool->Used -= Size; - DEBUG ((DEBUG_POOL, "FreePool: %p (len %lx) %,ld\n", Head->Data, (UINT64)(Head->Size - POOL_OVERHEAD), (UINT64) Pool->Used)); - - if (Head->Type == EfiACPIReclaimMemory || - Head->Type == EfiACPIMemoryNVS || - Head->Type == EfiRuntimeServicesCode || - Head->Type == EfiRuntimeServicesData) { - - Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - } else { - Granularity = DEFAULT_PAGE_ALLOCATION_GRANULARITY; - } - - if (PoolType != NULL) { - *PoolType = Head->Type; - } - - // - // Determine the pool list - // - Index = SIZE_TO_LIST(Size); - DEBUG_CLEAR_MEMORY (Head, Size); - - // - // If it's not on the list, it must be pool pages - // - if (Index >= SIZE_TO_LIST (Granularity)) { - - // - // Return the memory pages back to free memory - // - NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (Granularity) - 1; - NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1); - CoreFreePoolPagesI (Pool->MemoryType, (EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages); - - } else { - - // - // Put the pool entry onto the free pool list - // - Free = (POOL_FREE *) Head; - ASSERT(Free != NULL); - Free->Signature = POOL_FREE_SIGNATURE; - Free->Index = (UINT32)Index; - InsertHeadList (&Pool->FreeList[Index], &Free->Link); - - // - // See if all the pool entries in the same page as Free are freed pool - // entries - // - NewPage = (CHAR8 *)((UINTN)Free & ~(Granularity - 1)); - Free = (POOL_FREE *) &NewPage[0]; - ASSERT(Free != NULL); - - if (Free->Signature == POOL_FREE_SIGNATURE) { - - AllFree = TRUE; - Offset = 0; - - while ((Offset < Granularity) && (AllFree)) { - Free = (POOL_FREE *) &NewPage[Offset]; - ASSERT(Free != NULL); - if (Free->Signature != POOL_FREE_SIGNATURE) { - AllFree = FALSE; - } - Offset += LIST_TO_SIZE(Free->Index); - } - - if (AllFree) { - - // - // All of the pool entries in the same page as Free are free pool - // entries - // Remove all of these pool entries from the free loop lists. - // - Free = (POOL_FREE *) &NewPage[0]; - ASSERT(Free != NULL); - Offset = 0; - - while (Offset < Granularity) { - Free = (POOL_FREE *) &NewPage[Offset]; - ASSERT(Free != NULL); - RemoveEntryList (&Free->Link); - Offset += LIST_TO_SIZE(Free->Index); - } - - // - // Free the page - // - CoreFreePoolPagesI (Pool->MemoryType, (EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, - EFI_SIZE_TO_PAGES (Granularity)); - } - } - } - - // - // If this is an OS/OEM specific memory type, then check to see if the last - // portion of that memory type has been freed. If it has, then free the - // list entry for that memory type - // - if (((UINT32) Pool->MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) && Pool->Used == 0) { - RemoveEntryList (&Pool->Link); - CoreFreePoolI (Pool, NULL); - } - - return EFI_SUCCESS; -} - diff --git a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c deleted file mode 100644 index fda6d44043..0000000000 --- a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c +++ /dev/null @@ -1,288 +0,0 @@ -/** @file - Support functions for managing debug image info table when loading and unloading - images. - -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - - -EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = { - 0, // volatile UINT32 UpdateStatus; - 0, // UINT32 TableSize; - NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable; -}; - -UINTN mMaxTableEntries = 0; - -EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL; - -#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *)) - -/** - Creates and initializes the DebugImageInfo Table. Also creates the configuration - table and registers it into the system table. - -**/ -VOID -CoreInitializeDebugImageInfoTable ( - VOID - ) -{ - EFI_STATUS Status; - UINTN Pages; - EFI_PHYSICAL_ADDRESS Memory; - UINTN AlignedMemory; - UINTN AlignmentMask; - UINTN UnalignedPages; - UINTN RealPages; - - // - // Allocate 4M aligned page for the structure and fill in the data. - // Ideally we would update the CRC now as well, but the service may not yet be available. - // See comments in the CoreUpdateDebugTableCrc32() function below for details. - // - Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_SYSTEM_TABLE_POINTER)); - AlignmentMask = SIZE_4MB - 1; - RealPages = Pages + EFI_SIZE_TO_PAGES (SIZE_4MB); - - // - // Attempt to allocate memory below PcdMaxEfiSystemTablePointerAddress - // If PcdMaxEfiSystemTablePointerAddress is 0, then allocate memory below - // MAX_ADDRESS - // - Memory = PcdGet64 (PcdMaxEfiSystemTablePointerAddress); - if (Memory == 0) { - Memory = MAX_ADDRESS; - } - Status = CoreAllocatePages ( - AllocateMaxAddress, - EfiBootServicesData, - RealPages, - &Memory - ); - if (EFI_ERROR (Status)) { - if (PcdGet64 (PcdMaxEfiSystemTablePointerAddress) != 0) { - DEBUG ((EFI_D_INFO, "Allocate memory for EFI_SYSTEM_TABLE_POINTER below PcdMaxEfiSystemTablePointerAddress failed. \ - Retry to allocate memroy as close to the top of memory as feasible.\n")); - } - // - // If the initial memory allocation fails, then reattempt allocation - // as close to the top of memory as feasible. - // - Status = CoreAllocatePages ( - AllocateAnyPages, - EfiBootServicesData, - RealPages, - &Memory - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return; - } - } - - // - // Free overallocated pages - // - AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask; - UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory); - if (UnalignedPages > 0) { - // - // Free first unaligned page(s). - // - Status = CoreFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages); - UnalignedPages = RealPages - Pages - UnalignedPages; - if (UnalignedPages > 0) { - // - // Free last unaligned page(s). - // - Status = CoreFreePages (Memory, UnalignedPages); - ASSERT_EFI_ERROR (Status); - } - - // - // Set mDebugTable to the 4MB aligned allocated pages - // - mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(AlignedMemory); - ASSERT (mDebugTable != NULL); - - // - // Initialize EFI_SYSTEM_TABLE_POINTER structure - // - mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE; - mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gDxeCoreST; - mDebugTable->Crc32 = 0; - - // - // Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System - // Configuration Table - // - Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader); - ASSERT_EFI_ERROR (Status); -} - - -/** - Update the CRC32 in the Debug Table. - Since the CRC32 service is made available by the Runtime driver, we have to - wait for the Runtime Driver to be installed before the CRC32 can be computed. - This function is called elsewhere by the core when the runtime architectural - protocol is produced. - -**/ -VOID -CoreUpdateDebugTableCrc32 ( - VOID - ) -{ - ASSERT(mDebugTable != NULL); - mDebugTable->Crc32 = 0; - gBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32); -} - - -/** - Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates - the table if it's not large enough to accomidate another entry. - - @param ImageInfoType type of debug image information - @param LoadedImage pointer to the loaded image protocol for the image being - loaded - @param ImageHandle image handle for the image being loaded - -**/ -VOID -CoreNewDebugImageInfoEntry ( - IN UINT32 ImageInfoType, - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_HANDLE ImageHandle - ) -{ - EFI_DEBUG_IMAGE_INFO *Table; - EFI_DEBUG_IMAGE_INFO *NewTable; - UINTN Index; - UINTN TableSize; - - // - // Set the flag indicating that we're in the process of updating the table. - // - mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; - - Table = mDebugInfoTableHeader.EfiDebugImageInfoTable; - - if (mDebugInfoTableHeader.TableSize < mMaxTableEntries) { - // - // We still have empty entires in the Table, find the first empty entry. - // - Index = 0; - while (Table[Index].NormalImage != NULL) { - Index++; - } - // - // There must be an empty entry in the in the table. - // - ASSERT (Index < mMaxTableEntries); - } else { - // - // Table is full, so re-allocate another page for a larger table... - // - TableSize = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE; - NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE); - if (NewTable == NULL) { - mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; - return; - } - // - // Copy the old table into the new one - // - CopyMem (NewTable, Table, TableSize); - // - // Free the old table - // - CoreFreePool (Table); - // - // Update the table header - // - Table = NewTable; - mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable; - // - // Enlarge the max table entries and set the first empty entry index to - // be the original max table entries. - // - Index = mMaxTableEntries; - mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE; - } - - // - // Allocate data for new entry - // - Table[Index].NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL)); - if (Table[Index].NormalImage != NULL) { - // - // Update the entry - // - Table[Index].NormalImage->ImageInfoType = (UINT32) ImageInfoType; - Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage; - Table[Index].NormalImage->ImageHandle = ImageHandle; - // - // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. - // - mDebugInfoTableHeader.TableSize++; - mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; - } - mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; -} - - - -/** - Removes and frees an entry from the DebugImageInfo Table. - - @param ImageHandle image handle for the image being unloaded - -**/ -VOID -CoreRemoveDebugImageInfoEntry ( - EFI_HANDLE ImageHandle - ) -{ - EFI_DEBUG_IMAGE_INFO *Table; - UINTN Index; - - mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; - - Table = mDebugInfoTableHeader.EfiDebugImageInfoTable; - - for (Index = 0; Index < mMaxTableEntries; Index++) { - if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) { - // - // Found a match. Free up the record, then NULL the pointer to indicate the slot - // is free. - // - CoreFreePool (Table[Index].NormalImage); - Table[Index].NormalImage = NULL; - // - // Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status. - // - mDebugInfoTableHeader.TableSize--; - mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; - break; - } - } - mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; -} - - diff --git a/MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c b/MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c deleted file mode 100644 index e4735db7ba..0000000000 --- a/MdeModulePkg/Core/Dxe/Misc/InstallConfigurationTable.c +++ /dev/null @@ -1,171 +0,0 @@ -/** @file - UEFI Miscellaneous boot Services InstallConfigurationTable service - -Copyright (c) 2006 - 2011, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - -#define CONFIG_TABLE_SIZE_INCREASED 0x10 - -UINTN mSystemTableAllocateSize = 0; - -/** - Boot Service called to add, modify, or remove a system configuration table from - the EFI System Table. - - @param Guid Pointer to the GUID for the entry to add, update, or - remove - @param Table Pointer to the configuration table for the entry to add, - update, or remove, may be NULL. - - @return EFI_SUCCESS Guid, Table pair added, updated, or removed. - @return EFI_INVALID_PARAMETER Input GUID is NULL. - @return EFI_NOT_FOUND Attempted to delete non-existant entry - @return EFI_OUT_OF_RESOURCES Not enough memory available - -**/ -EFI_STATUS -EFIAPI -CoreInstallConfigurationTable ( - IN EFI_GUID *Guid, - IN VOID *Table - ) -{ - UINTN Index; - EFI_CONFIGURATION_TABLE *EfiConfigurationTable; - - // - // If Guid is NULL, then this operation cannot be performed - // - if (Guid == NULL) { - return EFI_INVALID_PARAMETER; - } - - EfiConfigurationTable = gDxeCoreST->ConfigurationTable; - - // - // Search all the table for an entry that matches Guid - // - for (Index = 0; Index < gDxeCoreST->NumberOfTableEntries; Index++) { - if (CompareGuid (Guid, &(gDxeCoreST->ConfigurationTable[Index].VendorGuid))) { - break; - } - } - - if (Index < gDxeCoreST->NumberOfTableEntries) { - // - // A match was found, so this is either a modify or a delete operation - // - if (Table != NULL) { - // - // If Table is not NULL, then this is a modify operation. - // Modify the table enty and return. - // - gDxeCoreST->ConfigurationTable[Index].VendorTable = Table; - - // - // Signal Configuration Table change - // - CoreNotifySignalList (Guid); - - return EFI_SUCCESS; - } - - // - // A match was found and Table is NULL, so this is a delete operation. - // - gDxeCoreST->NumberOfTableEntries--; - - // - // Copy over deleted entry - // - CopyMem ( - &(EfiConfigurationTable[Index]), - &(gDxeCoreST->ConfigurationTable[Index + 1]), - (gDxeCoreST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE) - ); - - } else { - - // - // No matching GUIDs were found, so this is an add operation. - // - - if (Table == NULL) { - // - // If Table is NULL on an add operation, then return an error. - // - return EFI_NOT_FOUND; - } - - // - // Assume that Index == gDxeCoreST->NumberOfTableEntries - // - if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) { - // - // Allocate a table with one additional entry. - // - mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE)); - EfiConfigurationTable = AllocateRuntimePool (mSystemTableAllocateSize); - if (EfiConfigurationTable == NULL) { - // - // If a new table could not be allocated, then return an error. - // - return EFI_OUT_OF_RESOURCES; - } - - if (gDxeCoreST->ConfigurationTable != NULL) { - // - // Copy the old table to the new table. - // - CopyMem ( - EfiConfigurationTable, - gDxeCoreST->ConfigurationTable, - Index * sizeof (EFI_CONFIGURATION_TABLE) - ); - - // - // Free Old Table - // - CoreFreePool (gDxeCoreST->ConfigurationTable); - } - - // - // Update System Table - // - gDxeCoreST->ConfigurationTable = EfiConfigurationTable; - } - - // - // Fill in the new entry - // - CopyGuid ((VOID *)&EfiConfigurationTable[Index].VendorGuid, Guid); - EfiConfigurationTable[Index].VendorTable = Table; - - // - // This is an add operation, so increment the number of table entries - // - gDxeCoreST->NumberOfTableEntries++; - } - - // - // Fix up the CRC-32 in the EFI System Table - // - CalculateEfiHdrCrc (&gDxeCoreST->Hdr); - - // - // Signal Configuration Table change - // - CoreNotifySignalList (Guid); - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c b/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c deleted file mode 100644 index 35156aea14..0000000000 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryAttributesTable.c +++ /dev/null @@ -1,268 +0,0 @@ -/** @file - UEFI MemoryAttributesTable support - -Copyright (c) 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "DxeMain.h" - -/** - This function for GetMemoryMap() with properties table capability. - - It calls original GetMemoryMap() to get the original memory map information. Then - plus the additional memory map entries for PE Code/Data seperation. - - @param MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -CoreGetMemoryMapWithSeparatedImageSection ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ); - -extern EFI_PROPERTIES_TABLE mPropertiesTable; -EFI_MEMORY_ATTRIBUTES_TABLE *mMemoryAttributesTable = NULL; -BOOLEAN mMemoryAttributesTableReadyToBoot = FALSE; - -/** - Install MemoryAttributesTable. - -**/ -VOID -InstallMemoryAttributesTable ( - VOID - ) -{ - UINTN MemoryMapSize; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - EFI_MEMORY_DESCRIPTOR *MemoryMapStart; - UINTN MapKey; - UINTN DescriptorSize; - UINT32 DescriptorVersion; - UINTN Index; - EFI_STATUS Status; - UINT32 RuntimeEntryCount; - EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; - - if (gMemoryMapTerminated) { - // - // Directly return after MemoryMap terminated. - // - return; - } - - if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { - DEBUG ((EFI_D_VERBOSE, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, ")); - DEBUG ((EFI_D_VERBOSE, "because Runtime Driver Section Alignment is not %dK.\n", RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10)); - return ; - } - - if (mMemoryAttributesTable == NULL) { - // - // InstallConfigurationTable here to occupy one entry for MemoryAttributesTable - // before GetMemoryMap below, as InstallConfigurationTable may allocate runtime - // memory for the new entry. - // - Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, (VOID *) (UINTN) MAX_ADDRESS); - ASSERT_EFI_ERROR (Status); - } - - MemoryMapSize = 0; - MemoryMap = NULL; - Status = CoreGetMemoryMapWithSeparatedImageSection ( - &MemoryMapSize, - MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion - ); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - do { - MemoryMap = AllocatePool (MemoryMapSize); - ASSERT (MemoryMap != NULL); - - Status = CoreGetMemoryMapWithSeparatedImageSection ( - &MemoryMapSize, - MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion - ); - if (EFI_ERROR (Status)) { - FreePool (MemoryMap); - } - } while (Status == EFI_BUFFER_TOO_SMALL); - - MemoryMapStart = MemoryMap; - RuntimeEntryCount = 0; - for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) { - switch (MemoryMap->Type) { - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: - RuntimeEntryCount ++; - break; - } - MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize); - } - - // - // Allocate MemoryAttributesTable - // - MemoryAttributesTable = AllocatePool (sizeof(EFI_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount); - ASSERT (MemoryAttributesTable != NULL); - MemoryAttributesTable->Version = EFI_MEMORY_ATTRIBUTES_TABLE_VERSION; - MemoryAttributesTable->NumberOfEntries = RuntimeEntryCount; - MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize; - MemoryAttributesTable->Reserved = 0; - DEBUG ((EFI_D_VERBOSE, "MemoryAttributesTable:\n")); - DEBUG ((EFI_D_VERBOSE, " Version - 0x%08x\n", MemoryAttributesTable->Version)); - DEBUG ((EFI_D_VERBOSE, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); - DEBUG ((EFI_D_VERBOSE, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize)); - MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1); - MemoryMap = MemoryMapStart; - for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) { - switch (MemoryMap->Type) { - case EfiRuntimeServicesCode: - case EfiRuntimeServicesData: - CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize); - MemoryAttributesEntry->Attribute &= (EFI_MEMORY_RO|EFI_MEMORY_XP|EFI_MEMORY_RUNTIME); - DEBUG ((EFI_D_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry)); - DEBUG ((EFI_D_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type)); - DEBUG ((EFI_D_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart)); - DEBUG ((EFI_D_VERBOSE, " VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart)); - DEBUG ((EFI_D_VERBOSE, " NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages)); - DEBUG ((EFI_D_VERBOSE, " Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute)); - MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR(MemoryAttributesEntry, DescriptorSize); - break; - } - MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize); - } - MemoryMap = MemoryMapStart; - FreePool (MemoryMap); - - // - // Update configuratoin table for MemoryAttributesTable. - // - Status = gBS->InstallConfigurationTable (&gEfiMemoryAttributesTableGuid, MemoryAttributesTable); - ASSERT_EFI_ERROR (Status); - - if (mMemoryAttributesTable != NULL) { - FreePool (mMemoryAttributesTable); - } - mMemoryAttributesTable = MemoryAttributesTable; -} - -/** - Install MemoryAttributesTable on memory allocation. - - @param[in] MemoryType EFI memory type. -**/ -VOID -InstallMemoryAttributesTableOnMemoryAllocation ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - // - // Install MemoryAttributesTable after ReadyToBoot on runtime memory allocation. - // - if (mMemoryAttributesTableReadyToBoot && - ((MemoryType == EfiRuntimeServicesCode) || (MemoryType == EfiRuntimeServicesData))) { - InstallMemoryAttributesTable (); - } -} - -/** - Install MemoryAttributesTable on ReadyToBoot. - - @param[in] Event The Event this notify function registered to. - @param[in] Context Pointer to the context data registered to the Event. -**/ -VOID -EFIAPI -InstallMemoryAttributesTableOnReadyToBoot ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - InstallMemoryAttributesTable (); - mMemoryAttributesTableReadyToBoot = TRUE; -} - -/** - Initialize MemoryAttrubutesTable support. -**/ -VOID -EFIAPI -CoreInitializeMemoryAttributesTable ( - VOID - ) -{ - EFI_STATUS Status; - EFI_EVENT ReadyToBootEvent; - - // - // Construct the table at ReadyToBoot. - // - Status = CoreCreateEventInternal ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK - 1, - InstallMemoryAttributesTableOnReadyToBoot, - NULL, - &gEfiEventReadyToBootGuid, - &ReadyToBootEvent - ); - ASSERT_EFI_ERROR (Status); - return ; -} diff --git a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c b/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c deleted file mode 100644 index a73c4ccd64..0000000000 --- a/MdeModulePkg/Core/Dxe/Misc/MemoryProtection.c +++ /dev/null @@ -1,1141 +0,0 @@ -/** @file - UEFI Memory Protection support. - - If the UEFI image is page aligned, the image code section is set to read only - and the image data section is set to non-executable. - - 1) This policy is applied for all UEFI image including boot service driver, - runtime driver or application. - 2) This policy is applied only if the UEFI image meets the page alignment - requirement. - 3) This policy is applied only if the Source UEFI image matches the - PcdImageProtectionPolicy definition. - 4) This policy is not applied to the non-PE image region. - - The DxeCore calls CpuArchProtocol->SetMemoryAttributes() to protect - the image. If the CpuArch protocol is not installed yet, the DxeCore - enqueues the protection request. Once the CpuArch is installed, the - DxeCore dequeues the protection request and applies policy. - - Once the image is unloaded, the protection is removed automatically. - -Copyright (c) 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "DxeMain.h" - -#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP) -#define MEMORY_ATTRIBUTE_MASK (EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RO) - -// -// Image type definitions -// -#define IMAGE_UNKNOWN 0x00000001 -#define IMAGE_FROM_FV 0x00000002 - -// -// Protection policy bit definition -// -#define DO_NOT_PROTECT 0x00000000 -#define PROTECT_IF_ALIGNED_ELSE_ALLOW 0x00000001 - -#define MEMORY_TYPE_OS_RESERVED_MIN 0x80000000 -#define MEMORY_TYPE_OEM_RESERVED_MIN 0x70000000 - -#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ - ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) - -UINT32 mImageProtectionPolicy; - -extern LIST_ENTRY mGcdMemorySpaceMap; - -STATIC LIST_ENTRY mProtectedImageRecordList; - -/** - Sort code section in image record, based upon CodeSegmentBase from low to high. - - @param ImageRecord image record to be sorted -**/ -VOID -SortImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ); - -/** - Check if code section in image record is valid. - - @param ImageRecord image record to be checked - - @retval TRUE image record is valid - @retval FALSE image record is invalid -**/ -BOOLEAN -IsImageRecordCodeSectionValid ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ); - -/** - Get the image type. - - @param[in] File This is a pointer to the device path of the file that is - being dispatched. - - @return UINT32 Image Type -**/ -UINT32 -GetImageType ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *File - ) -{ - EFI_STATUS Status; - EFI_HANDLE DeviceHandle; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - - if (File == NULL) { - return IMAGE_UNKNOWN; - } - - // - // First check to see if File is from a Firmware Volume - // - DeviceHandle = NULL; - TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) File; - Status = gBS->LocateDevicePath ( - &gEfiFirmwareVolume2ProtocolGuid, - &TempDevicePath, - &DeviceHandle - ); - if (!EFI_ERROR (Status)) { - Status = gBS->OpenProtocol ( - DeviceHandle, - &gEfiFirmwareVolume2ProtocolGuid, - NULL, - NULL, - NULL, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - return IMAGE_FROM_FV; - } - } - return IMAGE_UNKNOWN; -} - -/** - Get UEFI image protection policy based upon image type. - - @param[in] ImageType The UEFI image type - - @return UEFI image protection policy -**/ -UINT32 -GetProtectionPolicyFromImageType ( - IN UINT32 ImageType - ) -{ - if ((ImageType & mImageProtectionPolicy) == 0) { - return DO_NOT_PROTECT; - } else { - return PROTECT_IF_ALIGNED_ELSE_ALLOW; - } -} - -/** - Get UEFI image protection policy based upon loaded image device path. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol - - @return UEFI image protection policy -**/ -UINT32 -GetUefiImageProtectionPolicy ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath - ) -{ - BOOLEAN InSmm; - UINT32 ImageType; - UINT32 ProtectionPolicy; - - // - // Check SMM - // - InSmm = FALSE; - if (gSmmBase2 != NULL) { - gSmmBase2->InSmm (gSmmBase2, &InSmm); - } - if (InSmm) { - return FALSE; - } - - // - // Check DevicePath - // - if (LoadedImage == gDxeCoreLoadedImage) { - ImageType = IMAGE_FROM_FV; - } else { - ImageType = GetImageType (LoadedImageDevicePath); - } - ProtectionPolicy = GetProtectionPolicyFromImageType (ImageType); - return ProtectionPolicy; -} - - -/** - Set UEFI image memory attributes. - - @param[in] BaseAddress Specified start address - @param[in] Length Specified length - @param[in] Attributes Specified attributes -**/ -VOID -SetUefiImageMemoryAttributes ( - IN UINT64 BaseAddress, - IN UINT64 Length, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; - UINT64 FinalAttributes; - - Status = CoreGetMemorySpaceDescriptor(BaseAddress, &Descriptor); - ASSERT_EFI_ERROR(Status); - - FinalAttributes = (Descriptor.Attributes & CACHE_ATTRIBUTE_MASK) | (Attributes & MEMORY_ATTRIBUTE_MASK); - - DEBUG ((DEBUG_INFO, "SetUefiImageMemoryAttributes - 0x%016lx - 0x%016lx (0x%016lx)\n", BaseAddress, Length, FinalAttributes)); - - ASSERT(gCpu != NULL); - gCpu->SetMemoryAttributes (gCpu, BaseAddress, Length, FinalAttributes); -} - -/** - Set UEFI image protection attributes. - - @param[in] ImageRecord A UEFI image record -**/ -VOID -SetUefiImageProtectionAttributes ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - UINT64 CurrentBase; - UINT64 ImageEnd; - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - CurrentBase = ImageRecord->ImageBase; - ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - - ASSERT (CurrentBase <= ImageRecordCodeSection->CodeSegmentBase); - if (CurrentBase < ImageRecordCodeSection->CodeSegmentBase) { - // - // DATA - // - SetUefiImageMemoryAttributes ( - CurrentBase, - ImageRecordCodeSection->CodeSegmentBase - CurrentBase, - EFI_MEMORY_XP - ); - } - // - // CODE - // - SetUefiImageMemoryAttributes ( - ImageRecordCodeSection->CodeSegmentBase, - ImageRecordCodeSection->CodeSegmentSize, - EFI_MEMORY_RO - ); - CurrentBase = ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize; - } - // - // Last DATA - // - ASSERT (CurrentBase <= ImageEnd); - if (CurrentBase < ImageEnd) { - // - // DATA - // - SetUefiImageMemoryAttributes ( - CurrentBase, - ImageEnd - CurrentBase, - EFI_MEMORY_XP - ); - } - return ; -} - -/** - Return if the PE image section is aligned. - - @param[in] SectionAlignment PE/COFF section alignment - @param[in] MemoryType PE/COFF image memory type - - @retval TRUE The PE image section is aligned. - @retval FALSE The PE image section is not aligned. -**/ -BOOLEAN -IsMemoryProtectionSectionAligned ( - IN UINT32 SectionAlignment, - IN EFI_MEMORY_TYPE MemoryType - ) -{ - UINT32 PageAlignment; - - switch (MemoryType) { - case EfiRuntimeServicesCode: - case EfiACPIMemoryNVS: - PageAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - break; - case EfiRuntimeServicesData: - case EfiACPIReclaimMemory: - ASSERT (FALSE); - PageAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - break; - case EfiBootServicesCode: - case EfiLoaderCode: - case EfiReservedMemoryType: - PageAlignment = EFI_PAGE_SIZE; - break; - default: - ASSERT (FALSE); - PageAlignment = EFI_PAGE_SIZE; - break; - } - - if ((SectionAlignment & (PageAlignment - 1)) != 0) { - return FALSE; - } else { - return TRUE; - } -} - -/** - Free Image record. - - @param[in] ImageRecord A UEFI image record -**/ -VOID -FreeImageRecord ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - LIST_ENTRY *CodeSegmentListHead; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - - CodeSegmentListHead = &ImageRecord->CodeSegmentList; - while (!IsListEmpty (CodeSegmentListHead)) { - ImageRecordCodeSection = CR ( - CodeSegmentListHead->ForwardLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - RemoveEntryList (&ImageRecordCodeSection->Link); - FreePool (ImageRecordCodeSection); - } - - if (ImageRecord->Link.ForwardLink != NULL) { - RemoveEntryList (&ImageRecord->Link); - } - FreePool (ImageRecord); -} - -/** - Protect UEFI PE/COFF image. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol -**/ -VOID -ProtectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath - ) -{ - VOID *ImageAddress; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT32 PeCoffHeaderOffset; - UINT32 SectionAlignment; - EFI_IMAGE_SECTION_HEADER *Section; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - UINT8 *Name; - UINTN Index; - IMAGE_PROPERTIES_RECORD *ImageRecord; - CHAR8 *PdbPointer; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - UINT16 Magic; - BOOLEAN IsAligned; - UINT32 ProtectionPolicy; - - DEBUG ((DEBUG_INFO, "ProtectUefiImageCommon - 0x%x\n", LoadedImage)); - DEBUG ((DEBUG_INFO, " - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase, LoadedImage->ImageSize)); - - if (gCpu == NULL) { - return ; - } - - ProtectionPolicy = GetUefiImageProtectionPolicy (LoadedImage, LoadedImageDevicePath); - switch (ProtectionPolicy) { - case DO_NOT_PROTECT: - return ; - case PROTECT_IF_ALIGNED_ELSE_ALLOW: - break; - default: - ASSERT(FALSE); - return ; - } - - ImageRecord = AllocateZeroPool (sizeof(*ImageRecord)); - if (ImageRecord == NULL) { - return ; - } - ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE; - - // - // Step 1: record whole region - // - ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase; - ImageRecord->ImageSize = LoadedImage->ImageSize; - - ImageAddress = LoadedImage->ImageBase; - - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_VERBOSE, " Image - %a\n", PdbPointer)); - } - - // - // Check PE/COFF image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress; - PeCoffHeaderOffset = 0; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - PeCoffHeaderOffset = DosHdr->e_lfanew; - } - - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset); - if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - DEBUG ((DEBUG_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature)); - // It might be image in SMM. - goto Finish; - } - - // - // Get SectionAlignment - // - if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value - // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the - // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - } else { - // - // Get the magic value from the PE/COFF Optional Header - // - Magic = Hdr.Pe32->OptionalHeader.Magic; - } - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment; - } else { - SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment; - } - - IsAligned = IsMemoryProtectionSectionAligned (SectionAlignment, LoadedImage->ImageCodeType); - if (!IsAligned) { - DEBUG ((DEBUG_VERBOSE, "!!!!!!!! ProtectUefiImageCommon - Section Alignment(0x%x) is incorrect !!!!!!!!\n", - SectionAlignment)); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_VERBOSE, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); - } - goto Finish; - } - - Section = (EFI_IMAGE_SECTION_HEADER *) ( - (UINT8 *) (UINTN) ImageAddress + - PeCoffHeaderOffset + - sizeof(UINT32) + - sizeof(EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); - ImageRecord->CodeSegmentCount = 0; - InitializeListHead (&ImageRecord->CodeSegmentList); - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Name = Section[Index].Name; - DEBUG (( - DEBUG_VERBOSE, - " Section - '%c%c%c%c%c%c%c%c'\n", - Name[0], - Name[1], - Name[2], - Name[3], - Name[4], - Name[5], - Name[6], - Name[7] - )); - - // - // Instead of assuming that a PE/COFF section of type EFI_IMAGE_SCN_CNT_CODE - // can always be mapped read-only, classify a section as a code section only - // if it has the executable attribute set and the writable attribute cleared. - // - // This adheres more closely to the PE/COFF spec, and avoids issues with - // Linux OS loaders that may consist of a single read/write/execute section. - // - if ((Section[Index].Characteristics & (EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_EXECUTE)) == EFI_IMAGE_SCN_MEM_EXECUTE) { - DEBUG ((DEBUG_VERBOSE, " VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize)); - DEBUG ((DEBUG_VERBOSE, " VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress)); - DEBUG ((DEBUG_VERBOSE, " SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData)); - DEBUG ((DEBUG_VERBOSE, " PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData)); - DEBUG ((DEBUG_VERBOSE, " PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations)); - DEBUG ((DEBUG_VERBOSE, " PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers)); - DEBUG ((DEBUG_VERBOSE, " NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations)); - DEBUG ((DEBUG_VERBOSE, " NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers)); - DEBUG ((DEBUG_VERBOSE, " Characteristics - 0x%08x\n", Section[Index].Characteristics)); - - // - // Step 2: record code section - // - ImageRecordCodeSection = AllocatePool (sizeof(*ImageRecordCodeSection)); - if (ImageRecordCodeSection == NULL) { - return ; - } - ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE; - - ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress; - ImageRecordCodeSection->CodeSegmentSize = ALIGN_VALUE(Section[Index].SizeOfRawData, SectionAlignment); - - DEBUG ((DEBUG_VERBOSE, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize)); - - InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link); - ImageRecord->CodeSegmentCount++; - } - } - - if (ImageRecord->CodeSegmentCount == 0) { - // - // If a UEFI executable consists of a single read+write+exec PE/COFF - // section, that isn't actually an error. The image can be launched - // alright, only image protection cannot be applied to it fully. - // - // One example that elicits this is (some) Linux kernels (with the EFI stub - // of course). - // - DEBUG ((DEBUG_WARN, "!!!!!!!! ProtectUefiImageCommon - CodeSegmentCount is 0 !!!!!!!!\n")); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); - } - goto Finish; - } - - // - // Final - // - SortImageRecordCodeSection (ImageRecord); - // - // Check overlap all section in ImageBase/Size - // - if (!IsImageRecordCodeSectionValid (ImageRecord)) { - DEBUG ((DEBUG_ERROR, "IsImageRecordCodeSectionValid - FAIL\n")); - goto Finish; - } - - // - // Round up the ImageSize, some CPU arch may return EFI_UNSUPPORTED if ImageSize is not aligned. - // Given that the loader always allocates full pages, we know the space after the image is not used. - // - ImageRecord->ImageSize = ALIGN_VALUE(LoadedImage->ImageSize, EFI_PAGE_SIZE); - - // - // CPU ARCH present. Update memory attribute directly. - // - SetUefiImageProtectionAttributes (ImageRecord); - - // - // Record the image record in the list so we can undo the protections later - // - InsertTailList (&mProtectedImageRecordList, &ImageRecord->Link); - -Finish: - return ; -} - -/** - Unprotect UEFI image. - - @param[in] LoadedImage The loaded image protocol - @param[in] LoadedImageDevicePath The loaded image device path protocol -**/ -VOID -UnprotectUefiImage ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - IN EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - - if (PcdGet32(PcdImageProtectionPolicy) != 0) { - for (ImageRecordLink = mProtectedImageRecordList.ForwardLink; - ImageRecordLink != &mProtectedImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if (ImageRecord->ImageBase == (EFI_PHYSICAL_ADDRESS)(UINTN)LoadedImage->ImageBase) { - SetUefiImageMemoryAttributes (ImageRecord->ImageBase, - ImageRecord->ImageSize, - 0); - FreeImageRecord (ImageRecord); - return; - } - } - } -} - -/** - Return the EFI memory permission attribute associated with memory - type 'MemoryType' under the configured DXE memory protection policy. - - @param MemoryType Memory type. -**/ -STATIC -UINT64 -GetPermissionAttributeForMemoryType ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - UINT64 TestBit; - - if ((UINT32)MemoryType >= MEMORY_TYPE_OS_RESERVED_MIN) { - TestBit = BIT63; - } else if ((UINT32)MemoryType >= MEMORY_TYPE_OEM_RESERVED_MIN) { - TestBit = BIT62; - } else { - TestBit = LShiftU64 (1, MemoryType); - } - - if ((PcdGet64 (PcdDxeNxMemoryProtectionPolicy) & TestBit) != 0) { - return EFI_MEMORY_XP; - } else { - return 0; - } -} - -/** - Sort memory map entries based upon PhysicalStart, from low to high. - - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -SortMemoryMap ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - EFI_MEMORY_DESCRIPTOR TempMemoryMap; - - MemoryMapEntry = MemoryMap; - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); - while (MemoryMapEntry < MemoryMapEnd) { - while (NextMemoryMapEntry < MemoryMapEnd) { - if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) { - CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof(EFI_MEMORY_DESCRIPTOR)); - } - - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - } - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - } -} - -/** - Merge adjacent memory map entries if they use the same memory protection policy - - @param[in, out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the current memory map. On output, - it is the size of new memory map after merge. - @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -MergeMemoryMapForProtectionPolicy ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN OUT UINTN *MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - UINT64 MemoryBlockLength; - EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - UINT64 Attributes; - - SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize); - - MemoryMapEntry = MemoryMap; - NewMemoryMapEntry = MemoryMap; - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + *MemoryMapSize); - while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - - do { - MemoryBlockLength = (UINT64) (EFI_PAGES_TO_SIZE((UINTN)MemoryMapEntry->NumberOfPages)); - Attributes = GetPermissionAttributeForMemoryType (MemoryMapEntry->Type); - - if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && - Attributes == GetPermissionAttributeForMemoryType (NextMemoryMapEntry->Type) && - ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) { - MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; - if (NewMemoryMapEntry != MemoryMapEntry) { - NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; - } - - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - continue; - } else { - MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - break; - } - } while (TRUE); - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize); - } - - *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap; - - return ; -} - - -/** - Remove exec permissions from all regions whose type is identified by - PcdDxeNxMemoryProtectionPolicy. -**/ -STATIC -VOID -InitializeDxeNxMemoryProtectionPolicy ( - VOID - ) -{ - UINTN MemoryMapSize; - UINTN MapKey; - UINTN DescriptorSize; - UINT32 DescriptorVersion; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - EFI_STATUS Status; - UINT64 Attributes; - LIST_ENTRY *Link; - EFI_GCD_MAP_ENTRY *Entry; - - // - // Get the EFI memory map. - // - MemoryMapSize = 0; - MemoryMap = NULL; - - Status = gBS->GetMemoryMap ( - &MemoryMapSize, - MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion - ); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - do { - MemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (MemoryMapSize); - ASSERT (MemoryMap != NULL); - Status = gBS->GetMemoryMap ( - &MemoryMapSize, - MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion - ); - if (EFI_ERROR (Status)) { - FreePool (MemoryMap); - } - } while (Status == EFI_BUFFER_TOO_SMALL); - ASSERT_EFI_ERROR (Status); - - DEBUG((DEBUG_ERROR, "%a: applying strict permissions to active memory regions\n", - __FUNCTION__)); - - MergeMemoryMapForProtectionPolicy (MemoryMap, &MemoryMapSize, DescriptorSize); - - MemoryMapEntry = MemoryMap; - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); - while ((UINTN) MemoryMapEntry < (UINTN) MemoryMapEnd) { - - Attributes = GetPermissionAttributeForMemoryType (MemoryMapEntry->Type); - if (Attributes != 0) { - SetUefiImageMemoryAttributes ( - MemoryMapEntry->PhysicalStart, - LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT), - Attributes); - } - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - } - FreePool (MemoryMap); - - // - // Apply the policy for RAM regions that we know are present and - // accessible, but have not been added to the UEFI memory map (yet). - // - if (GetPermissionAttributeForMemoryType (EfiConventionalMemory) != 0) { - DEBUG((DEBUG_ERROR, - "%a: applying strict permissions to inactive memory regions\n", - __FUNCTION__)); - - CoreAcquireGcdMemoryLock (); - - Link = mGcdMemorySpaceMap.ForwardLink; - while (Link != &mGcdMemorySpaceMap) { - - Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE); - - if (Entry->GcdMemoryType == EfiGcdMemoryTypeReserved && - Entry->EndAddress < MAX_ADDRESS && - (Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) == - (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) { - - Attributes = GetPermissionAttributeForMemoryType (EfiConventionalMemory) | - (Entry->Attributes & CACHE_ATTRIBUTE_MASK); - - DEBUG ((DEBUG_INFO, - "Untested GCD memory space region: - 0x%016lx - 0x%016lx (0x%016lx)\n", - Entry->BaseAddress, Entry->EndAddress - Entry->BaseAddress + 1, - Attributes)); - - ASSERT(gCpu != NULL); - gCpu->SetMemoryAttributes (gCpu, Entry->BaseAddress, - Entry->EndAddress - Entry->BaseAddress + 1, Attributes); - } - - Link = Link->ForwardLink; - } - CoreReleaseGcdMemoryLock (); - } -} - - -/** - A notification for CPU_ARCH protocol. - - @param[in] Event Event whose notification function is being invoked. - @param[in] Context Pointer to the notification function's context, - which is implementation-dependent. - -**/ -VOID -EFIAPI -MemoryProtectionCpuArchProtocolNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; - UINTN NoHandles; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - DEBUG ((DEBUG_INFO, "MemoryProtectionCpuArchProtocolNotify:\n")); - Status = CoreLocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu); - if (EFI_ERROR (Status)) { - return; - } - - // - // Apply the memory protection policy on non-BScode/RTcode regions. - // - if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0) { - InitializeDxeNxMemoryProtectionPolicy (); - } - - if (mImageProtectionPolicy == 0) { - return; - } - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiLoadedImageProtocolGuid, - NULL, - &NoHandles, - &HandleBuffer - ); - if (EFI_ERROR (Status) && (NoHandles == 0)) { - return ; - } - - for (Index = 0; Index < NoHandles; Index++) { - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiLoadedImageProtocolGuid, - (VOID **)&LoadedImage - ); - if (EFI_ERROR(Status)) { - continue; - } - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiLoadedImageDevicePathProtocolGuid, - (VOID **)&LoadedImageDevicePath - ); - if (EFI_ERROR(Status)) { - LoadedImageDevicePath = NULL; - } - - ProtectUefiImage (LoadedImage, LoadedImageDevicePath); - } - - CoreCloseEvent (Event); - return; -} - -/** - ExitBootServices Callback function for memory protection. -**/ -VOID -MemoryProtectionExitBootServicesCallback ( - VOID - ) -{ - EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage; - LIST_ENTRY *Link; - - // - // We need remove the RT protection, because RT relocation need write code segment - // at SetVirtualAddressMap(). We cannot assume OS/Loader has taken over page table at that time. - // - // Firmware does not own page tables after ExitBootServices(), so the OS would - // have to relax protection of RT code pages across SetVirtualAddressMap(), or - // delay setting protections on RT code pages until after SetVirtualAddressMap(). - // OS may set protection on RT based upon EFI_MEMORY_ATTRIBUTES_TABLE later. - // - if (mImageProtectionPolicy != 0) { - for (Link = gRuntime->ImageHead.ForwardLink; Link != &gRuntime->ImageHead; Link = Link->ForwardLink) { - RuntimeImage = BASE_CR (Link, EFI_RUNTIME_IMAGE_ENTRY, Link); - SetUefiImageMemoryAttributes ((UINT64)(UINTN)RuntimeImage->ImageBase, ALIGN_VALUE(RuntimeImage->ImageSize, EFI_PAGE_SIZE), 0); - } - } -} - -/** - Initialize Memory Protection support. -**/ -VOID -EFIAPI -CoreInitializeMemoryProtection ( - VOID - ) -{ - EFI_STATUS Status; - EFI_EVENT Event; - VOID *Registration; - - mImageProtectionPolicy = PcdGet32(PcdImageProtectionPolicy); - - InitializeListHead (&mProtectedImageRecordList); - - // - // Sanity check the PcdDxeNxMemoryProtectionPolicy setting: - // - code regions should have no EFI_MEMORY_XP attribute - // - EfiConventionalMemory and EfiBootServicesData should use the - // same attribute - // - ASSERT ((GetPermissionAttributeForMemoryType (EfiBootServicesCode) & EFI_MEMORY_XP) == 0); - ASSERT ((GetPermissionAttributeForMemoryType (EfiRuntimeServicesCode) & EFI_MEMORY_XP) == 0); - ASSERT ((GetPermissionAttributeForMemoryType (EfiLoaderCode) & EFI_MEMORY_XP) == 0); - ASSERT (GetPermissionAttributeForMemoryType (EfiBootServicesData) == - GetPermissionAttributeForMemoryType (EfiConventionalMemory)); - - if (mImageProtectionPolicy != 0 || PcdGet64 (PcdDxeNxMemoryProtectionPolicy) != 0) { - Status = CoreCreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - MemoryProtectionCpuArchProtocolNotify, - NULL, - &Event - ); - ASSERT_EFI_ERROR(Status); - - // - // Register for protocol notifactions on this event - // - Status = CoreRegisterProtocolNotify ( - &gEfiCpuArchProtocolGuid, - Event, - &Registration - ); - ASSERT_EFI_ERROR(Status); - } - return ; -} - -/** - Returns whether we are currently executing in SMM mode. -**/ -STATIC -BOOLEAN -IsInSmm ( - VOID - ) -{ - BOOLEAN InSmm; - - InSmm = FALSE; - if (gSmmBase2 != NULL) { - gSmmBase2->InSmm (gSmmBase2, &InSmm); - } - return InSmm; -} - -/** - Manage memory permission attributes on a memory range, according to the - configured DXE memory protection policy. - - @param OldType The old memory type of the range - @param NewType The new memory type of the range - @param Memory The base address of the range - @param Length The size of the range (in bytes) - - @return EFI_SUCCESS If we are executing in SMM mode. No permission attributes - are updated in this case - @return EFI_SUCCESS If the the CPU arch protocol is not installed yet - @return EFI_SUCCESS If no DXE memory protection policy has been configured - @return EFI_SUCCESS If OldType and NewType use the same permission attributes - @return other Return value of gCpu->SetMemoryAttributes() - -**/ -EFI_STATUS -EFIAPI -ApplyMemoryProtectionPolicy ( - IN EFI_MEMORY_TYPE OldType, - IN EFI_MEMORY_TYPE NewType, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINT64 Length - ) -{ - UINT64 OldAttributes; - UINT64 NewAttributes; - - // - // The policy configured in PcdDxeNxMemoryProtectionPolicy - // does not apply to allocations performed in SMM mode. - // - if (IsInSmm ()) { - return EFI_SUCCESS; - } - - // - // If the CPU arch protocol is not installed yet, we cannot manage memory - // permission attributes, and it is the job of the driver that installs this - // protocol to set the permissions on existing allocations. - // - if (gCpu == NULL) { - return EFI_SUCCESS; - } - - // - // Check if a DXE memory protection policy has been configured - // - if (PcdGet64 (PcdDxeNxMemoryProtectionPolicy) == 0) { - return EFI_SUCCESS; - } - - // - // Update the executable permissions according to the DXE memory - // protection policy, but only if - // - the policy is different between the old and the new type, or - // - this is a newly added region (OldType == EfiMaxMemoryType) - // - NewAttributes = GetPermissionAttributeForMemoryType (NewType); - - if (OldType != EfiMaxMemoryType) { - OldAttributes = GetPermissionAttributeForMemoryType (OldType); - if (OldAttributes == NewAttributes) { - // policy is the same between OldType and NewType - return EFI_SUCCESS; - } - } else if (NewAttributes == 0) { - // newly added region of a type that does not require protection - return EFI_SUCCESS; - } - - return gCpu->SetMemoryAttributes (gCpu, Memory, Length, NewAttributes); -} diff --git a/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c b/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c deleted file mode 100644 index e7c4a95712..0000000000 --- a/MdeModulePkg/Core/Dxe/Misc/PropertiesTable.c +++ /dev/null @@ -1,1379 +0,0 @@ -/** @file - UEFI PropertiesTable support - -Copyright (c) 2015 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include - -#include "DxeMain.h" - -#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ - ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) - -#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D') - -typedef struct { - UINT32 Signature; - UINTN ImageRecordCount; - UINTN CodeSegmentCountMax; - LIST_ENTRY ImageRecordList; -} IMAGE_PROPERTIES_PRIVATE_DATA; - -IMAGE_PROPERTIES_PRIVATE_DATA mImagePropertiesPrivateData = { - IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE, - 0, - 0, - INITIALIZE_LIST_HEAD_VARIABLE (mImagePropertiesPrivateData.ImageRecordList) -}; - -EFI_PROPERTIES_TABLE mPropertiesTable = { - EFI_PROPERTIES_TABLE_VERSION, - sizeof(EFI_PROPERTIES_TABLE), - EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA -}; - -EFI_LOCK mPropertiesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); - -BOOLEAN mPropertiesTableEnable; - -// -// Below functions are for MemoryMap -// - -/** - Converts a number of EFI_PAGEs to a size in bytes. - - NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only. - - @param Pages The number of EFI_PAGES. - - @return The number of bytes associated with the number of EFI_PAGEs specified - by Pages. -**/ -STATIC -UINT64 -EfiPagesToSize ( - IN UINT64 Pages - ) -{ - return LShiftU64 (Pages, EFI_PAGE_SHIFT); -} - -/** - Converts a size, in bytes, to a number of EFI_PAGESs. - - NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only. - - @param Size A size in bytes. - - @return The number of EFI_PAGESs associated with the number of bytes specified - by Size. - -**/ -STATIC -UINT64 -EfiSizeToPages ( - IN UINT64 Size - ) -{ - return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0); -} - -/** - Acquire memory lock on mPropertiesTableLock. -**/ -STATIC -VOID -CoreAcquirePropertiesTableLock ( - VOID - ) -{ - CoreAcquireLock (&mPropertiesTableLock); -} - -/** - Release memory lock on mPropertiesTableLock. -**/ -STATIC -VOID -CoreReleasePropertiesTableLock ( - VOID - ) -{ - CoreReleaseLock (&mPropertiesTableLock); -} - -/** - Sort memory map entries based upon PhysicalStart, from low to high. - - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -SortMemoryMap ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - EFI_MEMORY_DESCRIPTOR TempMemoryMap; - - MemoryMapEntry = MemoryMap; - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); - while (MemoryMapEntry < MemoryMapEnd) { - while (NextMemoryMapEntry < MemoryMapEnd) { - if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) { - CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof(EFI_MEMORY_DESCRIPTOR)); - } - - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - } - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - } - - return ; -} - -/** - Merge continous memory map entries whose have same attributes. - - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the current memory map. On output, - it is the size of new memory map after merge. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -MergeMemoryMap ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN OUT UINTN *MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - UINT64 MemoryBlockLength; - EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - - MemoryMapEntry = MemoryMap; - NewMemoryMapEntry = MemoryMap; - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + *MemoryMapSize); - while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - - do { - MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages)); - if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && - (MemoryMapEntry->Type == NextMemoryMapEntry->Type) && - (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) && - ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) { - MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; - if (NewMemoryMapEntry != MemoryMapEntry) { - NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; - } - - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - continue; - } else { - MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - break; - } - } while (TRUE); - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize); - } - - *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap; - - return ; -} - -/** - Enforce memory map attributes. - This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP. - - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MemoryMapSize Size, in bytes, of the MemoryMap buffer. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -EnforceMemoryMapAttribute ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - - MemoryMapEntry = MemoryMap; - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); - while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - switch (MemoryMapEntry->Type) { - case EfiRuntimeServicesCode: - // do nothing - break; - case EfiRuntimeServicesData: - case EfiMemoryMappedIO: - case EfiMemoryMappedIOPortSpace: - MemoryMapEntry->Attribute |= EFI_MEMORY_XP; - break; - case EfiReservedMemoryType: - case EfiACPIMemoryNVS: - break; - } - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - } - - return ; -} - -/** - Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length]. - - @param Buffer Start Address - @param Length Address length - - @return first image record covered by [buffer, length] -**/ -STATIC -IMAGE_PROPERTIES_RECORD * -GetImageRecordByAddress ( - IN EFI_PHYSICAL_ADDRESS Buffer, - IN UINT64 Length - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *ImageRecordList; - - ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; - - for (ImageRecordLink = ImageRecordList->ForwardLink; - ImageRecordLink != ImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if ((Buffer <= ImageRecord->ImageBase) && - (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize)) { - return ImageRecord; - } - } - - return NULL; -} - -/** - Set the memory map to new entries, according to one old entry, - based upon PE code section and data section in image record - - @param ImageRecord An image record whose [ImageBase, ImageSize] covered - by old memory map entry. - @param NewRecord A pointer to several new memory map entries. - The caller gurantee the buffer size be 1 + - (SplitRecordCount * DescriptorSize) calculated - below. - @param OldRecord A pointer to one old memory map entry. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -UINTN -SetNewRecord ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord, - IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, - IN EFI_MEMORY_DESCRIPTOR *OldRecord, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR TempRecord; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - UINTN NewRecordCount; - UINT64 PhysicalEnd; - UINT64 ImageEnd; - - CopyMem (&TempRecord, OldRecord, sizeof(EFI_MEMORY_DESCRIPTOR)); - PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages); - NewRecordCount = 0; - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - - if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) { - // - // DATA - // - if (!mPropertiesTableEnable) { - NewRecord->Type = TempRecord.Type; - } else { - NewRecord->Type = EfiRuntimeServicesData; - } - NewRecord->PhysicalStart = TempRecord.PhysicalStart; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart); - NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP; - if (NewRecord->NumberOfPages != 0) { - NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount ++; - } - - // - // CODE - // - if (!mPropertiesTableEnable) { - NewRecord->Type = TempRecord.Type; - } else { - NewRecord->Type = EfiRuntimeServicesCode; - } - NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize); - NewRecord->Attribute = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO; - if (NewRecord->NumberOfPages != 0) { - NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount ++; - } - - TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize)); - TempRecord.NumberOfPages = EfiSizeToPages(PhysicalEnd - TempRecord.PhysicalStart); - if (TempRecord.NumberOfPages == 0) { - break; - } - } - } - - ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize; - - // - // Final DATA - // - if (TempRecord.PhysicalStart < ImageEnd) { - if (!mPropertiesTableEnable) { - NewRecord->Type = TempRecord.Type; - } else { - NewRecord->Type = EfiRuntimeServicesData; - } - NewRecord->PhysicalStart = TempRecord.PhysicalStart; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart); - NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP; - NewRecordCount ++; - } - - return NewRecordCount; -} - -/** - Return the max number of new splitted entries, according to one old entry, - based upon PE code section and data section. - - @param OldRecord A pointer to one old memory map entry. - - @retval 0 no entry need to be splitted. - @return the max number of new splitted entries -**/ -STATIC -UINTN -GetMaxSplitRecordCount ( - IN EFI_MEMORY_DESCRIPTOR *OldRecord - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - UINTN SplitRecordCount; - UINT64 PhysicalStart; - UINT64 PhysicalEnd; - - SplitRecordCount = 0; - PhysicalStart = OldRecord->PhysicalStart; - PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize(OldRecord->NumberOfPages); - - do { - ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart); - if (ImageRecord == NULL) { - break; - } - SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 1); - PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; - } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); - - if (SplitRecordCount != 0) { - SplitRecordCount--; - } - - return SplitRecordCount; -} - -/** - Split the memory map to new entries, according to one old entry, - based upon PE code section and data section. - - @param OldRecord A pointer to one old memory map entry. - @param NewRecord A pointer to several new memory map entries. - The caller gurantee the buffer size be 1 + - (SplitRecordCount * DescriptorSize) calculated - below. - @param MaxSplitRecordCount The max number of splitted entries - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. - - @retval 0 no entry is splitted. - @return the real number of splitted record. -**/ -STATIC -UINTN -SplitRecord ( - IN EFI_MEMORY_DESCRIPTOR *OldRecord, - IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, - IN UINTN MaxSplitRecordCount, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR TempRecord; - IMAGE_PROPERTIES_RECORD *ImageRecord; - IMAGE_PROPERTIES_RECORD *NewImageRecord; - UINT64 PhysicalStart; - UINT64 PhysicalEnd; - UINTN NewRecordCount; - UINTN TotalNewRecordCount; - BOOLEAN IsLastRecordData; - - if (MaxSplitRecordCount == 0) { - CopyMem (NewRecord, OldRecord, DescriptorSize); - return 0; - } - - TotalNewRecordCount = 0; - - // - // Override previous record - // - CopyMem (&TempRecord, OldRecord, sizeof(EFI_MEMORY_DESCRIPTOR)); - PhysicalStart = TempRecord.PhysicalStart; - PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages); - - ImageRecord = NULL; - do { - NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart); - if (NewImageRecord == NULL) { - // - // No more image covered by this range, stop - // - if ((PhysicalEnd > PhysicalStart) && (ImageRecord != NULL)) { - // - // If this is still address in this record, need record. - // - NewRecord = PREVIOUS_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - IsLastRecordData = FALSE; - if (!mPropertiesTableEnable) { - if ((NewRecord->Attribute & EFI_MEMORY_XP) != 0) { - IsLastRecordData = TRUE; - } - } else { - if (NewRecord->Type == EfiRuntimeServicesData) { - IsLastRecordData = TRUE; - } - } - if (IsLastRecordData) { - // - // Last record is DATA, just merge it. - // - NewRecord->NumberOfPages = EfiSizeToPages(PhysicalEnd - NewRecord->PhysicalStart); - } else { - // - // Last record is CODE, create a new DATA entry. - // - NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - if (!mPropertiesTableEnable) { - NewRecord->Type = TempRecord.Type; - } else { - NewRecord->Type = EfiRuntimeServicesData; - } - NewRecord->PhysicalStart = TempRecord.PhysicalStart; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = TempRecord.NumberOfPages; - NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP; - TotalNewRecordCount ++; - } - } - break; - } - ImageRecord = NewImageRecord; - - // - // Set new record - // - NewRecordCount = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize); - TotalNewRecordCount += NewRecordCount; - NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize); - - // - // Update PhysicalStart, in order to exclude the image buffer already splitted. - // - PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; - TempRecord.PhysicalStart = PhysicalStart; - TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart); - } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); - - return TotalNewRecordCount - 1; -} - -/** - Split the original memory map, and add more entries to describe PE code section and data section. - This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP. - This function will merge entries with same attributes finally. - - NOTE: It assumes PE code/data section are page aligned. - NOTE: It assumes enough entry is prepared for new memory map. - - Split table: - +---------------+ - | Record X | - +---------------+ - | Record RtCode | - +---------------+ - | Record Y | - +---------------+ - ==> - +---------------+ - | Record X | - +---------------+ ---- - | Record RtData | | - +---------------+ | - | Record RtCode | |-> PE/COFF1 - +---------------+ | - | Record RtData | | - +---------------+ ---- - | Record RtData | | - +---------------+ | - | Record RtCode | |-> PE/COFF2 - +---------------+ | - | Record RtData | | - +---------------+ ---- - | Record Y | - +---------------+ - - @param MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - old MemoryMap before split. The actual buffer - size of MemoryMap is MemoryMapSize + - (AdditionalRecordCount * DescriptorSize) calculated - below. On output, it is the size of new MemoryMap - after split. - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -SplitTable ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - INTN IndexOld; - INTN IndexNew; - UINTN MaxSplitRecordCount; - UINTN RealSplitRecordCount; - UINTN TotalSplitRecordCount; - UINTN AdditionalRecordCount; - - AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount; - - TotalSplitRecordCount = 0; - // - // Let old record point to end of valid MemoryMap buffer. - // - IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1; - // - // Let new record point to end of full MemoryMap buffer. - // - IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + AdditionalRecordCount; - for (; IndexOld >= 0; IndexOld--) { - MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize)); - // - // Split this MemoryMap record - // - IndexNew -= MaxSplitRecordCount; - RealSplitRecordCount = SplitRecord ( - (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), - (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize), - MaxSplitRecordCount, - DescriptorSize - ); - // - // Adjust IndexNew according to real split. - // - CopyMem ( - ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize), - ((UINT8 *)MemoryMap + IndexNew * DescriptorSize), - RealSplitRecordCount * DescriptorSize - ); - IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount; - TotalSplitRecordCount += RealSplitRecordCount; - IndexNew --; - } - // - // Move all records to the beginning. - // - CopyMem ( - MemoryMap, - (UINT8 *)MemoryMap + (AdditionalRecordCount - TotalSplitRecordCount) * DescriptorSize, - (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize - ); - - *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount; - - // - // Sort from low to high (Just in case) - // - SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize); - - // - // Set RuntimeData to XP - // - EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, DescriptorSize); - - // - // Merge same type to save entry size - // - MergeMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize); - - return ; -} - -/** - This function for GetMemoryMap() with properties table capability. - - It calls original GetMemoryMap() to get the original memory map information. Then - plus the additional memory map entries for PE Code/Data seperation. - - @param MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -CoreGetMemoryMapWithSeparatedImageSection ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ) -{ - EFI_STATUS Status; - UINTN OldMemoryMapSize; - UINTN AdditionalRecordCount; - - // - // If PE code/data is not aligned, just return. - // - if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { - return CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); - } - - if (MemoryMapSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - CoreAcquirePropertiesTableLock (); - - AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 1) * mImagePropertiesPrivateData.ImageRecordCount; - - OldMemoryMapSize = *MemoryMapSize; - Status = CoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); - if (Status == EFI_BUFFER_TOO_SMALL) { - *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount; - } else if (Status == EFI_SUCCESS) { - ASSERT (MemoryMap != NULL); - if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) { - *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount; - // - // Need update status to buffer too small - // - Status = EFI_BUFFER_TOO_SMALL; - } else { - // - // Split PE code/data - // - SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize); - } - } - - CoreReleasePropertiesTableLock (); - return Status; -} - -// -// Below functions are for ImageRecord -// - -/** - Set PropertiesTable according to PE/COFF image section alignment. - - @param SectionAlignment PE/COFF section alignment -**/ -STATIC -VOID -SetPropertiesTableSectionAlignment ( - IN UINT32 SectionAlignment - ) -{ - if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) && - ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0)) { - DEBUG ((EFI_D_VERBOSE, "SetPropertiesTableSectionAlignment - Clear\n")); - mPropertiesTable.MemoryProtectionAttribute &= ~((UINT64)EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); - gBS->GetMemoryMap = CoreGetMemoryMap; - gBS->Hdr.CRC32 = 0; - gBS->CalculateCrc32 ((UINT8 *)gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32); - } -} - -/** - Swap two code sections in image record. - - @param FirstImageRecordCodeSection first code section in image record - @param SecondImageRecordCodeSection second code section in image record -**/ -STATIC -VOID -SwapImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection; - - TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase; - TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize; - - FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase; - FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize; - - SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase; - SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize; -} - -/** - Sort code section in image record, based upon CodeSegmentBase from low to high. - - @param ImageRecord image record to be sorted -**/ -VOID -SortImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *NextImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - NextImageRecordCodeSection = CR ( - NextImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) { - SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection); - } - NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink; - } - - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - } -} - -/** - Check if code section in image record is valid. - - @param ImageRecord image record to be checked - - @retval TRUE image record is valid - @retval FALSE image record is invalid -**/ -BOOLEAN -IsImageRecordCodeSectionValid ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *LastImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - - DEBUG ((EFI_D_VERBOSE, "ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount)); - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - LastImageRecordCodeSection = NULL; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - if (ImageRecordCodeSection->CodeSegmentSize == 0) { - return FALSE; - } - if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) { - return FALSE; - } - if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) { - return FALSE; - } - if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) { - return FALSE; - } - if (LastImageRecordCodeSection != NULL) { - if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) { - return FALSE; - } - } - - LastImageRecordCodeSection = ImageRecordCodeSection; - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - } - - return TRUE; -} - -/** - Swap two image records. - - @param FirstImageRecord first image record. - @param SecondImageRecord second image record. -**/ -STATIC -VOID -SwapImageRecord ( - IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, - IN IMAGE_PROPERTIES_RECORD *SecondImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD TempImageRecord; - - TempImageRecord.ImageBase = FirstImageRecord->ImageBase; - TempImageRecord.ImageSize = FirstImageRecord->ImageSize; - TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount; - - FirstImageRecord->ImageBase = SecondImageRecord->ImageBase; - FirstImageRecord->ImageSize = SecondImageRecord->ImageSize; - FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount; - - SecondImageRecord->ImageBase = TempImageRecord.ImageBase; - SecondImageRecord->ImageSize = TempImageRecord.ImageSize; - SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount; - - SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList); -} - -/** - Sort image record based upon the ImageBase from low to high. -**/ -STATIC -VOID -SortImageRecord ( - VOID - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - IMAGE_PROPERTIES_RECORD *NextImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *NextImageRecordLink; - LIST_ENTRY *ImageRecordEndLink; - LIST_ENTRY *ImageRecordList; - - ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; - - ImageRecordLink = ImageRecordList->ForwardLink; - NextImageRecordLink = ImageRecordLink->ForwardLink; - ImageRecordEndLink = ImageRecordList; - while (ImageRecordLink != ImageRecordEndLink) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - while (NextImageRecordLink != ImageRecordEndLink) { - NextImageRecord = CR ( - NextImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - if (ImageRecord->ImageBase > NextImageRecord->ImageBase) { - SwapImageRecord (ImageRecord, NextImageRecord); - } - NextImageRecordLink = NextImageRecordLink->ForwardLink; - } - - ImageRecordLink = ImageRecordLink->ForwardLink; - NextImageRecordLink = ImageRecordLink->ForwardLink; - } -} - -/** - Dump image record. -**/ -STATIC -VOID -DumpImageRecord ( - VOID - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *ImageRecordList; - UINTN Index; - - ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; - - for (ImageRecordLink = ImageRecordList->ForwardLink, Index= 0; - ImageRecordLink != ImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink, Index++) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - DEBUG ((EFI_D_VERBOSE, " Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->ImageBase, ImageRecord->ImageSize)); - } -} - -/** - Insert image record. - - @param RuntimeImage Runtime image information -**/ -VOID -InsertImageRecord ( - IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage - ) -{ - VOID *ImageAddress; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT32 PeCoffHeaderOffset; - UINT32 SectionAlignment; - EFI_IMAGE_SECTION_HEADER *Section; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - UINT8 *Name; - UINTN Index; - IMAGE_PROPERTIES_RECORD *ImageRecord; - CHAR8 *PdbPointer; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - UINT16 Magic; - - DEBUG ((EFI_D_VERBOSE, "InsertImageRecord - 0x%x\n", RuntimeImage)); - DEBUG ((EFI_D_VERBOSE, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize)); - - ImageRecord = AllocatePool (sizeof(*ImageRecord)); - if (ImageRecord == NULL) { - return ; - } - ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE; - - DEBUG ((EFI_D_VERBOSE, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); - - // - // Step 1: record whole region - // - ImageRecord->ImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase; - ImageRecord->ImageSize = RuntimeImage->ImageSize; - - ImageAddress = RuntimeImage->ImageBase; - - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((EFI_D_VERBOSE, " Image - %a\n", PdbPointer)); - } - - // - // Check PE/COFF image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress; - PeCoffHeaderOffset = 0; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - PeCoffHeaderOffset = DosHdr->e_lfanew; - } - - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset); - if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - DEBUG ((EFI_D_VERBOSE, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature)); - // It might be image in SMM. - goto Finish; - } - - // - // Get SectionAlignment - // - if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value - // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the - // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - } else { - // - // Get the magic value from the PE/COFF Optional Header - // - Magic = Hdr.Pe32->OptionalHeader.Magic; - } - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment; - } else { - SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment; - } - - SetPropertiesTableSectionAlignment (SectionAlignment); - if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) { - DEBUG ((EFI_D_WARN, "!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n", - SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10)); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((EFI_D_WARN, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); - } - goto Finish; - } - - Section = (EFI_IMAGE_SECTION_HEADER *) ( - (UINT8 *) (UINTN) ImageAddress + - PeCoffHeaderOffset + - sizeof(UINT32) + - sizeof(EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); - ImageRecord->CodeSegmentCount = 0; - InitializeListHead (&ImageRecord->CodeSegmentList); - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Name = Section[Index].Name; - DEBUG (( - EFI_D_VERBOSE, - " Section - '%c%c%c%c%c%c%c%c'\n", - Name[0], - Name[1], - Name[2], - Name[3], - Name[4], - Name[5], - Name[6], - Name[7] - )); - - if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) { - DEBUG ((EFI_D_VERBOSE, " VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize)); - DEBUG ((EFI_D_VERBOSE, " VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress)); - DEBUG ((EFI_D_VERBOSE, " SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData)); - DEBUG ((EFI_D_VERBOSE, " PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData)); - DEBUG ((EFI_D_VERBOSE, " PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations)); - DEBUG ((EFI_D_VERBOSE, " PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers)); - DEBUG ((EFI_D_VERBOSE, " NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations)); - DEBUG ((EFI_D_VERBOSE, " NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers)); - DEBUG ((EFI_D_VERBOSE, " Characteristics - 0x%08x\n", Section[Index].Characteristics)); - - // - // Step 2: record code section - // - ImageRecordCodeSection = AllocatePool (sizeof(*ImageRecordCodeSection)); - if (ImageRecordCodeSection == NULL) { - return ; - } - ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE; - - ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress; - ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData; - - DEBUG ((EFI_D_VERBOSE, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize)); - - InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link); - ImageRecord->CodeSegmentCount++; - } - } - - if (ImageRecord->CodeSegmentCount == 0) { - SetPropertiesTableSectionAlignment (1); - DEBUG ((EFI_D_ERROR, "!!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n")); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((EFI_D_ERROR, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); - } - goto Finish; - } - - // - // Final - // - SortImageRecordCodeSection (ImageRecord); - // - // Check overlap all section in ImageBase/Size - // - if (!IsImageRecordCodeSectionValid (ImageRecord)) { - DEBUG ((EFI_D_ERROR, "IsImageRecordCodeSectionValid - FAIL\n")); - goto Finish; - } - - InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link); - mImagePropertiesPrivateData.ImageRecordCount++; - - SortImageRecord (); - - if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) { - mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount; - } - -Finish: - return ; -} - -/** - Find image record according to image base and size. - - @param ImageBase Base of PE image - @param ImageSize Size of PE image - - @return image record -**/ -STATIC -IMAGE_PROPERTIES_RECORD * -FindImageRecord ( - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *ImageRecordList; - - ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; - - for (ImageRecordLink = ImageRecordList->ForwardLink; - ImageRecordLink != ImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if ((ImageBase == ImageRecord->ImageBase) && - (ImageSize == ImageRecord->ImageSize)) { - return ImageRecord; - } - } - - return NULL; -} - -/** - Remove Image record. - - @param RuntimeImage Runtime image information -**/ -VOID -RemoveImageRecord ( - IN EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *CodeSegmentListHead; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - - DEBUG ((EFI_D_VERBOSE, "RemoveImageRecord - 0x%x\n", RuntimeImage)); - DEBUG ((EFI_D_VERBOSE, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize)); - - ImageRecord = FindImageRecord ((EFI_PHYSICAL_ADDRESS)(UINTN)RuntimeImage->ImageBase, RuntimeImage->ImageSize); - if (ImageRecord == NULL) { - DEBUG ((EFI_D_ERROR, "!!!!!!!! ImageRecord not found !!!!!!!!\n")); - return ; - } - - CodeSegmentListHead = &ImageRecord->CodeSegmentList; - while (!IsListEmpty (CodeSegmentListHead)) { - ImageRecordCodeSection = CR ( - CodeSegmentListHead->ForwardLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - RemoveEntryList (&ImageRecordCodeSection->Link); - FreePool (ImageRecordCodeSection); - } - - RemoveEntryList (&ImageRecord->Link); - FreePool (ImageRecord); - mImagePropertiesPrivateData.ImageRecordCount--; -} - - -/** - Install PropertiesTable. - - @param[in] Event The Event this notify function registered to. - @param[in] Context Pointer to the context data registered to the Event. -**/ -VOID -EFIAPI -InstallPropertiesTable ( - EFI_EVENT Event, - VOID *Context - ) -{ - if (PcdGetBool (PcdPropertiesTableEnable)) { - EFI_STATUS Status; - - Status = gBS->InstallConfigurationTable (&gEfiPropertiesTableGuid, &mPropertiesTable); - ASSERT_EFI_ERROR (Status); - - DEBUG ((EFI_D_INFO, "MemoryProtectionAttribute - 0x%016lx\n", mPropertiesTable.MemoryProtectionAttribute)); - if ((mPropertiesTable.MemoryProtectionAttribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { - DEBUG ((EFI_D_ERROR, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, ")); - DEBUG ((EFI_D_ERROR, "because Runtime Driver Section Alignment is not %dK.\n", RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10)); - return ; - } - - gBS->GetMemoryMap = CoreGetMemoryMapWithSeparatedImageSection; - gBS->Hdr.CRC32 = 0; - gBS->CalculateCrc32 ((UINT8 *)gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32); - - DEBUG ((EFI_D_VERBOSE, "Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); - DEBUG ((EFI_D_VERBOSE, "Dump ImageRecord:\n")); - DumpImageRecord (); - - mPropertiesTableEnable = TRUE; - } -} - -/** - Initialize PropertiesTable support. -**/ -VOID -EFIAPI -CoreInitializePropertiesTable ( - VOID - ) -{ - EFI_STATUS Status; - EFI_EVENT EndOfDxeEvent; - - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - InstallPropertiesTable, - NULL, - &gEfiEndOfDxeEventGroupGuid, - &EndOfDxeEvent - ); - ASSERT_EFI_ERROR (Status); - return ; -} diff --git a/MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c b/MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c deleted file mode 100644 index f153815e86..0000000000 --- a/MdeModulePkg/Core/Dxe/Misc/SetWatchdogTimer.c +++ /dev/null @@ -1,72 +0,0 @@ -/** @file - UEFI Miscellaneous boot Services SetWatchdogTimer service implementation - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - -#define WATCHDOG_TIMER_CALIBRATE_PER_SECOND 10000000 - -/** - Sets the system's watchdog timer. - - @param Timeout The number of seconds to set the watchdog timer to. - A value of zero disables the timer. - @param WatchdogCode The numeric code to log on a watchdog timer timeout - event. The firmware reserves codes 0x0000 to 0xFFFF. - Loaders and operating systems may use other timeout - codes. - @param DataSize The size, in bytes, of WatchdogData. - @param WatchdogData A data buffer that includes a Null-terminated Unicode - string, optionally followed by additional binary data. - The string is a description that the call may use to - further indicate the reason to be logged with a - watchdog event. - - @return EFI_SUCCESS Timeout has been set - @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet - @return EFI_UNSUPPORTED System does not have a timer (currently not used) - @return EFI_DEVICE_ERROR Could not complete due to hardware error - -**/ -EFI_STATUS -EFIAPI -CoreSetWatchdogTimer ( - IN UINTN Timeout, - IN UINT64 WatchdogCode, - IN UINTN DataSize, - IN CHAR16 *WatchdogData OPTIONAL - ) -{ - EFI_STATUS Status; - - // - // Check our architectural protocol - // - if (gWatchdogTimer == NULL) { - return EFI_NOT_AVAILABLE_YET; - } - - // - // Attempt to set the timeout - // - Status = gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, MultU64x32 (Timeout, WATCHDOG_TIMER_CALIBRATE_PER_SECOND)); - - // - // Check for errors - // - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/Dxe/Misc/Stall.c b/MdeModulePkg/Core/Dxe/Misc/Stall.c deleted file mode 100644 index 95a561546f..0000000000 --- a/MdeModulePkg/Core/Dxe/Misc/Stall.c +++ /dev/null @@ -1,113 +0,0 @@ -/** @file - UEFI Miscellaneous boot Services Stall service implementation - -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -// -// Include statements -// - -#include "DxeMain.h" - -/** - Internal worker function to call the Metronome Architectural Protocol for - the number of ticks specified by the UINT64 Counter value. WaitForTick() - service of the Metronome Architectural Protocol uses a UINT32 for the number - of ticks to wait, so this function loops when Counter is larger than 0xffffffff. - - @param Counter Number of ticks to wait. - -**/ -VOID -CoreInternalWaitForTick ( - IN UINT64 Counter - ) -{ - while (RShiftU64 (Counter, 32) > 0) { - gMetronome->WaitForTick (gMetronome, 0xffffffff); - Counter -= 0xffffffff; - } - gMetronome->WaitForTick (gMetronome, (UINT32)Counter); -} - -/** - Introduces a fine-grained stall. - - @param Microseconds The number of microseconds to stall execution. - - @retval EFI_SUCCESS Execution was stalled for at least the requested - amount of microseconds. - @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet - -**/ -EFI_STATUS -EFIAPI -CoreStall ( - IN UINTN Microseconds - ) -{ - UINT64 Counter; - UINT32 Remainder; - UINTN Index; - - if (gMetronome == NULL) { - return EFI_NOT_AVAILABLE_YET; - } - - // - // Counter = Microseconds * 10 / gMetronome->TickPeriod - // 0x1999999999999999 = (2^64 - 1) / 10 - // - if ((UINT64) Microseconds > 0x1999999999999999ULL) { - // - // Microseconds is too large to multiple by 10 first. Perform the divide - // operation first and loop 10 times to avoid 64-bit math overflow. - // - Counter = DivU64x32Remainder ( - Microseconds, - gMetronome->TickPeriod, - &Remainder - ); - for (Index = 0; Index < 10; Index++) { - CoreInternalWaitForTick (Counter); - } - - if (Remainder != 0) { - // - // If Remainder was not zero, then normally, Counter would be rounded - // up by 1 tick. In this case, since a loop for 10 counts was used - // to emulate the multiply by 10 operation, Counter needs to be rounded - // up by 10 counts. - // - CoreInternalWaitForTick (10); - } - } else { - // - // Calculate the number of ticks by dividing the number of microseconds by - // the TickPeriod. Calculation is based on 100ns unit. - // - Counter = DivU64x32Remainder ( - MultU64x32 (Microseconds, 10), - gMetronome->TickPeriod, - &Remainder - ); - if (Remainder != 0) { - // - // If Remainder is not zero, then round Counter up by one tick. - // - Counter++; - } - CoreInternalWaitForTick (Counter); - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c deleted file mode 100644 index 6622eeeaf1..0000000000 --- a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c +++ /dev/null @@ -1,1605 +0,0 @@ -/** @file - Section Extraction Protocol implementation. - - Stream database is implemented as a linked list of section streams, - where each stream contains a linked list of children, which may be leaves or - encapsulations. - - Children that are encapsulations generate new stream entries - when they are created. Streams can also be created by calls to - SEP->OpenSectionStream(). - - The database is only created far enough to return the requested data from - any given stream, or to determine that the requested data is not found. - - If a GUIDed encapsulation is encountered, there are three possiblilites. - - 1) A support protocol is found, in which the stream is simply processed with - the support protocol. - - 2) A support protocol is not found, but the data is available to be read - without processing. In this case, the database is built up through the - recursions to return the data, and a RPN event is set that will enable - the stream in question to be refreshed if and when the required section - extraction protocol is published.This insures the AuthenticationStatus - does not become stale in the cache. - - 3) A support protocol is not found, and the data is not available to be read - without it. This results in EFI_PROTOCOL_ERROR. - -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeMain.h" - -// -// Local defines and typedefs -// -#define CORE_SECTION_CHILD_SIGNATURE SIGNATURE_32('S','X','C','S') -#define CHILD_SECTION_NODE_FROM_LINK(Node) \ - CR (Node, CORE_SECTION_CHILD_NODE, Link, CORE_SECTION_CHILD_SIGNATURE) - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - UINT32 Type; - UINT32 Size; - // - // StreamBase + OffsetInStream == pointer to section header in stream. The - // stream base is always known when walking the sections within. - // - UINT32 OffsetInStream; - // - // Then EncapsulatedStreamHandle below is always 0 if the section is NOT an - // encapsulating section. Otherwise, it contains the stream handle - // of the encapsulated stream. This handle is ALWAYS produced any time an - // encapsulating child is encountered, irrespective of whether the - // encapsulated stream is processed further. - // - UINTN EncapsulatedStreamHandle; - EFI_GUID *EncapsulationGuid; - // - // If the section REQUIRES an extraction protocol, register for RPN - // when the required GUIDed extraction protocol becomes available. - // - EFI_EVENT Event; -} CORE_SECTION_CHILD_NODE; - -#define CORE_SECTION_STREAM_SIGNATURE SIGNATURE_32('S','X','S','S') -#define STREAM_NODE_FROM_LINK(Node) \ - CR (Node, CORE_SECTION_STREAM_NODE, Link, CORE_SECTION_STREAM_SIGNATURE) - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - UINTN StreamHandle; - UINT8 *StreamBuffer; - UINTN StreamLength; - LIST_ENTRY Children; - // - // Authentication status is from GUIDed encapsulations. - // - UINT32 AuthenticationStatus; -} CORE_SECTION_STREAM_NODE; - -#define NULL_STREAM_HANDLE 0 - -typedef struct { - CORE_SECTION_CHILD_NODE *ChildNode; - CORE_SECTION_STREAM_NODE *ParentStream; - VOID *Registration; -} RPN_EVENT_CONTEXT; - - -/** - The ExtractSection() function processes the input section and - allocates a buffer from the pool in which it returns the section - contents. If the section being extracted contains - authentication information (the section's - GuidedSectionHeader.Attributes field has the - EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values - returned in AuthenticationStatus must reflect the results of - the authentication operation. Depending on the algorithm and - size of the encapsulated data, the time that is required to do - a full authentication may be prohibitively long for some - classes of systems. To indicate this, use - EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by - the security policy driver (see the Platform Initialization - Driver Execution Environment Core Interface Specification for - more details and the GUID definition). If the - EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle - database, then, if possible, full authentication should be - skipped and the section contents simply returned in the - OutputBuffer. In this case, the - EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus - must be set on return. ExtractSection() is callable only from - TPL_NOTIFY and below. Behavior of ExtractSection() at any - EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is - defined in RaiseTPL() in the UEFI 2.0 specification. - - - @param This Indicates the - EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance. - @param InputSection Buffer containing the input GUIDed section - to be processed. OutputBuffer OutputBuffer - is allocated from boot services pool - memory and contains the new section - stream. The caller is responsible for - freeing this buffer. - @param OutputBuffer *OutputBuffer is allocated from boot services - pool memory and contains the new section stream. - The caller is responsible for freeing this buffer. - @param OutputSize A pointer to a caller-allocated UINTN in - which the size of OutputBuffer allocation - is stored. If the function returns - anything other than EFI_SUCCESS, the value - of OutputSize is undefined. - - @param AuthenticationStatus A pointer to a caller-allocated - UINT32 that indicates the - authentication status of the - output buffer. If the input - section's - GuidedSectionHeader.Attributes - field has the - EFI_GUIDED_SECTION_AUTH_STATUS_VAL - bit as clear, AuthenticationStatus - must return zero. Both local bits - (19:16) and aggregate bits (3:0) - in AuthenticationStatus are - returned by ExtractSection(). - These bits reflect the status of - the extraction operation. The bit - pattern in both regions must be - the same, as the local and - aggregate authentication statuses - have equivalent meaning at this - level. If the function returns - anything other than EFI_SUCCESS, - the value of AuthenticationStatus - is undefined. - - - @retval EFI_SUCCESS The InputSection was successfully - processed and the section contents were - returned. - - @retval EFI_OUT_OF_RESOURCES The system has insufficient - resources to process the - request. - - @retval EFI_INVALID_PARAMETER The GUID in InputSection does - not match this instance of the - GUIDed Section Extraction - Protocol. - -**/ -EFI_STATUS -EFIAPI -CustomGuidedSectionExtract ( - IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, - IN CONST VOID *InputSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize, - OUT UINT32 *AuthenticationStatus - ); - -// -// Module globals -// -LIST_ENTRY mStreamRoot = INITIALIZE_LIST_HEAD_VARIABLE (mStreamRoot); - -EFI_HANDLE mSectionExtractionHandle = NULL; - -EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL mCustomGuidedSectionExtractionProtocol = { - CustomGuidedSectionExtract -}; - - -/** - Entry point of the section extraction code. Initializes an instance of the - section extraction interface and installs it on a new handle. - - @param ImageHandle A handle for the image that is initializing this driver - @param SystemTable A pointer to the EFI system table - - @retval EFI_SUCCESS Driver initialized successfully - @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources - -**/ -EFI_STATUS -EFIAPI -InitializeSectionExtraction ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_GUID *ExtractHandlerGuidTable; - UINTN ExtractHandlerNumber; - - // - // Get custom extract guided section method guid list - // - ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable); - - Status = EFI_SUCCESS; - // - // Install custom guided extraction protocol - // - while (ExtractHandlerNumber-- > 0) { - Status = CoreInstallProtocolInterface ( - &mSectionExtractionHandle, - &ExtractHandlerGuidTable [ExtractHandlerNumber], - EFI_NATIVE_INTERFACE, - &mCustomGuidedSectionExtractionProtocol - ); - ASSERT_EFI_ERROR (Status); - } - - return Status; -} - - -/** - Check if a stream is valid. - - @param SectionStream The section stream to be checked - @param SectionStreamLength The length of section stream - - @return A boolean value indicating the validness of the section stream. - -**/ -BOOLEAN -IsValidSectionStream ( - IN VOID *SectionStream, - IN UINTN SectionStreamLength - ) -{ - UINTN TotalLength; - UINTN SectionLength; - EFI_COMMON_SECTION_HEADER *SectionHeader; - EFI_COMMON_SECTION_HEADER *NextSectionHeader; - - TotalLength = 0; - SectionHeader = (EFI_COMMON_SECTION_HEADER *)SectionStream; - - while (TotalLength < SectionStreamLength) { - if (IS_SECTION2 (SectionHeader)) { - SectionLength = SECTION2_SIZE (SectionHeader); - } else { - SectionLength = SECTION_SIZE (SectionHeader); - } - TotalLength += SectionLength; - - if (TotalLength == SectionStreamLength) { - return TRUE; - } - - // - // Move to the next byte following the section... - // - SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength); - - // - // Figure out where the next section begins - // - NextSectionHeader = ALIGN_POINTER(SectionHeader, 4); - TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader; - SectionHeader = NextSectionHeader; - } - - ASSERT (FALSE); - return FALSE; -} - - -/** - Worker function. Constructor for section streams. - - @param SectionStreamLength Size in bytes of the section stream. - @param SectionStream Buffer containing the new section stream. - @param AllocateBuffer Indicates whether the stream buffer is to be - copied or the input buffer is to be used in - place. AuthenticationStatus- Indicates the - default authentication status for the new - stream. - @param AuthenticationStatus A pointer to a caller-allocated UINT32 that - indicates the authentication status of the - output buffer. If the input section's - GuidedSectionHeader.Attributes field - has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID - bit as clear, AuthenticationStatus must return - zero. Both local bits (19:16) and aggregate - bits (3:0) in AuthenticationStatus are returned - by ExtractSection(). These bits reflect the - status of the extraction operation. The bit - pattern in both regions must be the same, as - the local and aggregate authentication statuses - have equivalent meaning at this level. If the - function returns anything other than - EFI_SUCCESS, the value of *AuthenticationStatus - is undefined. - @param SectionStreamHandle A pointer to a caller allocated section stream - handle. - - @retval EFI_SUCCESS Stream was added to stream database. - @retval EFI_OUT_OF_RESOURCES memory allocation failed. - -**/ -EFI_STATUS -OpenSectionStreamEx ( - IN UINTN SectionStreamLength, - IN VOID *SectionStream, - IN BOOLEAN AllocateBuffer, - IN UINT32 AuthenticationStatus, - OUT UINTN *SectionStreamHandle - ) -{ - CORE_SECTION_STREAM_NODE *NewStream; - EFI_TPL OldTpl; - - // - // Allocate a new stream - // - NewStream = AllocatePool (sizeof (CORE_SECTION_STREAM_NODE)); - if (NewStream == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (AllocateBuffer) { - // - // if we're here, we're double buffering, allocate the buffer and copy the - // data in - // - if (SectionStreamLength > 0) { - NewStream->StreamBuffer = AllocatePool (SectionStreamLength); - if (NewStream->StreamBuffer == NULL) { - CoreFreePool (NewStream); - return EFI_OUT_OF_RESOURCES; - } - // - // Copy in stream data - // - CopyMem (NewStream->StreamBuffer, SectionStream, SectionStreamLength); - } else { - // - // It's possible to have a zero length section stream. - // - NewStream->StreamBuffer = NULL; - } - } else { - // - // If were here, the caller has supplied the buffer (it's an internal call) - // so just assign the buffer. This happens when we open section streams - // as a result of expanding an encapsulating section. - // - NewStream->StreamBuffer = SectionStream; - } - - // - // Initialize the rest of the section stream - // - NewStream->Signature = CORE_SECTION_STREAM_SIGNATURE; - NewStream->StreamHandle = (UINTN) NewStream; - NewStream->StreamLength = SectionStreamLength; - InitializeListHead (&NewStream->Children); - NewStream->AuthenticationStatus = AuthenticationStatus; - - // - // Add new stream to stream list - // - OldTpl = CoreRaiseTpl (TPL_NOTIFY); - InsertTailList (&mStreamRoot, &NewStream->Link); - CoreRestoreTpl (OldTpl); - - *SectionStreamHandle = NewStream->StreamHandle; - - return EFI_SUCCESS; -} - - -/** - SEP member function. This function creates and returns a new section stream - handle to represent the new section stream. - - @param SectionStreamLength Size in bytes of the section stream. - @param SectionStream Buffer containing the new section stream. - @param SectionStreamHandle A pointer to a caller allocated UINTN that on - output contains the new section stream handle. - - @retval EFI_SUCCESS The section stream is created successfully. - @retval EFI_OUT_OF_RESOURCES memory allocation failed. - @retval EFI_INVALID_PARAMETER Section stream does not end concident with end - of last section. - -**/ -EFI_STATUS -EFIAPI -OpenSectionStream ( - IN UINTN SectionStreamLength, - IN VOID *SectionStream, - OUT UINTN *SectionStreamHandle - ) -{ - // - // Check to see section stream looks good... - // - if (!IsValidSectionStream (SectionStream, SectionStreamLength)) { - return EFI_INVALID_PARAMETER; - } - - return OpenSectionStreamEx ( - SectionStreamLength, - SectionStream, - FALSE, - 0, - SectionStreamHandle - ); -} - - - -/** - Worker function. Determine if the input stream:child matches the input type. - - @param Stream Indicates the section stream associated with the - child - @param Child Indicates the child to check - @param SearchType Indicates the type of section to check against - for - @param SectionDefinitionGuid Indicates the GUID to check against if the type - is EFI_SECTION_GUID_DEFINED - - @retval TRUE The child matches - @retval FALSE The child doesn't match - -**/ -BOOLEAN -ChildIsType ( - IN CORE_SECTION_STREAM_NODE *Stream, - IN CORE_SECTION_CHILD_NODE *Child, - IN EFI_SECTION_TYPE SearchType, - IN EFI_GUID *SectionDefinitionGuid - ) -{ - EFI_GUID_DEFINED_SECTION *GuidedSection; - - if (SearchType == EFI_SECTION_ALL) { - return TRUE; - } - if (Child->Type != SearchType) { - return FALSE; - } - if ((SearchType != EFI_SECTION_GUID_DEFINED) || (SectionDefinitionGuid == NULL)) { - return TRUE; - } - GuidedSection = (EFI_GUID_DEFINED_SECTION * )(Stream->StreamBuffer + Child->OffsetInStream); - if (IS_SECTION2 (GuidedSection)) { - return CompareGuid (&(((EFI_GUID_DEFINED_SECTION2 *) GuidedSection)->SectionDefinitionGuid), SectionDefinitionGuid); - } else { - return CompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid); - } -} - -/** - Verify the Guided Section GUID by checking if there is the Guided Section GUID configuration table recorded the GUID itself. - - @param GuidedSectionGuid The Guided Section GUID. - @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Protocol - for the Guided Section. - - @return TRUE The GuidedSectionGuid could be identified, and the pointer to - the Guided Section Extraction Protocol will be returned to *GuidedSectionExtraction. - @return FALSE The GuidedSectionGuid could not be identified, or - the Guided Section Extraction Protocol has not been installed yet. - -**/ -BOOLEAN -VerifyGuidedSectionGuid ( - IN EFI_GUID *GuidedSectionGuid, - OUT EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL **GuidedSectionExtraction - ) -{ - EFI_GUID *GuidRecorded; - VOID *Interface; - EFI_STATUS Status; - - Interface = NULL; - - // - // Check if there is the Guided Section GUID configuration table recorded the GUID itself. - // - Status = EfiGetSystemConfigurationTable (GuidedSectionGuid, (VOID **) &GuidRecorded); - if (Status == EFI_SUCCESS) { - if (CompareGuid (GuidRecorded, GuidedSectionGuid)) { - // - // Found the recorded GuidedSectionGuid. - // - Status = CoreLocateProtocol (GuidedSectionGuid, NULL, (VOID **) &Interface); - if (!EFI_ERROR (Status) && Interface != NULL) { - // - // Found the supported Guided Section Extraction Porotocol for the Guided Section. - // - *GuidedSectionExtraction = (EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *) Interface; - return TRUE; - } - return FALSE; - } - } - - return FALSE; -} - -/** - RPN callback function. Initializes the section stream - when GUIDED_SECTION_EXTRACTION_PROTOCOL is installed. - - @param Event The event that fired - @param RpnContext A pointer to the context that allows us to identify - the relevent encapsulation. -**/ -VOID -EFIAPI -NotifyGuidedExtraction ( - IN EFI_EVENT Event, - IN VOID *RpnContext - ) -{ - EFI_STATUS Status; - EFI_GUID_DEFINED_SECTION *GuidedHeader; - EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *GuidedExtraction; - VOID *NewStreamBuffer; - UINTN NewStreamBufferSize; - UINT32 AuthenticationStatus; - RPN_EVENT_CONTEXT *Context; - - Context = RpnContext; - - GuidedHeader = (EFI_GUID_DEFINED_SECTION *) (Context->ParentStream->StreamBuffer + Context->ChildNode->OffsetInStream); - ASSERT (GuidedHeader->CommonHeader.Type == EFI_SECTION_GUID_DEFINED); - - if (!VerifyGuidedSectionGuid (Context->ChildNode->EncapsulationGuid, &GuidedExtraction)) { - return; - } - - Status = GuidedExtraction->ExtractSection ( - GuidedExtraction, - GuidedHeader, - &NewStreamBuffer, - &NewStreamBufferSize, - &AuthenticationStatus - ); - ASSERT_EFI_ERROR (Status); - - // - // Make sure we initialize the new stream with the correct - // authentication status for both aggregate and local status fields. - // - if ((GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) { - // - // OR in the parent stream's aggregate status. - // - AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AUTH_STATUS_ALL; - } else { - // - // since there's no authentication data contributed by the section, - // just inherit the full value from our immediate parent. - // - AuthenticationStatus = Context->ParentStream->AuthenticationStatus; - } - - Status = OpenSectionStreamEx ( - NewStreamBufferSize, - NewStreamBuffer, - FALSE, - AuthenticationStatus, - &Context->ChildNode->EncapsulatedStreamHandle - ); - ASSERT_EFI_ERROR (Status); - - // - // Close the event when done. - // - gBS->CloseEvent (Event); - Context->ChildNode->Event = NULL; - FreePool (Context); -} - -/** - Constructor for RPN event when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears... - - @param ParentStream Indicates the parent of the ecnapsulation section (child) - @param ChildNode Indicates the child node that is the encapsulation section. - -**/ -VOID -CreateGuidedExtractionRpnEvent ( - IN CORE_SECTION_STREAM_NODE *ParentStream, - IN CORE_SECTION_CHILD_NODE *ChildNode - ) -{ - RPN_EVENT_CONTEXT *Context; - - // - // Allocate new event structure and context - // - Context = AllocatePool (sizeof (RPN_EVENT_CONTEXT)); - ASSERT (Context != NULL); - - Context->ChildNode = ChildNode; - Context->ParentStream = ParentStream; - - Context->ChildNode->Event = EfiCreateProtocolNotifyEvent ( - Context->ChildNode->EncapsulationGuid, - TPL_NOTIFY, - NotifyGuidedExtraction, - Context, - &Context->Registration - ); -} - -/** - Worker function. Constructor for new child nodes. - - @param Stream Indicates the section stream in which to add the - child. - @param ChildOffset Indicates the offset in Stream that is the - beginning of the child section. - @param ChildNode Indicates the Callee allocated and initialized - child. - - @retval EFI_SUCCESS Child node was found and returned. - EFI_OUT_OF_RESOURCES- Memory allocation failed. - @retval EFI_PROTOCOL_ERROR Encapsulation sections produce new stream - handles when the child node is created. If the - section type is GUID defined, and the extraction - GUID does not exist, and producing the stream - requires the GUID, then a protocol error is - generated and no child is produced. Values - returned by OpenSectionStreamEx. - -**/ -EFI_STATUS -CreateChildNode ( - IN CORE_SECTION_STREAM_NODE *Stream, - IN UINT32 ChildOffset, - OUT CORE_SECTION_CHILD_NODE **ChildNode - ) -{ - EFI_STATUS Status; - EFI_COMMON_SECTION_HEADER *SectionHeader; - EFI_COMPRESSION_SECTION *CompressionHeader; - EFI_GUID_DEFINED_SECTION *GuidedHeader; - EFI_DECOMPRESS_PROTOCOL *Decompress; - EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *GuidedExtraction; - VOID *NewStreamBuffer; - VOID *ScratchBuffer; - UINT32 ScratchSize; - UINTN NewStreamBufferSize; - UINT32 AuthenticationStatus; - VOID *CompressionSource; - UINT32 CompressionSourceSize; - UINT32 UncompressedLength; - UINT8 CompressionType; - UINT16 GuidedSectionAttributes; - - CORE_SECTION_CHILD_NODE *Node; - - SectionHeader = (EFI_COMMON_SECTION_HEADER *) (Stream->StreamBuffer + ChildOffset); - - // - // Allocate a new node - // - *ChildNode = AllocateZeroPool (sizeof (CORE_SECTION_CHILD_NODE)); - Node = *ChildNode; - if (Node == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Now initialize it - // - Node->Signature = CORE_SECTION_CHILD_SIGNATURE; - Node->Type = SectionHeader->Type; - if (IS_SECTION2 (SectionHeader)) { - Node->Size = SECTION2_SIZE (SectionHeader); - } else { - Node->Size = SECTION_SIZE (SectionHeader); - } - Node->OffsetInStream = ChildOffset; - Node->EncapsulatedStreamHandle = NULL_STREAM_HANDLE; - Node->EncapsulationGuid = NULL; - - // - // If it's an encapsulating section, then create the new section stream also - // - switch (Node->Type) { - case EFI_SECTION_COMPRESSION: - // - // Get the CompressionSectionHeader - // - if (Node->Size < sizeof (EFI_COMPRESSION_SECTION)) { - CoreFreePool (Node); - return EFI_NOT_FOUND; - } - - CompressionHeader = (EFI_COMPRESSION_SECTION *) SectionHeader; - - if (IS_SECTION2 (CompressionHeader)) { - CompressionSource = (VOID *) ((UINT8 *) CompressionHeader + sizeof (EFI_COMPRESSION_SECTION2)); - CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionHeader) - sizeof (EFI_COMPRESSION_SECTION2)); - UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionHeader)->UncompressedLength; - CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionHeader)->CompressionType; - } else { - CompressionSource = (VOID *) ((UINT8 *) CompressionHeader + sizeof (EFI_COMPRESSION_SECTION)); - CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionHeader) - sizeof (EFI_COMPRESSION_SECTION)); - UncompressedLength = CompressionHeader->UncompressedLength; - CompressionType = CompressionHeader->CompressionType; - } - - // - // Allocate space for the new stream - // - if (UncompressedLength > 0) { - NewStreamBufferSize = UncompressedLength; - NewStreamBuffer = AllocatePool (NewStreamBufferSize); - if (NewStreamBuffer == NULL) { - CoreFreePool (Node); - return EFI_OUT_OF_RESOURCES; - } - - if (CompressionType == EFI_NOT_COMPRESSED) { - // - // stream is not actually compressed, just encapsulated. So just copy it. - // - CopyMem (NewStreamBuffer, CompressionSource, NewStreamBufferSize); - } else if (CompressionType == EFI_STANDARD_COMPRESSION) { - // - // Only support the EFI_SATNDARD_COMPRESSION algorithm. - // - - // - // Decompress the stream - // - Status = CoreLocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **)&Decompress); - ASSERT_EFI_ERROR (Status); - ASSERT (Decompress != NULL); - - Status = Decompress->GetInfo ( - Decompress, - CompressionSource, - CompressionSourceSize, - (UINT32 *)&NewStreamBufferSize, - &ScratchSize - ); - if (EFI_ERROR (Status) || (NewStreamBufferSize != UncompressedLength)) { - CoreFreePool (Node); - CoreFreePool (NewStreamBuffer); - if (!EFI_ERROR (Status)) { - Status = EFI_BAD_BUFFER_SIZE; - } - return Status; - } - - ScratchBuffer = AllocatePool (ScratchSize); - if (ScratchBuffer == NULL) { - CoreFreePool (Node); - CoreFreePool (NewStreamBuffer); - return EFI_OUT_OF_RESOURCES; - } - - Status = Decompress->Decompress ( - Decompress, - CompressionSource, - CompressionSourceSize, - NewStreamBuffer, - (UINT32)NewStreamBufferSize, - ScratchBuffer, - ScratchSize - ); - CoreFreePool (ScratchBuffer); - if (EFI_ERROR (Status)) { - CoreFreePool (Node); - CoreFreePool (NewStreamBuffer); - return Status; - } - } - } else { - NewStreamBuffer = NULL; - NewStreamBufferSize = 0; - } - - Status = OpenSectionStreamEx ( - NewStreamBufferSize, - NewStreamBuffer, - FALSE, - Stream->AuthenticationStatus, - &Node->EncapsulatedStreamHandle - ); - if (EFI_ERROR (Status)) { - CoreFreePool (Node); - CoreFreePool (NewStreamBuffer); - return Status; - } - break; - - case EFI_SECTION_GUID_DEFINED: - GuidedHeader = (EFI_GUID_DEFINED_SECTION *) SectionHeader; - if (IS_SECTION2 (GuidedHeader)) { - Node->EncapsulationGuid = &(((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->SectionDefinitionGuid); - GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->Attributes; - } else { - Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid; - GuidedSectionAttributes = GuidedHeader->Attributes; - } - if (VerifyGuidedSectionGuid (Node->EncapsulationGuid, &GuidedExtraction)) { - // - // NewStreamBuffer is always allocated by ExtractSection... No caller - // allocation here. - // - Status = GuidedExtraction->ExtractSection ( - GuidedExtraction, - GuidedHeader, - &NewStreamBuffer, - &NewStreamBufferSize, - &AuthenticationStatus - ); - if (EFI_ERROR (Status)) { - CoreFreePool (*ChildNode); - return EFI_PROTOCOL_ERROR; - } - - // - // Make sure we initialize the new stream with the correct - // authentication status for both aggregate and local status fields. - // - if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) != 0) { - // - // OR in the parent stream's aggregate status. - // - AuthenticationStatus |= Stream->AuthenticationStatus & EFI_AUTH_STATUS_ALL; - } else { - // - // since there's no authentication data contributed by the section, - // just inherit the full value from our immediate parent. - // - AuthenticationStatus = Stream->AuthenticationStatus; - } - - Status = OpenSectionStreamEx ( - NewStreamBufferSize, - NewStreamBuffer, - FALSE, - AuthenticationStatus, - &Node->EncapsulatedStreamHandle - ); - if (EFI_ERROR (Status)) { - CoreFreePool (*ChildNode); - CoreFreePool (NewStreamBuffer); - return Status; - } - } else { - // - // There's no GUIDed section extraction protocol available. - // - if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) { - // - // If the section REQUIRES an extraction protocol, register for RPN - // when the required GUIDed extraction protocol becomes available. - // - CreateGuidedExtractionRpnEvent (Stream, Node); - } else { - // - // Figure out the proper authentication status - // - AuthenticationStatus = Stream->AuthenticationStatus; - - if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) { - AuthenticationStatus |= EFI_AUTH_STATUS_IMAGE_SIGNED | EFI_AUTH_STATUS_NOT_TESTED; - } - - if (IS_SECTION2 (GuidedHeader)) { - Status = OpenSectionStreamEx ( - SECTION2_SIZE (GuidedHeader) - ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->DataOffset, - (UINT8 *) GuidedHeader + ((EFI_GUID_DEFINED_SECTION2 *) GuidedHeader)->DataOffset, - TRUE, - AuthenticationStatus, - &Node->EncapsulatedStreamHandle - ); - } else { - Status = OpenSectionStreamEx ( - SECTION_SIZE (GuidedHeader) - ((EFI_GUID_DEFINED_SECTION *) GuidedHeader)->DataOffset, - (UINT8 *) GuidedHeader + ((EFI_GUID_DEFINED_SECTION *) GuidedHeader)->DataOffset, - TRUE, - AuthenticationStatus, - &Node->EncapsulatedStreamHandle - ); - } - if (EFI_ERROR (Status)) { - CoreFreePool (Node); - return Status; - } - } - } - - break; - - default: - - // - // Nothing to do if it's a leaf - // - break; - } - - // - // Last, add the new child node to the stream - // - InsertTailList (&Stream->Children, &Node->Link); - - return EFI_SUCCESS; -} - - -/** - Worker function Recursively searches / builds section stream database - looking for requested section. - - @param SourceStream Indicates the section stream in which to do the - search. - @param SearchType Indicates the type of section to search for. - @param SectionInstance Indicates which instance of section to find. - This is an in/out parameter to deal with - recursions. - @param SectionDefinitionGuid Guid of section definition - @param FoundChild Output indicating the child node that is found. - @param FoundStream Output indicating which section stream the child - was found in. If this stream was generated as a - result of an encapsulation section, the - streamhandle is visible within the SEP driver - only. - @param AuthenticationStatus Indicates the authentication status of the found section. - - @retval EFI_SUCCESS Child node was found and returned. - EFI_OUT_OF_RESOURCES- Memory allocation failed. - @retval EFI_NOT_FOUND Requested child node does not exist. - @retval EFI_PROTOCOL_ERROR a required GUIDED section extraction protocol - does not exist - -**/ -EFI_STATUS -FindChildNode ( - IN CORE_SECTION_STREAM_NODE *SourceStream, - IN EFI_SECTION_TYPE SearchType, - IN OUT UINTN *SectionInstance, - IN EFI_GUID *SectionDefinitionGuid, - OUT CORE_SECTION_CHILD_NODE **FoundChild, - OUT CORE_SECTION_STREAM_NODE **FoundStream, - OUT UINT32 *AuthenticationStatus - ) -{ - CORE_SECTION_CHILD_NODE *CurrentChildNode; - CORE_SECTION_CHILD_NODE *RecursedChildNode; - CORE_SECTION_STREAM_NODE *RecursedFoundStream; - UINT32 NextChildOffset; - EFI_STATUS ErrorStatus; - EFI_STATUS Status; - - CurrentChildNode = NULL; - ErrorStatus = EFI_NOT_FOUND; - - if (SourceStream->StreamLength == 0) { - return EFI_NOT_FOUND; - } - - if (IsListEmpty (&SourceStream->Children) && - SourceStream->StreamLength >= sizeof (EFI_COMMON_SECTION_HEADER)) { - // - // This occurs when a section stream exists, but no child sections - // have been parsed out yet. Therefore, extract the first child and add it - // to the list of children so we can get started. - // Section stream may contain an array of zero or more bytes. - // So, its size should be >= the size of commen section header. - // - Status = CreateChildNode (SourceStream, 0, &CurrentChildNode); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // At least one child has been parsed out of the section stream. So, walk - // through the sections that have already been parsed out looking for the - // requested section, if necessary, continue parsing section stream and - // adding children until either the requested section is found, or we run - // out of data - // - CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetFirstNode(&SourceStream->Children)); - - for (;;) { - ASSERT (CurrentChildNode != NULL); - if (ChildIsType (SourceStream, CurrentChildNode, SearchType, SectionDefinitionGuid)) { - // - // The type matches, so check the instance count to see if it's the one we want - // - (*SectionInstance)--; - if (*SectionInstance == 0) { - // - // Got it! - // - *FoundChild = CurrentChildNode; - *FoundStream = SourceStream; - *AuthenticationStatus = SourceStream->AuthenticationStatus; - return EFI_SUCCESS; - } - } - - if (CurrentChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) { - // - // If the current node is an encapsulating node, recurse into it... - // - Status = FindChildNode ( - (CORE_SECTION_STREAM_NODE *)CurrentChildNode->EncapsulatedStreamHandle, - SearchType, - SectionInstance, - SectionDefinitionGuid, - &RecursedChildNode, - &RecursedFoundStream, - AuthenticationStatus - ); - // - // If the status is not EFI_SUCCESS, just save the error code and continue - // to find the request child node in the rest stream. - // - if (*SectionInstance == 0) { - ASSERT_EFI_ERROR (Status); - *FoundChild = RecursedChildNode; - *FoundStream = RecursedFoundStream; - return EFI_SUCCESS; - } else { - ErrorStatus = Status; - } - } else if ((CurrentChildNode->Type == EFI_SECTION_GUID_DEFINED) && (SearchType != EFI_SECTION_GUID_DEFINED)) { - // - // When Node Type is GUIDED section, but Node has no encapsulated data, Node data should not be parsed - // because a required GUIDED section extraction protocol does not exist. - // If SearchType is not GUIDED section, EFI_PROTOCOL_ERROR should return. - // - ErrorStatus = EFI_PROTOCOL_ERROR; - } - - if (!IsNodeAtEnd (&SourceStream->Children, &CurrentChildNode->Link)) { - // - // We haven't found the child node we're interested in yet, but there's - // still more nodes that have already been parsed so get the next one - // and continue searching.. - // - CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetNextNode (&SourceStream->Children, &CurrentChildNode->Link)); - } else { - // - // We've exhausted children that have already been parsed, so see if - // there's any more data and continue parsing out more children if there - // is. - // - NextChildOffset = CurrentChildNode->OffsetInStream + CurrentChildNode->Size; - // - // Round up to 4 byte boundary - // - NextChildOffset += 3; - NextChildOffset &= ~(UINTN) 3; - if (NextChildOffset <= SourceStream->StreamLength - sizeof (EFI_COMMON_SECTION_HEADER)) { - // - // There's an unparsed child remaining in the stream, so create a new child node - // - Status = CreateChildNode (SourceStream, NextChildOffset, &CurrentChildNode); - if (EFI_ERROR (Status)) { - return Status; - } - } else { - ASSERT (EFI_ERROR (ErrorStatus)); - return ErrorStatus; - } - } - } -} - - -/** - Worker function. Search stream database for requested stream handle. - - @param SearchHandle Indicates which stream to look for. - @param FoundStream Output pointer to the found stream. - - @retval EFI_SUCCESS StreamHandle was found and *FoundStream contains - the stream node. - @retval EFI_NOT_FOUND SearchHandle was not found in the stream - database. - -**/ -EFI_STATUS -FindStreamNode ( - IN UINTN SearchHandle, - OUT CORE_SECTION_STREAM_NODE **FoundStream - ) -{ - CORE_SECTION_STREAM_NODE *StreamNode; - - if (!IsListEmpty (&mStreamRoot)) { - StreamNode = STREAM_NODE_FROM_LINK (GetFirstNode (&mStreamRoot)); - for (;;) { - if (StreamNode->StreamHandle == SearchHandle) { - *FoundStream = StreamNode; - return EFI_SUCCESS; - } else if (IsNodeAtEnd (&mStreamRoot, &StreamNode->Link)) { - break; - } else { - StreamNode = STREAM_NODE_FROM_LINK (GetNextNode (&mStreamRoot, &StreamNode->Link)); - } - } - } - - return EFI_NOT_FOUND; -} - - -/** - SEP member function. Retrieves requested section from section stream. - - @param SectionStreamHandle The section stream from which to extract the - requested section. - @param SectionType A pointer to the type of section to search for. - @param SectionDefinitionGuid If the section type is EFI_SECTION_GUID_DEFINED, - then SectionDefinitionGuid indicates which of - these types of sections to search for. - @param SectionInstance Indicates which instance of the requested - section to return. - @param Buffer Double indirection to buffer. If *Buffer is - non-null on input, then the buffer is caller - allocated. If Buffer is NULL, then the buffer - is callee allocated. In either case, the - required buffer size is returned in *BufferSize. - @param BufferSize On input, indicates the size of *Buffer if - *Buffer is non-null on input. On output, - indicates the required size (allocated size if - callee allocated) of *Buffer. - @param AuthenticationStatus A pointer to a caller-allocated UINT32 that - indicates the authentication status of the - output buffer. If the input section's - GuidedSectionHeader.Attributes field - has the EFI_GUIDED_SECTION_AUTH_STATUS_VALID - bit as clear, AuthenticationStatus must return - zero. Both local bits (19:16) and aggregate - bits (3:0) in AuthenticationStatus are returned - by ExtractSection(). These bits reflect the - status of the extraction operation. The bit - pattern in both regions must be the same, as - the local and aggregate authentication statuses - have equivalent meaning at this level. If the - function returns anything other than - EFI_SUCCESS, the value of *AuthenticationStatus - is undefined. - @param IsFfs3Fv Indicates the FV format. - - @retval EFI_SUCCESS Section was retrieved successfully - @retval EFI_PROTOCOL_ERROR A GUID defined section was encountered in the - section stream with its - EFI_GUIDED_SECTION_PROCESSING_REQUIRED bit set, - but there was no corresponding GUIDed Section - Extraction Protocol in the handle database. - *Buffer is unmodified. - @retval EFI_NOT_FOUND An error was encountered when parsing the - SectionStream. This indicates the SectionStream - is not correctly formatted. - @retval EFI_NOT_FOUND The requested section does not exist. - @retval EFI_OUT_OF_RESOURCES The system has insufficient resources to process - the request. - @retval EFI_INVALID_PARAMETER The SectionStreamHandle does not exist. - @retval EFI_WARN_TOO_SMALL The size of the caller allocated input buffer is - insufficient to contain the requested section. - The input buffer is filled and section contents - are truncated. - -**/ -EFI_STATUS -EFIAPI -GetSection ( - IN UINTN SectionStreamHandle, - IN EFI_SECTION_TYPE *SectionType, - IN EFI_GUID *SectionDefinitionGuid, - IN UINTN SectionInstance, - IN VOID **Buffer, - IN OUT UINTN *BufferSize, - OUT UINT32 *AuthenticationStatus, - IN BOOLEAN IsFfs3Fv - ) -{ - CORE_SECTION_STREAM_NODE *StreamNode; - EFI_TPL OldTpl; - EFI_STATUS Status; - CORE_SECTION_CHILD_NODE *ChildNode; - CORE_SECTION_STREAM_NODE *ChildStreamNode; - UINTN CopySize; - UINT32 ExtractedAuthenticationStatus; - UINTN Instance; - UINT8 *CopyBuffer; - UINTN SectionSize; - EFI_COMMON_SECTION_HEADER *Section; - - - ChildStreamNode = NULL; - OldTpl = CoreRaiseTpl (TPL_NOTIFY); - Instance = SectionInstance + 1; - - // - // Locate target stream - // - Status = FindStreamNode (SectionStreamHandle, &StreamNode); - if (EFI_ERROR (Status)) { - Status = EFI_INVALID_PARAMETER; - goto GetSection_Done; - } - - // - // Found the stream, now locate and return the appropriate section - // - if (SectionType == NULL) { - // - // SectionType == NULL means return the WHOLE section stream... - // - CopySize = StreamNode->StreamLength; - CopyBuffer = StreamNode->StreamBuffer; - *AuthenticationStatus = StreamNode->AuthenticationStatus; - } else { - // - // There's a requested section type, so go find it and return it... - // - Status = FindChildNode ( - StreamNode, - *SectionType, - &Instance, - SectionDefinitionGuid, - &ChildNode, - &ChildStreamNode, - &ExtractedAuthenticationStatus - ); - if (EFI_ERROR (Status)) { - goto GetSection_Done; - } - - Section = (EFI_COMMON_SECTION_HEADER *) (ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream); - - if (IS_SECTION2 (Section)) { - ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF); - if (!IsFfs3Fv) { - DEBUG ((DEBUG_ERROR, "It is a FFS3 formatted section in a non-FFS3 formatted FV.\n")); - Status = EFI_NOT_FOUND; - goto GetSection_Done; - } - CopySize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2); - CopyBuffer = (UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2); - } else { - CopySize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER); - CopyBuffer = (UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER); - } - *AuthenticationStatus = ExtractedAuthenticationStatus; - } - - SectionSize = CopySize; - if (*Buffer != NULL) { - // - // Caller allocated buffer. Fill to size and return required size... - // - if (*BufferSize < CopySize) { - Status = EFI_WARN_BUFFER_TOO_SMALL; - CopySize = *BufferSize; - } - } else { - // - // Callee allocated buffer. Allocate buffer and return size. - // - *Buffer = AllocatePool (CopySize); - if (*Buffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto GetSection_Done; - } - } - CopyMem (*Buffer, CopyBuffer, CopySize); - *BufferSize = SectionSize; - -GetSection_Done: - CoreRestoreTpl (OldTpl); - - return Status; -} - - -/** - Worker function. Destructor for child nodes. - - @param ChildNode Indicates the node to destroy - -**/ -VOID -FreeChildNode ( - IN CORE_SECTION_CHILD_NODE *ChildNode - ) -{ - ASSERT (ChildNode->Signature == CORE_SECTION_CHILD_SIGNATURE); - // - // Remove the child from it's list - // - RemoveEntryList (&ChildNode->Link); - - if (ChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) { - // - // If it's an encapsulating section, we close the resulting section stream. - // CloseSectionStream will free all memory associated with the stream. - // - CloseSectionStream (ChildNode->EncapsulatedStreamHandle, TRUE); - } - - if (ChildNode->Event != NULL) { - gBS->CloseEvent (ChildNode->Event); - } - - // - // Last, free the child node itself - // - CoreFreePool (ChildNode); -} - - -/** - SEP member function. Deletes an existing section stream - - @param StreamHandleToClose Indicates the stream to close - @param FreeStreamBuffer TRUE - Need to free stream buffer; - FALSE - No need to free stream buffer. - - @retval EFI_SUCCESS The section stream is closed sucessfully. - @retval EFI_OUT_OF_RESOURCES Memory allocation failed. - @retval EFI_INVALID_PARAMETER Section stream does not end concident with end - of last section. - -**/ -EFI_STATUS -EFIAPI -CloseSectionStream ( - IN UINTN StreamHandleToClose, - IN BOOLEAN FreeStreamBuffer - ) -{ - CORE_SECTION_STREAM_NODE *StreamNode; - EFI_TPL OldTpl; - EFI_STATUS Status; - LIST_ENTRY *Link; - CORE_SECTION_CHILD_NODE *ChildNode; - - OldTpl = CoreRaiseTpl (TPL_NOTIFY); - - // - // Locate target stream - // - Status = FindStreamNode (StreamHandleToClose, &StreamNode); - if (!EFI_ERROR (Status)) { - // - // Found the stream, so close it - // - RemoveEntryList (&StreamNode->Link); - while (!IsListEmpty (&StreamNode->Children)) { - Link = GetFirstNode (&StreamNode->Children); - ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link); - FreeChildNode (ChildNode); - } - if (FreeStreamBuffer) { - CoreFreePool (StreamNode->StreamBuffer); - } - CoreFreePool (StreamNode); - Status = EFI_SUCCESS; - } else { - Status = EFI_INVALID_PARAMETER; - } - - CoreRestoreTpl (OldTpl); - return Status; -} - - -/** - The ExtractSection() function processes the input section and - allocates a buffer from the pool in which it returns the section - contents. If the section being extracted contains - authentication information (the section's - GuidedSectionHeader.Attributes field has the - EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values - returned in AuthenticationStatus must reflect the results of - the authentication operation. Depending on the algorithm and - size of the encapsulated data, the time that is required to do - a full authentication may be prohibitively long for some - classes of systems. To indicate this, use - EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by - the security policy driver (see the Platform Initialization - Driver Execution Environment Core Interface Specification for - more details and the GUID definition). If the - EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle - database, then, if possible, full authentication should be - skipped and the section contents simply returned in the - OutputBuffer. In this case, the - EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus - must be set on return. ExtractSection() is callable only from - TPL_NOTIFY and below. Behavior of ExtractSection() at any - EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is - defined in RaiseTPL() in the UEFI 2.0 specification. - - - @param This Indicates the - EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance. - @param InputSection Buffer containing the input GUIDed section - to be processed. OutputBuffer OutputBuffer - is allocated from boot services pool - memory and contains the new section - stream. The caller is responsible for - freeing this buffer. - @param OutputBuffer *OutputBuffer is allocated from boot services - pool memory and contains the new section stream. - The caller is responsible for freeing this buffer. - @param OutputSize A pointer to a caller-allocated UINTN in - which the size of OutputBuffer allocation - is stored. If the function returns - anything other than EFI_SUCCESS, the value - of OutputSize is undefined. - - @param AuthenticationStatus A pointer to a caller-allocated - UINT32 that indicates the - authentication status of the - output buffer. If the input - section's - GuidedSectionHeader.Attributes - field has the - EFI_GUIDED_SECTION_AUTH_STATUS_VAL - bit as clear, AuthenticationStatus - must return zero. Both local bits - (19:16) and aggregate bits (3:0) - in AuthenticationStatus are - returned by ExtractSection(). - These bits reflect the status of - the extraction operation. The bit - pattern in both regions must be - the same, as the local and - aggregate authentication statuses - have equivalent meaning at this - level. If the function returns - anything other than EFI_SUCCESS, - the value of AuthenticationStatus - is undefined. - - - @retval EFI_SUCCESS The InputSection was successfully - processed and the section contents were - returned. - - @retval EFI_OUT_OF_RESOURCES The system has insufficient - resources to process the - request. - - @retval EFI_INVALID_PARAMETER The GUID in InputSection does - not match this instance of the - GUIDed Section Extraction - Protocol. - -**/ -EFI_STATUS -EFIAPI -CustomGuidedSectionExtract ( - IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This, - IN CONST VOID *InputSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize, - OUT UINT32 *AuthenticationStatus - ) -{ - EFI_STATUS Status; - VOID *ScratchBuffer; - VOID *AllocatedOutputBuffer; - UINT32 OutputBufferSize; - UINT32 ScratchBufferSize; - UINT16 SectionAttribute; - - // - // Init local variable - // - ScratchBuffer = NULL; - AllocatedOutputBuffer = NULL; - - // - // Call GetInfo to get the size and attribute of input guided section data. - // - Status = ExtractGuidedSectionGetInfo ( - InputSection, - &OutputBufferSize, - &ScratchBufferSize, - &SectionAttribute - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status)); - return Status; - } - - if (ScratchBufferSize > 0) { - // - // Allocate scratch buffer - // - ScratchBuffer = AllocatePool (ScratchBufferSize); - if (ScratchBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - if (OutputBufferSize > 0) { - // - // Allocate output buffer - // - AllocatedOutputBuffer = AllocatePool (OutputBufferSize); - if (AllocatedOutputBuffer == NULL) { - FreePool (ScratchBuffer); - return EFI_OUT_OF_RESOURCES; - } - *OutputBuffer = AllocatedOutputBuffer; - } - - // - // Call decode function to extract raw data from the guided section. - // - Status = ExtractGuidedSectionDecode ( - InputSection, - OutputBuffer, - ScratchBuffer, - AuthenticationStatus - ); - if (EFI_ERROR (Status)) { - // - // Decode failed - // - if (AllocatedOutputBuffer != NULL) { - CoreFreePool (AllocatedOutputBuffer); - } - if (ScratchBuffer != NULL) { - CoreFreePool (ScratchBuffer); - } - DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status)); - return Status; - } - - if (*OutputBuffer != AllocatedOutputBuffer) { - // - // OutputBuffer was returned as a different value, - // so copy section contents to the allocated memory buffer. - // - CopyMem (AllocatedOutputBuffer, *OutputBuffer, OutputBufferSize); - *OutputBuffer = AllocatedOutputBuffer; - } - - // - // Set real size of output buffer. - // - *OutputSize = (UINTN) OutputBufferSize; - - // - // Free unused scratch buffer. - // - if (ScratchBuffer != NULL) { - CoreFreePool (ScratchBuffer); - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c deleted file mode 100644 index 3acc4544b4..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/Arm/DxeLoadFunc.c +++ /dev/null @@ -1,77 +0,0 @@ -/** @file - ARM specifc functionality for DxeLoad. - -Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
-Portions copyright (c) 2008 - 2009, Apple Inc. 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeIpl.h" - -#include - -/** - Transfers control to DxeCore. - - This function performs a CPU architecture specific operations to execute - the entry point of DxeCore with the parameters of HobList. - It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase. - - @param DxeCoreEntryPoint The entry point of DxeCore. - @param HobList The start of HobList passed to DxeCore. - -**/ -VOID -HandOffToDxeCore ( - IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, - IN EFI_PEI_HOB_POINTERS HobList - ) -{ - VOID *BaseOfStack; - VOID *TopOfStack; - EFI_STATUS Status; - - // - // Allocate 128KB for the Stack - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - if (PcdGetBool (PcdSetNxForStack)) { - Status = ArmSetMemoryRegionNoExec ((UINTN)BaseOfStack, STACK_SIZE); - ASSERT_EFI_ERROR (Status); - } - - // - // Compute the top of the stack we were allocated. Pre-allocate a UINTN - // for safety. - // - TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - // - // End of PEI phase singal - // - Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi); - ASSERT_EFI_ERROR (Status); - - // - // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. - // - UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE); - - SwitchStack ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint, - HobList.Raw, - NULL, - TopOfStack - ); -} diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h deleted file mode 100644 index 72d2532f50..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h +++ /dev/null @@ -1,243 +0,0 @@ -/** @file - Master header file for DxeIpl PEIM. All source files in this module should - include this file for common definitions. - -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __PEI_DXEIPL_H__ -#define __PEI_DXEIPL_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define STACK_SIZE 0x20000 -#define BSP_STORE_SIZE 0x4000 - - -// -// This PPI is installed to indicate the end of the PEI usage of memory -// -extern CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi; - -/** - This function installs the PPIs that require permanent memory. - - @param PeiServices Indirect reference to the PEI Services Table. - @param NotifyDescriptor Address of the notification descriptor data structure. - @param Ppi Address of the PPI that was installed. - - @return EFI_SUCCESS The PPIs were installed successfully. - @return Others Some error occurs during the execution of this function. - -**/ -EFI_STATUS -EFIAPI -InstallIplPermanentMemoryPpis ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ); - -/** - Searches DxeCore in all firmware Volumes and loads the first - instance that contains DxeCore. - - @return FileHandle of DxeCore to load DxeCore. - -**/ -EFI_PEI_FILE_HANDLE -DxeIplFindDxeCore ( - VOID - ); - - -/** - Main entry point to last PEIM - - @param This Entry point for DXE IPL PPI - @param PeiServices General purpose services available to every PEIM. - @param HobList Address to the Pei HOB list - - @return EFI_SUCCESS DXE core was successfully loaded. - @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core. - -**/ -EFI_STATUS -EFIAPI -DxeLoadCore ( - IN CONST EFI_DXE_IPL_PPI *This, - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_HOB_POINTERS HobList - ); - - - -/** - Transfers control to DxeCore. - - This function performs a CPU architecture specific operations to execute - the entry point of DxeCore with the parameters of HobList. - It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase. - - @param DxeCoreEntryPoint The entry point of DxeCore. - @param HobList The start of HobList passed to DxeCore. - -**/ -VOID -HandOffToDxeCore ( - IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, - IN EFI_PEI_HOB_POINTERS HobList - ); - - - -/** - Updates the Stack HOB passed to DXE phase. - - This function traverses the whole HOB list and update the stack HOB to - reflect the real stack that is used by DXE core. - - @param BaseAddress The lower address of stack used by DxeCore. - @param Length The length of stack used by DxeCore. - -**/ -VOID -UpdateStackHob ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ); - -/** - The ExtractSection() function processes the input section and - returns a pointer to the section contents. If the section being - extracted does not require processing (if the section - GuidedSectionHeader.Attributes has the - EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then - OutputBuffer is just updated to point to the start of the - section's contents. Otherwise, *Buffer must be allocated - from PEI permanent memory. - - @param This Indicates the - EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance. - Buffer containing the input GUIDed section to be - processed. OutputBuffer OutputBuffer is - allocated from PEI permanent memory and contains - the new section stream. - @param InputSection A pointer to the input buffer, which contains - the input section to be processed. - @param OutputBuffer A pointer to a caller-allocated buffer, whose - size is specified by the contents of OutputSize. - @param OutputSize A pointer to a caller-allocated - UINTN in which the size of *OutputBuffer - allocation is stored. If the function - returns anything other than EFI_SUCCESS, - the value of OutputSize is undefined. - @param AuthenticationStatus A pointer to a caller-allocated - UINT32 that indicates the - authentication status of the - output buffer. If the input - section's GuidedSectionHeader. - Attributes field has the - EFI_GUIDED_SECTION_AUTH_STATUS_VALID - bit as clear, - AuthenticationStatus must return - zero. These bits reflect the - status of the extraction - operation. If the function - returns anything other than - EFI_SUCCESS, the value of - AuthenticationStatus is - undefined. - - @retval EFI_SUCCESS The InputSection was - successfully processed and the - section contents were returned. - - @retval EFI_OUT_OF_RESOURCES The system has insufficient - resources to process the request. - - @retval EFI_INVALID_PARAMETER The GUID in InputSection does - not match this instance of the - GUIDed Section Extraction PPI. - -**/ -EFI_STATUS -EFIAPI -CustomGuidedSectionExtract ( - IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This, - IN CONST VOID *InputSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize, - OUT UINT32 *AuthenticationStatus - ); - - -/** - Decompresses a section to the output buffer. - - This function looks up the compression type field in the input section and - applies the appropriate compression algorithm to compress the section to a - callee allocated buffer. - - @param This Points to this instance of the - EFI_PEI_DECOMPRESS_PEI PPI. - @param CompressionSection Points to the compressed section. - @param OutputBuffer Holds the returned pointer to the decompressed - sections. - @param OutputSize Holds the returned size of the decompress - section streams. - - @retval EFI_SUCCESS The section was decompressed successfully. - OutputBuffer contains the resulting data and - OutputSize contains the resulting size. - -**/ -EFI_STATUS -EFIAPI -Decompress ( - IN CONST EFI_PEI_DECOMPRESS_PPI *This, - IN CONST EFI_COMPRESSION_SECTION *CompressionSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize - ); - -#endif diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf deleted file mode 100644 index c54afe4aa6..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ /dev/null @@ -1,141 +0,0 @@ -## @file -# Last PEIM executed in PEI phase to load DXE Core from a Firmware Volume. -# -# This module produces a special PPI named the DXE Initial Program Load (IPL) -# PPI to discover and dispatch the DXE Foundation and components that are -# needed to run the DXE Foundation. -# -# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
-# Copyright (c) 2017, AMD Incorporated. 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 -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = DxeIpl - MODULE_UNI_FILE = DxeIpl.uni - FILE_GUID = 86D70125-BAA3-4296-A62F-602BEBBB9081 - MODULE_TYPE = PEIM - VERSION_STRING = 1.0 - - ENTRY_POINT = PeimInitializeDxeIpl - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only) AARCH64 -# - -[Sources] - DxeIpl.h - DxeLoad.c - -[Sources.Ia32] - X64/VirtualMemory.h - X64/VirtualMemory.c - Ia32/DxeLoadFunc.c - Ia32/IdtVectorAsm.nasm - Ia32/IdtVectorAsm.asm - Ia32/IdtVectorAsm.S - -[Sources.X64] - X64/VirtualMemory.h - X64/VirtualMemory.c - X64/DxeLoadFunc.c - -[Sources.IPF] - Ipf/DxeLoadFunc.c - -[Sources.EBC] - Ebc/DxeLoadFunc.c - -[Sources.ARM, Sources.AARCH64] - Arm/DxeLoadFunc.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[Packages.ARM, Packages.AARCH64] - ArmPkg/ArmPkg.dec - -[LibraryClasses] - PcdLib - MemoryAllocationLib - BaseMemoryLib - ExtractGuidedSectionLib - UefiDecompressLib - ReportStatusCodeLib - PeiServicesLib - HobLib - BaseLib - PeimEntryPoint - DebugLib - DebugAgentLib - PeiServicesTablePointerLib - -[LibraryClasses.ARM, LibraryClasses.AARCH64] - ArmMmuLib - -[Ppis] - gEfiDxeIplPpiGuid ## PRODUCES - gEfiPeiDecompressPpiGuid ## PRODUCES - gEfiEndOfPeiSignalPpiGuid ## SOMETIMES_PRODUCES # Not produced on S3 boot path - gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES - gEfiPeiLoadFilePpiGuid ## SOMETIMES_CONSUMES - gEfiPeiS3Resume2PpiGuid ## SOMETIMES_CONSUMES # Consumed on S3 boot path - gEfiPeiRecoveryModulePpiGuid ## SOMETIMES_CONSUMES # Consumed on recovery boot path - ## SOMETIMES_CONSUMES - ## UNDEFINED # HOB - gEfiVectorHandoffInfoPpiGuid - gEfiPeiMemoryDiscoveredPpiGuid ## SOMETIMES_CONSUMES - -[Guids] - ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation" - ## SOMETIMES_PRODUCES ## HOB - gEfiMemoryTypeInformationGuid - -[FeaturePcd.IA32] - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode ## CONSUMES - -[FeaturePcd.X64] - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables ## CONSUMES - -[FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress ## CONSUMES - -[Pcd.IA32,Pcd.X64] - gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask ## CONSUMES - -[Pcd.IA32,Pcd.X64,Pcd.ARM,Pcd.AARCH64] - gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack ## SOMETIMES_CONSUMES - -[Depex] - gEfiPeiLoadFilePpiGuid AND gEfiPeiMasterBootModePpiGuid - -# -# [BootMode] -# S3_RESUME ## SOMETIMES_CONSUMES -# RECOVERY_FULL ## SOMETIMES_CONSUMES -# -# -# [Hob] -# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # MEMORY_ALLOCATION_MODULE for DxeCore -# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # New Stack HoB -# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # Old Stack HOB -# -# [Hob.IPF] -# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES # MEMORY_ALLOCATION_BSP_STORE -# - -[UserExtensions.TianoCore."ExtraFiles"] - DxeIplExtra.uni diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.uni b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.uni deleted file mode 100644 index 1a319c209c..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.uni +++ /dev/null @@ -1,24 +0,0 @@ -// /** @file -// Last PEIM executed in PEI phase to load DXE Core from a Firmware Volume. -// -// This module produces a special PPI named the DXE Initial Program Load (IPL) -// PPI to discover and dispatch the DXE Foundation and components that are -// needed to run the DXE Foundation. -// -// Copyright (c) 2006 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Last PEIM executed in PEI phase to load DXE Core from a Firmware Volume" - -#string STR_MODULE_DESCRIPTION #language en-US "This module produces a special PPI named the DXE Initial Program Load (IPL) PPI to discover and dispatch the DXE Foundation and components that are needed to run the DXE Foundation." - diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIplExtra.uni b/MdeModulePkg/Core/DxeIplPeim/DxeIplExtra.uni deleted file mode 100644 index 883a246dc8..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIplExtra.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// DxeIpl Localized Strings and Content -// -// Copyright (c) 2013 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Core DXE Services Initial Program Loader" - - diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c deleted file mode 100644 index 50b5440d15..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ /dev/null @@ -1,827 +0,0 @@ -/** @file - Last PEIM. - Responsibility of this module is to load the DXE Core from a Firmware Volume. - -Copyright (c) 2016 HP Development Company, L.P. -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeIpl.h" - - -// -// Module Globals used in the DXE to PEI hand off -// These must be module globals, so the stack can be switched -// -CONST EFI_DXE_IPL_PPI mDxeIplPpi = { - DxeLoadCore -}; - -CONST EFI_PEI_PPI_DESCRIPTOR mDxeIplPpiList = { - EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, - &gEfiDxeIplPpiGuid, - (VOID *) &mDxeIplPpi -}; - -CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = { - CustomGuidedSectionExtract -}; - -CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = { - Decompress -}; - -CONST EFI_PEI_PPI_DESCRIPTOR mDecompressPpiList = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiPeiDecompressPpiGuid, - (VOID *) &mDecompressPpi -}; - -CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiEndOfPeiSignalPpiGuid, - NULL -}; - -CONST EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList = { - (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiPeiMemoryDiscoveredPpiGuid, - InstallIplPermanentMemoryPpis -}; - -/** - Entry point of DXE IPL PEIM. - - This function installs DXE IPL PPI. It also reloads - itself to memory on non-S3 resume boot path. - - @param FileHandle Handle of the file being invoked. - @param PeiServices Describes the list of possible PEI Services. - - @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully. - @retval Others Some error occurs during the execution of this function. - -**/ -EFI_STATUS -EFIAPI -PeimInitializeDxeIpl ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - EFI_STATUS Status; - EFI_BOOT_MODE BootMode; - VOID *Dummy; - - BootMode = GetBootModeHob (); - - if (BootMode != BOOT_ON_S3_RESUME) { - Status = PeiServicesRegisterForShadow (FileHandle); - if (Status == EFI_SUCCESS) { - // - // EFI_SUCESS means it is the first time to call register for shadow. - // - return Status; - } - - // - // Ensure that DXE IPL is shadowed to permanent memory. - // - ASSERT (Status == EFI_ALREADY_STARTED); - - // - // DXE core load requires permanent memory. - // - Status = PeiServicesLocatePpi ( - &gEfiPeiMemoryDiscoveredPpiGuid, - 0, - NULL, - (VOID **) &Dummy - ); - ASSERT_EFI_ERROR (Status); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Now the permanent memory exists, install the PPIs for decompression - // and section extraction. - // - Status = InstallIplPermanentMemoryPpis (NULL, NULL, NULL); - ASSERT_EFI_ERROR (Status); - } else { - // - // Install memory discovered PPI notification to install PPIs for - // decompression and section extraction. - // - Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList); - ASSERT_EFI_ERROR (Status); - } - - // - // Install DxeIpl PPI. - // - Status = PeiServicesInstallPpi (&mDxeIplPpiList); - ASSERT_EFI_ERROR(Status); - - return Status; -} - -/** - This function installs the PPIs that require permanent memory. - - @param PeiServices Indirect reference to the PEI Services Table. - @param NotifyDescriptor Address of the notification descriptor data structure. - @param Ppi Address of the PPI that was installed. - - @return EFI_SUCCESS The PPIs were installed successfully. - @return Others Some error occurs during the execution of this function. - -**/ -EFI_STATUS -EFIAPI -InstallIplPermanentMemoryPpis ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ) -{ - EFI_STATUS Status; - EFI_GUID *ExtractHandlerGuidTable; - UINTN ExtractHandlerNumber; - EFI_PEI_PPI_DESCRIPTOR *GuidPpi; - - // - // Get custom extract guided section method guid list - // - ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable); - - // - // Install custom guided section extraction PPI - // - if (ExtractHandlerNumber > 0) { - GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR)); - ASSERT (GuidPpi != NULL); - while (ExtractHandlerNumber-- > 0) { - GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; - GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi; - GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber]; - Status = PeiServicesInstallPpi (GuidPpi++); - ASSERT_EFI_ERROR(Status); - } - } - - // - // Install Decompress PPI. - // - Status = PeiServicesInstallPpi (&mDecompressPpiList); - ASSERT_EFI_ERROR(Status); - - return Status; -} - -/** - Validate variable data for the MemoryTypeInformation. - - @param MemoryData Variable data. - @param MemoryDataSize Variable data length. - - @return TRUE The variable data is valid. - @return FALSE The variable data is invalid. - -**/ -BOOLEAN -ValidateMemoryTypeInfoVariable ( - IN EFI_MEMORY_TYPE_INFORMATION *MemoryData, - IN UINTN MemoryDataSize - ) -{ - UINTN Count; - UINTN Index; - - // Check the input parameter. - if (MemoryData == NULL) { - return FALSE; - } - - // Get Count - Count = MemoryDataSize / sizeof (*MemoryData); - - // Check Size - if (Count * sizeof(*MemoryData) != MemoryDataSize) { - return FALSE; - } - - // Check last entry type filed. - if (MemoryData[Count - 1].Type != EfiMaxMemoryType) { - return FALSE; - } - - // Check the type filed. - for (Index = 0; Index < Count - 1; Index++) { - if (MemoryData[Index].Type >= EfiMaxMemoryType) { - return FALSE; - } - } - - return TRUE; -} - -/** - Main entry point to last PEIM. - - This function finds DXE Core in the firmware volume and transfer the control to - DXE core. - - @param This Entry point for DXE IPL PPI. - @param PeiServices General purpose services available to every PEIM. - @param HobList Address to the Pei HOB list. - - @return EFI_SUCCESS DXE core was successfully loaded. - @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core. - -**/ -EFI_STATUS -EFIAPI -DxeLoadCore ( - IN CONST EFI_DXE_IPL_PPI *This, - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_HOB_POINTERS HobList - ) -{ - EFI_STATUS Status; - EFI_FV_FILE_INFO DxeCoreFileInfo; - EFI_PHYSICAL_ADDRESS DxeCoreAddress; - UINT64 DxeCoreSize; - EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint; - EFI_BOOT_MODE BootMode; - EFI_PEI_FILE_HANDLE FileHandle; - EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; - EFI_PEI_LOAD_FILE_PPI *LoadFile; - UINTN Instance; - UINT32 AuthenticationState; - UINTN DataSize; - EFI_PEI_S3_RESUME2_PPI *S3Resume; - EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery; - EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; - - // - // if in S3 Resume, restore configure - // - BootMode = GetBootModeHob (); - - if (BootMode == BOOT_ON_S3_RESUME) { - Status = PeiServicesLocatePpi ( - &gEfiPeiS3Resume2PpiGuid, - 0, - NULL, - (VOID **) &S3Resume - ); - if (EFI_ERROR (Status)) { - // - // Report Status code that S3Resume PPI can not be found - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MAJOR, - (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND) - ); - } - ASSERT_EFI_ERROR (Status); - - Status = S3Resume->S3RestoreConfig2 (S3Resume); - ASSERT_EFI_ERROR (Status); - } else if (BootMode == BOOT_IN_RECOVERY_MODE) { - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN)); - Status = PeiServicesLocatePpi ( - &gEfiPeiRecoveryModulePpiGuid, - 0, - NULL, - (VOID **) &PeiRecovery - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status)); - // - // Report Status code the failure of locating Recovery PPI - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MAJOR, - (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND) - ); - CpuDeadLoop (); - } - - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD)); - Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status)); - // - // Report Status code that recovery image can not be found - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MAJOR, - (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE) - ); - CpuDeadLoop (); - } - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START)); - // - // Now should have a HOB with the DXE core - // - } - - if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) { - // - // Don't build GuidHob if GuidHob has been installed. - // - Status = PeiServicesLocatePpi ( - &gEfiPeiReadOnlyVariable2PpiGuid, - 0, - NULL, - (VOID **)&Variable - ); - if (!EFI_ERROR (Status)) { - DataSize = sizeof (MemoryData); - Status = Variable->GetVariable ( - Variable, - EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, - &gEfiMemoryTypeInformationGuid, - NULL, - &DataSize, - &MemoryData - ); - if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) { - // - // Build the GUID'd HOB for DXE - // - BuildGuidDataHob ( - &gEfiMemoryTypeInformationGuid, - MemoryData, - DataSize - ); - } - } - } - - // - // Look in all the FVs present in PEI and find the DXE Core FileHandle - // - FileHandle = DxeIplFindDxeCore (); - - // - // Load the DXE Core from a Firmware Volume. - // - Instance = 0; - do { - Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile); - // - // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully. - // - ASSERT_EFI_ERROR (Status); - - Status = LoadFile->LoadFile ( - LoadFile, - FileHandle, - &DxeCoreAddress, - &DxeCoreSize, - &DxeCoreEntryPoint, - &AuthenticationState - ); - } while (EFI_ERROR (Status)); - - // - // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name. - // - Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo); - ASSERT_EFI_ERROR (Status); - - // - // Add HOB for the DXE Core - // - BuildModuleHob ( - &DxeCoreFileInfo.FileName, - DxeCoreAddress, - ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE), - DxeCoreEntryPoint - ); - - // - // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT - // - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT)); - - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint))); - - // - // Transfer control to the DXE Core - // The hand off state is simply a pointer to the HOB list - // - HandOffToDxeCore (DxeCoreEntryPoint, HobList); - // - // If we get here, then the DXE Core returned. This is an error - // DxeCore should not return. - // - ASSERT (FALSE); - CpuDeadLoop (); - - return EFI_OUT_OF_RESOURCES; -} - - -/** - Searches DxeCore in all firmware Volumes and loads the first - instance that contains DxeCore. - - @return FileHandle of DxeCore to load DxeCore. - -**/ -EFI_PEI_FILE_HANDLE -DxeIplFindDxeCore ( - VOID - ) -{ - EFI_STATUS Status; - UINTN Instance; - EFI_PEI_FV_HANDLE VolumeHandle; - EFI_PEI_FILE_HANDLE FileHandle; - - Instance = 0; - while (TRUE) { - // - // Traverse all firmware volume instances - // - Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); - // - // If some error occurs here, then we cannot find any firmware - // volume that may contain DxeCore. - // - if (EFI_ERROR (Status)) { - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_EC_DXE_CORRUPT)); - } - ASSERT_EFI_ERROR (Status); - - // - // Find the DxeCore file type from the beginning in this firmware volume. - // - FileHandle = NULL; - Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle); - if (!EFI_ERROR (Status)) { - // - // Find DxeCore FileHandle in this volume, then we skip other firmware volume and - // return the FileHandle. - // - return FileHandle; - } - // - // We cannot find DxeCore in this firmware volume, then search the next volume. - // - Instance++; - } -} - - - -/** - The ExtractSection() function processes the input section and - returns a pointer to the section contents. If the section being - extracted does not require processing (if the section - GuidedSectionHeader.Attributes has the - EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then - OutputBuffer is just updated to point to the start of the - section's contents. Otherwise, *Buffer must be allocated - from PEI permanent memory. - - @param This Indicates the - EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance. - Buffer containing the input GUIDed section to be - processed. OutputBuffer OutputBuffer is - allocated from PEI permanent memory and contains - the new section stream. - @param InputSection A pointer to the input buffer, which contains - the input section to be processed. - @param OutputBuffer A pointer to a caller-allocated buffer, whose - size is specified by the contents of OutputSize. - @param OutputSize A pointer to a caller-allocated - UINTN in which the size of *OutputBuffer - allocation is stored. If the function - returns anything other than EFI_SUCCESS, - the value of OutputSize is undefined. - @param AuthenticationStatus A pointer to a caller-allocated - UINT32 that indicates the - authentication status of the - output buffer. If the input - section's GuidedSectionHeader. - Attributes field has the - EFI_GUIDED_SECTION_AUTH_STATUS_VALID - bit as clear, - AuthenticationStatus must return - zero. These bits reflect the - status of the extraction - operation. If the function - returns anything other than - EFI_SUCCESS, the value of - AuthenticationStatus is - undefined. - - @retval EFI_SUCCESS The InputSection was - successfully processed and the - section contents were returned. - - @retval EFI_OUT_OF_RESOURCES The system has insufficient - resources to process the request. - - @retval EFI_INVALID_PARAMETER The GUID in InputSection does - not match this instance of the - GUIDed Section Extraction PPI. - -**/ -EFI_STATUS -EFIAPI -CustomGuidedSectionExtract ( - IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This, - IN CONST VOID *InputSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize, - OUT UINT32 *AuthenticationStatus -) -{ - EFI_STATUS Status; - UINT8 *ScratchBuffer; - UINT32 ScratchBufferSize; - UINT32 OutputBufferSize; - UINT16 SectionAttribute; - - // - // Init local variable - // - ScratchBuffer = NULL; - - // - // Call GetInfo to get the size and attribute of input guided section data. - // - Status = ExtractGuidedSectionGetInfo ( - InputSection, - &OutputBufferSize, - &ScratchBufferSize, - &SectionAttribute - ); - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status)); - return Status; - } - - if (ScratchBufferSize != 0) { - // - // Allocate scratch buffer - // - ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize)); - if (ScratchBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) { - // - // Allocate output buffer - // - *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1); - if (*OutputBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer)); - // - // *OutputBuffer still is one section. Adjust *OutputBuffer offset, - // skip EFI section header to make section data at page alignment. - // - *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER)); - } - - Status = ExtractGuidedSectionDecode ( - InputSection, - OutputBuffer, - ScratchBuffer, - AuthenticationStatus - ); - if (EFI_ERROR (Status)) { - // - // Decode failed - // - DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status)); - return Status; - } - - *OutputSize = (UINTN) OutputBufferSize; - - return EFI_SUCCESS; -} - - - -/** - Decompresses a section to the output buffer. - - This function looks up the compression type field in the input section and - applies the appropriate compression algorithm to compress the section to a - callee allocated buffer. - - @param This Points to this instance of the - EFI_PEI_DECOMPRESS_PEI PPI. - @param CompressionSection Points to the compressed section. - @param OutputBuffer Holds the returned pointer to the decompressed - sections. - @param OutputSize Holds the returned size of the decompress - section streams. - - @retval EFI_SUCCESS The section was decompressed successfully. - OutputBuffer contains the resulting data and - OutputSize contains the resulting size. - -**/ -EFI_STATUS -EFIAPI -Decompress ( - IN CONST EFI_PEI_DECOMPRESS_PPI *This, - IN CONST EFI_COMPRESSION_SECTION *CompressionSection, - OUT VOID **OutputBuffer, - OUT UINTN *OutputSize - ) -{ - EFI_STATUS Status; - UINT8 *DstBuffer; - UINT8 *ScratchBuffer; - UINT32 DstBufferSize; - UINT32 ScratchBufferSize; - VOID *CompressionSource; - UINT32 CompressionSourceSize; - UINT32 UncompressedLength; - UINT8 CompressionType; - - if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) { - ASSERT (FALSE); - return EFI_INVALID_PARAMETER; - } - - if (IS_SECTION2 (CompressionSection)) { - CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2)); - CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2)); - UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength; - CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType; - } else { - CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION)); - CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION)); - UncompressedLength = CompressionSection->UncompressedLength; - CompressionType = CompressionSection->CompressionType; - } - - // - // This is a compression set, expand it - // - switch (CompressionType) { - case EFI_STANDARD_COMPRESSION: - if (FeaturePcdGet(PcdDxeIplSupportUefiDecompress)) { - // - // Load EFI standard compression. - // For compressed data, decompress them to destination buffer. - // - Status = UefiDecompressGetInfo ( - CompressionSource, - CompressionSourceSize, - &DstBufferSize, - &ScratchBufferSize - ); - if (EFI_ERROR (Status)) { - // - // GetInfo failed - // - DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status)); - return EFI_NOT_FOUND; - } - // - // Allocate scratch buffer - // - ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize)); - if (ScratchBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Allocate destination buffer, extra one page for adjustment - // - DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1); - if (DstBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header - // to make section data at page alignment. - // - DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER); - // - // Call decompress function - // - Status = UefiDecompress ( - CompressionSource, - DstBuffer, - ScratchBuffer - ); - if (EFI_ERROR (Status)) { - // - // Decompress failed - // - DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status)); - return EFI_NOT_FOUND; - } - break; - } else { - // - // PcdDxeIplSupportUefiDecompress is FALSE - // Don't support UEFI decompression algorithm. - // - ASSERT (FALSE); - return EFI_NOT_FOUND; - } - - case EFI_NOT_COMPRESSED: - // - // Allocate destination buffer - // - DstBufferSize = UncompressedLength; - DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1); - if (DstBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - // - // Adjust DstBuffer offset, skip EFI section header - // to make section data at page alignment. - // - DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER); - // - // stream is not actually compressed, just encapsulated. So just copy it. - // - CopyMem (DstBuffer, CompressionSource, DstBufferSize); - break; - - default: - // - // Don't support other unknown compression type. - // - ASSERT (FALSE); - return EFI_NOT_FOUND; - } - - *OutputSize = DstBufferSize; - *OutputBuffer = DstBuffer; - - return EFI_SUCCESS; -} - - -/** - Updates the Stack HOB passed to DXE phase. - - This function traverses the whole HOB list and update the stack HOB to - reflect the real stack that is used by DXE core. - - @param BaseAddress The lower address of stack used by DxeCore. - @param Length The length of stack used by DxeCore. - -**/ -VOID -UpdateStackHob ( - IN EFI_PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length - ) -{ - EFI_PEI_HOB_POINTERS Hob; - - Hob.Raw = GetHobList (); - while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) { - if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) { - // - // Build a new memory allocation HOB with old stack info with EfiBootServicesData type. Need to - // avoid this region be reclaimed by DXE core as the IDT built in SEC might be on stack, and some - // PEIMs may also keep key information on stack - // - BuildMemoryAllocationHob ( - Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress, - Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength, - EfiBootServicesData - ); - // - // Update the BSP Stack Hob to reflect the new stack info. - // - Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress; - Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length; - break; - } - Hob.Raw = GET_NEXT_HOB (Hob); - } -} diff --git a/MdeModulePkg/Core/DxeIplPeim/Ebc/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ebc/DxeLoadFunc.c deleted file mode 100644 index f06bd75891..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/Ebc/DxeLoadFunc.c +++ /dev/null @@ -1,73 +0,0 @@ -/** @file - EBC-specific functionality for DxeLoad. - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeIpl.h" - - - -/** - Transfers control to DxeCore. - - This function performs a CPU architecture specific operations to execute - the entry point of DxeCore with the parameters of HobList. - It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase. - - @param DxeCoreEntryPoint The entry point of DxeCore. - @param HobList The start of HobList passed to DxeCore. - -**/ -VOID -HandOffToDxeCore ( - IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, - IN EFI_PEI_HOB_POINTERS HobList - ) -{ - VOID *BaseOfStack; - VOID *TopOfStack; - EFI_STATUS Status; - - // - // Allocate 128KB for the Stack - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - // - // Compute the top of the stack we were allocated. Pre-allocate a UINTN - // for safety. - // - TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - // - // End of PEI phase signal - // - Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi); - ASSERT_EFI_ERROR (Status); - - // - // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. - // - UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE); - - // - // Transfer the control to the entry point of DxeCore. - // - SwitchStack ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint, - HobList.Raw, - NULL, - TopOfStack - ); -} diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c deleted file mode 100644 index 1957326caf..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c +++ /dev/null @@ -1,435 +0,0 @@ -/** @file - Ia32-specific functionality for DxeLoad. - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-Copyright (c) 2017, AMD Incorporated. 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeIpl.h" -#include "VirtualMemory.h" - -#define IDT_ENTRY_COUNT 32 - -typedef struct _X64_IDT_TABLE { - // - // Reserved 4 bytes preceding PeiService and IdtTable, - // since IDT base address should be 8-byte alignment. - // - UINT32 Reserved; - CONST EFI_PEI_SERVICES **PeiService; - X64_IDT_GATE_DESCRIPTOR IdtTable[IDT_ENTRY_COUNT]; -} X64_IDT_TABLE; - -// -// Global Descriptor Table (GDT) -// -GLOBAL_REMOVE_IF_UNREFERENCED IA32_GDT gGdtEntries[] = { -/* selector { Global Segment Descriptor } */ -/* 0x00 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, //null descriptor -/* 0x08 */ {{0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //linear data segment descriptor -/* 0x10 */ {{0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //linear code segment descriptor -/* 0x18 */ {{0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //system data segment descriptor -/* 0x20 */ {{0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //system code segment descriptor -/* 0x28 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, //spare segment descriptor -/* 0x30 */ {{0xffff, 0, 0, 0x2, 1, 0, 1, 0xf, 0, 0, 1, 1, 0}}, //system data segment descriptor -/* 0x38 */ {{0xffff, 0, 0, 0xa, 1, 0, 1, 0xf, 0, 1, 0, 1, 0}}, //system code segment descriptor -/* 0x40 */ {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, //spare segment descriptor -}; - -// -// IA32 Gdt register -// -GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR gGdt = { - sizeof (gGdtEntries) - 1, - (UINTN) gGdtEntries - }; - -GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR gLidtDescriptor = { - sizeof (X64_IDT_GATE_DESCRIPTOR) * IDT_ENTRY_COUNT - 1, - 0 -}; - -/** - Allocates and fills in the Page Directory and Page Table Entries to - establish a 4G page table. - - @param[in] StackBase Stack base address. - @param[in] StackSize Stack size. - - @return The address of page table. - -**/ -UINTN -Create4GPageTablesIa32Pae ( - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize - ) -{ - UINT8 PhysicalAddressBits; - EFI_PHYSICAL_ADDRESS PhysicalAddress; - UINTN IndexOfPdpEntries; - UINTN IndexOfPageDirectoryEntries; - UINT32 NumberOfPdpEntriesNeeded; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; - PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; - PAGE_TABLE_ENTRY *PageDirectoryEntry; - UINTN TotalPagesNum; - UINTN PageAddress; - UINT64 AddressEncMask; - - // - // Make sure AddressEncMask is contained to smallest supported address field - // - AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; - - PhysicalAddressBits = 32; - - // - // Calculate the table entries needed. - // - NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, (PhysicalAddressBits - 30)); - - TotalPagesNum = NumberOfPdpEntriesNeeded + 1; - PageAddress = (UINTN) AllocatePages (TotalPagesNum); - ASSERT (PageAddress != 0); - - PageMap = (VOID *) PageAddress; - PageAddress += SIZE_4KB; - - PageDirectoryPointerEntry = PageMap; - PhysicalAddress = 0; - - for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { - // - // Each Directory Pointer entries points to a page of Page Directory entires. - // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop. - // - PageDirectoryEntry = (VOID *) PageAddress; - PageAddress += SIZE_4KB; - - // - // Fill in a Page Directory Pointer Entries - // - PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry | AddressEncMask; - PageDirectoryPointerEntry->Bits.Present = 1; - - for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) { - if ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddress + SIZE_2MB) > StackBase)) { - // - // Need to split this 2M page that covers stack range. - // - Split2MPageTo4K (PhysicalAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize); - } else { - // - // Fill in the Page Directory entries - // - PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress | AddressEncMask; - PageDirectoryEntry->Bits.ReadWrite = 1; - PageDirectoryEntry->Bits.Present = 1; - PageDirectoryEntry->Bits.MustBe1 = 1; - } - } - } - - for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { - ZeroMem ( - PageDirectoryPointerEntry, - sizeof (PAGE_MAP_AND_DIRECTORY_POINTER) - ); - } - - return (UINTN) PageMap; -} - -/** - The function will check if IA32 PAE is supported. - - @retval TRUE IA32 PAE is supported. - @retval FALSE IA32 PAE is not supported. - -**/ -BOOLEAN -IsIa32PaeSupport ( - VOID - ) -{ - UINT32 RegEax; - UINT32 RegEdx; - BOOLEAN Ia32PaeSupport; - - Ia32PaeSupport = FALSE; - AsmCpuid (0x0, &RegEax, NULL, NULL, NULL); - if (RegEax >= 0x1) { - AsmCpuid (0x1, NULL, NULL, NULL, &RegEdx); - if ((RegEdx & BIT6) != 0) { - Ia32PaeSupport = TRUE; - } - } - - return Ia32PaeSupport; -} - -/** - The function will check if Execute Disable Bit is available. - - @retval TRUE Execute Disable Bit is available. - @retval FALSE Execute Disable Bit is not available. - -**/ -BOOLEAN -IsExecuteDisableBitAvailable ( - VOID - ) -{ - UINT32 RegEax; - UINT32 RegEdx; - BOOLEAN Available; - - Available = FALSE; - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - if (RegEax >= 0x80000001) { - AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); - if ((RegEdx & BIT20) != 0) { - // - // Bit 20: Execute Disable Bit available. - // - Available = TRUE; - } - } - - return Available; -} - -/** - Transfers control to DxeCore. - - This function performs a CPU architecture specific operations to execute - the entry point of DxeCore with the parameters of HobList. - It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase. - - @param DxeCoreEntryPoint The entry point of DxeCore. - @param HobList The start of HobList passed to DxeCore. - -**/ -VOID -HandOffToDxeCore ( - IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, - IN EFI_PEI_HOB_POINTERS HobList - ) -{ - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS BaseOfStack; - EFI_PHYSICAL_ADDRESS TopOfStack; - UINTN PageTables; - X64_IDT_GATE_DESCRIPTOR *IdtTable; - UINTN SizeOfTemplate; - VOID *TemplateBase; - EFI_PHYSICAL_ADDRESS VectorAddress; - UINT32 Index; - X64_IDT_TABLE *IdtTableForX64; - EFI_VECTOR_HANDOFF_INFO *VectorInfo; - EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi; - BOOLEAN BuildPageTablesIa32Pae; - - Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack); - ASSERT_EFI_ERROR (Status); - - if (FeaturePcdGet(PcdDxeIplSwitchToLongMode)) { - // - // Compute the top of the stack we were allocated, which is used to load X64 dxe core. - // Pre-allocate a 32 bytes which confroms to x64 calling convention. - // - // The first four parameters to a function are passed in rcx, rdx, r8 and r9. - // Any further parameters are pushed on the stack. Furthermore, space (4 * 8bytes) for the - // register parameters is reserved on the stack, in case the called function - // wants to spill them; this is important if the function is variadic. - // - TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - 32; - - // - // x64 Calling Conventions requires that the stack must be aligned to 16 bytes - // - TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, 16); - - // - // Load the GDT of Go64. Since the GDT of 32-bit Tiano locates in the BS_DATA - // memory, it may be corrupted when copying FV to high-end memory - // - AsmWriteGdtr (&gGdt); - // - // Create page table and save PageMapLevel4 to CR3 - // - PageTables = CreateIdentityMappingPageTables (BaseOfStack, STACK_SIZE); - - // - // End of PEI phase signal - // - Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi); - ASSERT_EFI_ERROR (Status); - - AsmWriteCr3 (PageTables); - - // - // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. - // - UpdateStackHob (BaseOfStack, STACK_SIZE); - - SizeOfTemplate = AsmGetVectorTemplatInfo (&TemplateBase); - - Status = PeiServicesAllocatePages ( - EfiBootServicesData, - EFI_SIZE_TO_PAGES(sizeof (X64_IDT_TABLE) + SizeOfTemplate * IDT_ENTRY_COUNT), - &VectorAddress - ); - ASSERT_EFI_ERROR (Status); - - // - // Store EFI_PEI_SERVICES** in the 4 bytes immediately preceding IDT to avoid that - // it may not be gotten correctly after IDT register is re-written. - // - IdtTableForX64 = (X64_IDT_TABLE *) (UINTN) VectorAddress; - IdtTableForX64->PeiService = GetPeiServicesTablePointer (); - - VectorAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (IdtTableForX64 + 1); - IdtTable = IdtTableForX64->IdtTable; - for (Index = 0; Index < IDT_ENTRY_COUNT; Index++) { - IdtTable[Index].Ia32IdtEntry.Bits.GateType = 0x8e; - IdtTable[Index].Ia32IdtEntry.Bits.Reserved_0 = 0; - IdtTable[Index].Ia32IdtEntry.Bits.Selector = SYS_CODE64_SEL; - - IdtTable[Index].Ia32IdtEntry.Bits.OffsetLow = (UINT16) VectorAddress; - IdtTable[Index].Ia32IdtEntry.Bits.OffsetHigh = (UINT16) (RShiftU64 (VectorAddress, 16)); - IdtTable[Index].Offset32To63 = (UINT32) (RShiftU64 (VectorAddress, 32)); - IdtTable[Index].Reserved = 0; - - CopyMem ((VOID *) (UINTN) VectorAddress, TemplateBase, SizeOfTemplate); - AsmVectorFixup ((VOID *) (UINTN) VectorAddress, (UINT8) Index); - - VectorAddress += SizeOfTemplate; - } - - gLidtDescriptor.Base = (UINTN) IdtTable; - - // - // Disable interrupt of Debug timer, since new IDT table cannot handle it. - // - SaveAndSetDebugTimerInterrupt (FALSE); - - AsmWriteIdtr (&gLidtDescriptor); - - DEBUG (( - DEBUG_INFO, - "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n", - __FUNCTION__, - BaseOfStack, - STACK_SIZE - )); - - // - // Go to Long Mode and transfer control to DxeCore. - // Interrupts will not get turned on until the CPU AP is loaded. - // Call x64 drivers passing in single argument, a pointer to the HOBs. - // - AsmEnablePaging64 ( - SYS_CODE64_SEL, - DxeCoreEntryPoint, - (EFI_PHYSICAL_ADDRESS)(UINTN)(HobList.Raw), - 0, - TopOfStack - ); - } else { - // - // Get Vector Hand-off Info PPI and build Guided HOB - // - Status = PeiServicesLocatePpi ( - &gEfiVectorHandoffInfoPpiGuid, - 0, - NULL, - (VOID **)&VectorHandoffInfoPpi - ); - if (Status == EFI_SUCCESS) { - DEBUG ((EFI_D_INFO, "Vector Hand-off Info PPI is gotten, GUIDed HOB is created!\n")); - VectorInfo = VectorHandoffInfoPpi->Info; - Index = 1; - while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) { - VectorInfo ++; - Index ++; - } - BuildGuidDataHob ( - &gEfiVectorHandoffInfoPpiGuid, - VectorHandoffInfoPpi->Info, - sizeof (EFI_VECTOR_HANDOFF_INFO) * Index - ); - } - - // - // Compute the top of the stack we were allocated. Pre-allocate a UINTN - // for safety. - // - TopOfStack = BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT; - TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - PageTables = 0; - BuildPageTablesIa32Pae = (BOOLEAN) (PcdGetBool (PcdSetNxForStack) && IsIa32PaeSupport () && IsExecuteDisableBitAvailable ()); - if (BuildPageTablesIa32Pae) { - PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE); - EnableExecuteDisableBit (); - } - - // - // End of PEI phase signal - // - Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi); - ASSERT_EFI_ERROR (Status); - - if (BuildPageTablesIa32Pae) { - AsmWriteCr3 (PageTables); - // - // Set Physical Address Extension (bit 5 of CR4). - // - AsmWriteCr4 (AsmReadCr4 () | BIT5); - } - - // - // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. - // - UpdateStackHob (BaseOfStack, STACK_SIZE); - - DEBUG (( - DEBUG_INFO, - "%a() Stack Base: 0x%lx, Stack Size: 0x%x\n", - __FUNCTION__, - BaseOfStack, - STACK_SIZE - )); - - // - // Transfer the control to the entry point of DxeCore. - // - if (BuildPageTablesIa32Pae) { - AsmEnablePaging32 ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint, - HobList.Raw, - NULL, - (VOID *) (UINTN) TopOfStack - ); - } else { - SwitchStack ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint, - HobList.Raw, - NULL, - (VOID *) (UINTN) TopOfStack - ); - } - } -} - diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.S b/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.S deleted file mode 100644 index 96a3acbac1..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.S +++ /dev/null @@ -1,80 +0,0 @@ -#/** @file -# -# IDT vector entry. -# -# Copyright (c) 2007 - 2009, 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 -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -#**/ - - .text - .code32 - - - .p2align 3 - ASM_GLOBAL ASM_PFX(AsmGetVectorTemplatInfo) - ASM_GLOBAL ASM_PFX(AsmVectorFixup) -/* -; -;----------------------------------------------------------------------- -; Template of IDT Vector Handlers. -; -;----------------------------------------------------------------------- -*/ -VectorTemplateBase: - pushl %eax - .byte 0x6a # push #VectorNum -VectorNum: - .byte 0 - movl CommonInterruptEntry, %eax - jmp *%eax -VectorTemplateEnd: - - -ASM_PFX(AsmGetVectorTemplatInfo): - movl 4(%esp), %ecx - movl $VectorTemplateBase, (%ecx) - movl $(VectorTemplateEnd - VectorTemplateBase), %eax - ret - -ASM_PFX(AsmVectorFixup): - movl 8(%esp), %eax - movl 4(%esp), %ecx - movb %al, (VectorNum - VectorTemplateBase)(%ecx) - ret - -/* -; The follow algorithm is used for the common interrupt routine. - -; -; +---------------------+ <-- 16-byte aligned ensured by processor -; + Old SS + -; +---------------------+ -; + Old RSP + -; +---------------------+ -; + RFlags + -; +---------------------+ -; + CS + -; +---------------------+ -; + RIP + -; +---------------------+ -; + Error Code + -; +---------------------+ -; + Vector Number + -; +---------------------+ -*/ - -CommonInterruptEntry: - cli -1: - jmp 1b - - - - diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.asm b/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.asm deleted file mode 100644 index 69fb9a15e7..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.asm +++ /dev/null @@ -1,88 +0,0 @@ -;/** @file -; -; IDT vector entry. -; -; Copyright (c) 2007 - 2008, 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 -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -; -;**/ - - .686p - .model flat,C - .code - -; -;------------------------------------------------------------------------------ -; Generic IDT Vector Handlers for the Host. -; -;------------------------------------------------------------------------------ - -ALIGN 8 -PUBLIC AsmGetVectorTemplatInfo -PUBLIC AsmVectorFixup - -PUBLIC AsmVectorFixup - -@VectorTemplateBase: - push eax - db 6ah ; push #VectorNumber -@VectorNum: - db 0 - mov eax, CommonInterruptEntry - jmp eax -@VectorTemplateEnd: - - -AsmGetVectorTemplatInfo PROC - mov ecx, [esp + 4] - mov [ecx], @VectorTemplateBase - mov eax, (@VectorTemplateEnd - @VectorTemplateBase) - ret -AsmGetVectorTemplatInfo ENDP - - -AsmVectorFixup PROC - mov eax, dword ptr [esp + 8] - mov ecx, [esp + 4] - mov [ecx + (@VectorNum - @VectorTemplateBase)], al - ret -AsmVectorFixup ENDP - - -;---------------------------------------; -; CommonInterruptEntry ; -;---------------------------------------; -; The follow algorithm is used for the common interrupt routine. - -; -; +---------------------+ <-- 16-byte aligned ensured by processor -; + Old SS + -; +---------------------+ -; + Old RSP + -; +---------------------+ -; + RFlags + -; +---------------------+ -; + CS + -; +---------------------+ -; + RIP + -; +---------------------+ -; + Error Code + -; +---------------------+ -; + Vector Number + -; +---------------------+ - -CommonInterruptEntry PROC - cli - - jmp $ -CommonInterruptEntry ENDP - -END - - diff --git a/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.nasm b/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.nasm deleted file mode 100644 index 99a0bbeea8..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/Ia32/IdtVectorAsm.nasm +++ /dev/null @@ -1,77 +0,0 @@ -;/** @file -; -; IDT vector entry. -; -; Copyright (c) 2007 - 2016, 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 -; http://opensource.org/licenses/bsd-license.php -; -; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -; -;**/ - - SECTION .text - -; -;------------------------------------------------------------------------------ -; Generic IDT Vector Handlers for the Host. -; -;------------------------------------------------------------------------------ - -ALIGN 8 -global ASM_PFX(AsmGetVectorTemplatInfo) -global ASM_PFX(AsmVectorFixup) - -@VectorTemplateBase: - push eax - db 0x6a ; push #VectorNumber -@VectorNum: - db 0 - mov eax, CommonInterruptEntry - jmp eax -@VectorTemplateEnd: - -global ASM_PFX(AsmGetVectorTemplatInfo) -ASM_PFX(AsmGetVectorTemplatInfo): - mov ecx, [esp + 4] - mov dword [ecx], @VectorTemplateBase - mov eax, (@VectorTemplateEnd - @VectorTemplateBase) - ret - -global ASM_PFX(AsmVectorFixup) -ASM_PFX(AsmVectorFixup): - mov eax, dword [esp + 8] - mov ecx, [esp + 4] - mov [ecx + (@VectorNum - @VectorTemplateBase)], al - ret - -;---------------------------------------; -; CommonInterruptEntry ; -;---------------------------------------; -; The follow algorithm is used for the common interrupt routine. - -; -; +---------------------+ <-- 16-byte aligned ensured by processor -; + Old SS + -; +---------------------+ -; + Old RSP + -; +---------------------+ -; + RFlags + -; +---------------------+ -; + CS + -; +---------------------+ -; + RIP + -; +---------------------+ -; + Error Code + -; +---------------------+ -; + Vector Number + -; +---------------------+ - -CommonInterruptEntry: - cli - - jmp $ - diff --git a/MdeModulePkg/Core/DxeIplPeim/Ipf/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/Ipf/DxeLoadFunc.c deleted file mode 100644 index 7443648017..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/Ipf/DxeLoadFunc.c +++ /dev/null @@ -1,85 +0,0 @@ -/** @file - Ipf-specific functionality for DxeLoad. - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeIpl.h" - - - -/** - Transfers control to DxeCore. - - This function performs a CPU architecture specific operations to execute - the entry point of DxeCore with the parameters of HobList. - It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase. - - @param DxeCoreEntryPoint The entry point of DxeCore. - @param HobList The start of HobList passed to DxeCore. - -**/ -VOID -HandOffToDxeCore ( - IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, - IN EFI_PEI_HOB_POINTERS HobList - ) -{ - VOID *BaseOfStack; - VOID *TopOfStack; - VOID *BspStore; - EFI_STATUS Status; - - // - // Allocate 128KB for the Stack - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - // - // Allocate 16KB for the BspStore - // - BspStore = AllocatePages (EFI_SIZE_TO_PAGES (BSP_STORE_SIZE)); - ASSERT (BspStore != NULL); - // - // Build BspStoreHob - // - BuildBspStoreHob ((EFI_PHYSICAL_ADDRESS) (UINTN) BspStore, BSP_STORE_SIZE, EfiBootServicesData); - - // - // Compute the top of the stack we were allocated. Pre-allocate a UINTN - // for safety. - // - TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - // - // End of PEI phase signal - // - Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi); - ASSERT_EFI_ERROR (Status); - - // - // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. - // - UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE); - - // - // Transfer the control to the entry point of DxeCore. - // - SwitchStack ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint, - HobList.Raw, - NULL, - TopOfStack, - BspStore - ); -} diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c b/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c deleted file mode 100644 index 6488880eab..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/X64/DxeLoadFunc.c +++ /dev/null @@ -1,120 +0,0 @@ -/** @file - x64-specifc functionality for DxeLoad. - -Copyright (c) 2006 - 2015, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeIpl.h" -#include "X64/VirtualMemory.h" - - - -/** - Transfers control to DxeCore. - - This function performs a CPU architecture specific operations to execute - the entry point of DxeCore with the parameters of HobList. - It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase. - - @param DxeCoreEntryPoint The entry point of DxeCore. - @param HobList The start of HobList passed to DxeCore. - -**/ -VOID -HandOffToDxeCore ( - IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint, - IN EFI_PEI_HOB_POINTERS HobList - ) -{ - VOID *BaseOfStack; - VOID *TopOfStack; - EFI_STATUS Status; - UINTN PageTables; - UINT32 Index; - EFI_VECTOR_HANDOFF_INFO *VectorInfo; - EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi; - - // - // Get Vector Hand-off Info PPI and build Guided HOB - // - Status = PeiServicesLocatePpi ( - &gEfiVectorHandoffInfoPpiGuid, - 0, - NULL, - (VOID **)&VectorHandoffInfoPpi - ); - if (Status == EFI_SUCCESS) { - DEBUG ((EFI_D_INFO, "Vector Hand-off Info PPI is gotten, GUIDed HOB is created!\n")); - VectorInfo = VectorHandoffInfoPpi->Info; - Index = 1; - while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) { - VectorInfo ++; - Index ++; - } - BuildGuidDataHob ( - &gEfiVectorHandoffInfoPpiGuid, - VectorHandoffInfoPpi->Info, - sizeof (EFI_VECTOR_HANDOFF_INFO) * Index - ); - } - - // - // Allocate 128KB for the Stack - // - BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE)); - ASSERT (BaseOfStack != NULL); - - // - // Compute the top of the stack we were allocated. Pre-allocate a UINTN - // for safety. - // - TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT); - TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); - - PageTables = 0; - if (FeaturePcdGet (PcdDxeIplBuildPageTables)) { - // - // Create page table and save PageMapLevel4 to CR3 - // - PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS) (UINTN) BaseOfStack, STACK_SIZE); - } else { - // - // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE - // for the DxeIpl and the DxeCore are both X64. - // - ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE); - } - - // - // End of PEI phase signal - // - Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi); - ASSERT_EFI_ERROR (Status); - - if (FeaturePcdGet (PcdDxeIplBuildPageTables)) { - AsmWriteCr3 (PageTables); - } - - // - // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore. - // - UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE); - - // - // Transfer the control to the entry point of DxeCore. - // - SwitchStack ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint, - HobList.Raw, - NULL, - TopOfStack - ); -} diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c deleted file mode 100644 index 48150be4e1..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c +++ /dev/null @@ -1,353 +0,0 @@ -/** @file - x64 Virtual Memory Management Services in the form of an IA-32 driver. - Used to establish a 1:1 Virtual to Physical Mapping that is required to - enter Long Mode (x64 64-bit mode). - - While we make a 1:1 mapping (identity mapping) for all physical pages - we still need to use the MTRR's to ensure that the cachability attributes - for all memory regions is correct. - - The basic idea is to use 2MB page table entries where ever possible. If - more granularity of cachability is required then 4K page tables are used. - - References: - 1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel - 2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel - 3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel - -Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
-Copyright (c) 2017, AMD Incorporated. 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "DxeIpl.h" -#include "VirtualMemory.h" - - -/** - Enable Execute Disable Bit. - -**/ -VOID -EnableExecuteDisableBit ( - VOID - ) -{ - UINT64 MsrRegisters; - - MsrRegisters = AsmReadMsr64 (0xC0000080); - MsrRegisters |= BIT11; - AsmWriteMsr64 (0xC0000080, MsrRegisters); -} - -/** - Split 2M page to 4K. - - @param[in] PhysicalAddress Start physical address the 2M page covered. - @param[in, out] PageEntry2M Pointer to 2M page entry. - @param[in] StackBase Stack base address. - @param[in] StackSize Stack size. - -**/ -VOID -Split2MPageTo4K ( - IN EFI_PHYSICAL_ADDRESS PhysicalAddress, - IN OUT UINT64 *PageEntry2M, - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize - ) -{ - EFI_PHYSICAL_ADDRESS PhysicalAddress4K; - UINTN IndexOfPageTableEntries; - PAGE_TABLE_4K_ENTRY *PageTableEntry; - UINT64 AddressEncMask; - - // - // Make sure AddressEncMask is contained to smallest supported address field - // - AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; - - PageTableEntry = AllocatePages (1); - ASSERT (PageTableEntry != NULL); - - // - // Fill in 2M page entry. - // - *PageEntry2M = (UINT64) (UINTN) PageTableEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; - - PhysicalAddress4K = PhysicalAddress; - for (IndexOfPageTableEntries = 0; IndexOfPageTableEntries < 512; IndexOfPageTableEntries++, PageTableEntry++, PhysicalAddress4K += SIZE_4KB) { - // - // Fill in the Page Table entries - // - PageTableEntry->Uint64 = (UINT64) PhysicalAddress4K | AddressEncMask; - PageTableEntry->Bits.ReadWrite = 1; - PageTableEntry->Bits.Present = 1; - if ((PhysicalAddress4K >= StackBase) && (PhysicalAddress4K < StackBase + StackSize)) { - // - // Set Nx bit for stack. - // - PageTableEntry->Bits.Nx = 1; - } - } -} - -/** - Split 1G page to 2M. - - @param[in] PhysicalAddress Start physical address the 1G page covered. - @param[in, out] PageEntry1G Pointer to 1G page entry. - @param[in] StackBase Stack base address. - @param[in] StackSize Stack size. - -**/ -VOID -Split1GPageTo2M ( - IN EFI_PHYSICAL_ADDRESS PhysicalAddress, - IN OUT UINT64 *PageEntry1G, - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize - ) -{ - EFI_PHYSICAL_ADDRESS PhysicalAddress2M; - UINTN IndexOfPageDirectoryEntries; - PAGE_TABLE_ENTRY *PageDirectoryEntry; - UINT64 AddressEncMask; - - // - // Make sure AddressEncMask is contained to smallest supported address field - // - AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; - - PageDirectoryEntry = AllocatePages (1); - ASSERT (PageDirectoryEntry != NULL); - - // - // Fill in 1G page entry. - // - *PageEntry1G = (UINT64) (UINTN) PageDirectoryEntry | AddressEncMask | IA32_PG_P | IA32_PG_RW; - - PhysicalAddress2M = PhysicalAddress; - for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress2M += SIZE_2MB) { - if ((PhysicalAddress2M < StackBase + StackSize) && ((PhysicalAddress2M + SIZE_2MB) > StackBase)) { - // - // Need to split this 2M page that covers stack range. - // - Split2MPageTo4K (PhysicalAddress2M, (UINT64 *) PageDirectoryEntry, StackBase, StackSize); - } else { - // - // Fill in the Page Directory entries - // - PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress2M | AddressEncMask; - PageDirectoryEntry->Bits.ReadWrite = 1; - PageDirectoryEntry->Bits.Present = 1; - PageDirectoryEntry->Bits.MustBe1 = 1; - } - } -} - -/** - Allocates and fills in the Page Directory and Page Table Entries to - establish a 1:1 Virtual to Physical mapping. - - @param[in] StackBase Stack base address. - @param[in] StackSize Stack size. - - @return The address of 4 level page map. - -**/ -UINTN -CreateIdentityMappingPageTables ( - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize - ) -{ - UINT32 RegEax; - UINT32 RegEdx; - UINT8 PhysicalAddressBits; - EFI_PHYSICAL_ADDRESS PageAddress; - UINTN IndexOfPml4Entries; - UINTN IndexOfPdpEntries; - UINTN IndexOfPageDirectoryEntries; - UINT32 NumberOfPml4EntriesNeeded; - UINT32 NumberOfPdpEntriesNeeded; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry; - PAGE_MAP_AND_DIRECTORY_POINTER *PageMap; - PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry; - PAGE_TABLE_ENTRY *PageDirectoryEntry; - UINTN TotalPagesNum; - UINTN BigPageAddress; - VOID *Hob; - BOOLEAN Page1GSupport; - PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry; - UINT64 AddressEncMask; - - // - // Make sure AddressEncMask is contained to smallest supported address field - // - AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64; - - Page1GSupport = FALSE; - if (PcdGetBool(PcdUse1GPageTable)) { - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - if (RegEax >= 0x80000001) { - AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx); - if ((RegEdx & BIT26) != 0) { - Page1GSupport = TRUE; - } - } - } - - // - // Get physical address bits supported. - // - Hob = GetFirstHob (EFI_HOB_TYPE_CPU); - if (Hob != NULL) { - PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace; - } else { - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - if (RegEax >= 0x80000008) { - AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); - PhysicalAddressBits = (UINT8) RegEax; - } else { - PhysicalAddressBits = 36; - } - } - - // - // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses. - // - ASSERT (PhysicalAddressBits <= 52); - if (PhysicalAddressBits > 48) { - PhysicalAddressBits = 48; - } - - // - // Calculate the table entries needed. - // - if (PhysicalAddressBits <= 39 ) { - NumberOfPml4EntriesNeeded = 1; - NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30)); - } else { - NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39)); - NumberOfPdpEntriesNeeded = 512; - } - - // - // Pre-allocate big pages to avoid later allocations. - // - if (!Page1GSupport) { - TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1; - } else { - TotalPagesNum = NumberOfPml4EntriesNeeded + 1; - } - BigPageAddress = (UINTN) AllocatePages (TotalPagesNum); - ASSERT (BigPageAddress != 0); - - // - // By architecture only one PageMapLevel4 exists - so lets allocate storage for it. - // - PageMap = (VOID *) BigPageAddress; - BigPageAddress += SIZE_4KB; - - PageMapLevel4Entry = PageMap; - PageAddress = 0; - for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) { - // - // Each PML4 entry points to a page of Page Directory Pointer entires. - // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop. - // - PageDirectoryPointerEntry = (VOID *) BigPageAddress; - BigPageAddress += SIZE_4KB; - - // - // Make a PML4 Entry - // - PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry | AddressEncMask; - PageMapLevel4Entry->Bits.ReadWrite = 1; - PageMapLevel4Entry->Bits.Present = 1; - - if (Page1GSupport) { - PageDirectory1GEntry = (VOID *) PageDirectoryPointerEntry; - - for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) { - if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_1GB) > StackBase)) { - Split1GPageTo2M (PageAddress, (UINT64 *) PageDirectory1GEntry, StackBase, StackSize); - } else { - // - // Fill in the Page Directory entries - // - PageDirectory1GEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; - PageDirectory1GEntry->Bits.ReadWrite = 1; - PageDirectory1GEntry->Bits.Present = 1; - PageDirectory1GEntry->Bits.MustBe1 = 1; - } - } - } else { - for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { - // - // Each Directory Pointer entries points to a page of Page Directory entires. - // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop. - // - PageDirectoryEntry = (VOID *) BigPageAddress; - BigPageAddress += SIZE_4KB; - - // - // Fill in a Page Directory Pointer Entries - // - PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry | AddressEncMask; - PageDirectoryPointerEntry->Bits.ReadWrite = 1; - PageDirectoryPointerEntry->Bits.Present = 1; - - for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) { - if (PcdGetBool (PcdSetNxForStack) && (PageAddress < StackBase + StackSize) && ((PageAddress + SIZE_2MB) > StackBase)) { - // - // Need to split this 2M page that covers stack range. - // - Split2MPageTo4K (PageAddress, (UINT64 *) PageDirectoryEntry, StackBase, StackSize); - } else { - // - // Fill in the Page Directory entries - // - PageDirectoryEntry->Uint64 = (UINT64)PageAddress | AddressEncMask; - PageDirectoryEntry->Bits.ReadWrite = 1; - PageDirectoryEntry->Bits.Present = 1; - PageDirectoryEntry->Bits.MustBe1 = 1; - } - } - } - - for (; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) { - ZeroMem ( - PageDirectoryPointerEntry, - sizeof(PAGE_MAP_AND_DIRECTORY_POINTER) - ); - } - } - } - - // - // For the PML4 entries we are not using fill in a null entry. - // - for (; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Entry++) { - ZeroMem ( - PageMapLevel4Entry, - sizeof (PAGE_MAP_AND_DIRECTORY_POINTER) - ); - } - - if (PcdGetBool (PcdSetNxForStack)) { - EnableExecuteDisableBit (); - } - - return (UINTN)PageMap; -} - diff --git a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h b/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h deleted file mode 100644 index 7c9bb49e3e..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.h +++ /dev/null @@ -1,231 +0,0 @@ -/** @file - x64 Long Mode Virtual Memory Management Definitions - - References: - 1) IA-32 Intel(R) Architecture Software Developer's Manual Volume 1:Basic Architecture, Intel - 2) IA-32 Intel(R) Architecture Software Developer's Manual Volume 2:Instruction Set Reference, Intel - 3) IA-32 Intel(R) Architecture Software Developer's Manual Volume 3:System Programmer's Guide, Intel - 4) AMD64 Architecture Programmer's Manual Volume 2: System Programming - -Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-Copyright (c) 2017, AMD Incorporated. 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ -#ifndef _VIRTUAL_MEMORY_H_ -#define _VIRTUAL_MEMORY_H_ - - -#define SYS_CODE64_SEL 0x38 - - -#pragma pack(1) - -typedef union { - struct { - UINT32 LimitLow : 16; - UINT32 BaseLow : 16; - UINT32 BaseMid : 8; - UINT32 Type : 4; - UINT32 System : 1; - UINT32 Dpl : 2; - UINT32 Present : 1; - UINT32 LimitHigh : 4; - UINT32 Software : 1; - UINT32 Reserved : 1; - UINT32 DefaultSize : 1; - UINT32 Granularity : 1; - UINT32 BaseHigh : 8; - } Bits; - UINT64 Uint64; -} IA32_GDT; - -typedef struct { - IA32_IDT_GATE_DESCRIPTOR Ia32IdtEntry; - UINT32 Offset32To63; - UINT32 Reserved; -} X64_IDT_GATE_DESCRIPTOR; - -// -// Page-Map Level-4 Offset (PML4) and -// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB -// - -typedef union { - struct { - UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User - UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Reserved:1; // Reserved - UINT64 MustBeZero:2; // Must Be Zero - UINT64 Available:3; // Available for use by system software - UINT64 PageTableBaseAddress:40; // Page Table Base Address - UINT64 AvabilableHigh:11; // Available for use by system software - UINT64 Nx:1; // No Execute bit - } Bits; - UINT64 Uint64; -} PAGE_MAP_AND_DIRECTORY_POINTER; - -// -// Page Table Entry 4KB -// -typedef union { - struct { - UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User - UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page - UINT64 PAT:1; // - UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available:3; // Available for use by system software - UINT64 PageTableBaseAddress:40; // Page Table Base Address - UINT64 AvabilableHigh:11; // Available for use by system software - UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} PAGE_TABLE_4K_ENTRY; - -// -// Page Table Entry 2MB -// -typedef union { - struct { - UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User - UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page - UINT64 MustBe1:1; // Must be 1 - UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available:3; // Available for use by system software - UINT64 PAT:1; // - UINT64 MustBeZero:8; // Must be zero; - UINT64 PageTableBaseAddress:31; // Page Table Base Address - UINT64 AvabilableHigh:11; // Available for use by system software - UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} PAGE_TABLE_ENTRY; - -// -// Page Table Entry 1GB -// -typedef union { - struct { - UINT64 Present:1; // 0 = Not present in memory, 1 = Present in memory - UINT64 ReadWrite:1; // 0 = Read-Only, 1= Read/Write - UINT64 UserSupervisor:1; // 0 = Supervisor, 1=User - UINT64 WriteThrough:1; // 0 = Write-Back caching, 1=Write-Through caching - UINT64 CacheDisabled:1; // 0 = Cached, 1=Non-Cached - UINT64 Accessed:1; // 0 = Not accessed, 1 = Accessed (set by CPU) - UINT64 Dirty:1; // 0 = Not Dirty, 1 = written by processor on access to page - UINT64 MustBe1:1; // Must be 1 - UINT64 Global:1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write - UINT64 Available:3; // Available for use by system software - UINT64 PAT:1; // - UINT64 MustBeZero:17; // Must be zero; - UINT64 PageTableBaseAddress:22; // Page Table Base Address - UINT64 AvabilableHigh:11; // Available for use by system software - UINT64 Nx:1; // 0 = Execute Code, 1 = No Code Execution - } Bits; - UINT64 Uint64; -} PAGE_TABLE_1G_ENTRY; - -#pragma pack() - -#define IA32_PG_P BIT0 -#define IA32_PG_RW BIT1 - -#define PAGING_1G_ADDRESS_MASK_64 0x000FFFFFC0000000ull - -/** - Enable Execute Disable Bit. - -**/ -VOID -EnableExecuteDisableBit ( - VOID - ); - -/** - Split 2M page to 4K. - - @param[in] PhysicalAddress Start physical address the 2M page covered. - @param[in, out] PageEntry2M Pointer to 2M page entry. - @param[in] StackBase Stack base address. - @param[in] StackSize Stack size. - -**/ -VOID -Split2MPageTo4K ( - IN EFI_PHYSICAL_ADDRESS PhysicalAddress, - IN OUT UINT64 *PageEntry2M, - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize - ); - -/** - Allocates and fills in the Page Directory and Page Table Entries to - establish a 1:1 Virtual to Physical mapping. - - @param[in] StackBase Stack base address. - @param[in] StackSize Stack size. - - @return The address of 4 level page map. - -**/ -UINTN -CreateIdentityMappingPageTables ( - IN EFI_PHYSICAL_ADDRESS StackBase, - IN UINTN StackSize - ); - - -/** - - Fix up the vector number in the vector code. - - @param VectorBase Base address of the vector handler. - @param VectorNum Index of vector. - -**/ -VOID -EFIAPI -AsmVectorFixup ( - VOID *VectorBase, - UINT8 VectorNum - ); - - -/** - - Get the information of vector template. - - @param TemplateBase Base address of the template code. - - @return Size of the Template code. - -**/ -UINTN -EFIAPI -AsmGetVectorTemplatInfo ( - OUT VOID **TemplateBase - ); - - -#endif diff --git a/MdeModulePkg/Core/Pei/BootMode/BootMode.c b/MdeModulePkg/Core/Pei/BootMode/BootMode.c deleted file mode 100644 index 39afeba838..0000000000 --- a/MdeModulePkg/Core/Pei/BootMode/BootMode.c +++ /dev/null @@ -1,86 +0,0 @@ -/** @file - This module provide function for ascertaining and updating the boot mode: - GetBootMode() - SetBootMode() - See PI Specification volume I, chapter 9 Boot Paths for additional information - on the boot mode. - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/** - This service enables PEIMs to ascertain the present value of the boot mode. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param BootMode A pointer to contain the value of the boot mode. - - @retval EFI_SUCCESS The boot mode was returned successfully. - @retval EFI_INVALID_PARAMETER BootMode is NULL. - -**/ -EFI_STATUS -EFIAPI -PeiGetBootMode ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN OUT EFI_BOOT_MODE *BootMode - ) -{ - PEI_CORE_INSTANCE *PrivateData; - EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; - - - if (BootMode == NULL) { - return EFI_INVALID_PARAMETER; - } - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - - HandOffHob = (PrivateData->HobList.HandoffInformationTable); - - *BootMode = HandOffHob->BootMode; - - - return EFI_SUCCESS; -} - - -/** - This service enables PEIMs to update the boot mode variable. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param BootMode The value of the boot mode to set. - - @return EFI_SUCCESS The value was successfully updated - -**/ -EFI_STATUS -EFIAPI -PeiSetBootMode ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_BOOT_MODE BootMode - ) -{ - PEI_CORE_INSTANCE *PrivateData; - EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; - - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - - HandOffHob = (PrivateData->HobList.HandoffInformationTable); - - HandOffHob->BootMode = BootMode; - - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/Pei/CpuIo/CpuIo.c b/MdeModulePkg/Core/Pei/CpuIo/CpuIo.c deleted file mode 100644 index c82c221540..0000000000 --- a/MdeModulePkg/Core/Pei/CpuIo/CpuIo.c +++ /dev/null @@ -1,541 +0,0 @@ -/** @file - The default version of EFI_PEI_CPU_IO_PPI support published by PeiServices in - PeiCore initialization phase. - - EFI_PEI_CPU_IO_PPI is installed by some platform or chipset-specific PEIM that - abstracts the processor-visible I/O operations. When PeiCore is started, the - default version of EFI_PEI_CPU_IO_PPI will be assigned to PeiServices table. - -Copyright (c) 2009, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/// -/// This default instance of EFI_PEI_CPU_IO_PPI install assigned to EFI_PEI_SERVICE.CpuIo -/// when PeiCore's initialization. -/// -EFI_PEI_CPU_IO_PPI gPeiDefaultCpuIoPpi = { - { - PeiDefaultMemRead, - PeiDefaultMemWrite - }, - { - PeiDefaultIoRead, - PeiDefaultIoWrite - }, - PeiDefaultIoRead8, - PeiDefaultIoRead16, - PeiDefaultIoRead32, - PeiDefaultIoRead64, - PeiDefaultIoWrite8, - PeiDefaultIoWrite16, - PeiDefaultIoWrite32, - PeiDefaultIoWrite64, - PeiDefaultMemRead8, - PeiDefaultMemRead16, - PeiDefaultMemRead32, - PeiDefaultMemRead64, - PeiDefaultMemWrite8, - PeiDefaultMemWrite16, - PeiDefaultMemWrite32, - PeiDefaultMemWrite64 -}; - -/** - Memory-based read services. - - This function is to perform the Memory Access Read service based on installed - instance of the EFI_PEI_CPU_IO_PPI. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - @param Address The physical address of the access. - @param Count The number of accesses to perform. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_YET_AVAILABLE The service has not been installed. -**/ -EFI_STATUS -EFIAPI -PeiDefaultMemRead ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN EFI_PEI_CPU_IO_PPI_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - return EFI_NOT_AVAILABLE_YET; -} - -/** - Memory-based write services. - - This function is to perform the Memory Access Write service based on installed - instance of the EFI_PEI_CPU_IO_PPI. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - @param Address The physical address of the access. - @param Count The number of accesses to perform. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_YET_AVAILABLE The service has not been installed. -**/ -EFI_STATUS -EFIAPI -PeiDefaultMemWrite ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN EFI_PEI_CPU_IO_PPI_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - return EFI_NOT_AVAILABLE_YET; -} - -/** - IO-based read services. - - This function is to perform the IO-base read service for the EFI_PEI_CPU_IO_PPI. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - @param Address The physical address of the access. - @param Count The number of accesses to perform. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_YET_AVAILABLE The service has not been installed. -**/ -EFI_STATUS -EFIAPI -PeiDefaultIoRead ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN EFI_PEI_CPU_IO_PPI_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - return EFI_NOT_AVAILABLE_YET; -} - -/** - IO-based write services. - - This function is to perform the IO-base write service for the EFI_PEI_CPU_IO_PPI. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - @param Address The physical address of the access. - @param Count The number of accesses to perform. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_YET_AVAILABLE The service has not been installed. -**/ -EFI_STATUS -EFIAPI -PeiDefaultIoWrite ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN EFI_PEI_CPU_IO_PPI_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ) -{ - return EFI_NOT_AVAILABLE_YET; -} - -/** - 8-bit I/O read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 8-bit value returned from the I/O space. -**/ -UINT8 -EFIAPI -PeiDefaultIoRead8 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ) -{ - return 0; -} - -/** - Reads an 16-bit I/O port. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return A 16-bit value returned from the I/O space. -**/ -UINT16 -EFIAPI -PeiDefaultIoRead16 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ) -{ - return 0; -} - -/** - Reads an 32-bit I/O port. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return A 32-bit value returned from the I/O space. -**/ -UINT32 -EFIAPI -PeiDefaultIoRead32 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ) -{ - return 0; -} - -/** - Reads an 64-bit I/O port. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return A 64-bit value returned from the I/O space. -**/ -UINT64 -EFIAPI -PeiDefaultIoRead64 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ) -{ - return 0; -} - -/** - 8-bit I/O write operations. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then do - nothing. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. -**/ -VOID -EFIAPI -PeiDefaultIoWrite8 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT8 Data - ) -{ -} - -/** - 16-bit I/O write operations. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then do - nothing. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. -**/ -VOID -EFIAPI -PeiDefaultIoWrite16 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT16 Data - ) -{ -} - -/** - 32-bit I/O write operations. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then do - nothing. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. -**/ -VOID -EFIAPI -PeiDefaultIoWrite32 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT32 Data - ) -{ -} - -/** - 64-bit I/O write operations. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then do - nothing. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. -**/ -VOID -EFIAPI -PeiDefaultIoWrite64 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT64 Data - ) -{ -} - -/** - 8-bit memory read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 8-bit value returned from the memory space. - -**/ -UINT8 -EFIAPI -PeiDefaultMemRead8 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ) -{ - return 0; -} - -/** - 16-bit memory read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 16-bit value returned from the memory space. - -**/ -UINT16 -EFIAPI -PeiDefaultMemRead16 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ) -{ - return 0; -} - -/** - 32-bit memory read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 32-bit value returned from the memory space. - -**/ -UINT32 -EFIAPI -PeiDefaultMemRead32 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ) -{ - return 0; -} - -/** - 64-bit memory read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 64-bit value returned from the memory space. - -**/ -UINT64 -EFIAPI -PeiDefaultMemRead64 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ) -{ - return 0; -} - -/** - 8-bit memory write operations. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then do - nothing. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. - -**/ -VOID -EFIAPI -PeiDefaultMemWrite8 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT8 Data - ) -{ -} - -/** - 16-bit memory write operations. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then do - nothing. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. - -**/ -VOID -EFIAPI -PeiDefaultMemWrite16 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT16 Data - ) -{ -} - -/** - 32-bit memory write operations. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then do - nothing. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. - -**/ -VOID -EFIAPI -PeiDefaultMemWrite32 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT32 Data - ) -{ -} - -/** - 64-bit memory write operations. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then do - nothing. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. - -**/ -VOID -EFIAPI -PeiDefaultMemWrite64 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT64 Data - ) -{ -} diff --git a/MdeModulePkg/Core/Pei/Dependency/Dependency.c b/MdeModulePkg/Core/Pei/Dependency/Dependency.c deleted file mode 100644 index e71566b5a7..0000000000 --- a/MdeModulePkg/Core/Pei/Dependency/Dependency.c +++ /dev/null @@ -1,253 +0,0 @@ -/** @file - PEI Dispatcher Dependency Evaluator - - This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine - if a driver can be scheduled for execution. The criteria for - schedulability is that the dependency expression is satisfied. - -Copyright (c) 2006 - 2014, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" -#include "Dependency.h" - -/** - - This routine determines if a PPI has been installed. - The truth value of a GUID is determined by if the PPI has - been published and can be queried from the PPI database. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param Stack Reference to EVAL_STACK_ENTRY that contains PPI GUID to check - - @retval TRUE if the PPI is already installed. - @retval FALSE if the PPI has yet to be installed. - -**/ -BOOLEAN -IsPpiInstalled ( - IN EFI_PEI_SERVICES **PeiServices, - IN EVAL_STACK_ENTRY *Stack - ) -{ - VOID *PeiInstance; - EFI_STATUS Status; - EFI_GUID PpiGuid; - - // - // If there is no GUID to evaluate, just return current result on stack. - // - if (Stack->Operator == NULL) { - return Stack->Result; - } - - // - // Copy the Guid into a locale variable so that there are no - // possibilities of alignment faults for cross-compilation - // environments such as Intel?Itanium(TM). - // - CopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID)); - - // - // Check if the PPI is installed. - // - Status = PeiServicesLocatePpi( - &PpiGuid, // GUID - 0, // INSTANCE - NULL, // EFI_PEI_PPI_DESCRIPTOR - &PeiInstance // PPI - ); - - if (EFI_ERROR(Status)) { - return FALSE; - } - - return TRUE; -} - -/** - - This is the POSTFIX version of the dependency evaluator. When a - PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on - the evaluation stack. When that entry is poped from the evaluation - stack, the PPI is checked if it is installed. This method allows - some time savings as not all PPIs must be checked for certain - operation types (AND, OR). - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param DependencyExpression Pointer to a dependency expression. The Grammar adheres to - the BNF described above and is stored in postfix notation. - - @retval TRUE if it is a well-formed Grammar - @retval FALSE if the dependency expression overflows the evaluation stack - if the dependency expression underflows the evaluation stack - if the dependency expression is not a well-formed Grammar. - -**/ -BOOLEAN -PeimDispatchReadiness ( - IN EFI_PEI_SERVICES **PeiServices, - IN VOID *DependencyExpression - ) -{ - DEPENDENCY_EXPRESSION_OPERAND *Iterator; - EVAL_STACK_ENTRY *StackPtr; - EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE]; - - Iterator = DependencyExpression; - - StackPtr = EvalStack; - - while (TRUE) { - - switch (*(Iterator++)) { - - // - // For performance reason we put the frequently used items in front of - // the rarely used items - // - - case (EFI_DEP_PUSH): - // - // Check to make sure the dependency grammar doesn't overflow the - // EvalStack on the push - // - if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n")); - return FALSE; - } - - // - // Push the pointer to the PUSH opcode operator (pointer to PPI GUID) - // We will evaluate if the PPI is insalled on the POP operation. - // - StackPtr->Operator = (VOID *) Iterator; - Iterator = Iterator + sizeof (EFI_GUID); - DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = %a\n", StackPtr->Operator, IsPpiInstalled (PeiServices, StackPtr) ? "TRUE" : "FALSE")); - StackPtr++; - break; - - case (EFI_DEP_AND): - case (EFI_DEP_OR): - if (*(Iterator - 1) == EFI_DEP_AND) { - DEBUG ((DEBUG_DISPATCH, " AND\n")); - } else { - DEBUG ((DEBUG_DISPATCH, " OR\n")); - } - // - // Check to make sure the dependency grammar doesn't underflow the - // EvalStack on the two POPs for the AND operation. Don't need to - // check for the overflow on PUSHing the result since we already - // did two POPs. - // - if (StackPtr < &EvalStack[2]) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n")); - return FALSE; - } - - // - // Evaluate the first POPed operator only. If the operand is - // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the - // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE, - // we don't need to check the second operator, and the result will be - // evaluation of the POPed operator. Otherwise, don't POP the second - // operator since it will now evaluate to the final result on the - // next operand that causes a POP. - // - StackPtr--; - // - // Iterator has increased by 1 after we retrieve the operand, so here we - // should get the value pointed by (Iterator - 1), in order to obtain the - // same operand. - // - if (*(Iterator - 1) == EFI_DEP_AND) { - if (!(IsPpiInstalled (PeiServices, StackPtr))) { - (StackPtr-1)->Result = FALSE; - (StackPtr-1)->Operator = NULL; - } - } else { - if (IsPpiInstalled (PeiServices, StackPtr)) { - (StackPtr-1)->Result = TRUE; - (StackPtr-1)->Operator = NULL; - } - } - break; - - case (EFI_DEP_END): - DEBUG ((DEBUG_DISPATCH, " END\n")); - StackPtr--; - // - // Check to make sure EvalStack is balanced. If not, then there is - // an error in the dependency grammar, so return EFI_INVALID_PARAMETER. - // - if (StackPtr != &EvalStack[0]) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n")); - return FALSE; - } - DEBUG ((DEBUG_DISPATCH, " RESULT = %a\n", IsPpiInstalled (PeiServices, StackPtr) ? "TRUE" : "FALSE")); - return IsPpiInstalled (PeiServices, StackPtr); - - case (EFI_DEP_NOT): - DEBUG ((DEBUG_DISPATCH, " NOT\n")); - // - // Check to make sure the dependency grammar doesn't underflow the - // EvalStack on the POP for the NOT operation. Don't need to - // check for the overflow on PUSHing the result since we already - // did a POP. - // - if (StackPtr < &EvalStack[1]) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n")); - return FALSE; - } - (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1)); - (StackPtr-1)->Operator = NULL; - break; - - case (EFI_DEP_TRUE): - case (EFI_DEP_FALSE): - if (*(Iterator - 1) == EFI_DEP_TRUE) { - DEBUG ((DEBUG_DISPATCH, " TRUE\n")); - } else { - DEBUG ((DEBUG_DISPATCH, " FALSE\n")); - } - // - // Check to make sure the dependency grammar doesn't overflow the - // EvalStack on the push - // - if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Underflow Error)\n")); - return FALSE; - } - // - // Iterator has increased by 1 after we retrieve the operand, so here we - // should get the value pointed by (Iterator - 1), in order to obtain the - // same operand. - // - if (*(Iterator - 1) == EFI_DEP_TRUE) { - StackPtr->Result = TRUE; - } else { - StackPtr->Result = FALSE; - } - StackPtr->Operator = NULL; - StackPtr++; - break; - - default: - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Invalid opcode)\n")); - // - // The grammar should never arrive here - // - return FALSE; - } - } -} diff --git a/MdeModulePkg/Core/Pei/Dependency/Dependency.h b/MdeModulePkg/Core/Pei/Dependency/Dependency.h deleted file mode 100644 index 5021ce056b..0000000000 --- a/MdeModulePkg/Core/Pei/Dependency/Dependency.h +++ /dev/null @@ -1,32 +0,0 @@ -/** @file - This module contains data specific to dependency expressions - and local function prototypes. - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _PEI_DEPENDENCY_H_ -#define _PEI_DEPENDENCY_H_ - - -#define MAX_GRAMMAR_SIZE 64 - -// -// type definitions -// -typedef UINT8 DEPENDENCY_EXPRESSION_OPERAND; - -typedef struct { - BOOLEAN Result; - VOID *Operator; -} EVAL_STACK_ENTRY; - -#endif diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c deleted file mode 100644 index ff43a90ba5..0000000000 --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c +++ /dev/null @@ -1,1353 +0,0 @@ -/** @file - EFI PEI Core dispatch services - -Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
-(C) Copyright 2016 Hewlett Packard Enterprise Development LP
-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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/// -/// temporary memory is filled with this initial value during SEC phase -/// -#define INIT_CAR_VALUE 0x5AA55AA5 - -/** - - Discover all Peims and optional Apriori file in one FV. There is at most one - Apriori file in one FV. - - - @param Private Pointer to the private data passed in from caller - @param CoreFileHandle The instance of PEI_CORE_FV_HANDLE. - -**/ -VOID -DiscoverPeimsAndOrderWithApriori ( - IN PEI_CORE_INSTANCE *Private, - IN PEI_CORE_FV_HANDLE *CoreFileHandle - ) -{ - EFI_STATUS Status; - EFI_PEI_FILE_HANDLE FileHandle; - EFI_PEI_FILE_HANDLE AprioriFileHandle; - EFI_GUID *Apriori; - UINTN Index; - UINTN Index2; - UINTN PeimIndex; - UINTN PeimCount; - EFI_GUID *Guid; - EFI_PEI_FILE_HANDLE *TempFileHandles; - EFI_GUID *FileGuid; - EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; - EFI_FV_FILE_INFO FileInfo; - - FvPpi = CoreFileHandle->FvPpi; - - // - // Walk the FV and find all the PEIMs and the Apriori file. - // - AprioriFileHandle = NULL; - Private->CurrentFvFileHandles[0] = NULL; - Guid = NULL; - FileHandle = NULL; - TempFileHandles = Private->FileHandles; - FileGuid = Private->FileGuid; - - // - // If the current Fv has been scanned, directly get its cachable record. - // - if (Private->Fv[Private->CurrentPeimFvCount].ScanFv) { - CopyMem (Private->CurrentFvFileHandles, Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv)); - return; - } - - // - // Go ahead to scan this Fv, and cache FileHandles within it. - // - Status = EFI_NOT_FOUND; - for (PeimCount = 0; PeimCount <= PcdGet32 (PcdPeiCoreMaxPeimPerFv); PeimCount++) { - Status = FvPpi->FindFileByType (FvPpi, PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, CoreFileHandle->FvHandle, &FileHandle); - if (Status != EFI_SUCCESS || PeimCount == PcdGet32 (PcdPeiCoreMaxPeimPerFv)) { - break; - } - - Private->CurrentFvFileHandles[PeimCount] = FileHandle; - } - - // - // Check whether the count of files exceeds the max support files in a FV image - // If more files are required in a FV image, PcdPeiCoreMaxPeimPerFv can be set to a larger value in DSC file. - // - ASSERT ((Status != EFI_SUCCESS) || (PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv))); - - // - // Get Apriori File handle - // - Private->AprioriCount = 0; - Status = FvPpi->FindFileByName (FvPpi, &gPeiAprioriFileNameGuid, &CoreFileHandle->FvHandle, &AprioriFileHandle); - if (!EFI_ERROR(Status) && AprioriFileHandle != NULL) { - // - // Read the Apriori file - // - Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, AprioriFileHandle, (VOID **) &Apriori); - if (!EFI_ERROR (Status)) { - // - // Calculate the number of PEIMs in the A Priori list - // - Status = FvPpi->GetFileInfo (FvPpi, AprioriFileHandle, &FileInfo); - ASSERT_EFI_ERROR (Status); - Private->AprioriCount = FileInfo.BufferSize; - if (IS_SECTION2 (FileInfo.Buffer)) { - Private->AprioriCount -= sizeof (EFI_COMMON_SECTION_HEADER2); - } else { - Private->AprioriCount -= sizeof (EFI_COMMON_SECTION_HEADER); - } - Private->AprioriCount /= sizeof (EFI_GUID); - - for (Index = 0; Index < PeimCount; Index++) { - // - // Make an array of file name guids that matches the FileHandle array so we can convert - // quickly from file name to file handle - // - Status = FvPpi->GetFileInfo (FvPpi, Private->CurrentFvFileHandles[Index], &FileInfo); - CopyMem (&FileGuid[Index], &FileInfo.FileName, sizeof(EFI_GUID)); - } - - // - // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file. - // Add available PEIMs in Apriori file into TempFileHandles array at first. - // - Index2 = 0; - for (Index = 0; Index2 < Private->AprioriCount; Index++) { - while (Index2 < Private->AprioriCount) { - Guid = ScanGuid (FileGuid, PeimCount * sizeof (EFI_GUID), &Apriori[Index2++]); - if (Guid != NULL) { - break; - } - } - if (Guid == NULL) { - break; - } - PeimIndex = ((UINTN)Guid - (UINTN)&FileGuid[0])/sizeof (EFI_GUID); - TempFileHandles[Index] = Private->CurrentFvFileHandles[PeimIndex]; - - // - // Since we have copied the file handle we can remove it from this list. - // - Private->CurrentFvFileHandles[PeimIndex] = NULL; - } - - // - // Update valid Aprioricount - // - Private->AprioriCount = Index; - - // - // Add in any PEIMs not in the Apriori file - // - for (;Index < PeimCount; Index++) { - for (Index2 = 0; Index2 < PeimCount; Index2++) { - if (Private->CurrentFvFileHandles[Index2] != NULL) { - TempFileHandles[Index] = Private->CurrentFvFileHandles[Index2]; - Private->CurrentFvFileHandles[Index2] = NULL; - break; - } - } - } - // - //Index the end of array contains re-range Pei moudle. - // - TempFileHandles[Index] = NULL; - - // - // Private->CurrentFvFileHandles is currently in PEIM in the FV order. - // We need to update it to start with files in the A Priori list and - // then the remaining files in PEIM order. - // - CopyMem (Private->CurrentFvFileHandles, TempFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv)); - } - } - // - // Cache the current Fv File Handle. So that we don't have to scan the Fv again. - // Instead, we can retrieve the file handles within this Fv from cachable data. - // - Private->Fv[Private->CurrentPeimFvCount].ScanFv = TRUE; - CopyMem (Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, Private->CurrentFvFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv)); - -} - -// -// This is the minimum memory required by DxeCore initialization. When LMFA feature enabled, -// This part of memory still need reserved on the very top of memory so that the DXE Core could -// use these memory for data initialization. This macro should be sync with the same marco -// defined in DXE Core. -// -#define MINIMUM_INITIAL_MEMORY_SIZE 0x10000 -/** - This function is to test if the memory range described in resource HOB is available or not. - - This function should only be invoked when Loading Module at Fixed Address(LMFA) feature is enabled. Some platform may allocate the - memory before PeiLoadFixAddressHook in invoked. so this function is to test if the memory range described by the input resource HOB is - available or not. - - @param PrivateData Pointer to the private data passed in from caller - @param ResourceHob Pointer to a resource HOB which described the memory range described by the input resource HOB -**/ -BOOLEAN -PeiLoadFixAddressIsMemoryRangeAvailable ( - IN PEI_CORE_INSTANCE *PrivateData, - IN EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob - ) -{ - EFI_HOB_MEMORY_ALLOCATION *MemoryHob; - BOOLEAN IsAvailable; - EFI_PEI_HOB_POINTERS Hob; - - IsAvailable = TRUE; - if (PrivateData == NULL || ResourceHob == NULL) { - return FALSE; - } - // - // test if the memory range describe in the HOB is already allocated. - // - for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - // - // See if this is a memory allocation HOB - // - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) { - MemoryHob = Hob.MemoryAllocation; - if(MemoryHob->AllocDescriptor.MemoryBaseAddress == ResourceHob->PhysicalStart && - MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength == ResourceHob->PhysicalStart + ResourceHob->ResourceLength) { - IsAvailable = FALSE; - break; - } - } - } - - return IsAvailable; - -} -/** - Hook function for Loading Module at Fixed Address feature - - This function should only be invoked when Loading Module at Fixed Address(LMFA) feature is enabled. When feature is - configured as Load Modules at Fix Absolute Address, this function is to validate the top address assigned by user. When - feature is configured as Load Modules at Fixed Offset, the functino is to find the top address which is TOLM-TSEG in general. - And also the function will re-install PEI memory. - - @param PrivateData Pointer to the private data passed in from caller - -**/ -VOID -PeiLoadFixAddressHook( - IN PEI_CORE_INSTANCE *PrivateData - ) -{ - EFI_PHYSICAL_ADDRESS TopLoadingAddress; - UINT64 PeiMemorySize; - UINT64 TotalReservedMemorySize; - UINT64 MemoryRangeEnd; - EFI_PHYSICAL_ADDRESS HighAddress; - EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob; - EFI_HOB_RESOURCE_DESCRIPTOR *NextResourceHob; - EFI_HOB_RESOURCE_DESCRIPTOR *CurrentResourceHob; - EFI_PEI_HOB_POINTERS CurrentHob; - EFI_PEI_HOB_POINTERS Hob; - EFI_PEI_HOB_POINTERS NextHob; - EFI_HOB_MEMORY_ALLOCATION *MemoryHob; - // - // Initialize Local Variables - // - CurrentResourceHob = NULL; - ResourceHob = NULL; - NextResourceHob = NULL; - HighAddress = 0; - TopLoadingAddress = 0; - MemoryRangeEnd = 0; - CurrentHob.Raw = PrivateData->HobList.Raw; - PeiMemorySize = PrivateData->PhysicalMemoryLength; - // - // The top reserved memory include 3 parts: the topest range is for DXE core initialization with the size MINIMUM_INITIAL_MEMORY_SIZE - // then RuntimeCodePage range and Boot time code range. - // - TotalReservedMemorySize = MINIMUM_INITIAL_MEMORY_SIZE + EFI_PAGES_TO_SIZE(PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber)); - TotalReservedMemorySize+= EFI_PAGES_TO_SIZE(PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber)) ; - // - // PEI memory range lies below the top reserved memory - // - TotalReservedMemorySize += PeiMemorySize; - - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressRuntimeCodePageNumber= 0x%x.\n", PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber))); - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressBootTimeCodePageNumber= 0x%x.\n", PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber))); - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressPeiCodePageNumber= 0x%x.\n", PcdGet32(PcdLoadFixAddressPeiCodePageNumber))); - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Total Reserved Memory Size = 0x%lx.\n", TotalReservedMemorySize)); - // - // Loop through the system memory typed hob to merge the adjacent memory range - // - for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - // - // See if this is a resource descriptor HOB - // - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - - ResourceHob = Hob.ResourceDescriptor; - // - // If range described in this hob is not system memory or heigher than MAX_ADDRESS, ignored. - // - if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY || - ResourceHob->PhysicalStart + ResourceHob->ResourceLength > MAX_ADDRESS) { - continue; - } - - for (NextHob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(NextHob); NextHob.Raw = GET_NEXT_HOB(NextHob)) { - if (NextHob.Raw == Hob.Raw){ - continue; - } - // - // See if this is a resource descriptor HOB - // - if (GET_HOB_TYPE (NextHob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - - NextResourceHob = NextHob.ResourceDescriptor; - // - // test if range described in this NextResourceHob is system memory and have the same attribute. - // Note: Here is a assumption that system memory should always be healthy even without test. - // - if (NextResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && - (((NextResourceHob->ResourceAttribute^ResourceHob->ResourceAttribute)&(~EFI_RESOURCE_ATTRIBUTE_TESTED)) == 0)){ - - // - // See if the memory range described in ResourceHob and NextResourceHob is adjacent - // - if ((ResourceHob->PhysicalStart <= NextResourceHob->PhysicalStart && - ResourceHob->PhysicalStart + ResourceHob->ResourceLength >= NextResourceHob->PhysicalStart)|| - (ResourceHob->PhysicalStart >= NextResourceHob->PhysicalStart&& - ResourceHob->PhysicalStart <= NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength)) { - - MemoryRangeEnd = ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength)>(NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength)) ? - (ResourceHob->PhysicalStart + ResourceHob->ResourceLength):(NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength); - - ResourceHob->PhysicalStart = (ResourceHob->PhysicalStart < NextResourceHob->PhysicalStart) ? - ResourceHob->PhysicalStart : NextResourceHob->PhysicalStart; - - - ResourceHob->ResourceLength = (MemoryRangeEnd - ResourceHob->PhysicalStart); - - ResourceHob->ResourceAttribute = ResourceHob->ResourceAttribute & (~EFI_RESOURCE_ATTRIBUTE_TESTED); - // - // Delete the NextResourceHob by marking it as unused. - // - GET_HOB_TYPE (NextHob) = EFI_HOB_TYPE_UNUSED; - - } - } - } - } - } - } - // - // Some platform is already allocated pages before the HOB re-org. Here to build dedicated resource HOB to describe - // the allocated memory range - // - for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - // - // See if this is a memory allocation HOB - // - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) { - MemoryHob = Hob.MemoryAllocation; - for (NextHob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(NextHob); NextHob.Raw = GET_NEXT_HOB(NextHob)) { - // - // See if this is a resource descriptor HOB - // - if (GET_HOB_TYPE (NextHob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - NextResourceHob = NextHob.ResourceDescriptor; - // - // If range described in this hob is not system memory or heigher than MAX_ADDRESS, ignored. - // - if (NextResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY || NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength > MAX_ADDRESS) { - continue; - } - // - // If the range describe in memory allocation HOB belongs to the memroy range described by the resource hob - // - if (MemoryHob->AllocDescriptor.MemoryBaseAddress >= NextResourceHob->PhysicalStart && - MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength <= NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength) { - // - // Build seperate resource hob for this allocated range - // - if (MemoryHob->AllocDescriptor.MemoryBaseAddress > NextResourceHob->PhysicalStart) { - BuildResourceDescriptorHob ( - EFI_RESOURCE_SYSTEM_MEMORY, - NextResourceHob->ResourceAttribute, - NextResourceHob->PhysicalStart, - (MemoryHob->AllocDescriptor.MemoryBaseAddress - NextResourceHob->PhysicalStart) - ); - } - if (MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength < NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength) { - BuildResourceDescriptorHob ( - EFI_RESOURCE_SYSTEM_MEMORY, - NextResourceHob->ResourceAttribute, - MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength, - (NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength -(MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength)) - ); - } - NextResourceHob->PhysicalStart = MemoryHob->AllocDescriptor.MemoryBaseAddress; - NextResourceHob->ResourceLength = MemoryHob->AllocDescriptor.MemoryLength; - break; - } - } - } - } - } - - // - // Try to find and validate the TOP address. - // - if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0 ) { - // - // The LMFA feature is enabled as load module at fixed absolute address. - // - TopLoadingAddress = (EFI_PHYSICAL_ADDRESS)PcdGet64(PcdLoadModuleAtFixAddressEnable); - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Loading module at fixed absolute address.\n")); - // - // validate the Address. Loop the resource descriptor HOB to make sure the address is in valid memory range - // - if ((TopLoadingAddress & EFI_PAGE_MASK) != 0) { - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:Top Address 0x%lx is invalid since top address should be page align. \n", TopLoadingAddress)); - ASSERT (FALSE); - } - // - // Search for a memory region that is below MAX_ADDRESS and in which TopLoadingAddress lies - // - for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - // - // See if this is a resource descriptor HOB - // - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - - ResourceHob = Hob.ResourceDescriptor; - // - // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS - // - if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && - ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) { - // - // See if Top address specified by user is valid. - // - if (ResourceHob->PhysicalStart + TotalReservedMemorySize < TopLoadingAddress && - (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MINIMUM_INITIAL_MEMORY_SIZE) >= TopLoadingAddress && - PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) { - CurrentResourceHob = ResourceHob; - CurrentHob = Hob; - break; - } - } - } - } - if (CurrentResourceHob != NULL) { - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO:Top Address 0x%lx is valid \n", TopLoadingAddress)); - TopLoadingAddress += MINIMUM_INITIAL_MEMORY_SIZE; - } else { - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:Top Address 0x%lx is invalid \n", TopLoadingAddress)); - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:The recommended Top Address for the platform is: \n")); - // - // Print the recomended Top address range. - // - for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - // - // See if this is a resource descriptor HOB - // - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - - ResourceHob = Hob.ResourceDescriptor; - // - // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS - // - if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && - ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) { - // - // See if Top address specified by user is valid. - // - if (ResourceHob->ResourceLength > TotalReservedMemorySize && PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) { - DEBUG ((EFI_D_INFO, "(0x%lx, 0x%lx)\n", - (ResourceHob->PhysicalStart + TotalReservedMemorySize -MINIMUM_INITIAL_MEMORY_SIZE), - (ResourceHob->PhysicalStart + ResourceHob->ResourceLength -MINIMUM_INITIAL_MEMORY_SIZE) - )); - } - } - } - } - // - // Assert here - // - ASSERT (FALSE); - return; - } - } else { - // - // The LMFA feature is enabled as load module at fixed offset relative to TOLM - // Parse the Hob list to find the topest available memory. Generally it is (TOLM - TSEG) - // - // - // Search for a tested memory region that is below MAX_ADDRESS - // - for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { - // - // See if this is a resource descriptor HOB - // - if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) { - - ResourceHob = Hob.ResourceDescriptor; - // - // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS - // - if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && - ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS && - ResourceHob->ResourceLength > TotalReservedMemorySize && PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) { - // - // See if this is the highest largest system memory region below MaxAddress - // - if (ResourceHob->PhysicalStart > HighAddress) { - CurrentResourceHob = ResourceHob; - CurrentHob = Hob; - HighAddress = CurrentResourceHob->PhysicalStart; - } - } - } - } - if (CurrentResourceHob == NULL) { - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:The System Memory is too small\n")); - // - // Assert here - // - ASSERT (FALSE); - return; - } else { - TopLoadingAddress = CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength ; - } - } - - if (CurrentResourceHob != NULL) { - // - // rebuild resource HOB for PEI memmory and reserved memory - // - BuildResourceDescriptorHob ( - EFI_RESOURCE_SYSTEM_MEMORY, - ( - EFI_RESOURCE_ATTRIBUTE_PRESENT | - EFI_RESOURCE_ATTRIBUTE_INITIALIZED | - EFI_RESOURCE_ATTRIBUTE_TESTED | - EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE - ), - (TopLoadingAddress - TotalReservedMemorySize), - TotalReservedMemorySize - ); - // - // rebuild resource for the remain memory if necessary - // - if (CurrentResourceHob->PhysicalStart < TopLoadingAddress - TotalReservedMemorySize) { - BuildResourceDescriptorHob ( - EFI_RESOURCE_SYSTEM_MEMORY, - ( - EFI_RESOURCE_ATTRIBUTE_PRESENT | - EFI_RESOURCE_ATTRIBUTE_INITIALIZED | - EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE - ), - CurrentResourceHob->PhysicalStart, - (TopLoadingAddress - TotalReservedMemorySize - CurrentResourceHob->PhysicalStart) - ); - } - if (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength > TopLoadingAddress ) { - BuildResourceDescriptorHob ( - EFI_RESOURCE_SYSTEM_MEMORY, - ( - EFI_RESOURCE_ATTRIBUTE_PRESENT | - EFI_RESOURCE_ATTRIBUTE_INITIALIZED | - EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | - EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE - ), - TopLoadingAddress, - (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength - TopLoadingAddress) - ); - } - // - // Delete CurrentHob by marking it as unused since the the memory range described by is rebuilt. - // - GET_HOB_TYPE (CurrentHob) = EFI_HOB_TYPE_UNUSED; - } - - // - // Cache the top address for Loading Module at Fixed Address feature - // - PrivateData->LoadModuleAtFixAddressTopAddress = TopLoadingAddress - MINIMUM_INITIAL_MEMORY_SIZE; - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Top address = 0x%lx\n", PrivateData->LoadModuleAtFixAddressTopAddress)); - // - // reinstall the PEI memory relative to TopLoadingAddress - // - PrivateData->PhysicalMemoryBegin = TopLoadingAddress - TotalReservedMemorySize; - PrivateData->FreePhysicalMemoryTop = PrivateData->PhysicalMemoryBegin + PeiMemorySize; -} - -/** - This routine is invoked in switch stack as PeiCore Entry. - - @param SecCoreData Points to a data structure containing information about the PEI core's operating - environment, such as the size and location of temporary RAM, the stack location and - the BFV location. - @param Private Pointer to old core data that is used to initialize the - core's data areas. -**/ -VOID -EFIAPI -PeiCoreEntry ( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN PEI_CORE_INSTANCE *Private - ) -{ - // - // Entry PEI Phase 2 - // - PeiCore (SecCoreData, NULL, Private); -} - -/** - Check SwitchStackSignal and switch stack if SwitchStackSignal is TRUE. - - @param[in] SecCoreData Points to a data structure containing information about the PEI core's operating - environment, such as the size and location of temporary RAM, the stack location and - the BFV location. - @param[in] Private Pointer to the private data passed in from caller. - -**/ -VOID -PeiCheckAndSwitchStack ( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN PEI_CORE_INSTANCE *Private - ) -{ - VOID *LoadFixPeiCodeBegin; - EFI_STATUS Status; - CONST EFI_PEI_SERVICES **PeiServices; - UINT64 NewStackSize; - EFI_PHYSICAL_ADDRESS TopOfOldStack; - EFI_PHYSICAL_ADDRESS TopOfNewStack; - UINTN StackOffset; - BOOLEAN StackOffsetPositive; - EFI_PHYSICAL_ADDRESS TemporaryRamBase; - UINTN TemporaryRamSize; - UINTN TemporaryStackSize; - VOID *TemporaryStackBase; - UINTN PeiTemporaryRamSize; - VOID *PeiTemporaryRamBase; - EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi; - EFI_PHYSICAL_ADDRESS BaseOfNewHeap; - EFI_PHYSICAL_ADDRESS HoleMemBase; - UINTN HoleMemSize; - UINTN HeapTemporaryRamSize; - EFI_PHYSICAL_ADDRESS TempBase1; - UINTN TempSize1; - EFI_PHYSICAL_ADDRESS TempBase2; - UINTN TempSize2; - UINTN Index; - - PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps; - - if (Private->SwitchStackSignal) { - // - // Before switch stack from temporary memory to permanent memory, calculate the heap and stack - // usage in temporary memory for debugging. - // - DEBUG_CODE_BEGIN (); - UINT32 *StackPointer; - - for (StackPointer = (UINT32*)SecCoreData->StackBase; - (StackPointer < (UINT32*)((UINTN)SecCoreData->StackBase + SecCoreData->StackSize)) \ - && (*StackPointer == INIT_CAR_VALUE); - StackPointer ++); - - DEBUG ((EFI_D_INFO, "Temp Stack : BaseAddress=0x%p Length=0x%X\n", SecCoreData->StackBase, (UINT32)SecCoreData->StackSize)); - DEBUG ((EFI_D_INFO, "Temp Heap : BaseAddress=0x%p Length=0x%X\n", Private->HobList.Raw, (UINT32)((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryTop - (UINTN) Private->HobList.Raw))); - DEBUG ((EFI_D_INFO, "Total temporary memory: %d bytes.\n", (UINT32)SecCoreData->TemporaryRamSize)); - DEBUG ((EFI_D_INFO, " temporary memory stack ever used: %d bytes.\n", - (UINT32)(SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN)SecCoreData->StackBase)) - )); - DEBUG ((EFI_D_INFO, " temporary memory heap used: %d bytes.\n", - (UINT32)((UINTN)Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN)Private->HobList.Raw) - )); - DEBUG_CODE_END (); - - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { - // - // Loading Module at Fixed Address is enabled - // - PeiLoadFixAddressHook (Private); - - // - // If Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range. - // - LoadFixPeiCodeBegin = AllocatePages((UINTN)PcdGet32(PcdLoadFixAddressPeiCodePageNumber)); - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PeiCodeBegin = 0x%lX, PeiCodeTop= 0x%lX\n", (UINT64)(UINTN)LoadFixPeiCodeBegin, (UINT64)((UINTN)LoadFixPeiCodeBegin + PcdGet32(PcdLoadFixAddressPeiCodePageNumber) * EFI_PAGE_SIZE))); - } - - // - // Reserve the size of new stack at bottom of physical memory - // - // The size of new stack in permanent memory must be the same size - // or larger than the size of old stack in temporary memory. - // But if new stack is smaller than the size of old stack, we also reserve - // the size of old stack at bottom of permanent memory. - // - NewStackSize = RShiftU64 (Private->PhysicalMemoryLength, 1); - NewStackSize = ALIGN_VALUE (NewStackSize, EFI_PAGE_SIZE); - NewStackSize = MIN (PcdGet32(PcdPeiCoreMaxPeiStackSize), NewStackSize); - DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (UINT32)SecCoreData->StackSize, (UINT32)NewStackSize)); - ASSERT (NewStackSize >= SecCoreData->StackSize); - - // - // Calculate stack offset and heap offset between temporary memory and new permement - // memory seperately. - // - TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize; - TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize; - if (TopOfNewStack >= TopOfOldStack) { - StackOffsetPositive = TRUE; - StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack); - } else { - StackOffsetPositive = FALSE; - StackOffset = (UINTN)(TopOfOldStack - TopOfNewStack); - } - Private->StackOffsetPositive = StackOffsetPositive; - Private->StackOffset = StackOffset; - - // - // Build Stack HOB that describes the permanent memory stack - // - DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n", TopOfNewStack - NewStackSize, NewStackSize)); - BuildStackHob (TopOfNewStack - NewStackSize, NewStackSize); - - // - // Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address - // - TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase; - TemporaryRamSize = SecCoreData->TemporaryRamSize; - TemporaryStackSize = SecCoreData->StackSize; - TemporaryStackBase = SecCoreData->StackBase; - PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize; - PeiTemporaryRamBase = SecCoreData->PeiTemporaryRamBase; - - // - // TemporaryRamSupportPpi is produced by platform's SEC - // - Status = PeiServicesLocatePpi ( - &gEfiTemporaryRamSupportPpiGuid, - 0, - NULL, - (VOID**)&TemporaryRamSupportPpi - ); - if (!EFI_ERROR (Status)) { - // - // Heap Offset - // - BaseOfNewHeap = TopOfNewStack; - if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) { - Private->HeapOffsetPositive = TRUE; - Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase); - } else { - Private->HeapOffsetPositive = FALSE; - Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap); - } - - DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64) Private->HeapOffset, (UINT64) Private->StackOffset)); - - // - // Calculate new HandOffTable and PrivateData address in permanent memory's stack - // - if (StackOffsetPositive) { - SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset); - Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset); - } else { - SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset); - Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset); - } - - // - // Temporary Ram Support PPI is provided by platform, it will copy - // temporary memory to permanent memory and do stack switching. - // After invoking Temporary Ram Support PPI, the following code's - // stack is in permanent memory. - // - TemporaryRamSupportPpi->TemporaryRamMigration ( - PeiServices, - TemporaryRamBase, - (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize), - TemporaryRamSize - ); - - // - // Entry PEI Phase 2 - // - PeiCore (SecCoreData, NULL, Private); - } else { - // - // Migrate the PEI Services Table pointer from temporary RAM to permanent RAM. - // - MigratePeiServicesTablePointer (); - - // - // Heap Offset - // - BaseOfNewHeap = TopOfNewStack; - HoleMemBase = TopOfNewStack; - HoleMemSize = TemporaryRamSize - PeiTemporaryRamSize - TemporaryStackSize; - if (HoleMemSize != 0) { - // - // Make sure HOB List start address is 8 byte alignment. - // - BaseOfNewHeap = ALIGN_VALUE (BaseOfNewHeap + HoleMemSize, 8); - } - if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) { - Private->HeapOffsetPositive = TRUE; - Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase); - } else { - Private->HeapOffsetPositive = FALSE; - Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap); - } - - DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64) Private->HeapOffset, (UINT64) Private->StackOffset)); - - // - // Migrate Heap - // - HeapTemporaryRamSize = (UINTN) (Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - Private->HobList.HandoffInformationTable->EfiMemoryBottom); - ASSERT (BaseOfNewHeap + HeapTemporaryRamSize <= Private->FreePhysicalMemoryTop); - CopyMem ((UINT8 *) (UINTN) BaseOfNewHeap, (UINT8 *) PeiTemporaryRamBase, HeapTemporaryRamSize); - - // - // Migrate Stack - // - CopyMem ((UINT8 *) (UINTN) (TopOfNewStack - TemporaryStackSize), TemporaryStackBase, TemporaryStackSize); - - // - // Copy Hole Range Data - // Convert PPI from Hole. - // - if (HoleMemSize != 0) { - // - // Prepare Hole - // - if (PeiTemporaryRamBase < TemporaryStackBase) { - TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase; - TempSize1 = PeiTemporaryRamSize; - TempBase2 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase; - TempSize2 = TemporaryStackSize; - } else { - TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase; - TempSize1 = TemporaryStackSize; - TempBase2 =(EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase; - TempSize2 = PeiTemporaryRamSize; - } - if (TemporaryRamBase < TempBase1) { - Private->HoleData[0].Base = TemporaryRamBase; - Private->HoleData[0].Size = (UINTN) (TempBase1 - TemporaryRamBase); - } - if (TempBase1 + TempSize1 < TempBase2) { - Private->HoleData[1].Base = TempBase1 + TempSize1; - Private->HoleData[1].Size = (UINTN) (TempBase2 - TempBase1 - TempSize1); - } - if (TempBase2 + TempSize2 < TemporaryRamBase + TemporaryRamSize) { - Private->HoleData[2].Base = TempBase2 + TempSize2; - Private->HoleData[2].Size = (UINTN) (TemporaryRamBase + TemporaryRamSize - TempBase2 - TempSize2); - } - - // - // Copy Hole Range data. - // - for (Index = 0; Index < HOLE_MAX_NUMBER; Index ++) { - if (Private->HoleData[Index].Size > 0) { - if (HoleMemBase > Private->HoleData[Index].Base) { - Private->HoleData[Index].OffsetPositive = TRUE; - Private->HoleData[Index].Offset = (UINTN) (HoleMemBase - Private->HoleData[Index].Base); - } else { - Private->HoleData[Index].OffsetPositive = FALSE; - Private->HoleData[Index].Offset = (UINTN) (Private->HoleData[Index].Base - HoleMemBase); - } - CopyMem ((VOID *) (UINTN) HoleMemBase, (VOID *) (UINTN) Private->HoleData[Index].Base, Private->HoleData[Index].Size); - HoleMemBase = HoleMemBase + Private->HoleData[Index].Size; - } - } - } - - // - // Switch new stack - // - SwitchStack ( - (SWITCH_STACK_ENTRY_POINT)(UINTN)PeiCoreEntry, - (VOID *) SecCoreData, - (VOID *) Private, - (VOID *) (UINTN) TopOfNewStack - ); - } - - // - // Code should not come here - // - ASSERT (FALSE); - } -} - -/** - Conduct PEIM dispatch. - - @param SecCoreData Points to a data structure containing information about the PEI core's operating - environment, such as the size and location of temporary RAM, the stack location and - the BFV location. - @param Private Pointer to the private data passed in from caller - -**/ -VOID -PeiDispatcher ( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN PEI_CORE_INSTANCE *Private - ) -{ - EFI_STATUS Status; - UINT32 Index1; - UINT32 Index2; - CONST EFI_PEI_SERVICES **PeiServices; - EFI_PEI_FILE_HANDLE PeimFileHandle; - UINTN FvCount; - UINTN PeimCount; - UINT32 AuthenticationState; - EFI_PHYSICAL_ADDRESS EntryPoint; - EFI_PEIM_ENTRY_POINT2 PeimEntryPoint; - UINTN SaveCurrentPeimCount; - UINTN SaveCurrentFvCount; - EFI_PEI_FILE_HANDLE SaveCurrentFileHandle; - EFI_FV_FILE_INFO FvFileInfo; - PEI_CORE_FV_HANDLE *CoreFvHandle; - - PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps; - PeimEntryPoint = NULL; - PeimFileHandle = NULL; - EntryPoint = 0; - - if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) { - // - // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile - // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE. - // - SaveCurrentPeimCount = Private->CurrentPeimCount; - SaveCurrentFvCount = Private->CurrentPeimFvCount; - SaveCurrentFileHandle = Private->CurrentFileHandle; - - for (Index1 = 0; Index1 <= SaveCurrentFvCount; Index1++) { - for (Index2 = 0; (Index2 < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) { - if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) { - PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2]; - Private->CurrentFileHandle = PeimFileHandle; - Private->CurrentPeimFvCount = Index1; - Private->CurrentPeimCount = Index2; - Status = PeiLoadImage ( - (CONST EFI_PEI_SERVICES **) &Private->Ps, - PeimFileHandle, - PEIM_STATE_REGISITER_FOR_SHADOW, - &EntryPoint, - &AuthenticationState - ); - if (Status == EFI_SUCCESS) { - // - // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE - // - Private->Fv[Index1].PeimState[Index2]++; - // - // Call the PEIM entry point - // - PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint; - - PERF_START (PeimFileHandle, "PEIM", NULL, 0); - PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->Ps); - PERF_END (PeimFileHandle, "PEIM", NULL, 0); - } - - // - // Process the Notify list and dispatch any notifies for - // newly installed PPIs. - // - ProcessNotifyList (Private); - } - } - } - Private->CurrentFileHandle = SaveCurrentFileHandle; - Private->CurrentPeimFvCount = SaveCurrentFvCount; - Private->CurrentPeimCount = SaveCurrentPeimCount; - } - - // - // This is the main dispatch loop. It will search known FVs for PEIMs and - // attempt to dispatch them. If any PEIM gets dispatched through a single - // pass of the dispatcher, it will start over from the Bfv again to see - // if any new PEIMs dependencies got satisfied. With a well ordered - // FV where PEIMs are found in the order their dependencies are also - // satisfied, this dipatcher should run only once. - // - do { - // - // In case that reenter PeiCore happens, the last pass record is still available. - // - if (!Private->PeimDispatcherReenter) { - Private->PeimNeedingDispatch = FALSE; - Private->PeimDispatchOnThisPass = FALSE; - } else { - Private->PeimDispatcherReenter = FALSE; - } - - for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) { - CoreFvHandle = FindNextCoreFvHandle (Private, FvCount); - ASSERT (CoreFvHandle != NULL); - - // - // If the FV has corresponding EFI_PEI_FIRMWARE_VOLUME_PPI instance, then dispatch it. - // - if (CoreFvHandle->FvPpi == NULL) { - continue; - } - - Private->CurrentPeimFvCount = FvCount; - - if (Private->CurrentPeimCount == 0) { - // - // When going through each FV, at first, search Apriori file to - // reorder all PEIMs to ensure the PEIMs in Apriori file to get - // dispatch at first. - // - DiscoverPeimsAndOrderWithApriori (Private, CoreFvHandle); - } - - // - // Start to dispatch all modules within the current Fv. - // - for (PeimCount = Private->CurrentPeimCount; - (PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->CurrentFvFileHandles[PeimCount] != NULL); - PeimCount++) { - Private->CurrentPeimCount = PeimCount; - PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount]; - - if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) { - if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) { - Private->PeimNeedingDispatch = TRUE; - } else { - Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeimFileHandle, &FvFileInfo); - ASSERT_EFI_ERROR (Status); - if (FvFileInfo.FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) { - // - // For Fv type file, Produce new FvInfo PPI and FV hob - // - Status = ProcessFvFile (Private, &Private->Fv[FvCount], PeimFileHandle); - if (Status == EFI_SUCCESS) { - // - // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED - // - Private->Fv[FvCount].PeimState[PeimCount]++; - Private->PeimDispatchOnThisPass = TRUE; - } else { - // - // The related GuidedSectionExtraction/Decompress PPI for the - // encapsulated FV image section may be installed in the rest - // of this do-while loop, so need to make another pass. - // - Private->PeimNeedingDispatch = TRUE; - } - } else { - // - // For PEIM driver, Load its entry point - // - Status = PeiLoadImage ( - PeiServices, - PeimFileHandle, - PEIM_STATE_NOT_DISPATCHED, - &EntryPoint, - &AuthenticationState - ); - if (Status == EFI_SUCCESS) { - // - // The PEIM has its dependencies satisfied, and its entry point - // has been found, so invoke it. - // - PERF_START (PeimFileHandle, "PEIM", NULL, 0); - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN), - (VOID *)(&PeimFileHandle), - sizeof (PeimFileHandle) - ); - - Status = VerifyPeim (Private, CoreFvHandle->FvHandle, PeimFileHandle, AuthenticationState); - if (Status != EFI_SECURITY_VIOLATION) { - // - // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED - // - Private->Fv[FvCount].PeimState[PeimCount]++; - // - // Call the PEIM entry point for PEIM driver - // - PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint; - PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices); - Private->PeimDispatchOnThisPass = TRUE; - } else { - // - // The related GuidedSectionExtraction PPI for the - // signed PEIM image section may be installed in the rest - // of this do-while loop, so need to make another pass. - // - Private->PeimNeedingDispatch = TRUE; - } - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END), - (VOID *)(&PeimFileHandle), - sizeof (PeimFileHandle) - ); - PERF_END (PeimFileHandle, "PEIM", NULL, 0); - - } - } - - PeiCheckAndSwitchStack (SecCoreData, Private); - - // - // Process the Notify list and dispatch any notifies for - // newly installed PPIs. - // - ProcessNotifyList (Private); - - // - // Recheck SwitchStackSignal after ProcessNotifyList() - // in case PeiInstallPeiMemory() is done in a callback with - // EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH. - // - PeiCheckAndSwitchStack (SecCoreData, Private); - - if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \ - (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) { - // - // If memory is available we shadow images by default for performance reasons. - // We call the entry point a 2nd time so the module knows it's shadowed. - // - //PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0); - if ((Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) && !PcdGetBool (PcdShadowPeimOnBoot)) { - // - // Load PEIM into Memory for Register for shadow PEIM. - // - Status = PeiLoadImage ( - PeiServices, - PeimFileHandle, - PEIM_STATE_REGISITER_FOR_SHADOW, - &EntryPoint, - &AuthenticationState - ); - if (Status == EFI_SUCCESS) { - PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint; - } - } - ASSERT (PeimEntryPoint != NULL); - PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices); - //PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0); - - // - // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE - // - Private->Fv[FvCount].PeimState[PeimCount]++; - - // - // Process the Notify list and dispatch any notifies for - // newly installed PPIs. - // - ProcessNotifyList (Private); - } - } - } - } - - // - // We set to NULL here to optimize the 2nd entry to this routine after - // memory is found. This reprevents rescanning of the FV. We set to - // NULL here so we start at the begining of the next FV - // - Private->CurrentFileHandle = NULL; - Private->CurrentPeimCount = 0; - // - // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL - // - SetMem (Private->CurrentFvFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv), 0); - } - - // - // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go - // through all the FV. - // - Private->CurrentPeimFvCount = 0; - - // - // PeimNeedingDispatch being TRUE means we found a PEIM/FV that did not get - // dispatched. So we need to make another pass - // - // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM/FV on this - // pass. If we did not dispatch a PEIM/FV there is no point in trying again - // as it will fail the next time too (nothing has changed). - // - } while (Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass); - -} - -/** - Initialize the Dispatcher's data members - - @param PrivateData PeiCore's private data structure - @param OldCoreData Old data from SecCore - NULL if being run in non-permament memory mode. - @param SecCoreData Points to a data structure containing information about the PEI core's operating - environment, such as the size and location of temporary RAM, the stack location and - the BFV location. - - @return None. - -**/ -VOID -InitializeDispatcherData ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_INSTANCE *OldCoreData, - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData - ) -{ - if (OldCoreData == NULL) { - PrivateData->PeimDispatcherReenter = FALSE; - PeiInitializeFv (PrivateData, SecCoreData); - } else { - PeiReinitializeFv (PrivateData); - } - - return; -} - -/** - This routine parses the Dependency Expression, if available, and - decides if the module can be executed. - - - @param Private PeiCore's private data structure - @param FileHandle PEIM's file handle - @param PeimCount Peim count in all dispatched PEIMs. - - @retval TRUE Can be dispatched - @retval FALSE Cannot be dispatched - -**/ -BOOLEAN -DepexSatisfied ( - IN PEI_CORE_INSTANCE *Private, - IN EFI_PEI_FILE_HANDLE FileHandle, - IN UINTN PeimCount - ) -{ - EFI_STATUS Status; - VOID *DepexData; - EFI_FV_FILE_INFO FileInfo; - - Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, "Evaluate PEI DEPEX for FFS(Unknown)\n")); - } else { - DEBUG ((DEBUG_DISPATCH, "Evaluate PEI DEPEX for FFS(%g)\n", &FileInfo.FileName)); - } - - if (PeimCount < Private->AprioriCount) { - // - // If its in the A priori file then we set Depex to TRUE - // - DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (Apriori)\n")); - return TRUE; - } - - // - // Depex section not in the encapsulated section. - // - Status = PeiServicesFfsFindSectionData ( - EFI_SECTION_PEI_DEPEX, - FileHandle, - (VOID **)&DepexData - ); - - if (EFI_ERROR (Status)) { - // - // If there is no DEPEX, assume the module can be executed - // - DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (No DEPEX)\n")); - return TRUE; - } - - // - // Evaluate a given DEPEX - // - return PeimDispatchReadiness (&Private->Ps, DepexData); -} - -/** - This routine enable a PEIM to register itself to shadow when PEI Foundation - discovery permanent memory. - - @param FileHandle File handle of a PEIM. - - @retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself. - @retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself. - @retval EFI_SUCCESS Successfully to register itself. - -**/ -EFI_STATUS -EFIAPI -PeiRegisterForShadow ( - IN EFI_PEI_FILE_HANDLE FileHandle - ) -{ - PEI_CORE_INSTANCE *Private; - Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ()); - - if (Private->CurrentFileHandle != FileHandle) { - // - // The FileHandle must be for the current PEIM - // - return EFI_NOT_FOUND; - } - - if (Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] >= PEIM_STATE_REGISITER_FOR_SHADOW) { - // - // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started - // - return EFI_ALREADY_STARTED; - } - - Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] = PEIM_STATE_REGISITER_FOR_SHADOW; - - return EFI_SUCCESS; -} - - - diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.c b/MdeModulePkg/Core/Pei/FwVol/FwVol.c deleted file mode 100644 index 0bbb86d958..0000000000 --- a/MdeModulePkg/Core/Pei/FwVol/FwVol.c +++ /dev/null @@ -1,2329 +0,0 @@ -/** @file - Pei Core Firmware File System service routines. - -Copyright (c) 2015 HP Development Company, L.P. -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "FwVol.h" - -EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList[] = { - { - EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, - &gEfiPeiFirmwareVolumeInfoPpiGuid, - FirmwareVolmeInfoPpiNotifyCallback - }, - { - (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiPeiFirmwareVolumeInfo2PpiGuid, - FirmwareVolmeInfoPpiNotifyCallback - } -}; - -PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = { - PEI_FW_VOL_SIGNATURE, - FALSE, - { - PeiFfsFvPpiProcessVolume, - PeiFfsFvPpiFindFileByType, - PeiFfsFvPpiFindFileByName, - PeiFfsFvPpiGetFileInfo, - PeiFfsFvPpiGetVolumeInfo, - PeiFfsFvPpiFindSectionByType, - PeiFfsFvPpiGetFileInfo2, - PeiFfsFvPpiFindSectionByType2, - EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE, - EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION - } -}; - -PEI_FW_VOL_INSTANCE mPeiFfs3FwVol = { - PEI_FW_VOL_SIGNATURE, - TRUE, - { - PeiFfsFvPpiProcessVolume, - PeiFfsFvPpiFindFileByType, - PeiFfsFvPpiFindFileByName, - PeiFfsFvPpiGetFileInfo, - PeiFfsFvPpiGetVolumeInfo, - PeiFfsFvPpiFindSectionByType, - PeiFfsFvPpiGetFileInfo2, - PeiFfsFvPpiFindSectionByType2, - EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE, - EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION - } -}; - -EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiFirmwareFileSystem2Guid, - &mPeiFfs2FwVol.Fv -}; - -EFI_PEI_PPI_DESCRIPTOR mPeiFfs3FvPpiList = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiFirmwareFileSystem3Guid, - &mPeiFfs3FwVol.Fv -}; - -/** -Required Alignment Alignment Value in FFS Alignment Value in -(bytes) Attributes Field Firmware Volume Interfaces -1 0 0 -16 1 4 -128 2 7 -512 3 9 -1 KB 4 10 -4 KB 5 12 -32 KB 6 15 -64 KB 7 16 -**/ -UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16}; - -/** - Convert the FFS File Attributes to FV File Attributes - - @param FfsAttributes The attributes of UINT8 type. - - @return The attributes of EFI_FV_FILE_ATTRIBUTES - -**/ -EFI_FV_FILE_ATTRIBUTES -FfsAttributes2FvFileAttributes ( - IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes - ) -{ - UINT8 DataAlignment; - EFI_FV_FILE_ATTRIBUTES FileAttribute; - - DataAlignment = (UINT8) ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3); - ASSERT (DataAlignment < 8); - - FileAttribute = (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[DataAlignment]; - - if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) { - FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED; - } - - return FileAttribute; -} - -/** - Returns the file state set by the highest zero bit in the State field - - @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY - in the Attributes field. - @param FfsHeader Pointer to FFS File Header. - - @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit - in the header State field. -**/ -EFI_FFS_FILE_STATE -GetFileState( - IN UINT8 ErasePolarity, - IN EFI_FFS_FILE_HEADER *FfsHeader - ) -{ - EFI_FFS_FILE_STATE FileState; - EFI_FFS_FILE_STATE HighestBit; - - FileState = FfsHeader->State; - - if (ErasePolarity != 0) { - FileState = (EFI_FFS_FILE_STATE)~FileState; - } - - // - // Get file state set by its highest none zero bit. - // - HighestBit = 0x80; - while (HighestBit != 0 && (HighestBit & FileState) == 0) { - HighestBit >>= 1; - } - - return HighestBit; -} - -/** - Calculates the checksum of the header of a file. - - @param FileHeader Pointer to FFS File Header. - - @return Checksum of the header. - Zero means the header is good. - Non-zero means the header is bad. -**/ -UINT8 -CalculateHeaderChecksum ( - IN EFI_FFS_FILE_HEADER *FileHeader - ) -{ - EFI_FFS_FILE_HEADER2 TestFileHeader; - - if (IS_FFS_FILE2 (FileHeader)) { - CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER2)); - // - // Ingore State and File field in FFS header. - // - TestFileHeader.State = 0; - TestFileHeader.IntegrityCheck.Checksum.File = 0; - - return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER2)); - } else { - CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER)); - // - // Ingore State and File field in FFS header. - // - TestFileHeader.State = 0; - TestFileHeader.IntegrityCheck.Checksum.File = 0; - - return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER)); - } -} - -/** - Find FV handler according to FileHandle in that FV. - - @param FileHandle Handle of file image - - @return Pointer to instance of PEI_CORE_FV_HANDLE. -**/ -PEI_CORE_FV_HANDLE* -FileHandleToVolume ( - IN EFI_PEI_FILE_HANDLE FileHandle - ) -{ - UINTN Index; - PEI_CORE_INSTANCE *PrivateData; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - UINTN BestIndex; - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ()); - BestIndex = PrivateData->FvCount; - - // - // Find the best matched FV image that includes this FileHandle. - // FV may include the child FV, and they are in the same continuous space. - // If FileHandle is from the child FV, the updated logic can find its matched FV. - // - for (Index = 0; Index < PrivateData->FvCount; Index++) { - FwVolHeader = PrivateData->Fv[Index].FvHeader; - if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \ - ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) { - if (BestIndex == PrivateData->FvCount) { - BestIndex = Index; - } else { - if ((UINT64) (UINTN) PrivateData->Fv[BestIndex].FvHeader < (UINT64) (UINTN) FwVolHeader) { - BestIndex = Index; - } - } - } - } - - if (BestIndex < PrivateData->FvCount) { - return &PrivateData->Fv[BestIndex]; - } - - return NULL; -} - -/** - Given the input file pointer, search for the first matching file in the - FFS volume as defined by SearchType. The search starts from FileHeader inside - the Firmware Volume defined by FwVolHeader. - If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type. - If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, - the first PEIM, or COMBINED PEIM or FV file type FFS file will return. - - @param FvHandle Pointer to the FV header of the volume to search - @param FileName File name - @param SearchType Filter to find only files of this type. - Type EFI_FV_FILETYPE_ALL causes no filtering to be done. - @param FileHandle This parameter must point to a valid FFS volume. - @param AprioriFile Pointer to AprioriFile image in this FV if has - - @return EFI_NOT_FOUND No files matching the search criteria were found - @retval EFI_SUCCESS Success to search given file - -**/ -EFI_STATUS -FindFileEx ( - IN CONST EFI_PEI_FV_HANDLE FvHandle, - IN CONST EFI_GUID *FileName, OPTIONAL - IN EFI_FV_FILETYPE SearchType, - IN OUT EFI_PEI_FILE_HANDLE *FileHandle, - IN OUT EFI_PEI_FILE_HANDLE *AprioriFile OPTIONAL - ) -{ - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExtHeader; - EFI_FFS_FILE_HEADER **FileHeader; - EFI_FFS_FILE_HEADER *FfsFileHeader; - UINT32 FileLength; - UINT32 FileOccupiedSize; - UINT32 FileOffset; - UINT64 FvLength; - UINT8 ErasePolarity; - UINT8 FileState; - UINT8 DataCheckSum; - BOOLEAN IsFfs3Fv; - - // - // Convert the handle of FV to FV header for memory-mapped firmware volume - // - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvHandle; - FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle; - - IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid); - - FvLength = FwVolHeader->FvLength; - if ((FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) { - ErasePolarity = 1; - } else { - ErasePolarity = 0; - } - - // - // If FileHeader is not specified (NULL) or FileName is not NULL, - // start with the first file in the firmware volume. Otherwise, - // start from the FileHeader. - // - if ((*FileHeader == NULL) || (FileName != NULL)) { - if (FwVolHeader->ExtHeaderOffset != 0) { - // - // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists. - // - FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->ExtHeaderOffset); - FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize); - FfsFileHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsFileHeader, 8); - } else { - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength); - } - } else { - if (IS_FFS_FILE2 (*FileHeader)) { - if (!IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader)->Name)); - } - FileLength = FFS_FILE2_SIZE (*FileHeader); - ASSERT (FileLength > 0x00FFFFFF); - } else { - FileLength = FFS_FILE_SIZE (*FileHeader); - } - // - // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned. - // - FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize); - } - - FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader); - ASSERT (FileOffset <= 0xFFFFFFFF); - - while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) { - // - // Get FileState which is the highest bit of the State - // - FileState = GetFileState (ErasePolarity, FfsFileHeader); - switch (FileState) { - - case EFI_FILE_HEADER_CONSTRUCTION: - case EFI_FILE_HEADER_INVALID: - if (IS_FFS_FILE2 (FfsFileHeader)) { - if (!IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name)); - } - FileOffset += sizeof (EFI_FFS_FILE_HEADER2); - FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2)); - } else { - FileOffset += sizeof (EFI_FFS_FILE_HEADER); - FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER)); - } - break; - - case EFI_FILE_DATA_VALID: - case EFI_FILE_MARKED_FOR_UPDATE: - if (CalculateHeaderChecksum (FfsFileHeader) != 0) { - ASSERT (FALSE); - *FileHeader = NULL; - return EFI_NOT_FOUND; - } - - if (IS_FFS_FILE2 (FfsFileHeader)) { - FileLength = FFS_FILE2_SIZE (FfsFileHeader); - ASSERT (FileLength > 0x00FFFFFF); - FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); - if (!IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name)); - FileOffset += FileOccupiedSize; - FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize); - break; - } - } else { - FileLength = FFS_FILE_SIZE (FfsFileHeader); - FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); - } - - DataCheckSum = FFS_FIXED_CHECKSUM; - if ((FfsFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) { - if (IS_FFS_FILE2 (FfsFileHeader)) { - DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FileLength - sizeof(EFI_FFS_FILE_HEADER2)); - } else { - DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER), FileLength - sizeof(EFI_FFS_FILE_HEADER)); - } - } - if (FfsFileHeader->IntegrityCheck.Checksum.File != DataCheckSum) { - ASSERT (FALSE); - *FileHeader = NULL; - return EFI_NOT_FOUND; - } - - if (FileName != NULL) { - if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) { - *FileHeader = FfsFileHeader; - return EFI_SUCCESS; - } - } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) { - if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || - (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) || - (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) { - - *FileHeader = FfsFileHeader; - return EFI_SUCCESS; - } else if (AprioriFile != NULL) { - if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) { - if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) { - *AprioriFile = FfsFileHeader; - } - } - } - } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) && - (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) { - *FileHeader = FfsFileHeader; - return EFI_SUCCESS; - } - - FileOffset += FileOccupiedSize; - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize); - break; - - case EFI_FILE_DELETED: - if (IS_FFS_FILE2 (FfsFileHeader)) { - if (!IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name)); - } - FileLength = FFS_FILE2_SIZE (FfsFileHeader); - ASSERT (FileLength > 0x00FFFFFF); - } else { - FileLength = FFS_FILE_SIZE (FfsFileHeader); - } - FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8); - FileOffset += FileOccupiedSize; - FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize); - break; - - default: - *FileHeader = NULL; - return EFI_NOT_FOUND; - } - } - - *FileHeader = NULL; - return EFI_NOT_FOUND; -} - -/** - Initialize PeiCore Fv List. - - @param PrivateData - Pointer to PEI_CORE_INSTANCE. - @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF. -**/ -VOID -PeiInitializeFv ( - IN PEI_CORE_INSTANCE *PrivateData, - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData - ) -{ - EFI_STATUS Status; - EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; - EFI_PEI_FV_HANDLE FvHandle; - EFI_FIRMWARE_VOLUME_HEADER *BfvHeader; - - // - // Install FV_PPI for FFS2 file system. - // - PeiServicesInstallPpi (&mPeiFfs2FvPpiList); - - // - // Install FV_PPI for FFS3 file system. - // - PeiServicesInstallPpi (&mPeiFfs3FvPpiList); - - BfvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase; - - // - // The FV_PPI in BFV's format should be installed. - // - Status = PeiServicesLocatePpi ( - &BfvHeader->FileSystemGuid, - 0, - NULL, - (VOID**)&FvPpi - ); - ASSERT_EFI_ERROR (Status); - - // - // Get handle of BFV - // - FvPpi->ProcessVolume ( - FvPpi, - SecCoreData->BootFirmwareVolumeBase, - (UINTN)BfvHeader->FvLength, - &FvHandle - ); - - // - // Update internal PEI_CORE_FV array. - // - PrivateData->Fv[PrivateData->FvCount].FvHeader = BfvHeader; - PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi; - PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle; - PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = 0; - DEBUG (( - EFI_D_INFO, - "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", - (UINT32) PrivateData->FvCount, - (VOID *) BfvHeader, - BfvHeader->FvLength, - FvHandle - )); - PrivateData->FvCount ++; - - // - // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose - // additional Fvs to PeiCore. - // - Status = PeiServicesNotifyPpi (mNotifyOnFvInfoList); - ASSERT_EFI_ERROR (Status); - -} - -/** - Process Firmware Volum Information once FvInfoPPI or FvInfo2PPI install. - The FV Info will be registered into PeiCore private data structure. - And search the inside FV image, if found, the new FV INFO(2) PPI will be installed. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param NotifyDescriptor Address of the notification descriptor data structure. - @param Ppi Address of the PPI that was installed. - - @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure. - @return if not EFI_SUCESS, fail to verify FV. - -**/ -EFI_STATUS -EFIAPI -FirmwareVolmeInfoPpiNotifyCallback ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ) -{ - EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI FvInfo2Ppi; - EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; - PEI_CORE_INSTANCE *PrivateData; - EFI_STATUS Status; - EFI_PEI_FV_HANDLE FvHandle; - UINTN FvIndex; - EFI_PEI_FILE_HANDLE FileHandle; - VOID *DepexData; - BOOLEAN IsFvInfo2; - UINTN CurFvCount; - - Status = EFI_SUCCESS; - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); - - if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiFirmwareVolumeInfo2PpiGuid)) { - // - // It is FvInfo2PPI. - // - CopyMem (&FvInfo2Ppi, Ppi, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI)); - IsFvInfo2 = TRUE; - } else { - // - // It is FvInfoPPI. - // - CopyMem (&FvInfo2Ppi, Ppi, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI)); - FvInfo2Ppi.AuthenticationStatus = 0; - IsFvInfo2 = FALSE; - } - - if (CompareGuid (&FvInfo2Ppi.FvFormat, &gEfiFirmwareFileSystem2Guid)) { - // - // gEfiFirmwareFileSystem2Guid is specified for FvFormat, then here to check the - // FileSystemGuid pointed by FvInfo against gEfiFirmwareFileSystem2Guid to make sure - // FvInfo has the firmware file system 2 format. - // - // If the ASSERT really appears, FvFormat needs to be specified correctly, for example, - // gEfiFirmwareFileSystem3Guid can be used for firmware file system 3 format, or - // ((EFI_FIRMWARE_VOLUME_HEADER *) FvInfo)->FileSystemGuid can be just used for both - // firmware file system 2 and 3 format. - // - ASSERT (CompareGuid (&(((EFI_FIRMWARE_VOLUME_HEADER *) FvInfo2Ppi.FvInfo)->FileSystemGuid), &gEfiFirmwareFileSystem2Guid)); - } - - // - // Locate the corresponding FV_PPI according to founded FV's format guid - // - Status = PeiServicesLocatePpi ( - &FvInfo2Ppi.FvFormat, - 0, - NULL, - (VOID**)&FvPpi - ); - if (!EFI_ERROR (Status)) { - // - // Process new found FV and get FV handle. - // - Status = FvPpi->ProcessVolume (FvPpi, FvInfo2Ppi.FvInfo, FvInfo2Ppi.FvInfoSize, &FvHandle); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Fail to process new found FV, FV may be corrupted!\n")); - return Status; - } - - // - // Check whether the FV has already been processed. - // - for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) { - if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) { - if (IsFvInfo2 && (FvInfo2Ppi.AuthenticationStatus != PrivateData->Fv[FvIndex].AuthenticationStatus)) { - PrivateData->Fv[FvIndex].AuthenticationStatus = FvInfo2Ppi.AuthenticationStatus; - DEBUG ((EFI_D_INFO, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex, FvInfo2Ppi.AuthenticationStatus)); - } - DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfo2Ppi.FvInfo)); - return EFI_SUCCESS; - } - } - - if (PrivateData->FvCount >= PcdGet32 (PcdPeiCoreMaxFvSupported)) { - DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, PcdGet32 (PcdPeiCoreMaxFvSupported))); - DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC")); - ASSERT (FALSE); - } - - // - // Update internal PEI_CORE_FV array. - // - PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfo2Ppi.FvInfo; - PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi; - PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle; - PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = FvInfo2Ppi.AuthenticationStatus; - CurFvCount = PrivateData->FvCount; - DEBUG (( - EFI_D_INFO, - "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", - (UINT32) CurFvCount, - (VOID *) FvInfo2Ppi.FvInfo, - FvInfo2Ppi.FvInfoSize, - FvHandle - )); - PrivateData->FvCount ++; - - // - // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE - // - FileHandle = NULL; - do { - Status = FvPpi->FindFileByType ( - FvPpi, - EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, - FvHandle, - &FileHandle - ); - if (!EFI_ERROR (Status)) { - Status = FvPpi->FindSectionByType ( - FvPpi, - EFI_SECTION_PEI_DEPEX, - FileHandle, - (VOID**)&DepexData - ); - if (!EFI_ERROR (Status)) { - if (!PeimDispatchReadiness (PeiServices, DepexData)) { - // - // Dependency is not satisfied. - // - continue; - } - } - - DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, CurFvCount, FvHandle)); - ProcessFvFile (PrivateData, &PrivateData->Fv[CurFvCount], FileHandle); - } - } while (FileHandle != NULL); - } else { - DEBUG ((EFI_D_ERROR, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi.FvInfo)); - - AddUnknownFormatFvInfo (PrivateData, &FvInfo2Ppi); - } - - return EFI_SUCCESS; -} - -/** - Verify the Guided Section GUID by checking if there is the Guided Section GUID HOB recorded the GUID itself. - - @param GuidedSectionGuid The Guided Section GUID. - @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Ppi - for the Guided Section. - - @return TRUE The GuidedSectionGuid could be identified, and the pointer to - the Guided Section Extraction Ppi will be returned to *GuidedSectionExtraction. - @return FALSE The GuidedSectionGuid could not be identified, or - the Guided Section Extraction Ppi has not been installed yet. - -**/ -BOOLEAN -VerifyGuidedSectionGuid ( - IN EFI_GUID *GuidedSectionGuid, - OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI **GuidedSectionExtraction - ) -{ - EFI_PEI_HOB_POINTERS Hob; - EFI_GUID *GuidRecorded; - VOID *Interface; - EFI_STATUS Status; - - // - // Check if there is the Guided Section GUID HOB recorded the GUID itself. - // - Hob.Raw = GetFirstGuidHob (GuidedSectionGuid); - if (Hob.Raw != NULL) { - GuidRecorded = (EFI_GUID *) GET_GUID_HOB_DATA (Hob); - if (CompareGuid (GuidRecorded, GuidedSectionGuid)) { - // - // Found the recorded GuidedSectionGuid. - // - Status = PeiServicesLocatePpi (GuidedSectionGuid, 0, NULL, (VOID **) &Interface); - if (!EFI_ERROR (Status) && Interface != NULL) { - // - // Found the supported Guided Section Extraction Ppi for the Guided Section. - // - *GuidedSectionExtraction = (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *) Interface; - return TRUE; - } - return FALSE; - } - } - - return FALSE; -} - -/** - Go through the file to search SectionType section. - Search within encapsulation sections (compression and GUIDed) recursively, - until the match section is found. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param SectionType Filter to find only section of this type. - @param SectionInstance Pointer to the filter to find the specific instance of section. - @param Section From where to search. - @param SectionSize The file size to search. - @param OutputBuffer A pointer to the discovered section, if successful. - NULL if section not found - @param AuthenticationStatus Updated upon return to point to the authentication status for this section. - @param IsFfs3Fv Indicates the FV format. - - @return EFI_NOT_FOUND The match section is not found. - @return EFI_SUCCESS The match section is found. - -**/ -EFI_STATUS -ProcessSection ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_SECTION_TYPE SectionType, - IN OUT UINTN *SectionInstance, - IN EFI_COMMON_SECTION_HEADER *Section, - IN UINTN SectionSize, - OUT VOID **OutputBuffer, - OUT UINT32 *AuthenticationStatus, - IN BOOLEAN IsFfs3Fv - ) -{ - EFI_STATUS Status; - UINT32 SectionLength; - UINT32 ParsedLength; - EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi; - EFI_PEI_DECOMPRESS_PPI *DecompressPpi; - VOID *PpiOutput; - UINTN PpiOutputSize; - UINTN Index; - UINT32 Authentication; - PEI_CORE_INSTANCE *PrivateData; - EFI_GUID *SectionDefinitionGuid; - BOOLEAN SectionCached; - VOID *TempOutputBuffer; - UINT32 TempAuthenticationStatus; - UINT16 GuidedSectionAttributes; - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); - *OutputBuffer = NULL; - ParsedLength = 0; - Index = 0; - Status = EFI_NOT_FOUND; - PpiOutput = NULL; - PpiOutputSize = 0; - while (ParsedLength < SectionSize) { - - if (IS_SECTION2 (Section)) { - ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF); - if (!IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n")); - SectionLength = SECTION2_SIZE (Section); - // - // SectionLength is adjusted it is 4 byte aligned. - // Go to the next section - // - SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); - ASSERT (SectionLength != 0); - ParsedLength += SectionLength; - Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength); - continue; - } - } - - if (Section->Type == SectionType) { - // - // The type matches, so check the instance count to see if it's the one we want. - // - (*SectionInstance)--; - if (*SectionInstance == 0) { - // - // Got it! - // - if (IS_SECTION2 (Section)) { - *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2)); - } else { - *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER)); - } - return EFI_SUCCESS; - } else { - if (IS_SECTION2 (Section)) { - SectionLength = SECTION2_SIZE (Section); - } else { - SectionLength = SECTION_SIZE (Section); - } - // - // SectionLength is adjusted it is 4 byte aligned. - // Go to the next section - // - SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); - ASSERT (SectionLength != 0); - ParsedLength += SectionLength; - Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength); - continue; - } - } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) { - // - // Check the encapsulated section is extracted into the cache data. - // - SectionCached = FALSE; - for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) { - if (Section == PrivateData->CacheSection.Section[Index]) { - SectionCached = TRUE; - PpiOutput = PrivateData->CacheSection.SectionData[Index]; - PpiOutputSize = PrivateData->CacheSection.SectionSize[Index]; - Authentication = PrivateData->CacheSection.AuthenticationStatus[Index]; - // - // Search section directly from the cache data. - // - TempAuthenticationStatus = 0; - Status = ProcessSection ( - PeiServices, - SectionType, - SectionInstance, - PpiOutput, - PpiOutputSize, - &TempOutputBuffer, - &TempAuthenticationStatus, - IsFfs3Fv - ); - if (!EFI_ERROR (Status)) { - *OutputBuffer = TempOutputBuffer; - *AuthenticationStatus = TempAuthenticationStatus | Authentication; - return EFI_SUCCESS; - } - } - } - - // - // If SectionCached is TRUE, the section data has been cached and scanned. - // - if (!SectionCached) { - Status = EFI_NOT_FOUND; - Authentication = 0; - if (Section->Type == EFI_SECTION_GUID_DEFINED) { - if (IS_SECTION2 (Section)) { - SectionDefinitionGuid = &((EFI_GUID_DEFINED_SECTION2 *)Section)->SectionDefinitionGuid; - GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION2 *)Section)->Attributes; - } else { - SectionDefinitionGuid = &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid; - GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION *)Section)->Attributes; - } - if (VerifyGuidedSectionGuid (SectionDefinitionGuid, &GuidSectionPpi)) { - Status = GuidSectionPpi->ExtractSection ( - GuidSectionPpi, - Section, - &PpiOutput, - &PpiOutputSize, - &Authentication - ); - } else if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) { - // - // Figure out the proper authentication status for GUIDED section without processing required - // - Status = EFI_SUCCESS; - if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) { - Authentication |= EFI_AUTH_STATUS_IMAGE_SIGNED | EFI_AUTH_STATUS_NOT_TESTED; - } - if (IS_SECTION2 (Section)) { - PpiOutputSize = SECTION2_SIZE (Section) - ((EFI_GUID_DEFINED_SECTION2 *) Section)->DataOffset; - PpiOutput = (UINT8 *) Section + ((EFI_GUID_DEFINED_SECTION2 *) Section)->DataOffset; - } else { - PpiOutputSize = SECTION_SIZE (Section) - ((EFI_GUID_DEFINED_SECTION *) Section)->DataOffset; - PpiOutput = (UINT8 *) Section + ((EFI_GUID_DEFINED_SECTION *) Section)->DataOffset; - } - } - } else if (Section->Type == EFI_SECTION_COMPRESSION) { - Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi); - if (!EFI_ERROR (Status)) { - Status = DecompressPpi->Decompress ( - DecompressPpi, - (CONST EFI_COMPRESSION_SECTION*) Section, - &PpiOutput, - &PpiOutputSize - ); - } - } - - if (!EFI_ERROR (Status)) { - if ((Authentication & EFI_AUTH_STATUS_NOT_TESTED) == 0) { - // - // Update cache section data. - // - if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) { - PrivateData->CacheSection.AllSectionCount ++; - } - PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex] = Section; - PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput; - PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize; - PrivateData->CacheSection.AuthenticationStatus [PrivateData->CacheSection.SectionIndex] = Authentication; - PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER; - } - - TempAuthenticationStatus = 0; - Status = ProcessSection ( - PeiServices, - SectionType, - SectionInstance, - PpiOutput, - PpiOutputSize, - &TempOutputBuffer, - &TempAuthenticationStatus, - IsFfs3Fv - ); - if (!EFI_ERROR (Status)) { - *OutputBuffer = TempOutputBuffer; - *AuthenticationStatus = TempAuthenticationStatus | Authentication; - return EFI_SUCCESS; - } - } - } - } - - if (IS_SECTION2 (Section)) { - SectionLength = SECTION2_SIZE (Section); - } else { - SectionLength = SECTION_SIZE (Section); - } - // - // SectionLength is adjusted it is 4 byte aligned. - // Go to the next section - // - SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); - ASSERT (SectionLength != 0); - ParsedLength += SectionLength; - Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength); - } - - return EFI_NOT_FOUND; -} - - -/** - Searches for the next matching section within the specified file. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param SectionType Filter to find only sections of this type. - @param FileHandle Pointer to the current file to search. - @param SectionData A pointer to the discovered section, if successful. - NULL if section not found - - @retval EFI_NOT_FOUND The section was not found. - @retval EFI_SUCCESS The section was found. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindSectionData ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_SECTION_TYPE SectionType, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData - ) -{ - PEI_CORE_FV_HANDLE *CoreFvHandle; - - CoreFvHandle = FileHandleToVolume (FileHandle); - if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) { - return EFI_NOT_FOUND; - } - - return CoreFvHandle->FvPpi->FindSectionByType (CoreFvHandle->FvPpi, SectionType, FileHandle, SectionData); -} - -/** - Searches for the next matching section within the specified file. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param SectionType The value of the section type to find. - @param SectionInstance Section instance to find. - @param FileHandle Handle of the firmware file to search. - @param SectionData A pointer to the discovered section, if successful. - @param AuthenticationStatus A pointer to the authentication status for this section. - - @retval EFI_SUCCESS The section was found. - @retval EFI_NOT_FOUND The section was not found. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindSectionData3 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_SECTION_TYPE SectionType, - IN UINTN SectionInstance, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData, - OUT UINT32 *AuthenticationStatus - ) -{ - PEI_CORE_FV_HANDLE *CoreFvHandle; - - CoreFvHandle = FileHandleToVolume (FileHandle); - if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) { - return EFI_NOT_FOUND; - } - - if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) && - (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) { - return CoreFvHandle->FvPpi->FindSectionByType2 (CoreFvHandle->FvPpi, SectionType, SectionInstance, FileHandle, SectionData, AuthenticationStatus); - } - // - // The old FvPpi doesn't support to find section by section instance - // and return authentication status, so return EFI_UNSUPPORTED. - // - return EFI_UNSUPPORTED; -} - -/** - Searches for the next matching file in the firmware volume. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param SearchType Filter to find only files of this type. - Type EFI_FV_FILETYPE_ALL causes no filtering to be done. - @param FvHandle Handle of firmware volume in which to search. - @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start - at the beginning of the firmware volume. On exit, points the file handle of the next file - in the volume or NULL if there are no more files. - - @retval EFI_NOT_FOUND The file was not found. - @retval EFI_NOT_FOUND The header checksum was not zero. - @retval EFI_SUCCESS The file was found. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindNextFile ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN UINT8 SearchType, - IN EFI_PEI_FV_HANDLE FvHandle, - IN OUT EFI_PEI_FILE_HANDLE *FileHandle - ) -{ - PEI_CORE_FV_HANDLE *CoreFvHandle; - - CoreFvHandle = FvHandleToCoreHandle (FvHandle); - - // - // To make backward compatiblity, if can not find corresponding the handle of FV - // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed - // to the address of first byte of FV. - // - if ((CoreFvHandle == NULL) && FeaturePcdGet (PcdFrameworkCompatibilitySupport)) { - return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL); - } - - if ((CoreFvHandle == NULL) || CoreFvHandle->FvPpi == NULL) { - return EFI_NOT_FOUND; - } - - return CoreFvHandle->FvPpi->FindFileByType (CoreFvHandle->FvPpi, SearchType, FvHandle, FileHandle); -} - - -/** - Search the firmware volumes by index - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware - Volume (BFV). - @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist. - - @retval EFI_INVALID_PARAMETER VolumeHandle is NULL - @retval EFI_NOT_FOUND The volume was not found. - @retval EFI_SUCCESS The volume was found. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindNextVolume ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN UINTN Instance, - IN OUT EFI_PEI_FV_HANDLE *VolumeHandle - ) -{ - PEI_CORE_INSTANCE *Private; - PEI_CORE_FV_HANDLE *CoreFvHandle; - - if (VolumeHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); - - CoreFvHandle = FindNextCoreFvHandle (Private, Instance); - if (CoreFvHandle == NULL) { - *VolumeHandle = NULL; - return EFI_NOT_FOUND; - } - - *VolumeHandle = CoreFvHandle->FvHandle; - - return EFI_SUCCESS; -} - - -/** - Find a file within a volume by its name. - - @param FileName A pointer to the name of the file to find within the firmware volume. - @param VolumeHandle The firmware volume to search - @param FileHandle Upon exit, points to the found file's handle - or NULL if it could not be found. - - @retval EFI_SUCCESS File was found. - @retval EFI_NOT_FOUND File was not found. - @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindFileByName ( - IN CONST EFI_GUID *FileName, - IN EFI_PEI_FV_HANDLE VolumeHandle, - OUT EFI_PEI_FILE_HANDLE *FileHandle - ) -{ - PEI_CORE_FV_HANDLE *CoreFvHandle; - - if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - CoreFvHandle = FvHandleToCoreHandle (VolumeHandle); - if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) { - return EFI_NOT_FOUND; - } - - return CoreFvHandle->FvPpi->FindFileByName (CoreFvHandle->FvPpi, FileName, &VolumeHandle, FileHandle); -} - -/** - Returns information about a specific file. - - @param FileHandle Handle of the file. - @param FileInfo Upon exit, points to the file's information. - - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file. - @retval EFI_SUCCESS File information returned. - -**/ -EFI_STATUS -EFIAPI -PeiFfsGetFileInfo ( - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO *FileInfo - ) -{ - PEI_CORE_FV_HANDLE *CoreFvHandle; - - if ((FileHandle == NULL) || (FileInfo == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Retrieve the FirmwareVolume which the file resides in. - // - CoreFvHandle = FileHandleToVolume (FileHandle); - if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) { - return EFI_INVALID_PARAMETER; - } - - return CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, FileHandle, FileInfo); -} - -/** - Returns information about a specific file. - - @param FileHandle Handle of the file. - @param FileInfo Upon exit, points to the file's information. - - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file. - @retval EFI_SUCCESS File information returned. - -**/ -EFI_STATUS -EFIAPI -PeiFfsGetFileInfo2 ( - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO2 *FileInfo - ) -{ - PEI_CORE_FV_HANDLE *CoreFvHandle; - - if ((FileHandle == NULL) || (FileInfo == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Retrieve the FirmwareVolume which the file resides in. - // - CoreFvHandle = FileHandleToVolume (FileHandle); - if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) && - (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) { - return CoreFvHandle->FvPpi->GetFileInfo2 (CoreFvHandle->FvPpi, FileHandle, FileInfo); - } - // - // The old FvPpi doesn't support to return file info with authentication status, - // so return EFI_UNSUPPORTED. - // - return EFI_UNSUPPORTED; -} - -/** - Returns information about the specified volume. - - This function returns information about a specific firmware - volume, including its name, type, attributes, starting address - and size. - - @param VolumeHandle Handle of the volume. - @param VolumeInfo Upon exit, points to the volume's information. - - @retval EFI_SUCCESS Volume information returned. - @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume. - @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL. - @retval EFI_SUCCESS Information successfully returned. - @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available. - -**/ -EFI_STATUS -EFIAPI -PeiFfsGetVolumeInfo ( - IN EFI_PEI_FV_HANDLE VolumeHandle, - OUT EFI_FV_INFO *VolumeInfo - ) -{ - PEI_CORE_FV_HANDLE *CoreHandle; - - if ((VolumeInfo == NULL) || (VolumeHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - CoreHandle = FvHandleToCoreHandle (VolumeHandle); - - if ((CoreHandle == NULL) || (CoreHandle->FvPpi == NULL)) { - return EFI_INVALID_PARAMETER; - } - - return CoreHandle->FvPpi->GetVolumeInfo (CoreHandle->FvPpi, VolumeHandle, VolumeInfo); -} - -/** - Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob. - - @param PrivateData PeiCore's private data structure - @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image. - @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image. - - @retval EFI_NOT_FOUND FV image can't be found. - @retval EFI_SUCCESS Successfully to process it. - @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image - @retval EFI_SECURITY_VIOLATION Image is illegal - @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section - -**/ -EFI_STATUS -ProcessFvFile ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_FV_HANDLE *ParentFvCoreHandle, - IN EFI_PEI_FILE_HANDLE ParentFvFileHandle - ) -{ - EFI_STATUS Status; - EFI_FV_INFO ParentFvImageInfo; - UINT32 FvAlignment; - VOID *NewFvBuffer; - EFI_PEI_HOB_POINTERS HobPtr; - EFI_PEI_FIRMWARE_VOLUME_PPI *ParentFvPpi; - EFI_PEI_FV_HANDLE ParentFvHandle; - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - EFI_FV_FILE_INFO FileInfo; - UINT64 FvLength; - UINT32 AuthenticationStatus; - - // - // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already - // been extracted. - // - HobPtr.Raw = GetHobList (); - while ((HobPtr.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobPtr.Raw)) != NULL) { - if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)ParentFvFileHandle)->Name), &HobPtr.FirmwareVolume2->FileName)) { - // - // this FILE has been dispatched, it will not be dispatched again. - // - DEBUG ((EFI_D_INFO, "FV file %p has been dispatched!\r\n", ParentFvFileHandle)); - return EFI_SUCCESS; - } - HobPtr.Raw = GET_NEXT_HOB (HobPtr); - } - - ParentFvHandle = ParentFvCoreHandle->FvHandle; - ParentFvPpi = ParentFvCoreHandle->FvPpi; - - // - // Find FvImage in FvFile - // - AuthenticationStatus = 0; - if ((ParentFvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) && - (ParentFvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) { - Status = ParentFvPpi->FindSectionByType2 ( - ParentFvPpi, - EFI_SECTION_FIRMWARE_VOLUME_IMAGE, - 0, - ParentFvFileHandle, - (VOID **)&FvHeader, - &AuthenticationStatus - ); - } else { - Status = ParentFvPpi->FindSectionByType ( - ParentFvPpi, - EFI_SECTION_FIRMWARE_VOLUME_IMAGE, - ParentFvFileHandle, - (VOID **)&FvHeader - ); - } - if (EFI_ERROR (Status)) { - return Status; - } - - Status = VerifyPeim (PrivateData, ParentFvHandle, ParentFvFileHandle, AuthenticationStatus); - if (Status == EFI_SECURITY_VIOLATION) { - return Status; - } - - // - // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume - // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from - // its initial linked location and maintain its alignment. - // - if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) { - // - // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value. - // - FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16); - if (FvAlignment < 8) { - FvAlignment = 8; - } - - // - // Check FvImage - // - if ((UINTN) FvHeader % FvAlignment != 0) { - FvLength = ReadUnaligned64 (&FvHeader->FvLength); - NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvLength), FvAlignment); - if (NewFvBuffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - CopyMem (NewFvBuffer, FvHeader, (UINTN) FvLength); - FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) NewFvBuffer; - } - } - - Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo); - ASSERT_EFI_ERROR (Status); - - Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo); - ASSERT_EFI_ERROR (Status); - - // - // Install FvInfo(2) Ppi - // NOTE: FvInfo2 must be installed before FvInfo so that recursive processing of encapsulated - // FVs inherit the proper AuthenticationStatus. - // - PeiServicesInstallFvInfo2Ppi( - &FvHeader->FileSystemGuid, - (VOID**)FvHeader, - (UINT32)FvHeader->FvLength, - &ParentFvImageInfo.FvName, - &FileInfo.FileName, - AuthenticationStatus - ); - - PeiServicesInstallFvInfoPpi ( - &FvHeader->FileSystemGuid, - (VOID**) FvHeader, - (UINT32) FvHeader->FvLength, - &ParentFvImageInfo.FvName, - &FileInfo.FileName - ); - - // - // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase - // - BuildFvHob ( - (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, - FvHeader->FvLength - ); - - // - // Makes the encapsulated volume show up in DXE phase to skip processing of - // encapsulated file again. - // - BuildFv2Hob ( - (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, - FvHeader->FvLength, - &ParentFvImageInfo.FvName, - &FileInfo.FileName - ); - - return EFI_SUCCESS; -} - -/** - Process a firmware volume and create a volume handle. - - Create a volume handle from the information in the buffer. For - memory-mapped firmware volumes, Buffer and BufferSize refer to - the start of the firmware volume and the firmware volume size. - For non memory-mapped firmware volumes, this points to a - buffer which contains the necessary information for creating - the firmware volume handle. Normally, these values are derived - from the EFI_FIRMWARE_VOLUME_INFO_PPI. - - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param Buffer Points to the start of the buffer. - @param BufferSize Size of the buffer. - @param FvHandle Points to the returned firmware volume - handle. The firmware volume handle must - be unique within the system. - - @retval EFI_SUCCESS Firmware volume handle created. - @retval EFI_VOLUME_CORRUPTED Volume was corrupt. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiProcessVolume ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN VOID *Buffer, - IN UINTN BufferSize, - OUT EFI_PEI_FV_HANDLE *FvHandle - ) -{ - EFI_STATUS Status; - - ASSERT (FvHandle != NULL); - - if (Buffer == NULL) { - return EFI_VOLUME_CORRUPTED; - } - - // - // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped - // FV image and the handle is pointed to Fv image's buffer. - // - *FvHandle = (EFI_PEI_FV_HANDLE) Buffer; - - // - // Do verify for given FV buffer. - // - Status = VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER*) Buffer); - if (EFI_ERROR(Status)) { - DEBUG ((EFI_D_ERROR, "Fail to verify FV which address is 0x%11p", Buffer)); - return EFI_VOLUME_CORRUPTED; - } - - return EFI_SUCCESS; -} - -/** - Finds the next file of the specified type. - - This service enables PEI modules to discover additional firmware files. - The FileHandle must be unique within the system. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param SearchType A filter to find only files of this type. Type - EFI_FV_FILETYPE_ALL causes no filtering to be - done. - @param FvHandle Handle of firmware volume in which to - search. - @param FileHandle Points to the current handle from which to - begin searching or NULL to start at the - beginning of the firmware volume. Updated - upon return to reflect the file found. - - @retval EFI_SUCCESS The file was found. - @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiFindFileByType ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_FV_FILETYPE SearchType, - IN EFI_PEI_FV_HANDLE FvHandle, - IN OUT EFI_PEI_FILE_HANDLE *FileHandle - ) -{ - return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL); -} - -/** - Find a file within a volume by its name. - - This service searches for files with a specific name, within - either the specified firmware volume or all firmware volumes. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param FileName A pointer to the name of the file to find - within the firmware volume. - @param FvHandle Upon entry, the pointer to the firmware - volume to search or NULL if all firmware - volumes should be searched. Upon exit, the - actual firmware volume in which the file was - found. - @param FileHandle Upon exit, points to the found file's - handle or NULL if it could not be found. - - @retval EFI_SUCCESS File was found. - @retval EFI_NOT_FOUND File was not found. - @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or - FileName was NULL. - - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiFindFileByName ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN CONST EFI_GUID *FileName, - IN EFI_PEI_FV_HANDLE *FvHandle, - OUT EFI_PEI_FILE_HANDLE *FileHandle - ) -{ - EFI_STATUS Status; - PEI_CORE_INSTANCE *PrivateData; - UINTN Index; - - if ((FvHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (*FvHandle != NULL) { - Status = FindFileEx (*FvHandle, FileName, 0, FileHandle, NULL); - if (Status == EFI_NOT_FOUND) { - *FileHandle = NULL; - } - } else { - // - // If *FvHandle = NULL, so search all FV for given filename - // - Status = EFI_NOT_FOUND; - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer()); - for (Index = 0; Index < PrivateData->FvCount; Index ++) { - // - // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance. - // - if (PrivateData->Fv[Index].FvPpi != NULL) { - Status = FindFileEx (PrivateData->Fv[Index].FvHandle, FileName, 0, FileHandle, NULL); - if (!EFI_ERROR (Status)) { - *FvHandle = PrivateData->Fv[Index].FvHandle; - break; - } - } - } - } - - return Status; -} - -/** - Returns information about a specific file. - - This function returns information about a specific - file, including its file name, type, attributes, starting - address and size. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param FileHandle Handle of the file. - @param FileInfo Upon exit, points to the file's - information. - - @retval EFI_SUCCESS File information returned. - @retval EFI_INVALID_PARAMETER If FileHandle does not - represent a valid file. - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiGetFileInfo ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO *FileInfo - ) -{ - UINT8 FileState; - UINT8 ErasePolarity; - EFI_FFS_FILE_HEADER *FileHeader; - PEI_CORE_FV_HANDLE *CoreFvHandle; - PEI_FW_VOL_INSTANCE *FwVolInstance; - - if ((FileHandle == NULL) || (FileInfo == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Retrieve the FirmwareVolume which the file resides in. - // - CoreFvHandle = FileHandleToVolume (FileHandle); - if (CoreFvHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This); - - if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) { - ErasePolarity = 1; - } else { - ErasePolarity = 0; - } - - // - // Get FileState which is the highest bit of the State - // - FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle); - - switch (FileState) { - case EFI_FILE_DATA_VALID: - case EFI_FILE_MARKED_FOR_UPDATE: - break; - default: - return EFI_INVALID_PARAMETER; - } - - FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle; - if (IS_FFS_FILE2 (FileHeader)) { - ASSERT (FFS_FILE2_SIZE (FileHeader) > 0x00FFFFFF); - if (!FwVolInstance->IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader->Name)); - return EFI_INVALID_PARAMETER; - } - FileInfo->BufferSize = FFS_FILE2_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER2); - FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER2); - } else { - FileInfo->BufferSize = FFS_FILE_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER); - FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER); - } - CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID)); - FileInfo->FileType = FileHeader->Type; - FileInfo->FileAttributes = FfsAttributes2FvFileAttributes (FileHeader->Attributes); - if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) { - FileInfo->FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED; - } - return EFI_SUCCESS; -} - -/** - Returns information about a specific file. - - This function returns information about a specific - file, including its file name, type, attributes, starting - address, size and authentication status. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param FileHandle Handle of the file. - @param FileInfo Upon exit, points to the file's - information. - - @retval EFI_SUCCESS File information returned. - @retval EFI_INVALID_PARAMETER If FileHandle does not - represent a valid file. - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiGetFileInfo2 ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO2 *FileInfo - ) -{ - EFI_STATUS Status; - PEI_CORE_FV_HANDLE *CoreFvHandle; - - if ((FileHandle == NULL) || (FileInfo == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Retrieve the FirmwareVolume which the file resides in. - // - CoreFvHandle = FileHandleToVolume (FileHandle); - if (CoreFvHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - Status = PeiFfsFvPpiGetFileInfo (This, FileHandle, (EFI_FV_FILE_INFO *) FileInfo); - if (!EFI_ERROR (Status)) { - FileInfo->AuthenticationStatus = CoreFvHandle->AuthenticationStatus; - } - - return Status; -} - -/** - This function returns information about the firmware volume. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param FvHandle Handle to the firmware handle. - @param VolumeInfo Points to the returned firmware volume - information. - - @retval EFI_SUCCESS Information returned successfully. - @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid - firmware volume or VolumeInfo is NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiGetVolumeInfo ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_PEI_FV_HANDLE FvHandle, - OUT EFI_FV_INFO *VolumeInfo - ) -{ - EFI_FIRMWARE_VOLUME_HEADER FwVolHeader; - EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo; - - if ((VolumeInfo == NULL) || (FvHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // VolumeHandle may not align at 8 byte, - // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte. - // So, Copy FvHeader into the local FvHeader structure. - // - CopyMem (&FwVolHeader, FvHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER)); - - // - // Check Fv Image Signature - // - if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - ZeroMem (VolumeInfo, sizeof (EFI_FV_INFO)); - VolumeInfo->FvAttributes = FwVolHeader.Attributes; - VolumeInfo->FvStart = (VOID *) FvHandle; - VolumeInfo->FvSize = FwVolHeader.FvLength; - CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID)); - - if (FwVolHeader.ExtHeaderOffset != 0) { - FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FvHandle) + FwVolHeader.ExtHeaderOffset); - CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID)); - } - - return EFI_SUCCESS; -} - -/** - Find the next matching section in the firmware file. - - This service enables PEI modules to discover sections - of a given type within a valid file. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param SearchType A filter to find only sections of this - type. - @param FileHandle Handle of firmware file in which to - search. - @param SectionData Updated upon return to point to the - section found. - - @retval EFI_SUCCESS Section was found. - @retval EFI_NOT_FOUND Section of the specified type was not - found. SectionData contains NULL. -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiFindSectionByType ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_SECTION_TYPE SearchType, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData - ) -{ - UINT32 AuthenticationStatus; - return PeiFfsFvPpiFindSectionByType2 (This, SearchType, 0, FileHandle, SectionData, &AuthenticationStatus); -} - -/** - Find the next matching section in the firmware file. - - This service enables PEI modules to discover sections - of a given instance and type within a valid file. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param SearchType A filter to find only sections of this - type. - @param SearchInstance A filter to find the specific instance - of sections. - @param FileHandle Handle of firmware file in which to - search. - @param SectionData Updated upon return to point to the - section found. - @param AuthenticationStatus Updated upon return to point to the - authentication status for this section. - - @retval EFI_SUCCESS Section was found. - @retval EFI_NOT_FOUND Section of the specified type was not - found. SectionData contains NULL. -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiFindSectionByType2 ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_SECTION_TYPE SearchType, - IN UINTN SearchInstance, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData, - OUT UINT32 *AuthenticationStatus - ) -{ - EFI_STATUS Status; - EFI_FFS_FILE_HEADER *FfsFileHeader; - UINT32 FileSize; - EFI_COMMON_SECTION_HEADER *Section; - PEI_FW_VOL_INSTANCE *FwVolInstance; - PEI_CORE_FV_HANDLE *CoreFvHandle; - UINTN Instance; - UINT32 ExtractedAuthenticationStatus; - - if (SectionData == NULL) { - return EFI_NOT_FOUND; - } - - FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This); - - // - // Retrieve the FirmwareVolume which the file resides in. - // - CoreFvHandle = FileHandleToVolume (FileHandle); - if (CoreFvHandle == NULL) { - return EFI_NOT_FOUND; - } - - FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle); - - if (IS_FFS_FILE2 (FfsFileHeader)) { - ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF); - if (!FwVolInstance->IsFfs3Fv) { - DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name)); - return EFI_NOT_FOUND; - } - Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2)); - FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2); - } else { - Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER)); - FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER); - } - - Instance = SearchInstance + 1; - ExtractedAuthenticationStatus = 0; - Status = ProcessSection ( - GetPeiServicesTablePointer (), - SearchType, - &Instance, - Section, - FileSize, - SectionData, - &ExtractedAuthenticationStatus, - FwVolInstance->IsFfs3Fv - ); - if (!EFI_ERROR (Status)) { - // - // Inherit the authentication status. - // - *AuthenticationStatus = ExtractedAuthenticationStatus | CoreFvHandle->AuthenticationStatus; - } - return Status; -} - -/** - Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE. - - @param FvHandle The handle of a FV. - - @retval NULL if can not find. - @return Pointer of corresponding PEI_CORE_FV_HANDLE. -**/ -PEI_CORE_FV_HANDLE * -FvHandleToCoreHandle ( - IN EFI_PEI_FV_HANDLE FvHandle - ) -{ - UINTN Index; - PEI_CORE_INSTANCE *PrivateData; - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer()); - for (Index = 0; Index < PrivateData->FvCount; Index ++) { - if (FvHandle == PrivateData->Fv[Index].FvHandle) { - return &PrivateData->Fv[Index]; - } - } - - return NULL; -} - -/** - Get instance of PEI_CORE_FV_HANDLE for next volume according to given index. - - This routine also will install FvInfo ppi for FV hob in PI ways. - - @param Private Pointer of PEI_CORE_INSTANCE - @param Instance The index of FV want to be searched. - - @return Instance of PEI_CORE_FV_HANDLE. -**/ -PEI_CORE_FV_HANDLE * -FindNextCoreFvHandle ( - IN PEI_CORE_INSTANCE *Private, - IN UINTN Instance - ) -{ - UINTN Index; - BOOLEAN Match; - EFI_HOB_FIRMWARE_VOLUME *FvHob; - - // - // Handle Framework FvHob and Install FvInfo Ppi for it. - // - if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) { - // - // Loop to search the wanted FirmwareVolume which supports FFS - // - FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetFirstHob (EFI_HOB_TYPE_FV); - while (FvHob != NULL) { - // - // Search whether FvHob has been installed into PeiCore's FV database. - // If found, no need install new FvInfoPpi for it. - // - for (Index = 0, Match = FALSE; Index < Private->FvCount; Index++) { - if ((EFI_PEI_FV_HANDLE)(UINTN)FvHob->BaseAddress == Private->Fv[Index].FvHeader) { - Match = TRUE; - break; - } - } - - // - // Search whether FvHob has been cached into PeiCore's Unknown FV database. - // If found, no need install new FvInfoPpi for it. - // - if (!Match) { - for (Index = 0; Index < Private->UnknownFvInfoCount; Index ++) { - if ((UINTN)FvHob->BaseAddress == (UINTN)Private->UnknownFvInfo[Index].FvInfo) { - Match = TRUE; - break; - } - } - } - - // - // If the Fv in FvHob has not been installed into PeiCore's FV database and has - // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi - // for it then PeiCore will dispatch it in callback of FvInfoPpi. - // - if (!Match) { - PeiServicesInstallFvInfoPpi ( - &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress)->FileSystemGuid), - (VOID *)(UINTN)FvHob->BaseAddress, - (UINT32)FvHob->Length, - NULL, - NULL - ); - } - - FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetNextHob (EFI_HOB_TYPE_FV, (VOID *)((UINTN)FvHob + FvHob->Header.HobLength)); - } - } - - ASSERT (Private->FvCount <= PcdGet32 (PcdPeiCoreMaxFvSupported)); - if (Instance >= Private->FvCount) { - return NULL; - } - - return &Private->Fv[Instance]; -} - -/** - After PeiCore image is shadowed into permanent memory, all build-in FvPpi should - be re-installed with the instance in permanent memory and all cached FvPpi pointers in - PrivateData->Fv[] array should be fixed up to be pointed to the one in permanent - memory. - - @param PrivateData Pointer to PEI_CORE_INSTANCE. -**/ -VOID -PeiReinitializeFv ( - IN PEI_CORE_INSTANCE *PrivateData - ) -{ - VOID *OldFfsFvPpi; - EFI_PEI_PPI_DESCRIPTOR *OldDescriptor; - UINTN Index; - EFI_STATUS Status; - - // - // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which - // in flash. - // - Status = PeiServicesLocatePpi ( - &gEfiFirmwareFileSystem2Guid, - 0, - &OldDescriptor, - &OldFfsFvPpi - ); - ASSERT_EFI_ERROR (Status); - - // - // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2 - // which is shadowed from flash to permanent memory within PeiCore image. - // - Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs2FvPpiList); - ASSERT_EFI_ERROR (Status); - - // - // Fixup all FvPpi pointers for the implementation in flash to permanent memory. - // - for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) { - if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) { - PrivateData->Fv[Index].FvPpi = &mPeiFfs2FwVol.Fv; - } - } - - // - // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which - // in flash. - // - Status = PeiServicesLocatePpi ( - &gEfiFirmwareFileSystem3Guid, - 0, - &OldDescriptor, - &OldFfsFvPpi - ); - ASSERT_EFI_ERROR (Status); - - // - // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3 - // which is shadowed from flash to permanent memory within PeiCore image. - // - Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs3FvPpiList); - ASSERT_EFI_ERROR (Status); - - // - // Fixup all FvPpi pointers for the implementation in flash to permanent memory. - // - for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) { - if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) { - PrivateData->Fv[Index].FvPpi = &mPeiFfs3FwVol.Fv; - } - } -} - -/** - Report the information for a new discoveried FV in unknown third-party format. - - If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but - the FV in this format has been discoveried, then this FV's information will be cached into - PEI_CORE_INSTANCE's UnknownFvInfo array. - Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI - is installed later by platform's PEIM, the original unknown third-party FV will be processed by - using new installed EFI_PEI_FIRMWARE_VOLUME_PPI. - - @param PrivateData Point to instance of PEI_CORE_INSTANCE - @param FvInfo2Ppi Point to FvInfo2 PPI. - - @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces. - @retval EFI_SUCCESS Success to add the information for unknown FV. -**/ -EFI_STATUS -AddUnknownFormatFvInfo ( - IN PEI_CORE_INSTANCE *PrivateData, - IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI *FvInfo2Ppi - ) -{ - PEI_CORE_UNKNOW_FORMAT_FV_INFO *NewUnknownFv; - - if (PrivateData->UnknownFvInfoCount + 1 >= PcdGet32 (PcdPeiCoreMaxFvSupported)) { - return EFI_OUT_OF_RESOURCES; - } - - NewUnknownFv = &PrivateData->UnknownFvInfo[PrivateData->UnknownFvInfoCount]; - PrivateData->UnknownFvInfoCount ++; - - CopyGuid (&NewUnknownFv->FvFormat, &FvInfo2Ppi->FvFormat); - NewUnknownFv->FvInfo = FvInfo2Ppi->FvInfo; - NewUnknownFv->FvInfoSize = FvInfo2Ppi->FvInfoSize; - NewUnknownFv->AuthenticationStatus = FvInfo2Ppi->AuthenticationStatus; - NewUnknownFv->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST); - NewUnknownFv->NotifyDescriptor.Guid = &NewUnknownFv->FvFormat; - NewUnknownFv->NotifyDescriptor.Notify = ThirdPartyFvPpiNotifyCallback; - - PeiServicesNotifyPpi (&NewUnknownFv->NotifyDescriptor); - return EFI_SUCCESS; -} - -/** - Find the FV information according to third-party FV format guid. - - This routine also will remove the FV information found by given FV format guid from - PrivateData->UnknownFvInfo[]. - - @param PrivateData Point to instance of PEI_CORE_INSTANCE - @param Format Point to given FV format guid - @param FvInfo On return, the pointer of FV information buffer - @param FvInfoSize On return, the size of FV information buffer. - @param AuthenticationStatus On return, the authentication status of FV information buffer. - - @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI - @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI. -**/ -EFI_STATUS -FindUnknownFormatFvInfo ( - IN PEI_CORE_INSTANCE *PrivateData, - IN EFI_GUID *Format, - OUT VOID **FvInfo, - OUT UINT32 *FvInfoSize, - OUT UINT32 *AuthenticationStatus - ) -{ - UINTN Index; - UINTN Index2; - - Index = 0; - for (; Index < PrivateData->UnknownFvInfoCount; Index ++) { - if (CompareGuid (Format, &PrivateData->UnknownFvInfo[Index].FvFormat)) { - break; - } - } - - if (Index == PrivateData->UnknownFvInfoCount) { - return EFI_NOT_FOUND; - } - - *FvInfo = PrivateData->UnknownFvInfo[Index].FvInfo; - *FvInfoSize = PrivateData->UnknownFvInfo[Index].FvInfoSize; - *AuthenticationStatus = PrivateData->UnknownFvInfo[Index].AuthenticationStatus; - - // - // Remove an entry from UnknownFvInfo array. - // - Index2 = Index + 1; - for (;Index2 < PrivateData->UnknownFvInfoCount; Index2 ++, Index ++) { - CopyMem (&PrivateData->UnknownFvInfo[Index], &PrivateData->UnknownFvInfo[Index2], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO)); - } - PrivateData->UnknownFvInfoCount --; - return EFI_SUCCESS; -} - -/** - Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI. - - When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this - routine is called to process all discoveried FVs in this format. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param NotifyDescriptor Address of the notification descriptor data structure. - @param Ppi Address of the PPI that was installed. - - @retval EFI_SUCCESS The notification callback is processed correctly. -**/ -EFI_STATUS -EFIAPI -ThirdPartyFvPpiNotifyCallback ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ) -{ - PEI_CORE_INSTANCE *PrivateData; - EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; - VOID *FvInfo; - UINT32 FvInfoSize; - UINT32 AuthenticationStatus; - EFI_STATUS Status; - EFI_PEI_FV_HANDLE FvHandle; - BOOLEAN IsProcessed; - UINTN FvIndex; - EFI_PEI_FILE_HANDLE FileHandle; - VOID *DepexData; - UINTN CurFvCount; - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); - FvPpi = (EFI_PEI_FIRMWARE_VOLUME_PPI*) Ppi; - - do { - Status = FindUnknownFormatFvInfo (PrivateData, NotifyDescriptor->Guid, &FvInfo, &FvInfoSize, &AuthenticationStatus); - if (EFI_ERROR (Status)) { - return EFI_SUCCESS; - } - - // - // Process new found FV and get FV handle. - // - Status = FvPpi->ProcessVolume (FvPpi, FvInfo, FvInfoSize, &FvHandle); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo)); - continue; - } - - // - // Check whether the FV has already been processed. - // - IsProcessed = FALSE; - for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) { - if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) { - DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfo)); - IsProcessed = TRUE; - break; - } - } - - if (IsProcessed) { - continue; - } - - if (PrivateData->FvCount >= PcdGet32 (PcdPeiCoreMaxFvSupported)) { - DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, PcdGet32 (PcdPeiCoreMaxFvSupported))); - DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC")); - ASSERT (FALSE); - } - - // - // Update internal PEI_CORE_FV array. - // - PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfo; - PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi; - PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle; - PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = AuthenticationStatus; - CurFvCount = PrivateData->FvCount; - DEBUG (( - EFI_D_INFO, - "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", - (UINT32) CurFvCount, - (VOID *) FvInfo, - FvInfoSize, - FvHandle - )); - PrivateData->FvCount ++; - - // - // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE - // - FileHandle = NULL; - do { - Status = FvPpi->FindFileByType ( - FvPpi, - EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, - FvHandle, - &FileHandle - ); - if (!EFI_ERROR (Status)) { - Status = FvPpi->FindSectionByType ( - FvPpi, - EFI_SECTION_PEI_DEPEX, - FileHandle, - (VOID**)&DepexData - ); - if (!EFI_ERROR (Status)) { - if (!PeimDispatchReadiness (PeiServices, DepexData)) { - // - // Dependency is not satisfied. - // - continue; - } - } - - DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, CurFvCount, FvHandle)); - ProcessFvFile (PrivateData, &PrivateData->Fv[CurFvCount], FileHandle); - } - } while (FileHandle != NULL); - } while (TRUE); -} diff --git a/MdeModulePkg/Core/Pei/FwVol/FwVol.h b/MdeModulePkg/Core/Pei/FwVol/FwVol.h deleted file mode 100644 index 1daeb6d97b..0000000000 --- a/MdeModulePkg/Core/Pei/FwVol/FwVol.h +++ /dev/null @@ -1,377 +0,0 @@ -/** @file - The internal header file for firmware volume related definitions. - -Copyright (c) 2009 - 2011, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _FWVOL_H_ -#define _FWVOL_H_ - -#include "PeiMain.h" - -#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \ - ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))) - - -#define PEI_FW_VOL_SIGNATURE SIGNATURE_32('P','F','W','V') - -typedef struct { - UINTN Signature; - BOOLEAN IsFfs3Fv; - EFI_PEI_FIRMWARE_VOLUME_PPI Fv; -} PEI_FW_VOL_INSTANCE; - -#define PEI_FW_VOL_INSTANCE_FROM_FV_THIS(a) \ - CR(a, PEI_FW_VOL_INSTANCE, Fv, PEI_FW_VOL_SIGNATURE) - - -/** - Process a firmware volume and create a volume handle. - - Create a volume handle from the information in the buffer. For - memory-mapped firmware volumes, Buffer and BufferSize refer to - the start of the firmware volume and the firmware volume size. - For non memory-mapped firmware volumes, this points to a - buffer which contains the necessary information for creating - the firmware volume handle. Normally, these values are derived - from the EFI_FIRMWARE_VOLUME_INFO_PPI. - - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param Buffer Points to the start of the buffer. - @param BufferSize Size of the buffer. - @param FvHandle Points to the returned firmware volume - handle. The firmware volume handle must - be unique within the system. - - @retval EFI_SUCCESS Firmware volume handle created. - @retval EFI_VOLUME_CORRUPTED Volume was corrupt. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiProcessVolume ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN VOID *Buffer, - IN UINTN BufferSize, - OUT EFI_PEI_FV_HANDLE *FvHandle - ); - -/** - Finds the next file of the specified type. - - This service enables PEI modules to discover additional firmware files. - The FileHandle must be unique within the system. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param SearchType A filter to find only files of this type. Type - EFI_FV_FILETYPE_ALL causes no filtering to be - done. - @param FvHandle Handle of firmware volume in which to - search. - @param FileHandle Points to the current handle from which to - begin searching or NULL to start at the - beginning of the firmware volume. Updated - upon return to reflect the file found. - - @retval EFI_SUCCESS The file was found. - @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiFindFileByType ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_FV_FILETYPE SearchType, - IN EFI_PEI_FV_HANDLE FvHandle, - IN OUT EFI_PEI_FILE_HANDLE *FileHandle - ); - -/** - Find a file within a volume by its name. - - This service searches for files with a specific name, within - either the specified firmware volume or all firmware volumes. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param FileName A pointer to the name of the file to find - within the firmware volume. - @param FvHandle Upon entry, the pointer to the firmware - volume to search or NULL if all firmware - volumes should be searched. Upon exit, the - actual firmware volume in which the file was - found. - @param FileHandle Upon exit, points to the found file's - handle or NULL if it could not be found. - - @retval EFI_SUCCESS File was found. - @retval EFI_NOT_FOUND File was not found. - @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or - FileName was NULL. - - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiFindFileByName ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN CONST EFI_GUID *FileName, - IN EFI_PEI_FV_HANDLE *FvHandle, - OUT EFI_PEI_FILE_HANDLE *FileHandle - ); - -/** - Find the next matching section in the firmware file. - - This service enables PEI modules to discover sections - of a given type within a valid file. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param SearchType A filter to find only sections of this - type. - @param FileHandle Handle of firmware file in which to - search. - @param SectionData Updated upon return to point to the - section found. - - @retval EFI_SUCCESS Section was found. - @retval EFI_NOT_FOUND Section of the specified type was not - found. SectionData contains NULL. -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiFindSectionByType ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_SECTION_TYPE SearchType, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData - ); - -/** - Find the next matching section in the firmware file. - - This service enables PEI modules to discover sections - of a given instance and type within a valid file. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param SearchType A filter to find only sections of this - type. - @param SearchInstance A filter to find the specific instance - of sections. - @param FileHandle Handle of firmware file in which to - search. - @param SectionData Updated upon return to point to the - section found. - @param AuthenticationStatus Updated upon return to point to the - authentication status for this section. - - @retval EFI_SUCCESS Section was found. - @retval EFI_NOT_FOUND Section of the specified type was not - found. SectionData contains NULL. -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiFindSectionByType2 ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_SECTION_TYPE SearchType, - IN UINTN SearchInstance, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData, - OUT UINT32 *AuthenticationStatus - ); - -/** - Returns information about a specific file. - - This function returns information about a specific - file, including its file name, type, attributes, starting - address and size. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param FileHandle Handle of the file. - @param FileInfo Upon exit, points to the file's - information. - - @retval EFI_SUCCESS File information returned. - @retval EFI_INVALID_PARAMETER If FileHandle does not - represent a valid file. - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiGetFileInfo ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO *FileInfo - ); - -/** - Returns information about a specific file. - - This function returns information about a specific - file, including its file name, type, attributes, starting - address, size and authentication status. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param FileHandle Handle of the file. - @param FileInfo Upon exit, points to the file's - information. - - @retval EFI_SUCCESS File information returned. - @retval EFI_INVALID_PARAMETER If FileHandle does not - represent a valid file. - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiGetFileInfo2 ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO2 *FileInfo - ); - -/** - This function returns information about the firmware volume. - - @param This Points to this instance of the - EFI_PEI_FIRMWARE_VOLUME_PPI. - @param FvHandle Handle to the firmware handle. - @param VolumeInfo Points to the returned firmware volume - information. - - @retval EFI_SUCCESS Information returned successfully. - @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid - firmware volume or VolumeInfo is NULL. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFvPpiGetVolumeInfo ( - IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, - IN EFI_PEI_FV_HANDLE FvHandle, - OUT EFI_FV_INFO *VolumeInfo - ); - -/** - Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE. - - @param FvHandle The handle of a FV. - - @retval NULL if can not find. - @return Pointer of corresponding PEI_CORE_FV_HANDLE. -**/ -PEI_CORE_FV_HANDLE * -FvHandleToCoreHandle ( - IN EFI_PEI_FV_HANDLE FvHandle - ); - -/** - Given the input file pointer, search for the next matching file in the - FFS volume as defined by SearchType. The search starts from FileHeader inside - the Firmware Volume defined by FwVolHeader. - - - @param FvHandle Pointer to the FV header of the volume to search - @param FileName File name - @param SearchType Filter to find only files of this type. - Type EFI_FV_FILETYPE_ALL causes no filtering to be done. - @param FileHandle This parameter must point to a valid FFS volume. - @param AprioriFile Pointer to AprioriFile image in this FV if has - - @return EFI_NOT_FOUND No files matching the search criteria were found - @retval EFI_SUCCESS Success to search given file - -**/ -EFI_STATUS -FindFileEx ( - IN CONST EFI_PEI_FV_HANDLE FvHandle, - IN CONST EFI_GUID *FileName, OPTIONAL - IN EFI_FV_FILETYPE SearchType, - IN OUT EFI_PEI_FILE_HANDLE *FileHandle, - IN OUT EFI_PEI_FV_HANDLE *AprioriFile OPTIONAL - ); - -/** - Report the information for a new discoveried FV in unknown format. - - If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for specifical FV format, but - the FV in this FV format has been discoveried, then the information of this FV - will be cached into PEI_CORE_INSTANCE's UnknownFvInfo array. - Also a notification would be installed for unknown FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI - is installed later by platform's PEIM, the original unknown FV will be processed by - using new installed EFI_PEI_FIRMWARE_VOLUME_PPI. - - @param PrivateData Point to instance of PEI_CORE_INSTANCE - @param FvInfo2Ppi Point to FvInfo2 PPI. - - @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces. - @retval EFI_SUCCESS Success to add the information for unknown FV. -**/ -EFI_STATUS -AddUnknownFormatFvInfo ( - IN PEI_CORE_INSTANCE *PrivateData, - IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI *FvInfo2Ppi - ); - -/** - Find the FV information according to FV format guid. - - This routine also will remove the FV information found by given FV format guid from - PrivateData->UnknownFvInfo[]. - - @param PrivateData Point to instance of PEI_CORE_INSTANCE - @param Format Point to given FV format guid - @param FvInfo On return, the pointer of FV information buffer in given FV format guid - @param FvInfoSize On return, the size of FV information buffer. - @param AuthenticationStatus On return, the authentication status of FV information buffer. - - @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI - @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI. -**/ -EFI_STATUS -FindUnknownFormatFvInfo ( - IN PEI_CORE_INSTANCE *PrivateData, - IN EFI_GUID *Format, - OUT VOID **FvInfo, - OUT UINT32 *FvInfoSize, - OUT UINT32 *AuthenticationStatus - ); - -/** - Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI. - - When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this - routine is called to process all discoveried FVs in this format. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param NotifyDescriptor Address of the notification descriptor data structure. - @param Ppi Address of the PPI that was installed. - - @retval EFI_SUCCESS The notification callback is processed correctly. -**/ -EFI_STATUS -EFIAPI -ThirdPartyFvPpiNotifyCallback ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ); - -#endif diff --git a/MdeModulePkg/Core/Pei/Hob/Hob.c b/MdeModulePkg/Core/Pei/Hob/Hob.c deleted file mode 100644 index e0ee8e7f10..0000000000 --- a/MdeModulePkg/Core/Pei/Hob/Hob.c +++ /dev/null @@ -1,168 +0,0 @@ -/** @file - This module provide Hand-Off Block manupulation. - -Copyright (c) 2006 - 2012, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/** - - Gets the pointer to the HOB List. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param HobList Pointer to the HOB List. - - @retval EFI_SUCCESS Get the pointer of HOB List - @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published - @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode) - -**/ -EFI_STATUS -EFIAPI -PeiGetHobList ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN OUT VOID **HobList - ) -{ - PEI_CORE_INSTANCE *PrivateData; - - // - // Only check this parameter in debug mode - // - - DEBUG_CODE_BEGIN (); - if (HobList == NULL) { - return EFI_INVALID_PARAMETER; - } - DEBUG_CODE_END (); - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - - *HobList = PrivateData->HobList.Raw; - - return EFI_SUCCESS; -} - - -/** - Add a new HOB to the HOB List. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param Type Type of the new HOB. - @param Length Length of the new HOB to allocate. - @param Hob Pointer to the new HOB. - - @return EFI_SUCCESS Success to create hob. - @retval EFI_INVALID_PARAMETER if Hob is NULL - @retval EFI_NOT_AVAILABLE_YET if HobList is still not available. - @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist. - -**/ -EFI_STATUS -EFIAPI -PeiCreateHob ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN UINT16 Type, - IN UINT16 Length, - IN OUT VOID **Hob - ) -{ - EFI_STATUS Status; - EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; - EFI_HOB_GENERIC_HEADER *HobEnd; - EFI_PHYSICAL_ADDRESS FreeMemory; - - - Status = PeiGetHobList (PeiServices, Hob); - if (EFI_ERROR(Status)) { - return Status; - } - - HandOffHob = *Hob; - - // - // Check Length to avoid data overflow. - // - if (0x10000 - Length <= 0x7) { - return EFI_INVALID_PARAMETER; - } - Length = (UINT16)((Length + 0x7) & (~0x7)); - - FreeMemory = HandOffHob->EfiFreeMemoryTop - - HandOffHob->EfiFreeMemoryBottom; - - if (FreeMemory < Length) { - DEBUG ((EFI_D_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length)); - DEBUG ((EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop)); - DEBUG ((EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom)); - return EFI_OUT_OF_RESOURCES; - } - - *Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList; - ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType = Type; - ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length; - ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved = 0; - - HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length); - HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd; - - HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; - HobEnd->HobLength = (UINT16) sizeof (EFI_HOB_GENERIC_HEADER); - HobEnd->Reserved = 0; - HobEnd++; - HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd; - - return EFI_SUCCESS; -} - -/** - - Builds a Handoff Information Table HOB - - @param BootMode - Current Bootmode - @param MemoryBegin - Start Memory Address. - @param MemoryLength - Length of Memory. - - @return EFI_SUCCESS Always success to initialize HOB. - -**/ -EFI_STATUS -PeiCoreBuildHobHandoffInfoTable ( - IN EFI_BOOT_MODE BootMode, - IN EFI_PHYSICAL_ADDRESS MemoryBegin, - IN UINT64 MemoryLength - ) -{ - EFI_HOB_HANDOFF_INFO_TABLE *Hob; - EFI_HOB_GENERIC_HEADER *HobEnd; - - Hob = (VOID *)(UINTN)MemoryBegin; - HobEnd = (EFI_HOB_GENERIC_HEADER*) (Hob+1); - Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF; - Hob->Header.HobLength = (UINT16) sizeof (EFI_HOB_HANDOFF_INFO_TABLE); - Hob->Header.Reserved = 0; - - HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; - HobEnd->HobLength = (UINT16) sizeof (EFI_HOB_GENERIC_HEADER); - HobEnd->Reserved = 0; - - Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION; - Hob->BootMode = BootMode; - - Hob->EfiMemoryTop = MemoryBegin + MemoryLength; - Hob->EfiMemoryBottom = MemoryBegin; - Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength; - Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd + 1); - Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd; - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c deleted file mode 100644 index 1985411285..0000000000 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ /dev/null @@ -1,932 +0,0 @@ -/** @file - Pei Core Load Image Support - -Copyright (c) 2006 - 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - - -EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = { - PeiLoadImageLoadImageWrapper -}; - - -EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiPeiLoadFilePpiGuid, - &mPeiLoadImagePpi -}; - -/** - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file. - The function is used for XIP code to have optimized memory copy. - - @param FileHandle - The handle to the PE/COFF file - @param FileOffset - The offset, in bytes, into the file to read - @param ReadSize - The number of bytes to read from the file starting at FileOffset - @param Buffer - A pointer to the buffer to read the data into. - - @return EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - -**/ -EFI_STATUS -EFIAPI -PeiImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - CHAR8 *Destination8; - CHAR8 *Source8; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - if (Destination8 != Source8) { - CopyMem (Destination8, Source8, *ReadSize); - } - - return EFI_SUCCESS; -} - -/** - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file. - The function is implemented as PIC so as to support shadowing. - - @param FileHandle - The handle to the PE/COFF file - @param FileOffset - The offset, in bytes, into the file to read - @param ReadSize - The number of bytes to read from the file starting at FileOffset - @param Buffer - A pointer to the buffer to read the data into. - - @return EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - -**/ -EFI_STATUS -EFIAPI -PeiImageReadForShadow ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN UINTN *ReadSize, - OUT VOID *Buffer - ) -{ - volatile CHAR8 *Destination8; - CHAR8 *Source8; - UINTN Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - if (Destination8 != Source8) { - Length = *ReadSize; - while ((Length--) > 0) { - *(Destination8++) = *(Source8++); - } - } - - return EFI_SUCCESS; -} - -/** - - Support routine to get the Image read file function. - - @param ImageContext - The context of the image being loaded - - @retval EFI_SUCCESS - If Image function location is found - -**/ -EFI_STATUS -GetImageReadFunction ( - IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ -#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) - PEI_CORE_INSTANCE *Private; - EFI_PHYSICAL_ADDRESS MemoryBuffer; - - Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ()); - MemoryBuffer = 0; - - if (Private->PeiMemoryInstalled && (((Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) && PcdGetBool (PcdShadowPeimOnBoot)) || - ((Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME) && PcdGetBool (PcdShadowPeimOnS3Boot)))) { - // - // Shadow algorithm makes lots of non ANSI C assumptions and only works for IA32 and X64 - // compilers that have been tested - // - if (Private->ShadowedImageRead == NULL) { - PeiServicesAllocatePages (EfiBootServicesCode, 0x400 / EFI_PAGE_SIZE + 1, &MemoryBuffer); - ASSERT (MemoryBuffer != 0); - CopyMem ((VOID *)(UINTN)MemoryBuffer, (CONST VOID *) (UINTN) PeiImageReadForShadow, 0x400); - Private->ShadowedImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer; - } - - ImageContext->ImageRead = Private->ShadowedImageRead; - } else { - ImageContext->ImageRead = PeiImageRead; - } -#else - ImageContext->ImageRead = PeiImageRead; -#endif - return EFI_SUCCESS; -} -/** - To check memory usage bit map array to figure out if the memory range the image will be loaded in is available or not. If - memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used. - The function is only invoked when load modules at fixed address feature is enabled. - - @param Private Pointer to the private data passed in from caller - @param ImageBase The base address the image will be loaded at. - @param ImageSize The size of the image - - @retval EFI_SUCCESS The memory range the image will be loaded in is available - @retval EFI_NOT_FOUND The memory range the image will be loaded in is not available -**/ -EFI_STATUS -CheckAndMarkFixLoadingMemoryUsageBitMap ( - IN PEI_CORE_INSTANCE *Private, - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINT32 ImageSize - ) -{ - UINT32 DxeCodePageNumber; - UINT64 ReservedCodeSize; - EFI_PHYSICAL_ADDRESS PeiCodeBase; - UINT32 BaseOffsetPageNumber; - UINT32 TopOffsetPageNumber; - UINT32 Index; - UINT64 *MemoryUsageBitMap; - - - // - // The reserved code range includes RuntimeCodePage range, Boot time code range and PEI code range. - // - DxeCodePageNumber = PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber); - DxeCodePageNumber += PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber); - ReservedCodeSize = EFI_PAGES_TO_SIZE(DxeCodePageNumber + PcdGet32(PcdLoadFixAddressPeiCodePageNumber)); - PeiCodeBase = Private->LoadModuleAtFixAddressTopAddress - ReservedCodeSize; - - // - // Test the memory range for loading the image in the PEI code range. - // - if ((Private->LoadModuleAtFixAddressTopAddress - EFI_PAGES_TO_SIZE(DxeCodePageNumber)) < (ImageBase + ImageSize) || - (PeiCodeBase > ImageBase)) { - return EFI_NOT_FOUND; - } - - // - // Test if the memory is avalaible or not. - // - MemoryUsageBitMap = Private->PeiCodeMemoryRangeUsageBitMap; - BaseOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase - PeiCodeBase)); - TopOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - PeiCodeBase)); - for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) { - if ((MemoryUsageBitMap[Index / 64] & LShiftU64(1, (Index % 64))) != 0) { - // - // This page is already used. - // - return EFI_NOT_FOUND; - } - } - - // - // Being here means the memory range is available. So mark the bits for the memory range - // - for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) { - MemoryUsageBitMap[Index / 64] |= LShiftU64(1, (Index % 64)); - } - return EFI_SUCCESS; -} -/** - - Get the fixed loading address from image header assigned by build tool. This function only be called - when Loading module at Fixed address feature enabled. - - @param ImageContext Pointer to the image context structure that describes the PE/COFF - image that needs to be examined by this function. - @param Private Pointer to the private data passed in from caller - - @retval EFI_SUCCESS An fixed loading address is assigned to this image by build tools . - @retval EFI_NOT_FOUND The image has no assigned fixed loading address. - -**/ -EFI_STATUS -GetPeCoffImageFixLoadingAssignedAddress( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN PEI_CORE_INSTANCE *Private - ) -{ - UINTN SectionHeaderOffset; - EFI_STATUS Status; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_PHYSICAL_ADDRESS FixLoadingAddress; - UINT16 Index; - UINTN Size; - UINT16 NumberOfSections; - UINT64 ValueInSectionHeader; - - - FixLoadingAddress = 0; - Status = EFI_NOT_FOUND; - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset); - if (ImageContext->IsTeImage) { - // - // for TE image, the fix loading address is saved in first section header that doesn't point - // to code section. - // - SectionHeaderOffset = sizeof (EFI_TE_IMAGE_HEADER); - NumberOfSections = ImgHdr->Te.NumberOfSections; - } else { - SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; - NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; - } - // - // Get base address from the first section header that doesn't point to code section. - // - for (Index = 0; Index < NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EFI_NOT_FOUND; - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - // - // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header - // that doesn't point to code section in image header, as well as ImageBase field of image header. A notable thing is - // that for PEIM, the value in ImageBase field may not be equal to the value in PointerToRelocations & PointerToLineNumbers because - // for XIP PEIM, ImageBase field holds the image base address running on the Flash. And PointerToRelocations & PointerToLineNumbers - // hold the image base address when it is shadow to the memory. And there is an assumption that when the feature is enabled, if a - // module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers fields should NOT be Zero, or - // else, these 2 fields should be set to Zero - // - ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations); - if (ValueInSectionHeader != 0) { - // - // Found first section header that doesn't point to code section. - // - if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0) { - // - // When LMFA feature is configured as Load Module at Fixed Absolute Address mode, PointerToRelocations & PointerToLineNumbers field - // hold the absolute address of image base running in memory - // - FixLoadingAddress = ValueInSectionHeader; - } else { - // - // When LMFA feature is configured as Load Module at Fixed offset mode, PointerToRelocations & PointerToLineNumbers field - // hold the offset relative to a platform-specific top address. - // - FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(Private->LoadModuleAtFixAddressTopAddress + (INT64)ValueInSectionHeader); - } - // - // Check if the memory range is available. - // - Status = CheckAndMarkFixLoadingMemoryUsageBitMap (Private, FixLoadingAddress, (UINT32) ImageContext->ImageSize); - if (!EFI_ERROR(Status)) { - // - // The assigned address is valid. Return the specified loading address - // - ImageContext->ImageAddress = FixLoadingAddress; - } - } - break; - } - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address 0x%11p. Status= %r \n", (VOID *)(UINTN)FixLoadingAddress, Status)); - return Status; -} -/** - - Loads and relocates a PE/COFF image into memory. - If the image is not relocatable, it will not be loaded into memory and be loaded as XIP image. - - @param FileHandle - Pointer to the FFS file header of the image. - @param Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated - @param ImageAddress - The base address of the relocated PE/COFF image - @param ImageSize - The size of the relocated PE/COFF image - @param EntryPoint - The entry point of the relocated PE/COFF image - - @retval EFI_SUCCESS The file was loaded and relocated - @retval EFI_OUT_OF_RESOURCES There was not enough memory to load and relocate the PE/COFF file - @retval EFI_WARN_BUFFER_TOO_SMALL - There is not enough heap to allocate the requested size. - This will not prevent the XIP image from being invoked. - -**/ -EFI_STATUS -LoadAndRelocatePeCoffImage ( - IN EFI_PEI_FILE_HANDLE FileHandle, - IN VOID *Pe32Data, - OUT EFI_PHYSICAL_ADDRESS *ImageAddress, - OUT UINT64 *ImageSize, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint - ) -{ - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - PEI_CORE_INSTANCE *Private; - UINT64 AlignImageSize; - BOOLEAN IsXipImage; - EFI_STATUS ReturnStatus; - BOOLEAN IsS3Boot; - BOOLEAN IsPeiModule; - BOOLEAN IsRegisterForShadow; - EFI_FV_FILE_INFO FileInfo; - - Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ()); - - ReturnStatus = EFI_SUCCESS; - IsXipImage = FALSE; - ZeroMem (&ImageContext, sizeof (ImageContext)); - ImageContext.Handle = Pe32Data; - Status = GetImageReadFunction (&ImageContext); - - ASSERT_EFI_ERROR (Status); - - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Initilize local IsS3Boot and IsRegisterForShadow variable - // - IsS3Boot = FALSE; - if (Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME) { - IsS3Boot = TRUE; - } - IsRegisterForShadow = FALSE; - if ((Private->CurrentFileHandle == FileHandle) - && (Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW)) { - IsRegisterForShadow = TRUE; - } - - // - // XIP image that ImageAddress is same to Image handle. - // - if (ImageContext.ImageAddress == (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) { - IsXipImage = TRUE; - } - - // - // Get file type first - // - Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo); - ASSERT_EFI_ERROR (Status); - - // - // Check whether the file type is PEI module. - // - IsPeiModule = FALSE; - if (FileInfo.FileType == EFI_FV_FILETYPE_PEI_CORE || - FileInfo.FileType == EFI_FV_FILETYPE_PEIM || - FileInfo.FileType == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) { - IsPeiModule = TRUE; - } - - // - // When Image has no reloc section, it can't be relocated into memory. - // - if (ImageContext.RelocationsStripped && (Private->PeiMemoryInstalled) && ((!IsPeiModule) || - (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) || (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))) { - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "The image at 0x%08x without reloc section can't be loaded into memory\n", (UINTN) Pe32Data)); - } - - // - // Set default base address to current image address. - // - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data; - - // - // Allocate Memory for the image when memory is ready, and image is relocatable. - // On normal boot, PcdShadowPeimOnBoot decides whether load PEIM or PeiCore into memory. - // On S3 boot, PcdShadowPeimOnS3Boot decides whether load PEIM or PeiCore into memory. - // - if ((!ImageContext.RelocationsStripped) && (Private->PeiMemoryInstalled) && ((!IsPeiModule) || - (!IsS3Boot && (PcdGetBool (PcdShadowPeimOnBoot) || IsRegisterForShadow)) || (IsS3Boot && PcdGetBool (PcdShadowPeimOnS3Boot)))) { - // - // Allocate more buffer to avoid buffer overflow. - // - if (ImageContext.IsTeImage) { - AlignImageSize = ImageContext.ImageSize + ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER); - } else { - AlignImageSize = ImageContext.ImageSize; - } - - if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { - AlignImageSize += ImageContext.SectionAlignment; - } - - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { - Status = GetPeCoffImageFixLoadingAssignedAddress(&ImageContext, Private); - if (EFI_ERROR (Status)){ - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); - // - // The PEIM is not assiged valid address, try to allocate page to load it. - // - Status = PeiServicesAllocatePages (EfiBootServicesCode, - EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize), - &ImageContext.ImageAddress); - } - } else { - Status = PeiServicesAllocatePages (EfiBootServicesCode, - EFI_SIZE_TO_PAGES ((UINT32) AlignImageSize), - &ImageContext.ImageAddress); - } - if (!EFI_ERROR (Status)) { - // - // Adjust the Image Address to make sure it is section alignment. - // - if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) { - ImageContext.ImageAddress = - (ImageContext.ImageAddress + ImageContext.SectionAlignment - 1) & - ~((UINTN)ImageContext.SectionAlignment - 1); - } - // - // Fix alignment requirement when Load IPF TeImage into memory. - // Skip the reserved space for the stripped PeHeader when load TeImage into memory. - // - if (ImageContext.IsTeImage) { - ImageContext.ImageAddress = ImageContext.ImageAddress + - ((EFI_TE_IMAGE_HEADER *) Pe32Data)->StrippedSize - - sizeof (EFI_TE_IMAGE_HEADER); - } - } else { - // - // No enough memory resource. - // - if (IsXipImage) { - // - // XIP image can still be invoked. - // - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data; - ReturnStatus = EFI_WARN_BUFFER_TOO_SMALL; - } else { - // - // Non XIP image can't be loaded because no enough memory is allocated. - // - ASSERT (FALSE); - return EFI_OUT_OF_RESOURCES; - } - } - } - - // - // Load the image to our new buffer - // - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Flush the instruction cache so the image data is written before we execute it - // - if (ImageContext.ImageAddress != (EFI_PHYSICAL_ADDRESS)(UINTN) Pe32Data) { - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); - } - - *ImageAddress = ImageContext.ImageAddress; - *ImageSize = ImageContext.ImageSize; - *EntryPoint = ImageContext.EntryPoint; - - return ReturnStatus; -} - -/** - Loads a PEIM into memory for subsequent execution. If there are compressed - images or images that need to be relocated into memory for performance reasons, - this service performs that transformation. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param FileHandle Pointer to the FFS file header of the image. - @param ImageAddressArg Pointer to PE/TE image. - @param ImageSizeArg Size of PE/TE image. - @param EntryPoint Pointer to entry point of specified image file for output. - @param AuthenticationState - Pointer to attestation authentication state of image. - - @retval EFI_SUCCESS Image is successfully loaded. - @retval EFI_NOT_FOUND Fail to locate necessary PPI. - @retval EFI_UNSUPPORTED Image Machine Type is not supported. - @retval EFI_WARN_BUFFER_TOO_SMALL - There is not enough heap to allocate the requested size. - This will not prevent the XIP image from being invoked. - -**/ -EFI_STATUS -PeiLoadImageLoadImage ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL - OUT UINT64 *ImageSizeArg, OPTIONAL - OUT EFI_PHYSICAL_ADDRESS *EntryPoint, - OUT UINT32 *AuthenticationState - ) -{ - EFI_STATUS Status; - VOID *Pe32Data; - EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; - EFI_PHYSICAL_ADDRESS ImageEntryPoint; - UINT16 Machine; - EFI_SECTION_TYPE SearchType1; - EFI_SECTION_TYPE SearchType2; - - *EntryPoint = 0; - ImageSize = 0; - *AuthenticationState = 0; - - if (FeaturePcdGet (PcdPeiCoreImageLoaderSearchTeSectionFirst)) { - SearchType1 = EFI_SECTION_TE; - SearchType2 = EFI_SECTION_PE32; - } else { - SearchType1 = EFI_SECTION_PE32; - SearchType2 = EFI_SECTION_TE; - } - - // - // Try to find a first exe section (if PcdPeiCoreImageLoaderSearchTeSectionFirst - // is true, TE will be searched first). - // - Status = PeiServicesFfsFindSectionData3 ( - SearchType1, - 0, - FileHandle, - &Pe32Data, - AuthenticationState - ); - // - // If we didn't find a first exe section, try to find the second exe section. - // - if (EFI_ERROR (Status)) { - Status = PeiServicesFfsFindSectionData3 ( - SearchType2, - 0, - FileHandle, - &Pe32Data, - AuthenticationState - ); - if (EFI_ERROR (Status)) { - // - // PEI core only carry the loader function for TE and PE32 executables - // If this two section does not exist, just return. - // - return Status; - } - } - - // - // If memory is installed, perform the shadow operations - // - Status = LoadAndRelocatePeCoffImage ( - FileHandle, - Pe32Data, - &ImageAddress, - &ImageSize, - &ImageEntryPoint - ); - - ASSERT_EFI_ERROR (Status); - - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Got the entry point from the loaded Pe32Data - // - Pe32Data = (VOID *) ((UINTN) ImageAddress); - *EntryPoint = ImageEntryPoint; - - Machine = PeCoffLoaderGetMachineType (Pe32Data); - - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Machine)) { - if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Machine)) { - return EFI_UNSUPPORTED; - } - } - - if (ImageAddressArg != NULL) { - *ImageAddressArg = ImageAddress; - } - - if (ImageSizeArg != NULL) { - *ImageSizeArg = ImageSize; - } - - DEBUG_CODE_BEGIN (); - CHAR8 *AsciiString; - CHAR8 EfiFileName[512]; - INT32 Index; - INT32 StartIndex; - - // - // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi - // - if (Machine != EFI_IMAGE_MACHINE_IA64) { - DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)*EntryPoint)); - } else { - // - // For IPF Image, the real entry point should be print. - // - DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%11p EntryPoint=0x%11p ", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)(*(UINT64 *)(UINTN)*EntryPoint))); - } - - // - // Print Module Name by PeImage PDB file name. - // - AsciiString = PeCoffLoaderGetPdbPointer (Pe32Data); - - if (AsciiString != NULL) { - StartIndex = 0; - for (Index = 0; AsciiString[Index] != 0; Index++) { - if (AsciiString[Index] == '\\' || AsciiString[Index] == '/') { - StartIndex = Index + 1; - } - } - - // - // Copy the PDB file name to our temporary string, and replace .pdb with .efi - // The PDB file name is limited in the range of 0~511. - // If the length is bigger than 511, trim the redudant characters to avoid overflow in array boundary. - // - for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) { - EfiFileName[Index] = AsciiString[Index + StartIndex]; - if (EfiFileName[Index] == 0) { - EfiFileName[Index] = '.'; - } - if (EfiFileName[Index] == '.') { - EfiFileName[Index + 1] = 'e'; - EfiFileName[Index + 2] = 'f'; - EfiFileName[Index + 3] = 'i'; - EfiFileName[Index + 4] = 0; - break; - } - } - - if (Index == sizeof (EfiFileName) - 4) { - EfiFileName[Index] = 0; - } - - DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a", EfiFileName)); - } - - DEBUG_CODE_END (); - - DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n")); - - return EFI_SUCCESS; - -} - - -/** - The wrapper function of PeiLoadImageLoadImage(). - - @param This - Pointer to EFI_PEI_LOAD_FILE_PPI. - @param FileHandle - Pointer to the FFS file header of the image. - @param ImageAddressArg - Pointer to PE/TE image. - @param ImageSizeArg - Size of PE/TE image. - @param EntryPoint - Pointer to entry point of specified image file for output. - @param AuthenticationState - Pointer to attestation authentication state of image. - - @return Status of PeiLoadImageLoadImage(). - -**/ -EFI_STATUS -EFIAPI -PeiLoadImageLoadImageWrapper ( - IN CONST EFI_PEI_LOAD_FILE_PPI *This, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL - OUT UINT64 *ImageSizeArg, OPTIONAL - OUT EFI_PHYSICAL_ADDRESS *EntryPoint, - OUT UINT32 *AuthenticationState - ) -{ - return PeiLoadImageLoadImage ( - GetPeiServicesTablePointer (), - FileHandle, - ImageAddressArg, - ImageSizeArg, - EntryPoint, - AuthenticationState - ); -} - -/** - Check whether the input image has the relocation. - - @param Pe32Data Pointer to the PE/COFF or TE image. - - @retval TRUE Relocation is stripped. - @retval FALSE Relocation is not stripped. - -**/ -BOOLEAN -RelocationIsStrip ( - IN VOID *Pe32Data - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_DOS_HEADER *DosHdr; - - ASSERT (Pe32Data != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - // - // Three cases with regards to relocations: - // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable - // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable - // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but - // has no base relocs to apply - // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid. - // - // Look at the file header to determine if relocations have been stripped, and - // save this info in the image context for later use. - // - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - if ((Hdr.Te->DataDirectory[0].Size == 0) && (Hdr.Te->DataDirectory[0].VirtualAddress == 0)) { - return TRUE; - } else { - return FALSE; - } - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - if ((Hdr.Pe32->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) { - return TRUE; - } else { - return FALSE; - } - } - - return FALSE; -} - -/** - Routine to load image file for subsequent execution by LoadFile Ppi. - If any LoadFile Ppi is not found, the build-in support function for the PE32+/TE - XIP image format is used. - - @param PeiServices - An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param FileHandle - Pointer to the FFS file header of the image. - @param PeimState - The dispatch state of the input PEIM handle. - @param EntryPoint - Pointer to entry point of specified image file for output. - @param AuthenticationState - Pointer to attestation authentication state of image. - - @retval EFI_SUCCESS - Image is successfully loaded. - @retval EFI_NOT_FOUND - Fail to locate necessary PPI - @retval Others - Fail to load file. - -**/ -EFI_STATUS -PeiLoadImage ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_FILE_HANDLE FileHandle, - IN UINT8 PeimState, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint, - OUT UINT32 *AuthenticationState - ) -{ - EFI_STATUS PpiStatus; - EFI_STATUS Status; - UINTN Index; - EFI_PEI_LOAD_FILE_PPI *LoadFile; - EFI_PHYSICAL_ADDRESS ImageAddress; - UINT64 ImageSize; - BOOLEAN IsStrip; - - IsStrip = FALSE; - // - // If any instances of PEI_LOAD_FILE_PPI are installed, they are called. - // one at a time, until one reports EFI_SUCCESS. - // - Index = 0; - do { - PpiStatus = PeiServicesLocatePpi ( - &gEfiPeiLoadFilePpiGuid, - Index, - NULL, - (VOID **)&LoadFile - ); - if (!EFI_ERROR (PpiStatus)) { - Status = LoadFile->LoadFile ( - LoadFile, - FileHandle, - &ImageAddress, - &ImageSize, - EntryPoint, - AuthenticationState - ); - if (!EFI_ERROR (Status) || Status == EFI_WARN_BUFFER_TOO_SMALL) { - // - // The shadowed PEIM must be relocatable. - // - if (PeimState == PEIM_STATE_REGISITER_FOR_SHADOW) { - IsStrip = RelocationIsStrip ((VOID *) (UINTN) ImageAddress); - ASSERT (!IsStrip); - if (IsStrip) { - return EFI_UNSUPPORTED; - } - } - - // - // The image to be started must have the machine type supported by PeiCore. - // - ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))); - if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))) { - return EFI_UNSUPPORTED; - } - return EFI_SUCCESS; - } - } - Index++; - } while (!EFI_ERROR (PpiStatus)); - - return PpiStatus; -} - - -/** - - Install Pei Load File PPI. - - - @param PrivateData - Pointer to PEI_CORE_INSTANCE. - @param OldCoreData - Pointer to PEI_CORE_INSTANCE. - -**/ -VOID -InitializeImageServices ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_INSTANCE *OldCoreData - ) -{ - if (OldCoreData == NULL) { - // - // The first time we are XIP (running from FLASH). We need to remember the - // FLASH address so we can reinstall the memory version that runs faster - // - PrivateData->XipLoadFile = &gPpiLoadFilePpiList; - PeiServicesInstallPpi (PrivateData->XipLoadFile); - } else { - // - // 2nd time we are running from memory so replace the XIP version with the - // new memory version. - // - PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList); - } -} - - - - diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c deleted file mode 100644 index 719372e061..0000000000 --- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c +++ /dev/null @@ -1,307 +0,0 @@ -/** @file - EFI PEI Core memory services - -Copyright (c) 2006 - 2015, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/** - - Initialize the memory services. - - @param PrivateData Points to PeiCore's private instance data. - @param SecCoreData Points to a data structure containing information about the PEI core's operating - environment, such as the size and location of temporary RAM, the stack location and - the BFV location. - @param OldCoreData Pointer to the PEI Core data. - NULL if being run in non-permament memory mode. - -**/ -VOID -InitializeMemoryServices ( - IN PEI_CORE_INSTANCE *PrivateData, - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN PEI_CORE_INSTANCE *OldCoreData - ) -{ - - PrivateData->SwitchStackSignal = FALSE; - - // - // First entering PeiCore, following code will initialized some field - // in PeiCore's private data according to hand off data from sec core. - // - if (OldCoreData == NULL) { - - PrivateData->PeiMemoryInstalled = FALSE; - PrivateData->HobList.Raw = SecCoreData->PeiTemporaryRamBase; - - PeiCoreBuildHobHandoffInfoTable ( - BOOT_WITH_FULL_CONFIGURATION, - (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->PeiTemporaryRamBase, - (UINTN) SecCoreData->PeiTemporaryRamSize - ); - - // - // Set Ps to point to ServiceTableShadow in Cache - // - PrivateData->Ps = &(PrivateData->ServiceTableShadow); - } - - return; -} - -/** - - This function registers the found memory configuration with the PEI Foundation. - - The usage model is that the PEIM that discovers the permanent memory shall invoke this service. - This routine will hold discoveried memory information into PeiCore's private data, - and set SwitchStackSignal flag. After PEIM who discovery memory is dispatched, - PeiDispatcher will migrate temporary memory to permenement memory. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param MemoryBegin Start of memory address. - @param MemoryLength Length of memory. - - @return EFI_SUCCESS Always success. - -**/ -EFI_STATUS -EFIAPI -PeiInstallPeiMemory ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PHYSICAL_ADDRESS MemoryBegin, - IN UINT64 MemoryLength - ) -{ - PEI_CORE_INSTANCE *PrivateData; - - DEBUG ((EFI_D_INFO, "PeiInstallPeiMemory MemoryBegin 0x%LX, MemoryLength 0x%LX\n", MemoryBegin, MemoryLength)); - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); - - // - // PEI_SERVICE.InstallPeiMemory should only be called one time during whole PEI phase. - // If it is invoked more than one time, ASSERT information is given for developer debugging in debug tip and - // simply return EFI_SUCESS in release tip to ignore it. - // - if (PrivateData->PeiMemoryInstalled) { - DEBUG ((EFI_D_ERROR, "ERROR: PeiInstallPeiMemory is called more than once!\n")); - ASSERT (FALSE); - return EFI_SUCCESS; - } - - PrivateData->PhysicalMemoryBegin = MemoryBegin; - PrivateData->PhysicalMemoryLength = MemoryLength; - PrivateData->FreePhysicalMemoryTop = MemoryBegin + MemoryLength; - - PrivateData->SwitchStackSignal = TRUE; - - return EFI_SUCCESS; -} - -/** - The purpose of the service is to publish an interface that allows - PEIMs to allocate memory ranges that are managed by the PEI Foundation. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param MemoryType The type of memory to allocate. - @param Pages The number of contiguous 4 KB pages to allocate. - @param Memory Pointer to a physical address. On output, the address is set to the base - of the page range that was allocated. - - @retval EFI_SUCCESS The memory range was successfully allocated. - @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. - @retval EFI_INVALID_PARAMETER Type is not equal to EfiLoaderCode, EfiLoaderData, EfiRuntimeServicesCode, - EfiRuntimeServicesData, EfiBootServicesCode, EfiBootServicesData, - EfiACPIReclaimMemory, EfiReservedMemoryType, or EfiACPIMemoryNVS. - -**/ -EFI_STATUS -EFIAPI -PeiAllocatePages ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT EFI_PHYSICAL_ADDRESS *Memory - ) -{ - PEI_CORE_INSTANCE *PrivateData; - EFI_PEI_HOB_POINTERS Hob; - EFI_PHYSICAL_ADDRESS *FreeMemoryTop; - EFI_PHYSICAL_ADDRESS *FreeMemoryBottom; - UINTN RemainingPages; - UINTN Granularity; - UINTN Padding; - - if ((MemoryType != EfiLoaderCode) && - (MemoryType != EfiLoaderData) && - (MemoryType != EfiRuntimeServicesCode) && - (MemoryType != EfiRuntimeServicesData) && - (MemoryType != EfiBootServicesCode) && - (MemoryType != EfiBootServicesData) && - (MemoryType != EfiACPIReclaimMemory) && - (MemoryType != EfiReservedMemoryType) && - (MemoryType != EfiACPIMemoryNVS)) { - return EFI_INVALID_PARAMETER; - } - - Granularity = DEFAULT_PAGE_ALLOCATION_GRANULARITY; - - if (RUNTIME_PAGE_ALLOCATION_GRANULARITY > DEFAULT_PAGE_ALLOCATION_GRANULARITY && - (MemoryType == EfiACPIReclaimMemory || - MemoryType == EfiACPIMemoryNVS || - MemoryType == EfiRuntimeServicesCode || - MemoryType == EfiRuntimeServicesData)) { - - Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY; - - DEBUG ((DEBUG_INFO, "AllocatePages: aligning allocation to %d KB\n", - Granularity / SIZE_1KB)); - } - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); - Hob.Raw = PrivateData->HobList.Raw; - - // - // Check if Hob already available - // - if (!PrivateData->PeiMemoryInstalled) { - // - // When PeiInstallMemory is called but temporary memory has *not* been moved to temporary memory, - // the AllocatePage will depend on the field of PEI_CORE_INSTANCE structure. - // - if (!PrivateData->SwitchStackSignal) { - return EFI_NOT_AVAILABLE_YET; - } else { - FreeMemoryTop = &(PrivateData->FreePhysicalMemoryTop); - FreeMemoryBottom = &(PrivateData->PhysicalMemoryBegin); - } - } else { - FreeMemoryTop = &(Hob.HandoffInformationTable->EfiFreeMemoryTop); - FreeMemoryBottom = &(Hob.HandoffInformationTable->EfiFreeMemoryBottom); - } - - // - // Check to see if on correct boundary for the memory type. - // If not aligned, make the allocation aligned. - // - Padding = *(FreeMemoryTop) & (Granularity - 1); - if ((UINTN) (*FreeMemoryTop - *FreeMemoryBottom) < Padding) { - DEBUG ((DEBUG_ERROR, "AllocatePages failed: Out of space after padding.\n")); - return EFI_OUT_OF_RESOURCES; - } - - *(FreeMemoryTop) -= Padding; - if (Padding >= EFI_PAGE_SIZE) { - // - // Create a memory allocation HOB to cover - // the pages that we will lose to rounding - // - BuildMemoryAllocationHob ( - *(FreeMemoryTop), - Padding & ~(UINTN)EFI_PAGE_MASK, - EfiConventionalMemory - ); - } - - // - // Verify that there is sufficient memory to satisfy the allocation. - // For page allocation, the overhead sizeof (EFI_HOB_MEMORY_ALLOCATION) needs to be considered. - // - if ((UINTN) (*FreeMemoryTop - *FreeMemoryBottom) < (UINTN) ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION), 8)) { - DEBUG ((EFI_D_ERROR, "AllocatePages failed: No space to build memory allocation hob.\n")); - return EFI_OUT_OF_RESOURCES; - } - RemainingPages = (UINTN)(*FreeMemoryTop - *FreeMemoryBottom - ALIGN_VALUE (sizeof (EFI_HOB_MEMORY_ALLOCATION), 8)) >> EFI_PAGE_SHIFT; - // - // The number of remaining pages needs to be greater than or equal to that of the request pages. - // - Pages = ALIGN_VALUE (Pages, EFI_SIZE_TO_PAGES (Granularity)); - if (RemainingPages < Pages) { - DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%lx Pages is available.\n", (UINT64) Pages)); - DEBUG ((EFI_D_ERROR, "There is only left 0x%lx pages memory resource to be allocated.\n", (UINT64) RemainingPages)); - return EFI_OUT_OF_RESOURCES; - } else { - // - // Update the PHIT to reflect the memory usage - // - *(FreeMemoryTop) -= Pages * EFI_PAGE_SIZE; - - // - // Update the value for the caller - // - *Memory = *(FreeMemoryTop); - - // - // Create a memory allocation HOB. - // - BuildMemoryAllocationHob ( - *(FreeMemoryTop), - Pages * EFI_PAGE_SIZE, - MemoryType - ); - - return EFI_SUCCESS; - } -} - -/** - - Pool allocation service. Before permanent memory is discoveried, the pool will - be allocated the heap in the temporary memory. Genenrally, the size of heap in temporary - memory does not exceed to 64K, so the biggest pool size could be allocated is - 64K. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param Size Amount of memory required - @param Buffer Address of pointer to the buffer - - @retval EFI_SUCCESS The allocation was successful - @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement - to allocate the requested size. - -**/ -EFI_STATUS -EFIAPI -PeiAllocatePool ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN UINTN Size, - OUT VOID **Buffer - ) -{ - EFI_STATUS Status; - EFI_HOB_MEMORY_POOL *Hob; - - // - // If some "post-memory" PEIM wishes to allocate larger pool, - // it should use AllocatePages service instead. - // - - // - // Generally, the size of heap in temporary memory does not exceed to 64K, - // HobLength is multiples of 8 bytes, so the maxmium size of pool is 0xFFF8 - sizeof (EFI_HOB_MEMORY_POOL) - // - if (Size > (0xFFF8 - sizeof (EFI_HOB_MEMORY_POOL))) { - return EFI_OUT_OF_RESOURCES; - } - - Status = PeiServicesCreateHob ( - EFI_HOB_TYPE_MEMORY_POOL, - (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size), - (VOID **)&Hob - ); - ASSERT_EFI_ERROR (Status); - *Buffer = Hob+1; - - return Status; -} diff --git a/MdeModulePkg/Core/Pei/PciCfg2/PciCfg2.c b/MdeModulePkg/Core/Pei/PciCfg2/PciCfg2.c deleted file mode 100644 index a20e7c00c5..0000000000 --- a/MdeModulePkg/Core/Pei/PciCfg2/PciCfg2.c +++ /dev/null @@ -1,128 +0,0 @@ -/** @file - The default version of EFI_PEI_PCI_CFG2_PPI support published by PeiServices in - PeiCore initialization phase. - - EFI_PEI_PCI_CFG2_PPI is installed by the PEIM which supports a PCI root bridge. - When PeiCore is started, the default version of EFI_PEI_PCI_CFG2_PPI will be assigned - to PeiServices table. - -Copyright (c) 2009, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/// -/// This default instance of EFI_PEI_PCI_CFG2_PPI install assigned to EFI_PEI_SERVICE.PciCfg -/// when PeiCore's initialization. -/// -EFI_PEI_PCI_CFG2_PPI gPeiDefaultPciCfg2Ppi = { - PeiDefaultPciCfg2Read, - PeiDefaultPciCfg2Write, - PeiDefaultPciCfg2Modify -}; - -/** - Reads from a given location in the PCI configuration space. - - If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - See EFI_PEI_PCI_CFG_PPI_WIDTH above. - @param Address The physical address of the access. The format of - the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER The invalid access width. - @retval EFI_NOT_YET_AVAILABLE If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM. - -**/ -EFI_STATUS -EFIAPI -PeiDefaultPciCfg2Read ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PCI_CFG2_PPI *This, - IN EFI_PEI_PCI_CFG_PPI_WIDTH Width, - IN UINT64 Address, - IN OUT VOID *Buffer - ) -{ - return EFI_NOT_AVAILABLE_YET; -} - -/** - Write to a given location in the PCI configuration space. - - If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - See EFI_PEI_PCI_CFG_PPI_WIDTH above. - @param Address The physical address of the access. The format of - the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER The invalid access width. - @retval EFI_NOT_YET_AVAILABLE If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM. -**/ -EFI_STATUS -EFIAPI -PeiDefaultPciCfg2Write ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PCI_CFG2_PPI *This, - IN EFI_PEI_PCI_CFG_PPI_WIDTH Width, - IN UINT64 Address, - IN OUT VOID *Buffer - ) -{ - return EFI_NOT_AVAILABLE_YET; -} - -/** - This function performs a read-modify-write operation on the contents from a given - location in the PCI configuration space. - If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. Type - EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read(). - @param Address The physical address of the access. - @param SetBits Points to value to bitwise-OR with the read configuration value. - The size of the value is determined by Width. - @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value. - The size of the value is determined by Width. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER The invalid access width. - @retval EFI_NOT_YET_AVAILABLE If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM. -**/ -EFI_STATUS -EFIAPI -PeiDefaultPciCfg2Modify ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PCI_CFG2_PPI *This, - IN EFI_PEI_PCI_CFG_PPI_WIDTH Width, - IN UINT64 Address, - IN VOID *SetBits, - IN VOID *ClearBits - ) -{ - return EFI_NOT_AVAILABLE_YET; -} diff --git a/MdeModulePkg/Core/Pei/PeiCore.uni b/MdeModulePkg/Core/Pei/PeiCore.uni deleted file mode 100644 index 79db0cc791..0000000000 --- a/MdeModulePkg/Core/Pei/PeiCore.uni +++ /dev/null @@ -1,27 +0,0 @@ -// /** @file -// PeiMain module is core module in PEI phase. -// -// It takes responsibilities of: -// 1) Initialize memory, PPI, image services etc, to establish PEIM runtime environment. -// 2) Dispatch PEIM from discovered FV. -// 3) Handoff control to DxeIpl to load DXE core and enter DXE phase. -// -// Copyright (c) 2006 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Core module in PEI phase" - -#string STR_MODULE_DESCRIPTION #language en-US "It takes responsibilities of:
\n" - "1) Initializing memory, PPI, image services etc., to establish the PEIM runtime environment.
\n" - "2) Dispatches PEIM from discovered FV.
\n" - "3) Handsoff control to DxeIpl to load DXE core and enters DXE phase.
" - diff --git a/MdeModulePkg/Core/Pei/PeiCoreExtra.uni b/MdeModulePkg/Core/Pei/PeiCoreExtra.uni deleted file mode 100644 index ec430fccae..0000000000 --- a/MdeModulePkg/Core/Pei/PeiCoreExtra.uni +++ /dev/null @@ -1,19 +0,0 @@ -// /** @file -// PeiCore Localized Strings and Content -// -// Copyright (c) 2013 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Core PEI Services Module" - - diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h deleted file mode 100644 index 69eea51492..0000000000 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ /dev/null @@ -1,1745 +0,0 @@ -/** @file - Definition of Pei Core Structures and Services - -Copyright (c) 2006 - 2015, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _PEI_MAIN_H_ -#define _PEI_MAIN_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/// -/// It is an FFS type extension used for PeiFindFileEx. It indicates current -/// Ffs searching is for all PEIMs can be dispatched by PeiCore. -/// -#define PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE 0xff - -/// -/// Pei Core private data structures -/// -typedef union { - EFI_PEI_PPI_DESCRIPTOR *Ppi; - EFI_PEI_NOTIFY_DESCRIPTOR *Notify; - VOID *Raw; -} PEI_PPI_LIST_POINTERS; - -/// -/// PPI database structure which contains two link: PpiList and NotifyList. PpiList -/// is in head of PpiListPtrs array and notify is in end of PpiListPtrs. -/// -typedef struct { - /// - /// index of end of PpiList link list. - /// - INTN PpiListEnd; - /// - /// index of end of notify link list. - /// - INTN NotifyListEnd; - /// - /// index of the dispatched notify list. - /// - INTN DispatchListEnd; - /// - /// index of last installed Ppi description in PpiList link list. - /// - INTN LastDispatchedInstall; - /// - /// index of last dispatched notify in Notify link list. - /// - INTN LastDispatchedNotify; - /// - /// Ppi database has the PcdPeiCoreMaxPpiSupported number of entries. - /// - PEI_PPI_LIST_POINTERS *PpiListPtrs; -} PEI_PPI_DATABASE; - - -// -// PEI_CORE_FV_HANDE.PeimState -// Do not change these values as there is code doing math to change states. -// Look for Private->Fv[FvCount].PeimState[PeimCount]++; -// -#define PEIM_STATE_NOT_DISPATCHED 0x00 -#define PEIM_STATE_DISPATCHED 0x01 -#define PEIM_STATE_REGISITER_FOR_SHADOW 0x02 -#define PEIM_STATE_DONE 0x03 - -typedef struct { - EFI_FIRMWARE_VOLUME_HEADER *FvHeader; - EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi; - EFI_PEI_FV_HANDLE FvHandle; - // - // Ponter to the buffer with the PcdPeiCoreMaxPeimPerFv number of Entries. - // - UINT8 *PeimState; - // - // Ponter to the buffer with the PcdPeiCoreMaxPeimPerFv number of Entries. - // - EFI_PEI_FILE_HANDLE *FvFileHandles; - BOOLEAN ScanFv; - UINT32 AuthenticationStatus; -} PEI_CORE_FV_HANDLE; - -typedef struct { - EFI_GUID FvFormat; - VOID *FvInfo; - UINT32 FvInfoSize; - UINT32 AuthenticationStatus; - EFI_PEI_NOTIFY_DESCRIPTOR NotifyDescriptor; -} PEI_CORE_UNKNOW_FORMAT_FV_INFO; - -#define CACHE_SETION_MAX_NUMBER 0x10 -typedef struct { - EFI_COMMON_SECTION_HEADER* Section[CACHE_SETION_MAX_NUMBER]; - VOID* SectionData[CACHE_SETION_MAX_NUMBER]; - UINTN SectionSize[CACHE_SETION_MAX_NUMBER]; - UINT32 AuthenticationStatus[CACHE_SETION_MAX_NUMBER]; - UINTN AllSectionCount; - UINTN SectionIndex; -} CACHE_SECTION_DATA; - -#define HOLE_MAX_NUMBER 0x3 -typedef struct { - EFI_PHYSICAL_ADDRESS Base; - UINTN Size; - UINTN Offset; - BOOLEAN OffsetPositive; -} HOLE_MEMORY_DATA; - -/// -/// Forward declaration for PEI_CORE_INSTANCE -/// -typedef struct _PEI_CORE_INSTANCE PEI_CORE_INSTANCE; - - -/** - Function Pointer type for PeiCore function. - @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size - and location of temporary RAM, the stack location and the BFV location. - @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core. - An empty PPI list consists of a single descriptor with the end-tag - EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization - phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such - that both the PEI Foundation and any modules can leverage the associated service - calls and/or code in these early PPIs - @param OldCoreData Pointer to old core data that is used to initialize the - core's data areas. -**/ -typedef -EFI_STATUS -(EFIAPI *PEICORE_FUNCTION_POINTER)( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, - IN PEI_CORE_INSTANCE *OldCoreData - ); - -#define PEI_CORE_HANDLE_SIGNATURE SIGNATURE_32('P','e','i','C') - -/// -/// Pei Core private data structure instance -/// -struct _PEI_CORE_INSTANCE { - UINTN Signature; - - /// - /// Point to ServiceTableShadow - /// - EFI_PEI_SERVICES *Ps; - PEI_PPI_DATABASE PpiData; - - /// - /// The count of FVs which contains FFS and could be dispatched by PeiCore. - /// - UINTN FvCount; - - /// - /// Pointer to the buffer with the PcdPeiCoreMaxFvSupported number of entries. - /// Each entry is for one FV which contains FFS and could be dispatched by PeiCore. - /// - PEI_CORE_FV_HANDLE *Fv; - - /// - /// Pointer to the buffer with the PcdPeiCoreMaxFvSupported number of entries. - /// Each entry is for one FV which could not be dispatched by PeiCore. - /// - PEI_CORE_UNKNOW_FORMAT_FV_INFO *UnknownFvInfo; - UINTN UnknownFvInfoCount; - - /// - /// Pointer to the buffer with the PcdPeiCoreMaxPeimPerFv number of entries. - /// - EFI_PEI_FILE_HANDLE *CurrentFvFileHandles; - UINTN AprioriCount; - UINTN CurrentPeimFvCount; - UINTN CurrentPeimCount; - EFI_PEI_FILE_HANDLE CurrentFileHandle; - BOOLEAN PeimNeedingDispatch; - BOOLEAN PeimDispatchOnThisPass; - BOOLEAN PeimDispatcherReenter; - EFI_PEI_HOB_POINTERS HobList; - BOOLEAN SwitchStackSignal; - BOOLEAN PeiMemoryInstalled; - VOID *CpuIo; - EFI_PEI_SECURITY2_PPI *PrivateSecurityPpi; - EFI_PEI_SERVICES ServiceTableShadow; - EFI_PEI_PPI_DESCRIPTOR *XipLoadFile; - EFI_PHYSICAL_ADDRESS PhysicalMemoryBegin; - UINT64 PhysicalMemoryLength; - EFI_PHYSICAL_ADDRESS FreePhysicalMemoryTop; - UINTN HeapOffset; - BOOLEAN HeapOffsetPositive; - UINTN StackOffset; - BOOLEAN StackOffsetPositive; - PEICORE_FUNCTION_POINTER ShadowedPeiCore; - CACHE_SECTION_DATA CacheSection; - // - // For Loading modules at fixed address feature to cache the top address below which the - // Runtime code, boot time code and PEI memory will be placed. Please note that the offset between this field - // and Ps should not be changed since maybe user could get this top address by using the offet to Ps. - // - EFI_PHYSICAL_ADDRESS LoadModuleAtFixAddressTopAddress; - // - // The field is define for Loading modules at fixed address feature to tracker the PEI code - // memory range usage. It is a bit mapped array in which every bit indicates the correspoding memory page - // available or not. - // - UINT64 *PeiCodeMemoryRangeUsageBitMap; - // - // This field points to the shadowed image read function - // - PE_COFF_LOADER_READ_FILE ShadowedImageRead; - - // - // Pointer to the temp buffer with the PcdPeiCoreMaxPeimPerFv + 1 number of entries. - // - EFI_PEI_FILE_HANDLE *FileHandles; - // - // Pointer to the temp buffer with the PcdPeiCoreMaxPeimPerFv number of entries. - // - EFI_GUID *FileGuid; - - // - // Temp Memory Range is not covered by PeiTempMem and Stack. - // Those Memory Range will be migrated into phisical memory. - // - HOLE_MEMORY_DATA HoleData[HOLE_MAX_NUMBER]; -}; - -/// -/// Pei Core Instance Data Macros -/// -#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \ - CR(a, PEI_CORE_INSTANCE, Ps, PEI_CORE_HANDLE_SIGNATURE) - -/// -/// Union of temporarily used function pointers (to save stack space) -/// -typedef union { - PEICORE_FUNCTION_POINTER PeiCore; - EFI_PEIM_ENTRY_POINT2 PeimEntry; - EFI_PEIM_NOTIFY_ENTRY_POINT PeimNotifyEntry; - EFI_DXE_IPL_PPI *DxeIpl; - EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; - EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor; - VOID *Raw; -} PEI_CORE_TEMP_POINTERS; - -typedef struct { - CONST EFI_SEC_PEI_HAND_OFF *SecCoreData; - EFI_PEI_PPI_DESCRIPTOR *PpiList; - VOID *Data; -} PEI_CORE_PARAMETERS; - -// -// PeiCore function -// -/** - - The entry routine to Pei Core, invoked by PeiMain during transition - from SEC to PEI. After switching stack in the PEI core, it will restart - with the old core data. - - - @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size - and location of temporary RAM, the stack location and the BFV location. - @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core. - An empty PPI list consists of a single descriptor with the end-tag - EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization - phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such - that both the PEI Foundation and any modules can leverage the associated service - calls and/or code in these early PPIs - @param Data Pointer to old core data that is used to initialize the - core's data areas. - -**/ -VOID -EFIAPI -PeiCore ( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, - IN VOID *Data - ); - -// -// Dispatcher support functions -// - -/** - - This is the POSTFIX version of the dependency evaluator. When a - PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on - the evaluation stack. When that entry is poped from the evaluation - stack, the PPI is checked if it is installed. This method allows - some time savings as not all PPIs must be checked for certain - operation types (AND, OR). - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param DependencyExpression Pointer to a dependency expression. The Grammar adheres to - the BNF described above and is stored in postfix notation. - - @retval TRUE if it is a well-formed Grammar - @retval FALSE if the dependency expression overflows the evaluation stack - if the dependency expression underflows the evaluation stack - if the dependency expression is not a well-formed Grammar. - -**/ -BOOLEAN -PeimDispatchReadiness ( - IN EFI_PEI_SERVICES **PeiServices, - IN VOID *DependencyExpression - ); - -/** - Conduct PEIM dispatch. - - @param SecCoreData Pointer to the data structure containing SEC to PEI handoff data - @param PrivateData Pointer to the private data passed in from caller - -**/ -VOID -PeiDispatcher ( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN PEI_CORE_INSTANCE *PrivateData - ); - -/** - Initialize the Dispatcher's data members - - @param PrivateData PeiCore's private data structure - @param OldCoreData Old data from SecCore - NULL if being run in non-permament memory mode. - @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size - and location of temporary RAM, the stack location and the BFV location. - -**/ -VOID -InitializeDispatcherData ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_INSTANCE *OldCoreData, - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData - ); - -/** - This routine parses the Dependency Expression, if available, and - decides if the module can be executed. - - - @param Private PeiCore's private data structure - @param FileHandle PEIM's file handle - @param PeimCount The index of last dispatched PEIM. - - @retval TRUE Can be dispatched - @retval FALSE Cannot be dispatched - -**/ -BOOLEAN -DepexSatisfied ( - IN PEI_CORE_INSTANCE *Private, - IN EFI_PEI_FILE_HANDLE FileHandle, - IN UINTN PeimCount - ); - -// -// PPI support functions -// -/** - - Initialize PPI services. - - @param PrivateData Pointer to the PEI Core data. - @param OldCoreData Pointer to old PEI Core data. - NULL if being run in non-permament memory mode. - -**/ -VOID -InitializePpiServices ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_INSTANCE *OldCoreData - ); - -/** - - Migrate the Hob list from the temporary memory stack to PEI installed memory. - - @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size - and location of temporary RAM, the stack location and the BFV location. - @param PrivateData Pointer to PeiCore's private data structure. - -**/ -VOID -ConvertPpiPointers ( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN PEI_CORE_INSTANCE *PrivateData - ); - -/** - - Install PPI services. It is implementation of EFI_PEI_SERVICE.InstallPpi. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param PpiList Pointer to ppi array that want to be installed. - - @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed. - @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer - if any PPI in PpiList is not valid - @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI - -**/ -EFI_STATUS -EFIAPI -PeiInstallPpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList - ); - -/** - - Re-Install PPI services. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param OldPpi Pointer to the old PEI PPI Descriptors. - @param NewPpi Pointer to the new PEI PPI Descriptors. - - @retval EFI_SUCCESS if the operation was successful - @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL - if NewPpi is not valid - @retval EFI_NOT_FOUND if the PPI was not in the database - -**/ -EFI_STATUS -EFIAPI -PeiReInstallPpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, - IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi - ); - -/** - - Locate a given named PPI. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param Guid Pointer to GUID of the PPI. - @param Instance Instance Number to discover. - @param PpiDescriptor Pointer to reference the found descriptor. If not NULL, - returns a pointer to the descriptor (includes flags, etc) - @param Ppi Pointer to reference the found PPI - - @retval EFI_SUCCESS if the PPI is in the database - @retval EFI_NOT_FOUND if the PPI is not in the database - -**/ -EFI_STATUS -EFIAPI -PeiLocatePpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_GUID *Guid, - IN UINTN Instance, - IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, - IN OUT VOID **Ppi - ); - -/** - - Install a notification for a given PPI. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param NotifyList Pointer to list of Descriptors to notify upon. - - @retval EFI_SUCCESS if successful - @retval EFI_OUT_OF_RESOURCES if no space in the database - @retval EFI_INVALID_PARAMETER if not a good decriptor - -**/ -EFI_STATUS -EFIAPI -PeiNotifyPpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList - ); - -/** - - Process the Notify List at dispatch level. - - @param PrivateData PeiCore's private data structure. - -**/ -VOID -ProcessNotifyList ( - IN PEI_CORE_INSTANCE *PrivateData - ); - -/** - - Dispatch notifications. - - @param PrivateData PeiCore's private data structure - @param NotifyType Type of notify to fire. - @param InstallStartIndex Install Beginning index. - @param InstallStopIndex Install Ending index. - @param NotifyStartIndex Notify Beginning index. - @param NotifyStopIndex Notify Ending index. - -**/ -VOID -DispatchNotify ( - IN PEI_CORE_INSTANCE *PrivateData, - IN UINTN NotifyType, - IN INTN InstallStartIndex, - IN INTN InstallStopIndex, - IN INTN NotifyStartIndex, - IN INTN NotifyStopIndex - ); - -// -// Boot mode support functions -// -/** - This service enables PEIMs to ascertain the present value of the boot mode. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param BootMode A pointer to contain the value of the boot mode. - - @retval EFI_SUCCESS The boot mode was returned successfully. - @retval EFI_INVALID_PARAMETER BootMode is NULL. - -**/ -EFI_STATUS -EFIAPI -PeiGetBootMode ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN OUT EFI_BOOT_MODE *BootMode - ); - -/** - This service enables PEIMs to update the boot mode variable. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param BootMode The value of the boot mode to set. - - @return EFI_SUCCESS The value was successfully updated - -**/ -EFI_STATUS -EFIAPI -PeiSetBootMode ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_BOOT_MODE BootMode - ); - -// -// Security support functions -// -/** - - Initialize the security services. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param OldCoreData Pointer to the old core data. - NULL if being run in non-permament memory mode. - -**/ -VOID -InitializeSecurityServices ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_CORE_INSTANCE *OldCoreData - ); - -/** - Verify a Firmware volume. - - @param CurrentFvAddress Pointer to the current Firmware Volume under consideration - - @retval EFI_SUCCESS Firmware Volume is legal - @retval EFI_SECURITY_VIOLATION Firmware Volume fails integrity test - -**/ -EFI_STATUS -VerifyFv ( - IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress - ); - -/** - Provide a callout to the security verification service. - - @param PrivateData PeiCore's private data structure - @param VolumeHandle Handle of FV - @param FileHandle Handle of PEIM's ffs - @param AuthenticationStatus Authentication status - - @retval EFI_SUCCESS Image is OK - @retval EFI_SECURITY_VIOLATION Image is illegal - @retval EFI_NOT_FOUND If security PPI is not installed. -**/ -EFI_STATUS -VerifyPeim ( - IN PEI_CORE_INSTANCE *PrivateData, - IN EFI_PEI_FV_HANDLE VolumeHandle, - IN EFI_PEI_FILE_HANDLE FileHandle, - IN UINT32 AuthenticationStatus - ); - -/** - - Gets the pointer to the HOB List. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param HobList Pointer to the HOB List. - - @retval EFI_SUCCESS Get the pointer of HOB List - @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published - @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode) - -**/ -EFI_STATUS -EFIAPI -PeiGetHobList ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN OUT VOID **HobList - ); - -/** - Add a new HOB to the HOB List. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param Type Type of the new HOB. - @param Length Length of the new HOB to allocate. - @param Hob Pointer to the new HOB. - - @return EFI_SUCCESS Success to create hob. - @retval EFI_INVALID_PARAMETER if Hob is NULL - @retval EFI_NOT_AVAILABLE_YET if HobList is still not available. - @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist. - -**/ -EFI_STATUS -EFIAPI -PeiCreateHob ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN UINT16 Type, - IN UINT16 Length, - IN OUT VOID **Hob - ); - -/** - - Builds a Handoff Information Table HOB - - @param BootMode - Current Bootmode - @param MemoryBegin - Start Memory Address. - @param MemoryLength - Length of Memory. - - @return EFI_SUCCESS Always success to initialize HOB. - -**/ -EFI_STATUS -PeiCoreBuildHobHandoffInfoTable ( - IN EFI_BOOT_MODE BootMode, - IN EFI_PHYSICAL_ADDRESS MemoryBegin, - IN UINT64 MemoryLength - ); - - -// -// FFS Fw Volume support functions -// -/** - Searches for the next matching file in the firmware volume. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param SearchType Filter to find only files of this type. - Type EFI_FV_FILETYPE_ALL causes no filtering to be done. - @param FvHandle Handle of firmware volume in which to search. - @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start - at the beginning of the firmware volume. On exit, points the file handle of the next file - in the volume or NULL if there are no more files. - - @retval EFI_NOT_FOUND The file was not found. - @retval EFI_NOT_FOUND The header checksum was not zero. - @retval EFI_SUCCESS The file was found. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindNextFile ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN UINT8 SearchType, - IN EFI_PEI_FV_HANDLE FvHandle, - IN OUT EFI_PEI_FILE_HANDLE *FileHandle - ); - -/** - Searches for the next matching section within the specified file. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param SectionType Filter to find only sections of this type. - @param FileHandle Pointer to the current file to search. - @param SectionData A pointer to the discovered section, if successful. - NULL if section not found - - @retval EFI_NOT_FOUND The section was not found. - @retval EFI_SUCCESS The section was found. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindSectionData ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_SECTION_TYPE SectionType, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData - ); - -/** - Searches for the next matching section within the specified file. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param SectionType The value of the section type to find. - @param SectionInstance Section instance to find. - @param FileHandle Handle of the firmware file to search. - @param SectionData A pointer to the discovered section, if successful. - @param AuthenticationStatus A pointer to the authentication status for this section. - - @retval EFI_SUCCESS The section was found. - @retval EFI_NOT_FOUND The section was not found. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindSectionData3 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_SECTION_TYPE SectionType, - IN UINTN SectionInstance, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT VOID **SectionData, - OUT UINT32 *AuthenticationStatus - ); - -/** - Search the firmware volumes by index - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation - @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware - Volume (BFV). - @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist. - - @retval EFI_INVALID_PARAMETER VolumeHandle is NULL - @retval EFI_NOT_FOUND The volume was not found. - @retval EFI_SUCCESS The volume was found. - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindNextVolume ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN UINTN Instance, - IN OUT EFI_PEI_FV_HANDLE *VolumeHandle - ); - -// -// Memory support functions -// -/** - - Initialize the memory services. - - @param PrivateData PeiCore's private data structure - @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size - and location of temporary RAM, the stack location and the BFV location. - @param OldCoreData Pointer to the PEI Core data. - NULL if being run in non-permament memory mode. - -**/ -VOID -InitializeMemoryServices ( - IN PEI_CORE_INSTANCE *PrivateData, - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN PEI_CORE_INSTANCE *OldCoreData - ); - -/** - - Install the permanent memory is now available. - Creates HOB (PHIT and Stack). - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param MemoryBegin Start of memory address. - @param MemoryLength Length of memory. - - @return EFI_SUCCESS Always success. - -**/ -EFI_STATUS -EFIAPI -PeiInstallPeiMemory ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PHYSICAL_ADDRESS MemoryBegin, - IN UINT64 MemoryLength - ); - -/** - - Memory allocation service on permanent memory, - not usable prior to the memory installation. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param MemoryType Type of memory to allocate. - @param Pages Number of pages to allocate. - @param Memory Pointer of memory allocated. - - @retval EFI_SUCCESS The allocation was successful - @retval EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported. - @retval EFI_NOT_AVAILABLE_YET Called with permanent memory not available - @retval EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement - to allocate the number of pages. - -**/ -EFI_STATUS -EFIAPI -PeiAllocatePages ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Pages, - OUT EFI_PHYSICAL_ADDRESS *Memory - ); - -/** - - Memory allocation service on the temporary memory. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param Size Amount of memory required - @param Buffer Address of pointer to the buffer - - @retval EFI_SUCCESS The allocation was successful - @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement - to allocate the requested size. - -**/ -EFI_STATUS -EFIAPI -PeiAllocatePool ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - - Routine for load image file. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param FileHandle Pointer to the FFS file header of the image. - @param PeimState The dispatch state of the input PEIM handle. - @param EntryPoint Pointer to entry point of specified image file for output. - @param AuthenticationState Pointer to attestation authentication state of image. - - @retval EFI_SUCCESS Image is successfully loaded. - @retval EFI_NOT_FOUND Fail to locate necessary PPI - @retval Others Fail to load file. - -**/ -EFI_STATUS -PeiLoadImage ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_FILE_HANDLE FileHandle, - IN UINT8 PeimState, - OUT EFI_PHYSICAL_ADDRESS *EntryPoint, - OUT UINT32 *AuthenticationState - ); - -/** - - Core version of the Status Code reporter - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param CodeType Type of Status Code. - @param Value Value to output for Status Code. - @param Instance Instance Number of this status code. - @param CallerId ID of the caller of this status code. - @param Data Optional data associated with this status code. - - @retval EFI_SUCCESS if status code is successfully reported - @retval EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed - -**/ -EFI_STATUS -EFIAPI -PeiReportStatusCode ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_STATUS_CODE_TYPE CodeType, - IN EFI_STATUS_CODE_VALUE Value, - IN UINT32 Instance, - IN CONST EFI_GUID *CallerId, - IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL - ); - -/** - - Core version of the Reset System - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - - @retval EFI_NOT_AVAILABLE_YET PPI not available yet. - @retval EFI_DEVICE_ERROR Did not reset system. - Otherwise, resets the system. - -**/ -EFI_STATUS -EFIAPI -PeiResetSystem ( - IN CONST EFI_PEI_SERVICES **PeiServices - ); - -/** - Resets the entire platform. - - @param[in] ResetType The type of reset to perform. - @param[in] ResetStatus The status code for the reset. - @param[in] DataSize The size, in bytes, of WatchdogData. - @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown - the data buffer starts with a Null-terminated string, optionally - followed by additional binary data. The string is a description - that the caller may use to further indicate the reason for the - system reset. ResetData is only valid if ResetStatus is something - other than EFI_SUCCESS unless the ResetType is EfiResetPlatformSpecific - where a minimum amount of ResetData is always required. - -**/ -VOID -EFIAPI -PeiResetSystem2 ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ); - -/** - - Initialize PeiCore Fv List. - - - @param PrivateData - Pointer to PEI_CORE_INSTANCE. - @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF. - -**/ -VOID -PeiInitializeFv ( - IN PEI_CORE_INSTANCE *PrivateData, - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData - ); - -/** - Process Firmware Volum Information once FvInfoPPI install. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param NotifyDescriptor Address of the notification descriptor data structure. - @param Ppi Address of the PPI that was installed. - - @retval EFI_SUCCESS if the interface could be successfully installed - -**/ -EFI_STATUS -EFIAPI -FirmwareVolmeInfoPpiNotifyCallback ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ); - -/** - - Given the input VolumeHandle, search for the next matching name file. - - @param FileName File name to search. - @param VolumeHandle The current FV to search. - @param FileHandle Pointer to the file matching name in VolumeHandle. - NULL if file not found - - @retval EFI_NOT_FOUND No files matching the search criteria were found - @retval EFI_SUCCESS Success to search given file - -**/ -EFI_STATUS -EFIAPI -PeiFfsFindFileByName ( - IN CONST EFI_GUID *FileName, - IN EFI_PEI_FV_HANDLE VolumeHandle, - OUT EFI_PEI_FILE_HANDLE *FileHandle - ); - -/** - Returns information about a specific file. - - @param FileHandle Handle of the file. - @param FileInfo Upon exit, points to the file's information. - - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file. - @retval EFI_SUCCESS File information returned. - -**/ -EFI_STATUS -EFIAPI -PeiFfsGetFileInfo ( - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO *FileInfo - ); - -/** - Returns information about a specific file. - - @param FileHandle Handle of the file. - @param FileInfo Upon exit, points to the file's information. - - @retval EFI_INVALID_PARAMETER If FileInfo is NULL. - @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file. - @retval EFI_SUCCESS File information returned. - -**/ -EFI_STATUS -EFIAPI -PeiFfsGetFileInfo2 ( - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_FV_FILE_INFO2 *FileInfo - ); - -/** - Returns information about the specified volume. - - @param VolumeHandle Handle of the volume. - @param VolumeInfo Upon exit, points to the volume's information. - - @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume. - @retval EFI_INVALID_PARAMETER If VolumeInfo is NULL. - @retval EFI_SUCCESS Volume information returned. -**/ -EFI_STATUS -EFIAPI -PeiFfsGetVolumeInfo ( - IN EFI_PEI_FV_HANDLE VolumeHandle, - OUT EFI_FV_INFO *VolumeInfo - ); - -/** - This routine enable a PEIM to register itself to shadow when PEI Foundation - discovery permanent memory. - - @param FileHandle File handle of a PEIM. - - @retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself. - @retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself. - @retval EFI_SUCCESS Successfully to register itself. - -**/ -EFI_STATUS -EFIAPI -PeiRegisterForShadow ( - IN EFI_PEI_FILE_HANDLE FileHandle - ); - -/** - Initialize image service that install PeiLoadFilePpi. - - @param PrivateData Pointer to PeiCore's private data structure PEI_CORE_INSTANCE. - @param OldCoreData Pointer to Old PeiCore's private data. - If NULL, PeiCore is entered at first time, stack/heap in temporary memory. - If not NULL, PeiCore is entered at second time, stack/heap has been moved - to permanent memory. - -**/ -VOID -InitializeImageServices ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_INSTANCE *OldCoreData - ); - -/** - The wrapper function of PeiLoadImageLoadImage(). - - @param This Pointer to EFI_PEI_LOAD_FILE_PPI. - @param FileHandle Pointer to the FFS file header of the image. - @param ImageAddressArg Pointer to PE/TE image. - @param ImageSizeArg Size of PE/TE image. - @param EntryPoint Pointer to entry point of specified image file for output. - @param AuthenticationState Pointer to attestation authentication state of image. - - @return Status of PeiLoadImageLoadImage(). - -**/ -EFI_STATUS -EFIAPI -PeiLoadImageLoadImageWrapper ( - IN CONST EFI_PEI_LOAD_FILE_PPI *This, - IN EFI_PEI_FILE_HANDLE FileHandle, - OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL - OUT UINT64 *ImageSizeArg, OPTIONAL - OUT EFI_PHYSICAL_ADDRESS *EntryPoint, - OUT UINT32 *AuthenticationState - ); - -/** - - Provide a callback for when the security PPI is installed. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param NotifyDescriptor The descriptor for the notification event. - @param Ppi Pointer to the PPI in question. - - @return Always success - -**/ -EFI_STATUS -EFIAPI -SecurityPpiNotifyCallback ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ); - -/** - Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob. - - @param PrivateData PeiCore's private data structure - @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image. - @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image. - - @retval EFI_NOT_FOUND FV image can't be found. - @retval EFI_SUCCESS Successfully to process it. - @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image - @retval EFI_SECURITY_VIOLATION Image is illegal - @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section - -**/ -EFI_STATUS -ProcessFvFile ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_FV_HANDLE *ParentFvCoreHandle, - IN EFI_PEI_FILE_HANDLE ParentFvFileHandle - ); - -/** - Get instance of PEI_CORE_FV_HANDLE for next volume according to given index. - - This routine also will install FvInfo ppi for FV hob in PI ways. - - @param Private Pointer of PEI_CORE_INSTANCE - @param Instance The index of FV want to be searched. - - @return Instance of PEI_CORE_FV_HANDLE. -**/ -PEI_CORE_FV_HANDLE * -FindNextCoreFvHandle ( - IN PEI_CORE_INSTANCE *Private, - IN UINTN Instance - ); - -// -// Default EFI_PEI_CPU_IO_PPI support for EFI_PEI_SERVICES table when PeiCore initialization. -// - -/** - Memory-based read services. - - This function is to perform the Memory Access Read service based on installed - instance of the EFI_PEI_CPU_IO_PPI. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - @param Address The physical address of the access. - @param Count The number of accesses to perform. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_YET_AVAILABLE The service has not been installed. -**/ -EFI_STATUS -EFIAPI -PeiDefaultMemRead ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN EFI_PEI_CPU_IO_PPI_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - Memory-based write services. - - This function is to perform the Memory Access Write service based on installed - instance of the EFI_PEI_CPU_IO_PPI. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - @param Address The physical address of the access. - @param Count The number of accesses to perform. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_YET_AVAILABLE The service has not been installed. -**/ -EFI_STATUS -EFIAPI -PeiDefaultMemWrite ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN EFI_PEI_CPU_IO_PPI_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - IO-based read services. - - This function is to perform the IO-base read service for the EFI_PEI_CPU_IO_PPI. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - @param Address The physical address of the access. - @param Count The number of accesses to perform. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_YET_AVAILABLE The service has not been installed. -**/ -EFI_STATUS -EFIAPI -PeiDefaultIoRead ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN EFI_PEI_CPU_IO_PPI_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - IO-based write services. - - This function is to perform the IO-base write service for the EFI_PEI_CPU_IO_PPI. - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - @param Address The physical address of the access. - @param Count The number of accesses to perform. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_NOT_YET_AVAILABLE The service has not been installed. -**/ -EFI_STATUS -EFIAPI -PeiDefaultIoWrite ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN EFI_PEI_CPU_IO_PPI_WIDTH Width, - IN UINT64 Address, - IN UINTN Count, - IN OUT VOID *Buffer - ); - -/** - 8-bit I/O read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 8-bit value returned from the I/O space. -**/ -UINT8 -EFIAPI -PeiDefaultIoRead8 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ); - -/** - Reads an 16-bit I/O port. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return A 16-bit value returned from the I/O space. -**/ -UINT16 -EFIAPI -PeiDefaultIoRead16 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ); - -/** - Reads an 32-bit I/O port. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return A 32-bit value returned from the I/O space. -**/ -UINT32 -EFIAPI -PeiDefaultIoRead32 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ); - -/** - Reads an 64-bit I/O port. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return A 64-bit value returned from the I/O space. -**/ -UINT64 -EFIAPI -PeiDefaultIoRead64 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ); - -/** - 8-bit I/O write operations. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. -**/ -VOID -EFIAPI -PeiDefaultIoWrite8 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT8 Data - ); - -/** - 16-bit I/O write operations. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. -**/ -VOID -EFIAPI -PeiDefaultIoWrite16 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT16 Data - ); - -/** - 32-bit I/O write operations. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. -**/ -VOID -EFIAPI -PeiDefaultIoWrite32 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT32 Data - ); - -/** - 64-bit I/O write operations. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. -**/ -VOID -EFIAPI -PeiDefaultIoWrite64 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT64 Data - ); - -/** - 8-bit memory read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 8-bit value returned from the memory space. - -**/ -UINT8 -EFIAPI -PeiDefaultMemRead8 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ); - -/** - 16-bit memory read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 16-bit value returned from the memory space. - -**/ -UINT16 -EFIAPI -PeiDefaultMemRead16 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ); - -/** - 32-bit memory read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 32-bit value returned from the memory space. - -**/ -UINT32 -EFIAPI -PeiDefaultMemRead32 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ); - -/** - 64-bit memory read operations. - - If the EFI_PEI_CPU_IO_PPI is not installed by platform/chipset PEIM, then - return 0. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - - @return An 64-bit value returned from the memory space. - -**/ -UINT64 -EFIAPI -PeiDefaultMemRead64 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address - ); - -/** - 8-bit memory write operations. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. - -**/ -VOID -EFIAPI -PeiDefaultMemWrite8 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT8 Data - ); - -/** - 16-bit memory write operations. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. - -**/ -VOID -EFIAPI -PeiDefaultMemWrite16 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT16 Data - ); - -/** - 32-bit memory write operations. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. - -**/ -VOID -EFIAPI -PeiDefaultMemWrite32 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT32 Data - ); - -/** - 64-bit memory write operations. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Address The physical address of the access. - @param Data The data to write. - -**/ -VOID -EFIAPI -PeiDefaultMemWrite64 ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_CPU_IO_PPI *This, - IN UINT64 Address, - IN UINT64 Data - ); - -extern EFI_PEI_CPU_IO_PPI gPeiDefaultCpuIoPpi; - -// -// Default EFI_PEI_PCI_CFG2_PPI support for EFI_PEI_SERVICES table when PeiCore initialization. -// - -/** - Reads from a given location in the PCI configuration space. - - If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - See EFI_PEI_PCI_CFG_PPI_WIDTH above. - @param Address The physical address of the access. The format of - the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER The invalid access width. - @retval EFI_NOT_YET_AVAILABLE If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM. - -**/ -EFI_STATUS -EFIAPI -PeiDefaultPciCfg2Read ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PCI_CFG2_PPI *This, - IN EFI_PEI_PCI_CFG_PPI_WIDTH Width, - IN UINT64 Address, - IN OUT VOID *Buffer - ); - -/** - Write to a given location in the PCI configuration space. - - If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM, then - return EFI_NOT_YET_AVAILABLE. - - @param PeiServices An indirect pointer to the PEI Services Table published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. - See EFI_PEI_PCI_CFG_PPI_WIDTH above. - @param Address The physical address of the access. The format of - the address is described by EFI_PEI_PCI_CFG_PPI_PCI_ADDRESS. - @param Buffer A pointer to the buffer of data. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER The invalid access width. - @retval EFI_NOT_YET_AVAILABLE If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM. -**/ -EFI_STATUS -EFIAPI -PeiDefaultPciCfg2Write ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PCI_CFG2_PPI *This, - IN EFI_PEI_PCI_CFG_PPI_WIDTH Width, - IN UINT64 Address, - IN OUT VOID *Buffer - ); - -/** - This function performs a read-modify-write operation on the contents from a given - location in the PCI configuration space. - - @param PeiServices An indirect pointer to the PEI Services Table - published by the PEI Foundation. - @param This Pointer to local data for the interface. - @param Width The width of the access. Enumerated in bytes. Type - EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read(). - @param Address The physical address of the access. - @param SetBits Points to value to bitwise-OR with the read configuration value. - The size of the value is determined by Width. - @param ClearBits Points to the value to negate and bitwise-AND with the read configuration value. - The size of the value is determined by Width. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_INVALID_PARAMETER The invalid access width. - @retval EFI_NOT_YET_AVAILABLE If the EFI_PEI_PCI_CFG2_PPI is not installed by platform/chipset PEIM. -**/ -EFI_STATUS -EFIAPI -PeiDefaultPciCfg2Modify ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PCI_CFG2_PPI *This, - IN EFI_PEI_PCI_CFG_PPI_WIDTH Width, - IN UINT64 Address, - IN VOID *SetBits, - IN VOID *ClearBits - ); - -extern EFI_PEI_PCI_CFG2_PPI gPeiDefaultPciCfg2Ppi; - -/** - After PeiCore image is shadowed into permanent memory, all build-in FvPpi should - be re-installed with the instance in permanent memory and all cached FvPpi pointers in - PrivateData->Fv[] array should be fixed up to be pointed to the one in permanent - memory. - - @param PrivateData Pointer to PEI_CORE_INSTANCE. -**/ -VOID -PeiReinitializeFv ( - IN PEI_CORE_INSTANCE *PrivateData - ); - -#endif diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf deleted file mode 100644 index 39a464f326..0000000000 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ /dev/null @@ -1,134 +0,0 @@ -## @file -# PeiMain module is core module in PEI phase. -# -# It takes responsibilities of: -# 1) Initialize memory, PPI, image services etc, to establish PEIM runtime environment. -# 2) Dispatch PEIM from discovered FV. -# 3) Handoff control to DxeIpl to load DXE core and enter DXE phase. -# -# Copyright (c) 2006 - 2015, 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 -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = PeiCore - MODULE_UNI_FILE = PeiCore.uni - FILE_GUID = 52C05B14-0B98-496c-BC3B-04B50211D680 - MODULE_TYPE = PEI_CORE - VERSION_STRING = 1.0 - ENTRY_POINT = PeiCore - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC (EBC is for build only) -# - -[Sources] - StatusCode/StatusCode.c - Security/Security.c - Reset/Reset.c - Ppi/Ppi.c - PeiMain/PeiMain.c - Memory/MemoryServices.c - Image/Image.c - Hob/Hob.c - FwVol/FwVol.c - FwVol/FwVol.h - Dispatcher/Dispatcher.c - Dependency/Dependency.c - Dependency/Dependency.h - BootMode/BootMode.c - CpuIo/CpuIo.c - PciCfg2/PciCfg2.c - PeiMain.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - BaseMemoryLib - PeCoffGetEntryPointLib - ReportStatusCodeLib - PeiServicesLib - PerformanceLib - HobLib - BaseLib - PeiCoreEntryPoint - DebugLib - MemoryAllocationLib - CacheMaintenanceLib - PeCoffLib - PeiServicesTablePointerLib - PcdLib - -[Guids] - gPeiAprioriFileNameGuid ## SOMETIMES_CONSUMES ## File - ## PRODUCES ## UNDEFINED # Install ppi - ## CONSUMES ## UNDEFINED # Locate ppi - gEfiFirmwareFileSystem2Guid - ## PRODUCES ## UNDEFINED # Install ppi - ## CONSUMES ## UNDEFINED # Locate ppi - ## CONSUMES ## GUID # Used to compare with FV's file system guid and get the FV's file system format - gEfiFirmwareFileSystem3Guid - -[Ppis] - gEfiPeiStatusCodePpiGuid ## SOMETIMES_CONSUMES # PeiReportStatusService is not ready if this PPI doesn't exist - gEfiPeiResetPpiGuid ## SOMETIMES_CONSUMES # PeiResetService is not ready if this PPI doesn't exist - gEfiDxeIplPpiGuid ## CONSUMES - gEfiPeiMemoryDiscoveredPpiGuid ## PRODUCES - gEfiPeiDecompressPpiGuid ## SOMETIMES_CONSUMES - ## NOTIFY - ## SOMETIMES_PRODUCES # Produce FvInfoPpi if the encapsulated FvImage is found - gEfiPeiFirmwareVolumeInfoPpiGuid - ## NOTIFY - ## SOMETIMES_PRODUCES # Produce FvInfoPpi2 if the encapsulated FvImage is found - gEfiPeiFirmwareVolumeInfo2PpiGuid - ## PRODUCES - ## CONSUMES - gEfiPeiLoadFilePpiGuid - gEfiPeiSecurity2PpiGuid ## NOTIFY - gEfiTemporaryRamSupportPpiGuid ## SOMETIMES_CONSUMES - gEfiTemporaryRamDonePpiGuid ## SOMETIMES_CONSUMES - gEfiPeiReset2PpiGuid ## SOMETIMES_CONSUMES - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPpiSupported ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressPeiCodePageNumber ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressBootTimeCodePageNumber ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressRuntimeCodePageNumber ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnS3Boot ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot ## CONSUMES - -# [BootMode] -# S3_RESUME ## SOMETIMES_CONSUMES - -# [Hob] -# PHIT ## PRODUCES -# RESOURCE_DESCRIPTOR ## SOMETIMES_PRODUCES -# RESOURCE_DESCRIPTOR ## SOMETIMES_CONSUMES -# MEMORY_ALLOCATION ## SOMETIMES_CONSUMES -# FIRMWARE_VOLUME ## SOMETIMES_PRODUCES -# FIRMWARE_VOLUME ## SOMETIMES_CONSUMES -# MEMORY_ALLOCATION ## SOMETIMES_PRODUCES -# MEMORY_ALLOCATION ## PRODUCES # MEMORY_ALLOCATION_STACK -# UNDEFINED ## PRODUCES # MEMORY_POOL - -[UserExtensions.TianoCore."ExtraFiles"] - PeiCoreExtra.uni diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c deleted file mode 100644 index 27484bafc5..0000000000 --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c +++ /dev/null @@ -1,475 +0,0 @@ -/** @file - Pei Core Main Entry Point - -Copyright (c) 2006 - 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), - &gEfiPeiMemoryDiscoveredPpiGuid, - NULL -}; - -/// -/// Pei service instance -/// -EFI_PEI_SERVICES gPs = { - { - PEI_SERVICES_SIGNATURE, - PEI_SERVICES_REVISION, - sizeof (EFI_PEI_SERVICES), - 0, - 0 - }, - PeiInstallPpi, - PeiReInstallPpi, - PeiLocatePpi, - PeiNotifyPpi, - - PeiGetBootMode, - PeiSetBootMode, - - PeiGetHobList, - PeiCreateHob, - - PeiFfsFindNextVolume, - PeiFfsFindNextFile, - PeiFfsFindSectionData, - - PeiInstallPeiMemory, - PeiAllocatePages, - PeiAllocatePool, - (EFI_PEI_COPY_MEM)CopyMem, - (EFI_PEI_SET_MEM)SetMem, - - PeiReportStatusCode, - PeiResetSystem, - - &gPeiDefaultCpuIoPpi, - &gPeiDefaultPciCfg2Ppi, - - PeiFfsFindFileByName, - PeiFfsGetFileInfo, - PeiFfsGetVolumeInfo, - PeiRegisterForShadow, - PeiFfsFindSectionData3, - PeiFfsGetFileInfo2, - PeiResetSystem2 -}; - -/** - Shadow PeiCore module from flash to installed memory. - - @param PrivateData PeiCore's private data structure - - @return PeiCore function address after shadowing. -**/ -PEICORE_FUNCTION_POINTER -ShadowPeiCore ( - IN PEI_CORE_INSTANCE *PrivateData - ) -{ - EFI_PEI_FILE_HANDLE PeiCoreFileHandle; - EFI_PHYSICAL_ADDRESS EntryPoint; - EFI_STATUS Status; - UINT32 AuthenticationState; - - PeiCoreFileHandle = NULL; - - // - // Find the PEI Core in the BFV - // - Status = PrivateData->Fv[0].FvPpi->FindFileByType ( - PrivateData->Fv[0].FvPpi, - EFI_FV_FILETYPE_PEI_CORE, - PrivateData->Fv[0].FvHandle, - &PeiCoreFileHandle - ); - ASSERT_EFI_ERROR (Status); - - // - // Shadow PEI Core into memory so it will run faster - // - Status = PeiLoadImage ( - GetPeiServicesTablePointer (), - *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle), - PEIM_STATE_REGISITER_FOR_SHADOW, - &EntryPoint, - &AuthenticationState - ); - ASSERT_EFI_ERROR (Status); - - // - // Compute the PeiCore's function address after shaowed PeiCore. - // _ModuleEntryPoint is PeiCore main function entry - // - return (PEICORE_FUNCTION_POINTER)((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint); -} - -/** - This routine is invoked by main entry of PeiMain module during transition - from SEC to PEI. After switching stack in the PEI core, it will restart - with the old core data. - - @param SecCoreDataPtr Points to a data structure containing information about the PEI core's operating - environment, such as the size and location of temporary RAM, the stack location and - the BFV location. - @param PpiList Points to a list of one or more PPI descriptors to be installed initially by the PEI core. - An empty PPI list consists of a single descriptor with the end-tag - EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. As part of its initialization - phase, the PEI Foundation will add these SEC-hosted PPIs to its PPI database such - that both the PEI Foundation and any modules can leverage the associated service - calls and/or code in these early PPIs - @param Data Pointer to old core data that is used to initialize the - core's data areas. - If NULL, it is first PeiCore entering. - -**/ -VOID -EFIAPI -PeiCore ( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreDataPtr, - IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, - IN VOID *Data - ) -{ - PEI_CORE_INSTANCE PrivateData; - EFI_SEC_PEI_HAND_OFF *SecCoreData; - EFI_SEC_PEI_HAND_OFF NewSecCoreData; - EFI_STATUS Status; - PEI_CORE_TEMP_POINTERS TempPtr; - PEI_CORE_INSTANCE *OldCoreData; - EFI_PEI_CPU_IO_PPI *CpuIo; - EFI_PEI_PCI_CFG2_PPI *PciCfg; - EFI_HOB_HANDOFF_INFO_TABLE *HandoffInformationTable; - EFI_PEI_TEMPORARY_RAM_DONE_PPI *TemporaryRamDonePpi; - UINTN Index; - - // - // Retrieve context passed into PEI Core - // - OldCoreData = (PEI_CORE_INSTANCE *) Data; - SecCoreData = (EFI_SEC_PEI_HAND_OFF *) SecCoreDataPtr; - - // - // Perform PEI Core phase specific actions. - // - if (OldCoreData == NULL) { - // - // If OldCoreData is NULL, means current is the first entry into the PEI Core before memory is available. - // - ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE)); - PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE; - CopyMem (&PrivateData.ServiceTableShadow, &gPs, sizeof (gPs)); - } else { - // - // Memory is available to the PEI Core. See if the PEI Core has been shadowed to memory yet. - // - if (OldCoreData->ShadowedPeiCore == NULL) { - // - // Fixup the PeiCore's private data - // - OldCoreData->Ps = &OldCoreData->ServiceTableShadow; - OldCoreData->CpuIo = &OldCoreData->ServiceTableShadow.CpuIo; - if (OldCoreData->HeapOffsetPositive) { - OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw + OldCoreData->HeapOffset); - OldCoreData->UnknownFvInfo = (PEI_CORE_UNKNOW_FORMAT_FV_INFO *) ((UINT8 *) OldCoreData->UnknownFvInfo + OldCoreData->HeapOffset); - OldCoreData->CurrentFvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->CurrentFvFileHandles + OldCoreData->HeapOffset); - OldCoreData->PpiData.PpiListPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.PpiListPtrs + OldCoreData->HeapOffset); - OldCoreData->Fv = (PEI_CORE_FV_HANDLE *) ((UINT8 *) OldCoreData->Fv + OldCoreData->HeapOffset); - for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) { - OldCoreData->Fv[Index].PeimState = (UINT8 *) OldCoreData->Fv[Index].PeimState + OldCoreData->HeapOffset; - OldCoreData->Fv[Index].FvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->Fv[Index].FvFileHandles + OldCoreData->HeapOffset); - } - OldCoreData->FileGuid = (EFI_GUID *) ((UINT8 *) OldCoreData->FileGuid + OldCoreData->HeapOffset); - OldCoreData->FileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->FileHandles + OldCoreData->HeapOffset); - } else { - OldCoreData->HobList.Raw = (VOID *)(OldCoreData->HobList.Raw - OldCoreData->HeapOffset); - OldCoreData->UnknownFvInfo = (PEI_CORE_UNKNOW_FORMAT_FV_INFO *) ((UINT8 *) OldCoreData->UnknownFvInfo - OldCoreData->HeapOffset); - OldCoreData->CurrentFvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->CurrentFvFileHandles - OldCoreData->HeapOffset); - OldCoreData->PpiData.PpiListPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.PpiListPtrs - OldCoreData->HeapOffset); - OldCoreData->Fv = (PEI_CORE_FV_HANDLE *) ((UINT8 *) OldCoreData->Fv - OldCoreData->HeapOffset); - for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) { - OldCoreData->Fv[Index].PeimState = (UINT8 *) OldCoreData->Fv[Index].PeimState - OldCoreData->HeapOffset; - OldCoreData->Fv[Index].FvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->Fv[Index].FvFileHandles - OldCoreData->HeapOffset); - } - OldCoreData->FileGuid = (EFI_GUID *) ((UINT8 *) OldCoreData->FileGuid - OldCoreData->HeapOffset); - OldCoreData->FileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->FileHandles - OldCoreData->HeapOffset); - } - - // - // Fixup for PeiService's address - // - SetPeiServicesTablePointer ((CONST EFI_PEI_SERVICES **)&OldCoreData->Ps); - - // - // Initialize libraries that the PEI Core is linked against - // - ProcessLibraryConstructorList (NULL, (CONST EFI_PEI_SERVICES **)&OldCoreData->Ps); - - // - // Update HandOffHob for new installed permanent memory - // - HandoffInformationTable = OldCoreData->HobList.HandoffInformationTable; - if (OldCoreData->HeapOffsetPositive) { - HandoffInformationTable->EfiEndOfHobList = HandoffInformationTable->EfiEndOfHobList + OldCoreData->HeapOffset; - } else { - HandoffInformationTable->EfiEndOfHobList = HandoffInformationTable->EfiEndOfHobList - OldCoreData->HeapOffset; - } - HandoffInformationTable->EfiMemoryTop = OldCoreData->PhysicalMemoryBegin + OldCoreData->PhysicalMemoryLength; - HandoffInformationTable->EfiMemoryBottom = OldCoreData->PhysicalMemoryBegin; - HandoffInformationTable->EfiFreeMemoryTop = OldCoreData->FreePhysicalMemoryTop; - HandoffInformationTable->EfiFreeMemoryBottom = HandoffInformationTable->EfiEndOfHobList + sizeof (EFI_HOB_GENERIC_HEADER); - - // - // We need convert the PPI descriptor's pointer - // - ConvertPpiPointers (SecCoreData, OldCoreData); - - // - // After the whole temporary memory is migrated, then we can allocate page in - // permanent memory. - // - OldCoreData->PeiMemoryInstalled = TRUE; - - // - // Indicate that PeiCore reenter - // - OldCoreData->PeimDispatcherReenter = TRUE; - - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0 && (OldCoreData->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) { - // - // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array. - // Every bit in the array indicate the status of the corresponding memory page available or not - // - OldCoreData->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32(PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof(UINT64)); - } - - // - // Shadow PEI Core. When permanent memory is avaiable, shadow - // PEI Core and PEIMs to get high performance. - // - OldCoreData->ShadowedPeiCore = (PEICORE_FUNCTION_POINTER) (UINTN) PeiCore; - if ((HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME && PcdGetBool (PcdShadowPeimOnS3Boot)) - || (HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME && PcdGetBool (PcdShadowPeimOnBoot))) { - OldCoreData->ShadowedPeiCore = ShadowPeiCore (OldCoreData); - } - - // - // PEI Core has now been shadowed to memory. Restart PEI Core in memory. - // - OldCoreData->ShadowedPeiCore (SecCoreData, PpiList, OldCoreData); - - // - // Should never reach here. - // - ASSERT (FALSE); - CpuDeadLoop(); - - UNREACHABLE (); - } - - // - // Memory is available to the PEI Core and the PEI Core has been shadowed to memory. - // - CopyMem (&NewSecCoreData, SecCoreDataPtr, sizeof (NewSecCoreData)); - SecCoreData = &NewSecCoreData; - - CopyMem (&PrivateData, OldCoreData, sizeof (PrivateData)); - - CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo; - PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg; - - CopyMem (&PrivateData.ServiceTableShadow, &gPs, sizeof (gPs)); - - PrivateData.ServiceTableShadow.CpuIo = CpuIo; - PrivateData.ServiceTableShadow.PciCfg = PciCfg; - } - - // - // Cache a pointer to the PEI Services Table that is either in temporary memory or permanent memory - // - PrivateData.Ps = &PrivateData.ServiceTableShadow; - - // - // Save PeiServicePointer so that it can be retrieved anywhere. - // - SetPeiServicesTablePointer ((CONST EFI_PEI_SERVICES **)&PrivateData.Ps); - - // - // Initialize libraries that the PEI Core is linked against - // - ProcessLibraryConstructorList (NULL, (CONST EFI_PEI_SERVICES **)&PrivateData.Ps); - - // - // Initialize PEI Core Services - // - InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData); - if (OldCoreData == NULL) { - // - // Initialize PEI Core Private Data Buffer - // - PrivateData.PpiData.PpiListPtrs = AllocateZeroPool (sizeof (PEI_PPI_LIST_POINTERS) * PcdGet32 (PcdPeiCoreMaxPpiSupported)); - ASSERT (PrivateData.PpiData.PpiListPtrs != NULL); - PrivateData.Fv = AllocateZeroPool (sizeof (PEI_CORE_FV_HANDLE) * PcdGet32 (PcdPeiCoreMaxFvSupported)); - ASSERT (PrivateData.Fv != NULL); - PrivateData.Fv[0].PeimState = AllocateZeroPool (sizeof (UINT8) * PcdGet32 (PcdPeiCoreMaxPeimPerFv) * PcdGet32 (PcdPeiCoreMaxFvSupported)); - ASSERT (PrivateData.Fv[0].PeimState != NULL); - PrivateData.Fv[0].FvFileHandles = AllocateZeroPool (sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv) * PcdGet32 (PcdPeiCoreMaxFvSupported)); - ASSERT (PrivateData.Fv[0].FvFileHandles != NULL); - for (Index = 1; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) { - PrivateData.Fv[Index].PeimState = PrivateData.Fv[Index - 1].PeimState + PcdGet32 (PcdPeiCoreMaxPeimPerFv); - PrivateData.Fv[Index].FvFileHandles = PrivateData.Fv[Index - 1].FvFileHandles + PcdGet32 (PcdPeiCoreMaxPeimPerFv); - } - PrivateData.UnknownFvInfo = AllocateZeroPool (sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO) * PcdGet32 (PcdPeiCoreMaxFvSupported)); - ASSERT (PrivateData.UnknownFvInfo != NULL); - PrivateData.CurrentFvFileHandles = AllocateZeroPool (sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv)); - ASSERT (PrivateData.CurrentFvFileHandles != NULL); - PrivateData.FileGuid = AllocatePool (sizeof (EFI_GUID) * PcdGet32 (PcdPeiCoreMaxPeimPerFv)); - ASSERT (PrivateData.FileGuid != NULL); - PrivateData.FileHandles = AllocatePool (sizeof (EFI_PEI_FILE_HANDLE) * (PcdGet32 (PcdPeiCoreMaxPeimPerFv) + 1)); - ASSERT (PrivateData.FileHandles != NULL); - } - InitializePpiServices (&PrivateData, OldCoreData); - - // - // Update performance measurements - // - if (OldCoreData == NULL) { - PERF_START (NULL, "SEC", NULL, 1); - PERF_END (NULL, "SEC", NULL, 0); - - // - // If first pass, start performance measurement. - // - PERF_START (NULL,"PEI", NULL, 0); - PERF_START (NULL,"PreMem", NULL, 0); - - } else { - PERF_END (NULL,"PreMem", NULL, 0); - PERF_START (NULL,"PostMem", NULL, 0); - } - - // - // Complete PEI Core Service initialization - // - InitializeSecurityServices (&PrivateData.Ps, OldCoreData); - InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData); - InitializeImageServices (&PrivateData, OldCoreData); - - // - // Perform PEI Core Phase specific actions - // - if (OldCoreData == NULL) { - // - // Report Status Code EFI_SW_PC_INIT - // - REPORT_STATUS_CODE ( - EFI_PROGRESS_CODE, - (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT) - ); - - // - // If SEC provided any PPI services to PEI, install them. - // - if (PpiList != NULL) { - Status = PeiServicesInstallPpi (PpiList); - ASSERT_EFI_ERROR (Status); - } - } else { - // - // Try to locate Temporary RAM Done Ppi. - // - Status = PeiServicesLocatePpi ( - &gEfiTemporaryRamDonePpiGuid, - 0, - NULL, - (VOID**)&TemporaryRamDonePpi - ); - if (!EFI_ERROR (Status)) { - // - // Disable the use of Temporary RAM after the transition from Temporary RAM to Permanent RAM is complete. - // - TemporaryRamDonePpi->TemporaryRamDone (); - } - - // - // Alert any listeners that there is permanent memory available - // - PERF_START (NULL,"DisMem", NULL, 0); - Status = PeiServicesInstallPpi (&mMemoryDiscoveredPpi); - - // - // Process the Notify list and dispatch any notifies for the Memory Discovered PPI - // - ProcessNotifyList (&PrivateData); - - PERF_END (NULL,"DisMem", NULL, 0); - } - - // - // Call PEIM dispatcher - // - PeiDispatcher (SecCoreData, &PrivateData); - - if (PrivateData.HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) { - // - // Check if InstallPeiMemory service was called on non-S3 resume boot path. - // - ASSERT(PrivateData.PeiMemoryInstalled == TRUE); - } - - // - // Measure PEI Core execution time. - // - PERF_END (NULL, "PostMem", NULL, 0); - - // - // Lookup DXE IPL PPI - // - Status = PeiServicesLocatePpi ( - &gEfiDxeIplPpiGuid, - 0, - NULL, - (VOID **)&TempPtr.DxeIpl - ); - ASSERT_EFI_ERROR (Status); - - if (EFI_ERROR (Status)) { - // - // Report status code to indicate DXE IPL PPI could not be found. - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MAJOR, - (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_DXEIPL_NOT_FOUND) - ); - CpuDeadLoop (); - } - - // - // Enter DxeIpl to load Dxe core. - // - DEBUG ((EFI_D_INFO, "DXE IPL Entry\n")); - Status = TempPtr.DxeIpl->Entry ( - TempPtr.DxeIpl, - &PrivateData.Ps, - PrivateData.HobList - ); - // - // Should never reach here. - // - ASSERT_EFI_ERROR (Status); - CpuDeadLoop(); - - UNREACHABLE (); -} diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c deleted file mode 100644 index db6eded6d6..0000000000 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ /dev/null @@ -1,646 +0,0 @@ -/** @file - EFI PEI Core PPI services - -Copyright (c) 2006 - 2014, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/** - - Initialize PPI services. - - @param PrivateData Pointer to the PEI Core data. - @param OldCoreData Pointer to old PEI Core data. - NULL if being run in non-permament memory mode. - -**/ -VOID -InitializePpiServices ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_INSTANCE *OldCoreData - ) -{ - if (OldCoreData == NULL) { - PrivateData->PpiData.NotifyListEnd = PcdGet32 (PcdPeiCoreMaxPpiSupported)-1; - PrivateData->PpiData.DispatchListEnd = PcdGet32 (PcdPeiCoreMaxPpiSupported)-1; - PrivateData->PpiData.LastDispatchedNotify = PcdGet32 (PcdPeiCoreMaxPpiSupported)-1; - } -} - -/** - - Migrate Single PPI Pointer from the temporary memory to PEI installed memory. - - @param PpiPointer Pointer to Ppi - @param TempBottom Base of old temporary memory - @param TempTop Top of old temporary memory - @param Offset Offset of new memory to old temporary memory. - @param OffsetPositive Positive flag of Offset value. - -**/ -VOID -ConvertSinglePpiPointer ( - IN PEI_PPI_LIST_POINTERS *PpiPointer, - IN UINTN TempBottom, - IN UINTN TempTop, - IN UINTN Offset, - IN BOOLEAN OffsetPositive - ) -{ - if (((UINTN)PpiPointer->Raw < TempTop) && - ((UINTN)PpiPointer->Raw >= TempBottom)) { - // - // Convert the pointer to the PPI descriptor from the old TempRam - // to the relocated physical memory. - // - if (OffsetPositive) { - PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Offset); - } else { - PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw - Offset); - } - - // - // Only when the PEIM descriptor is in the old TempRam should it be necessary - // to try to convert the pointers in the PEIM descriptor - // - - if (((UINTN)PpiPointer->Ppi->Guid < TempTop) && - ((UINTN)PpiPointer->Ppi->Guid >= TempBottom)) { - // - // Convert the pointer to the GUID in the PPI or NOTIFY descriptor - // from the old TempRam to the relocated physical memory. - // - if (OffsetPositive) { - PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Offset); - } else { - PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid - Offset); - } - } - - // - // Convert the pointer to the PPI interface structure in the PPI descriptor - // from the old TempRam to the relocated physical memory. - // - if ((UINTN)PpiPointer->Ppi->Ppi < TempTop && - (UINTN)PpiPointer->Ppi->Ppi >= TempBottom) { - if (OffsetPositive) { - PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi + Offset); - } else { - PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi - Offset); - } - } - } -} - -/** - - Migrate PPI Pointers from the temporary memory stack to PEI installed memory. - - @param SecCoreData Points to a data structure containing SEC to PEI handoff data, such as the size - and location of temporary RAM, the stack location and the BFV location. - @param PrivateData Pointer to PeiCore's private data structure. - -**/ -VOID -ConvertPpiPointers ( - IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, - IN PEI_CORE_INSTANCE *PrivateData - ) -{ - UINT8 Index; - UINT8 IndexHole; - - for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxPpiSupported); Index++) { - if (Index < PrivateData->PpiData.PpiListEnd || Index > PrivateData->PpiData.NotifyListEnd) { - // - // Convert PPI pointer in old Heap - // - ConvertSinglePpiPointer ( - &PrivateData->PpiData.PpiListPtrs[Index], - (UINTN)SecCoreData->PeiTemporaryRamBase, - (UINTN)SecCoreData->PeiTemporaryRamBase + SecCoreData->PeiTemporaryRamSize, - PrivateData->HeapOffset, - PrivateData->HeapOffsetPositive - ); - - // - // Convert PPI pointer in old Stack - // - ConvertSinglePpiPointer ( - &PrivateData->PpiData.PpiListPtrs[Index], - (UINTN)SecCoreData->StackBase, - (UINTN)SecCoreData->StackBase + SecCoreData->StackSize, - PrivateData->StackOffset, - PrivateData->StackOffsetPositive - ); - - // - // Convert PPI pointer in old TempRam Hole - // - for (IndexHole = 0; IndexHole < HOLE_MAX_NUMBER; IndexHole ++) { - if (PrivateData->HoleData[IndexHole].Size == 0) { - continue; - } - - ConvertSinglePpiPointer ( - &PrivateData->PpiData.PpiListPtrs[Index], - (UINTN)PrivateData->HoleData[IndexHole].Base, - (UINTN)PrivateData->HoleData[IndexHole].Base + PrivateData->HoleData[IndexHole].Size, - PrivateData->HoleData[IndexHole].Offset, - PrivateData->HoleData[IndexHole].OffsetPositive - ); - } - } - } -} - -/** - - This function installs an interface in the PEI PPI database by GUID. - The purpose of the service is to publish an interface that other parties - can use to call additional PEIMs. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param PpiList Pointer to a list of PEI PPI Descriptors. - - @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed. - @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer - if any PPI in PpiList is not valid - @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI - -**/ -EFI_STATUS -EFIAPI -PeiInstallPpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList - ) -{ - PEI_CORE_INSTANCE *PrivateData; - INTN Index; - INTN LastCallbackInstall; - - - if (PpiList == NULL) { - return EFI_INVALID_PARAMETER; - } - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - - Index = PrivateData->PpiData.PpiListEnd; - LastCallbackInstall = Index; - - // - // This is loop installs all PPI descriptors in the PpiList. It is terminated - // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last - // EFI_PEI_PPI_DESCRIPTOR in the list. - // - - for (;;) { - // - // Since PpiData is used for NotifyList and PpiList, max resource - // is reached if the Install reaches the NotifyList - // PcdPeiCoreMaxPpiSupported can be set to a larger value in DSC to satisfy more PPI requirement. - // - if (Index == PrivateData->PpiData.NotifyListEnd + 1) { - return EFI_OUT_OF_RESOURCES; - } - // - // Check if it is a valid PPI. - // If not, rollback list to exclude all in this list. - // Try to indicate which item failed. - // - if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) { - PrivateData->PpiData.PpiListEnd = LastCallbackInstall; - DEBUG((EFI_D_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, PpiList->Ppi)); - return EFI_INVALID_PARAMETER; - } - - DEBUG((EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid)); - PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*) PpiList; - PrivateData->PpiData.PpiListEnd++; - - // - // Continue until the end of the PPI List. - // - if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == - EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) { - break; - } - PpiList++; - Index++; - } - - // - // Dispatch any callback level notifies for newly installed PPIs. - // - DispatchNotify ( - PrivateData, - EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, - LastCallbackInstall, - PrivateData->PpiData.PpiListEnd, - PrivateData->PpiData.DispatchListEnd, - PrivateData->PpiData.NotifyListEnd - ); - - - return EFI_SUCCESS; -} - -/** - - This function reinstalls an interface in the PEI PPI database by GUID. - The purpose of the service is to publish an interface that other parties can - use to replace an interface of the same name in the protocol database with a - different interface. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param OldPpi Pointer to the old PEI PPI Descriptors. - @param NewPpi Pointer to the new PEI PPI Descriptors. - - @retval EFI_SUCCESS if the operation was successful - @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL - @retval EFI_INVALID_PARAMETER if NewPpi is not valid - @retval EFI_NOT_FOUND if the PPI was not in the database - -**/ -EFI_STATUS -EFIAPI -PeiReInstallPpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, - IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi - ) -{ - PEI_CORE_INSTANCE *PrivateData; - INTN Index; - - - if ((OldPpi == NULL) || (NewPpi == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) { - return EFI_INVALID_PARAMETER; - } - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - - // - // Find the old PPI instance in the database. If we can not find it, - // return the EFI_NOT_FOUND error. - // - for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) { - if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) { - break; - } - } - if (Index == PrivateData->PpiData.PpiListEnd) { - return EFI_NOT_FOUND; - } - - // - // Remove the old PPI from the database, add the new one. - // - DEBUG((EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid)); - ASSERT (Index < (INTN)(PcdGet32 (PcdPeiCoreMaxPpiSupported))); - PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *) NewPpi; - - // - // Dispatch any callback level notifies for the newly installed PPI. - // - DispatchNotify ( - PrivateData, - EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, - Index, - Index+1, - PrivateData->PpiData.DispatchListEnd, - PrivateData->PpiData.NotifyListEnd - ); - - - return EFI_SUCCESS; -} - -/** - - Locate a given named PPI. - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param Guid Pointer to GUID of the PPI. - @param Instance Instance Number to discover. - @param PpiDescriptor Pointer to reference the found descriptor. If not NULL, - returns a pointer to the descriptor (includes flags, etc) - @param Ppi Pointer to reference the found PPI - - @retval EFI_SUCCESS if the PPI is in the database - @retval EFI_NOT_FOUND if the PPI is not in the database - -**/ -EFI_STATUS -EFIAPI -PeiLocatePpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_GUID *Guid, - IN UINTN Instance, - IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, - IN OUT VOID **Ppi - ) -{ - PEI_CORE_INSTANCE *PrivateData; - INTN Index; - EFI_GUID *CheckGuid; - EFI_PEI_PPI_DESCRIPTOR *TempPtr; - - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - - // - // Search the data base for the matching instance of the GUIDed PPI. - // - for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) { - TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi; - CheckGuid = TempPtr->Guid; - - // - // Don't use CompareGuid function here for performance reasons. - // Instead we compare the GUID as INT32 at a time and branch - // on the first failed comparison. - // - if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) && - (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) && - (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) && - (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) { - if (Instance == 0) { - - if (PpiDescriptor != NULL) { - *PpiDescriptor = TempPtr; - } - - if (Ppi != NULL) { - *Ppi = TempPtr->Ppi; - } - - - return EFI_SUCCESS; - } - Instance--; - } - } - - return EFI_NOT_FOUND; -} - -/** - - This function installs a notification service to be called back when a given - interface is installed or reinstalled. The purpose of the service is to publish - an interface that other parties can use to call additional PPIs that may materialize later. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param NotifyList Pointer to list of Descriptors to notify upon. - - @retval EFI_SUCCESS if successful - @retval EFI_OUT_OF_RESOURCES if no space in the database - @retval EFI_INVALID_PARAMETER if not a good decriptor - -**/ -EFI_STATUS -EFIAPI -PeiNotifyPpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList - ) -{ - PEI_CORE_INSTANCE *PrivateData; - INTN Index; - INTN NotifyIndex; - INTN LastCallbackNotify; - EFI_PEI_NOTIFY_DESCRIPTOR *NotifyPtr; - UINTN NotifyDispatchCount; - - - NotifyDispatchCount = 0; - - if (NotifyList == NULL) { - return EFI_INVALID_PARAMETER; - } - - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - - Index = PrivateData->PpiData.NotifyListEnd; - LastCallbackNotify = Index; - - // - // This is loop installs all Notify descriptors in the NotifyList. It is - // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last - // EFI_PEI_NOTIFY_DESCRIPTOR in the list. - // - - for (;;) { - // - // Since PpiData is used for NotifyList and InstallList, max resource - // is reached if the Install reaches the PpiList - // PcdPeiCoreMaxPpiSupported can be set to a larger value in DSC to satisfy more Notify PPIs requirement. - // - if (Index == PrivateData->PpiData.PpiListEnd - 1) { - return EFI_OUT_OF_RESOURCES; - } - - // - // If some of the PPI data is invalid restore original Notify PPI database value - // - if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) { - PrivateData->PpiData.NotifyListEnd = LastCallbackNotify; - DEBUG((EFI_D_ERROR, "ERROR -> InstallNotify: %g %p\n", NotifyList->Guid, NotifyList->Notify)); - return EFI_INVALID_PARAMETER; - } - - if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) { - NotifyDispatchCount ++; - } - - PrivateData->PpiData.PpiListPtrs[Index].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *) NotifyList; - - PrivateData->PpiData.NotifyListEnd--; - DEBUG((EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid)); - if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == - EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) { - break; - } - // - // Go the next descriptor. Remember the NotifyList moves down. - // - NotifyList++; - Index--; - } - - // - // If there is Dispatch Notify PPI installed put them on the bottom - // - if (NotifyDispatchCount > 0) { - for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) { - if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) { - NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify; - - for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){ - PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify; - } - PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr; - PrivateData->PpiData.DispatchListEnd--; - } - } - - LastCallbackNotify -= NotifyDispatchCount; - } - - // - // Dispatch any callback level notifies for all previously installed PPIs. - // - DispatchNotify ( - PrivateData, - EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, - 0, - PrivateData->PpiData.PpiListEnd, - LastCallbackNotify, - PrivateData->PpiData.NotifyListEnd - ); - - return EFI_SUCCESS; -} - - -/** - - Process the Notify List at dispatch level. - - @param PrivateData PeiCore's private data structure. - -**/ -VOID -ProcessNotifyList ( - IN PEI_CORE_INSTANCE *PrivateData - ) -{ - INTN TempValue; - - while (TRUE) { - // - // Check if the PEIM that was just dispatched resulted in any - // Notifies getting installed. If so, go process any dispatch - // level Notifies that match the previouly installed PPIs. - // Use "while" instead of "if" since DispatchNotify can modify - // DispatchListEnd (with NotifyPpi) so we have to iterate until the same. - // - while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) { - TempValue = PrivateData->PpiData.DispatchListEnd; - DispatchNotify ( - PrivateData, - EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH, - 0, - PrivateData->PpiData.LastDispatchedInstall, - PrivateData->PpiData.LastDispatchedNotify, - PrivateData->PpiData.DispatchListEnd - ); - PrivateData->PpiData.LastDispatchedNotify = TempValue; - } - - - // - // Check if the PEIM that was just dispatched resulted in any - // PPIs getting installed. If so, go process any dispatch - // level Notifies that match the installed PPIs. - // Use "while" instead of "if" since DispatchNotify can modify - // PpiListEnd (with InstallPpi) so we have to iterate until the same. - // - while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) { - TempValue = PrivateData->PpiData.PpiListEnd; - DispatchNotify ( - PrivateData, - EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH, - PrivateData->PpiData.LastDispatchedInstall, - PrivateData->PpiData.PpiListEnd, - PcdGet32 (PcdPeiCoreMaxPpiSupported)-1, - PrivateData->PpiData.DispatchListEnd - ); - PrivateData->PpiData.LastDispatchedInstall = TempValue; - } - - if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) { - break; - } - } - return; -} - -/** - - Dispatch notifications. - - @param PrivateData PeiCore's private data structure - @param NotifyType Type of notify to fire. - @param InstallStartIndex Install Beginning index. - @param InstallStopIndex Install Ending index. - @param NotifyStartIndex Notify Beginning index. - @param NotifyStopIndex Notify Ending index. - -**/ -VOID -DispatchNotify ( - IN PEI_CORE_INSTANCE *PrivateData, - IN UINTN NotifyType, - IN INTN InstallStartIndex, - IN INTN InstallStopIndex, - IN INTN NotifyStartIndex, - IN INTN NotifyStopIndex - ) -{ - INTN Index1; - INTN Index2; - EFI_GUID *SearchGuid; - EFI_GUID *CheckGuid; - EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor; - - // - // Remember that Installs moves up and Notifies moves down. - // - for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) { - NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify; - - CheckGuid = NotifyDescriptor->Guid; - - for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) { - SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid; - // - // Don't use CompareGuid function here for performance reasons. - // Instead we compare the GUID as INT32 at a time and branch - // on the first failed comparison. - // - if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) && - (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) && - (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) && - (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) { - DEBUG ((EFI_D_INFO, "Notify: PPI Guid: %g, Peim notify entry point: %p\n", - SearchGuid, - NotifyDescriptor->Notify - )); - NotifyDescriptor->Notify ( - (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (), - NotifyDescriptor, - (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi - ); - } - } - } -} - diff --git a/MdeModulePkg/Core/Pei/Reset/Reset.c b/MdeModulePkg/Core/Pei/Reset/Reset.c deleted file mode 100644 index 2e9ac8215b..0000000000 --- a/MdeModulePkg/Core/Pei/Reset/Reset.c +++ /dev/null @@ -1,108 +0,0 @@ -/** @file - Pei Core Reset System Support - -Copyright (c) 2006, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/** - - Core version of the Reset System - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - - @retval EFI_NOT_AVAILABLE_YET PPI not available yet. - @retval EFI_DEVICE_ERROR Did not reset system. - Otherwise, resets the system. - -**/ -EFI_STATUS -EFIAPI -PeiResetSystem ( - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - EFI_STATUS Status; - EFI_PEI_RESET_PPI *ResetPpi; - - Status = PeiServicesLocatePpi ( - &gEfiPeiResetPpiGuid, - 0, - NULL, - (VOID **)&ResetPpi - ); - - // - // LocatePpi returns EFI_NOT_FOUND on error - // - if (!EFI_ERROR (Status)) { - return ResetPpi->ResetSystem (PeiServices); - } - // - // Report Status Code that Reset PPI is not available - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_SOFTWARE_PEI_CORE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE) - ); - return EFI_NOT_AVAILABLE_YET; -} - -/** - Resets the entire platform. - - @param[in] ResetType The type of reset to perform. - @param[in] ResetStatus The status code for the reset. - @param[in] DataSize The size, in bytes, of WatchdogData. - @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown - the data buffer starts with a Null-terminated string, optionally - followed by additional binary data. The string is a description - that the caller may use to further indicate the reason for the - system reset. ResetData is only valid if ResetStatus is something - other than EFI_SUCCESS unless the ResetType is EfiResetPlatformSpecific - where a minimum amount of ResetData is always required. - -**/ -VOID -EFIAPI -PeiResetSystem2 ( - IN EFI_RESET_TYPE ResetType, - IN EFI_STATUS ResetStatus, - IN UINTN DataSize, - IN VOID *ResetData OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_PEI_RESET2_PPI *Reset2Ppi; - - Status = PeiServicesLocatePpi ( - &gEfiPeiReset2PpiGuid, - 0, - NULL, - (VOID **)&Reset2Ppi - ); - - if (!EFI_ERROR (Status)) { - Reset2Ppi->ResetSystem (ResetType, ResetStatus, DataSize, ResetData); - return; - } - - // - // Report Status Code that Reset2 PPI is not available. - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_SOFTWARE_PEI_CORE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE) - ); -} - diff --git a/MdeModulePkg/Core/Pei/Security/Security.c b/MdeModulePkg/Core/Pei/Security/Security.c deleted file mode 100644 index 763126057d..0000000000 --- a/MdeModulePkg/Core/Pei/Security/Security.c +++ /dev/null @@ -1,151 +0,0 @@ -/** @file - EFI PEI Core Security services - -Copyright (c) 2006 - 2014, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - - -EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = { - EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, - &gEfiPeiSecurity2PpiGuid, - SecurityPpiNotifyCallback -}; - -/** - Initialize the security services. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param OldCoreData Pointer to the old core data. - NULL if being run in non-permament memory mode. - -**/ -VOID -InitializeSecurityServices ( - IN EFI_PEI_SERVICES **PeiServices, - IN PEI_CORE_INSTANCE *OldCoreData - ) -{ - if (OldCoreData == NULL) { - PeiServicesNotifyPpi (&mNotifyList); - } - return; -} - -/** - - Provide a callback for when the security PPI is installed. - This routine will cache installed security PPI into PeiCore's private data. - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param NotifyDescriptor The descriptor for the notification event. - @param Ppi Pointer to the PPI in question. - - @return Always success - -**/ -EFI_STATUS -EFIAPI -SecurityPpiNotifyCallback ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, - IN VOID *Ppi - ) -{ - PEI_CORE_INSTANCE *PrivateData; - - // - // Get PEI Core private data - // - PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); - - // - // If there isn't a security PPI installed, use the one from notification - // - if (PrivateData->PrivateSecurityPpi == NULL) { - PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY2_PPI *)Ppi; - } - return EFI_SUCCESS; -} - -/** - Provide a callout to the security verification service. - - @param PrivateData PeiCore's private data structure - @param VolumeHandle Handle of FV - @param FileHandle Handle of PEIM's ffs - @param AuthenticationStatus Authentication status - - @retval EFI_SUCCESS Image is OK - @retval EFI_SECURITY_VIOLATION Image is illegal - @retval EFI_NOT_FOUND If security PPI is not installed. -**/ -EFI_STATUS -VerifyPeim ( - IN PEI_CORE_INSTANCE *PrivateData, - IN EFI_PEI_FV_HANDLE VolumeHandle, - IN EFI_PEI_FILE_HANDLE FileHandle, - IN UINT32 AuthenticationStatus - ) -{ - EFI_STATUS Status; - BOOLEAN DeferExection; - - Status = EFI_NOT_FOUND; - if (PrivateData->PrivateSecurityPpi == NULL) { - // - // Check AuthenticationStatus first. - // - if ((AuthenticationStatus & EFI_AUTH_STATUS_IMAGE_SIGNED) != 0) { - if ((AuthenticationStatus & (EFI_AUTH_STATUS_TEST_FAILED | EFI_AUTH_STATUS_NOT_TESTED)) != 0) { - Status = EFI_SECURITY_VIOLATION; - } - } - } else { - // - // Check to see if the image is OK - // - Status = PrivateData->PrivateSecurityPpi->AuthenticationState ( - (CONST EFI_PEI_SERVICES **) &PrivateData->Ps, - PrivateData->PrivateSecurityPpi, - AuthenticationStatus, - VolumeHandle, - FileHandle, - &DeferExection - ); - if (DeferExection) { - Status = EFI_SECURITY_VIOLATION; - } - } - return Status; -} - - -/** - Verify a Firmware volume. - - @param CurrentFvAddress Pointer to the current Firmware Volume under consideration - - @retval EFI_SUCCESS Firmware Volume is legal - -**/ -EFI_STATUS -VerifyFv ( - IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress - ) -{ - // - // Right now just pass the test. Future can authenticate and/or check the - // FV-header or other metric for goodness of binary. - // - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/Pei/StatusCode/StatusCode.c b/MdeModulePkg/Core/Pei/StatusCode/StatusCode.c deleted file mode 100644 index a7fb524ff4..0000000000 --- a/MdeModulePkg/Core/Pei/StatusCode/StatusCode.c +++ /dev/null @@ -1,74 +0,0 @@ -/** @file - Pei Core Status Code Support - -Copyright (c) 2006, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PeiMain.h" - -/** - - Core version of the Status Code reporter - - - @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. - @param CodeType Type of Status Code. - @param Value Value to output for Status Code. - @param Instance Instance Number of this status code. - @param CallerId ID of the caller of this status code. - @param Data Optional data associated with this status code. - - @retval EFI_SUCCESS if status code is successfully reported - @retval EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed - -**/ -EFI_STATUS -EFIAPI -PeiReportStatusCode ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_STATUS_CODE_TYPE CodeType, - IN EFI_STATUS_CODE_VALUE Value, - IN UINT32 Instance, - IN CONST EFI_GUID *CallerId, - IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_PEI_PROGRESS_CODE_PPI *StatusCodePpi; - - // - // Locate StatusCode Ppi. - // - Status = PeiServicesLocatePpi ( - &gEfiPeiStatusCodePpiGuid, - 0, - NULL, - (VOID **)&StatusCodePpi - ); - - if (!EFI_ERROR (Status)) { - Status = StatusCodePpi->ReportStatusCode ( - PeiServices, - CodeType, - Value, - Instance, - CallerId, - Data - ); - - return Status; - } - - return EFI_NOT_AVAILABLE_YET; -} - - - diff --git a/MdeModulePkg/Core/PiSmmCore/Dependency.c b/MdeModulePkg/Core/PiSmmCore/Dependency.c deleted file mode 100644 index deaf4b445e..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/Dependency.c +++ /dev/null @@ -1,388 +0,0 @@ -/** @file - SMM Driver Dispatcher Dependency Evaluator - - This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine - if a driver can be scheduled for execution. The criteria for - schedulability is that the dependency expression is satisfied. - - Copyright (c) 2009 - 2010, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -/// -/// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependency expression -/// to save time. A EFI_DEP_PUSH is evaluated one an -/// replaced with EFI_DEP_REPLACE_TRUE. If PI spec's Vol 2 -/// Driver Execution Environment Core Interface use 0xff -/// as new DEPEX opcode. EFI_DEP_REPLACE_TRUE should be -/// defined to a new value that is not conflicting with PI spec. -/// -#define EFI_DEP_REPLACE_TRUE 0xff - -/// -/// Define the initial size of the dependency expression evaluation stack -/// -#define DEPEX_STACK_SIZE_INCREMENT 0x1000 - -// -// Global stack used to evaluate dependency expressions -// -BOOLEAN *mDepexEvaluationStack = NULL; -BOOLEAN *mDepexEvaluationStackEnd = NULL; -BOOLEAN *mDepexEvaluationStackPointer = NULL; - -/** - Grow size of the Depex stack - - @retval EFI_SUCCESS Stack successfully growed. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -GrowDepexStack ( - VOID - ) -{ - BOOLEAN *NewStack; - UINTN Size; - - Size = DEPEX_STACK_SIZE_INCREMENT; - if (mDepexEvaluationStack != NULL) { - Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack); - } - - NewStack = AllocatePool (Size * sizeof (BOOLEAN)); - if (NewStack == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (mDepexEvaluationStack != NULL) { - // - // Copy to Old Stack to the New Stack - // - CopyMem ( - NewStack, - mDepexEvaluationStack, - (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (BOOLEAN) - ); - - // - // Free The Old Stack - // - FreePool (mDepexEvaluationStack); - } - - // - // Make the Stack pointer point to the old data in the new stack - // - mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack); - mDepexEvaluationStack = NewStack; - mDepexEvaluationStackEnd = NewStack + Size; - - return EFI_SUCCESS; -} - -/** - Push an element onto the Boolean Stack. - - @param Value BOOLEAN to push. - - @retval EFI_SUCCESS The value was pushed onto the stack. - @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack. - -**/ -EFI_STATUS -PushBool ( - IN BOOLEAN Value - ) -{ - EFI_STATUS Status; - - // - // Check for a stack overflow condition - // - if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) { - // - // Grow the stack - // - Status = GrowDepexStack (); - if (EFI_ERROR (Status)) { - return Status; - } - } - - // - // Push the item onto the stack - // - *mDepexEvaluationStackPointer = Value; - mDepexEvaluationStackPointer++; - - return EFI_SUCCESS; -} - -/** - Pop an element from the Boolean stack. - - @param Value BOOLEAN to pop. - - @retval EFI_SUCCESS The value was popped onto the stack. - @retval EFI_ACCESS_DENIED The pop operation underflowed the stack. - -**/ -EFI_STATUS -PopBool ( - OUT BOOLEAN *Value - ) -{ - // - // Check for a stack underflow condition - // - if (mDepexEvaluationStackPointer == mDepexEvaluationStack) { - return EFI_ACCESS_DENIED; - } - - // - // Pop the item off the stack - // - mDepexEvaluationStackPointer--; - *Value = *mDepexEvaluationStackPointer; - return EFI_SUCCESS; -} - -/** - This is the POSTFIX version of the dependency evaluator. This code does - not need to handle Before or After, as it is not valid to call this - routine in this case. POSTFIX means all the math is done on top of the stack. - - @param DriverEntry DriverEntry element to update. - - @retval TRUE If driver is ready to run. - @retval FALSE If driver is not ready to run or some fatal error - was found. - -**/ -BOOLEAN -SmmIsSchedulable ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry - ) -{ - EFI_STATUS Status; - UINT8 *Iterator; - BOOLEAN Operator; - BOOLEAN Operator2; - EFI_GUID DriverGuid; - VOID *Interface; - - Operator = FALSE; - Operator2 = FALSE; - - if (DriverEntry->After || DriverEntry->Before) { - // - // If Before or After Depex skip as SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter () - // processes them. - // - return FALSE; - } - - DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - - if (DriverEntry->Depex == NULL) { - // - // A NULL Depex means that the SMM driver is not built correctly. - // All SMM drivers must have a valid depex expressiion. - // - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Depex is empty)\n")); - ASSERT (FALSE); - return FALSE; - } - - // - // Clean out memory leaks in Depex Boolean stack. Leaks are only caused by - // incorrectly formed DEPEX expressions - // - mDepexEvaluationStackPointer = mDepexEvaluationStack; - - - Iterator = DriverEntry->Depex; - - while (TRUE) { - // - // Check to see if we are attempting to fetch dependency expression instructions - // past the end of the dependency expression. - // - if (((UINTN)Iterator - (UINTN)DriverEntry->Depex) >= DriverEntry->DepexSize) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Attempt to fetch past end of depex)\n")); - return FALSE; - } - - // - // Look at the opcode of the dependency expression instruction. - // - switch (*Iterator) { - case EFI_DEP_BEFORE: - case EFI_DEP_AFTER: - // - // For a well-formed Dependency Expression, the code should never get here. - // The BEFORE and AFTER are processed prior to this routine's invocation. - // If the code flow arrives at this point, there was a BEFORE or AFTER - // that were not the first opcodes. - // - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected BEFORE or AFTER opcode)\n")); - ASSERT (FALSE); - - case EFI_DEP_PUSH: - // - // Push operator is followed by a GUID. Test to see if the GUID protocol - // is installed and push the boolean result on the stack. - // - CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID)); - - Status = SmmLocateProtocol (&DriverGuid, NULL, &Interface); - if (EFI_ERROR (Status)) { - // - // For SMM Driver, it may depend on uefi protocols - // - Status = gBS->LocateProtocol (&DriverGuid, NULL, &Interface); - } - - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = FALSE\n", &DriverGuid)); - Status = PushBool (FALSE); - } else { - DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = TRUE\n", &DriverGuid)); - *Iterator = EFI_DEP_REPLACE_TRUE; - Status = PushBool (TRUE); - } - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Iterator += sizeof (EFI_GUID); - break; - - case EFI_DEP_AND: - DEBUG ((DEBUG_DISPATCH, " AND\n")); - Status = PopBool (&Operator); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PopBool (&Operator2); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PushBool ((BOOLEAN)(Operator && Operator2)); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_OR: - DEBUG ((DEBUG_DISPATCH, " OR\n")); - Status = PopBool (&Operator); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PopBool (&Operator2); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PushBool ((BOOLEAN)(Operator || Operator2)); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_NOT: - DEBUG ((DEBUG_DISPATCH, " NOT\n")); - Status = PopBool (&Operator); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Status = PushBool ((BOOLEAN)(!Operator)); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_TRUE: - DEBUG ((DEBUG_DISPATCH, " TRUE\n")); - Status = PushBool (TRUE); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_FALSE: - DEBUG ((DEBUG_DISPATCH, " FALSE\n")); - Status = PushBool (FALSE); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - break; - - case EFI_DEP_END: - DEBUG ((DEBUG_DISPATCH, " END\n")); - Status = PopBool (&Operator); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - DEBUG ((DEBUG_DISPATCH, " RESULT = %a\n", Operator ? "TRUE" : "FALSE")); - return Operator; - - case EFI_DEP_REPLACE_TRUE: - CopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID)); - DEBUG ((DEBUG_DISPATCH, " PUSH GUID(%g) = TRUE\n", &DriverGuid)); - Status = PushBool (TRUE); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unexpected error)\n")); - return FALSE; - } - - Iterator += sizeof (EFI_GUID); - break; - - default: - DEBUG ((DEBUG_DISPATCH, " RESULT = FALSE (Unknown opcode)\n")); - goto Done; - } - - // - // Skip over the Dependency Op Code we just processed in the switch. - // The math is done out of order, but it should not matter. That is - // we may add in the sizeof (EFI_GUID) before we account for the OP Code. - // This is not an issue, since we just need the correct end result. You - // need to be careful using Iterator in the loop as it's intermediate value - // may be strange. - // - Iterator++; - } - -Done: - return FALSE; -} diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c deleted file mode 100644 index b2a6822048..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c +++ /dev/null @@ -1,1504 +0,0 @@ -/** @file - SMM Driver Dispatcher. - - Step #1 - When a FV protocol is added to the system every driver in the FV - is added to the mDiscoveredList. The Before, and After Depex are - pre-processed as drivers are added to the mDiscoveredList. If an Apriori - file exists in the FV those drivers are addeded to the - mScheduledQueue. The mFvHandleList is used to make sure a - FV is only processed once. - - Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and - start it. After mScheduledQueue is drained check the - mDiscoveredList to see if any item has a Depex that is ready to - be placed on the mScheduledQueue. - - Step #3 - Adding to the mScheduledQueue requires that you process Before - and After dependencies. This is done recursively as the call to add - to the mScheduledQueue checks for Before and recursively adds - all Befores. It then addes the item that was passed in and then - processess the After dependecies by recursively calling the routine. - - Dispatcher Rules: - The rules for the dispatcher are similar to the DXE dispatcher. - - The rules for DXE dispatcher are in chapter 10 of the DXE CIS. Figure 10-3 - is the state diagram for the DXE dispatcher - - Depex - Dependency Expresion. - - Copyright (c) 2014, Hewlett-Packard Development Company, L.P. - Copyright (c) 2009 - 2017, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -// -// SMM Dispatcher Data structures -// -#define KNOWN_HANDLE_SIGNATURE SIGNATURE_32('k','n','o','w') -typedef struct { - UINTN Signature; - LIST_ENTRY Link; // mFvHandleList - EFI_HANDLE Handle; -} KNOWN_HANDLE; - -// -// Function Prototypes -// - -/** - Insert InsertedDriverEntry onto the mScheduledQueue. To do this you - must add any driver with a before dependency on InsertedDriverEntry first. - You do this by recursively calling this routine. After all the Befores are - processed you can add InsertedDriverEntry to the mScheduledQueue. - Then you can add any driver with an After dependency on InsertedDriverEntry - by recursively calling this routine. - - @param InsertedDriverEntry The driver to insert on the ScheduledLink Queue - -**/ -VOID -SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter ( - IN EFI_SMM_DRIVER_ENTRY *InsertedDriverEntry - ); - -// -// The Driver List contains one copy of every driver that has been discovered. -// Items are never removed from the driver list. List of EFI_SMM_DRIVER_ENTRY -// -LIST_ENTRY mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList); - -// -// Queue of drivers that are ready to dispatch. This queue is a subset of the -// mDiscoveredList.list of EFI_SMM_DRIVER_ENTRY. -// -LIST_ENTRY mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue); - -// -// List of handles who's Fv's have been parsed and added to the mFwDriverList. -// -LIST_ENTRY mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList); - -// -// Flag for the SMM Dispacher. TRUE if dispatcher is execuing. -// -BOOLEAN gDispatcherRunning = FALSE; - -// -// Flag for the SMM Dispacher. TRUE if there is one or more SMM drivers ready to be dispatched -// -BOOLEAN gRequestDispatch = FALSE; - -// -// List of file types supported by dispatcher -// -EFI_FV_FILETYPE mSmmFileTypes[] = { - EFI_FV_FILETYPE_SMM, - EFI_FV_FILETYPE_COMBINED_SMM_DXE, - EFI_FV_FILETYPE_SMM_CORE, - // - // Note: DXE core will process the FV image file, so skip it in SMM core - // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE - // -}; - -typedef struct { - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH File; - EFI_DEVICE_PATH_PROTOCOL End; -} FV_FILEPATH_DEVICE_PATH; - -FV_FILEPATH_DEVICE_PATH mFvDevicePath; - -// -// DXE Architecture Protocols -// -EFI_SECURITY_ARCH_PROTOCOL *mSecurity = NULL; -EFI_SECURITY2_ARCH_PROTOCOL *mSecurity2 = NULL; - -// -// The global variable is defined for Loading modules at fixed address feature to track the SMM code -// memory range usage. It is a bit mapped array in which every bit indicates the corresponding -// memory page available or not. -// -GLOBAL_REMOVE_IF_UNREFERENCED UINT64 *mSmmCodeMemoryRangeUsageBitMap=NULL; - -/** - To check memory usage bit map array to figure out if the memory range in which the image will be loaded is available or not. If - memory range is available, the function will mark the corresponding bits to 1 which indicates the memory range is used. - The function is only invoked when load modules at fixed address feature is enabled. - - @param ImageBase The base address the image will be loaded at. - @param ImageSize The size of the image - - @retval EFI_SUCCESS The memory range the image will be loaded in is available - @retval EFI_NOT_FOUND The memory range the image will be loaded in is not available -**/ -EFI_STATUS -CheckAndMarkFixLoadingMemoryUsageBitMap ( - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINTN ImageSize - ) -{ - UINT32 SmmCodePageNumber; - UINT64 SmmCodeSize; - EFI_PHYSICAL_ADDRESS SmmCodeBase; - UINTN BaseOffsetPageNumber; - UINTN TopOffsetPageNumber; - UINTN Index; - // - // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber - // - SmmCodePageNumber = PcdGet32(PcdLoadFixAddressSmmCodePageNumber); - SmmCodeSize = EFI_PAGES_TO_SIZE (SmmCodePageNumber); - SmmCodeBase = gLoadModuleAtFixAddressSmramBase; - - // - // If the memory usage bit map is not initialized, do it. Every bit in the array - // indicate the status of the corresponding memory page, available or not - // - if (mSmmCodeMemoryRangeUsageBitMap == NULL) { - mSmmCodeMemoryRangeUsageBitMap = AllocateZeroPool(((SmmCodePageNumber / 64) + 1)*sizeof(UINT64)); - } - // - // If the Dxe code memory range is not allocated or the bit map array allocation failed, return EFI_NOT_FOUND - // - if (mSmmCodeMemoryRangeUsageBitMap == NULL) { - return EFI_NOT_FOUND; - } - // - // see if the memory range for loading the image is in the SMM code range. - // - if (SmmCodeBase + SmmCodeSize < ImageBase + ImageSize || SmmCodeBase > ImageBase) { - return EFI_NOT_FOUND; - } - // - // Test if the memory is avalaible or not. - // - BaseOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase - SmmCodeBase)); - TopOffsetPageNumber = EFI_SIZE_TO_PAGES((UINT32)(ImageBase + ImageSize - SmmCodeBase)); - for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) { - if ((mSmmCodeMemoryRangeUsageBitMap[Index / 64] & LShiftU64(1, (Index % 64))) != 0) { - // - // This page is already used. - // - return EFI_NOT_FOUND; - } - } - - // - // Being here means the memory range is available. So mark the bits for the memory range - // - for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index ++) { - mSmmCodeMemoryRangeUsageBitMap[Index / 64] |= LShiftU64(1, (Index % 64)); - } - return EFI_SUCCESS; -} -/** - Get the fixed loading address from image header assigned by build tool. This function only be called - when Loading module at Fixed address feature enabled. - - @param ImageContext Pointer to the image context structure that describes the PE/COFF - image that needs to be examined by this function. - @retval EFI_SUCCESS An fixed loading address is assigned to this image by build tools . - @retval EFI_NOT_FOUND The image has no assigned fixed loading address. - -**/ -EFI_STATUS -GetPeCoffImageFixLoadingAssignedAddress( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - UINTN SectionHeaderOffset; - EFI_STATUS Status; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_PHYSICAL_ADDRESS FixLoadingAddress; - UINT16 Index; - UINTN Size; - UINT16 NumberOfSections; - UINT64 ValueInSectionHeader; - - FixLoadingAddress = 0; - Status = EFI_NOT_FOUND; - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset); - SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; - NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; - - // - // Get base address from the first section header that doesn't point to code section. - // - for (Index = 0; Index < NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EFI_NOT_FOUND; - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - // - // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header - // that doesn't point to code section in image header.So there is an assumption that when the feature is enabled, - // if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields - // should not be Zero, or else, these 2 fields should be set to Zero - // - ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations); - if (ValueInSectionHeader != 0) { - // - // Found first section header that doesn't point to code section in which build tool saves the - // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields - // - FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader); - // - // Check if the memory range is available. - // - Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment)); - if (!EFI_ERROR(Status)) { - // - // The assigned address is valid. Return the specified loading address - // - ImageContext->ImageAddress = FixLoadingAddress; - } - } - break; - } - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status)); - return Status; -} -/** - Loads an EFI image into SMRAM. - - @param DriverEntry EFI_SMM_DRIVER_ENTRY instance - - @return EFI_STATUS - -**/ -EFI_STATUS -EFIAPI -SmmLoadImage ( - IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry - ) -{ - UINT32 AuthenticationStatus; - UINTN FilePathSize; - VOID *Buffer; - UINTN Size; - UINTN PageCount; - EFI_GUID *NameGuid; - EFI_STATUS Status; - EFI_STATUS SecurityStatus; - EFI_HANDLE DeviceHandle; - EFI_PHYSICAL_ADDRESS DstBuffer; - EFI_DEVICE_PATH_PROTOCOL *FilePath; - EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath; - EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINT64 Tick; - - Tick = 0; - PERF_CODE ( - Tick = GetPerformanceCounter (); - ); - - Buffer = NULL; - Size = 0; - Fv = DriverEntry->Fv; - NameGuid = &DriverEntry->FileName; - FilePath = DriverEntry->FvFileDevicePath; - - OriginalFilePath = FilePath; - HandleFilePath = FilePath; - DeviceHandle = NULL; - SecurityStatus = EFI_SUCCESS; - Status = EFI_SUCCESS; - AuthenticationStatus = 0; - - // - // Try to get the image device handle by checking the match protocol. - // - Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle); - if (EFI_ERROR(Status)) { - return Status; - } - - // - // If the Security2 and Security Architectural Protocol has not been located yet, then attempt to locate it - // - if (mSecurity2 == NULL) { - gBS->LocateProtocol (&gEfiSecurity2ArchProtocolGuid, NULL, (VOID**)&mSecurity2); - } - if (mSecurity == NULL) { - gBS->LocateProtocol (&gEfiSecurityArchProtocolGuid, NULL, (VOID**)&mSecurity); - } - // - // When Security2 is installed, Security Architectural Protocol must be published. - // - ASSERT (mSecurity2 == NULL || mSecurity != NULL); - - // - // Pull out just the file portion of the DevicePath for the LoadedImage FilePath - // - FilePath = OriginalFilePath; - Status = gBS->HandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath); - if (!EFI_ERROR (Status)) { - FilePathSize = GetDevicePathSize (HandleFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); - FilePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *)FilePath) + FilePathSize ); - } - - // - // Try reading PE32 section firstly - // - Status = Fv->ReadSection ( - Fv, - NameGuid, - EFI_SECTION_PE32, - 0, - &Buffer, - &Size, - &AuthenticationStatus - ); - - if (EFI_ERROR (Status)) { - // - // Try reading TE section secondly - // - Buffer = NULL; - Size = 0; - Status = Fv->ReadSection ( - Fv, - NameGuid, - EFI_SECTION_TE, - 0, - &Buffer, - &Size, - &AuthenticationStatus - ); - } - - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - return Status; - } - - // - // Verify File Authentication through the Security2 Architectural Protocol - // - if (mSecurity2 != NULL) { - SecurityStatus = mSecurity2->FileAuthentication ( - mSecurity2, - OriginalFilePath, - Buffer, - Size, - FALSE - ); - } - - // - // Verify the Authentication Status through the Security Architectural Protocol - // Only on images that have been read using Firmware Volume protocol. - // All SMM images are from FV protocol. - // - if (!EFI_ERROR (SecurityStatus) && (mSecurity != NULL)) { - SecurityStatus = mSecurity->FileAuthenticationState ( - mSecurity, - AuthenticationStatus, - OriginalFilePath - ); - } - - if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) { - Status = SecurityStatus; - return Status; - } - - // - // Initialize ImageContext - // - ImageContext.Handle = Buffer; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - - // - // Get information about the image being loaded - // - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - return Status; - } - // - // if Loading module at Fixed Address feature is enabled, then cut out a memory range started from TESG BASE - // to hold the Smm driver code - // - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { - // - // Get the fixed loading address assigned by Build tool - // - Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext); - if (!EFI_ERROR (Status)) { - // - // Since the memory range to load Smm core alreay been cut out, so no need to allocate and free this range - // following statements is to bypass SmmFreePages - // - PageCount = 0; - DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase; - } else { - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n")); - // - // allocate the memory to load the SMM driver - // - PageCount = (UINTN)EFI_SIZE_TO_PAGES((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); - DstBuffer = (UINTN)(-1); - - Status = SmmAllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesCode, - PageCount, - &DstBuffer - ); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - return Status; - } - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer; - } - } else { - PageCount = (UINTN)EFI_SIZE_TO_PAGES((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); - DstBuffer = (UINTN)(-1); - - Status = SmmAllocatePages ( - AllocateMaxAddress, - EfiRuntimeServicesCode, - PageCount, - &DstBuffer - ); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - return Status; - } - - ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer; - } - // - // Align buffer on section boundary - // - ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; - ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); - - // - // Load the image to our new buffer - // - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - SmmFreePages (DstBuffer, PageCount); - return Status; - } - - // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - SmmFreePages (DstBuffer, PageCount); - return Status; - } - - // - // Flush the instruction cache so the image data are written before we execute it - // - InvalidateInstructionCacheRange ((VOID *)(UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.ImageSize); - - // - // Save Image EntryPoint in DriverEntry - // - DriverEntry->ImageEntryPoint = ImageContext.EntryPoint; - DriverEntry->ImageBuffer = DstBuffer; - DriverEntry->NumberOfPage = PageCount; - - // - // Allocate a Loaded Image Protocol in EfiBootServicesData - // - Status = gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_LOADED_IMAGE_PROTOCOL), (VOID **)&DriverEntry->LoadedImage); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - SmmFreePages (DstBuffer, PageCount); - return Status; - } - - ZeroMem (DriverEntry->LoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL)); - // - // Fill in the remaining fields of the Loaded Image Protocol instance. - // Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed. - // - DriverEntry->LoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; - DriverEntry->LoadedImage->ParentHandle = gSmmCorePrivate->SmmIplImageHandle; - DriverEntry->LoadedImage->SystemTable = gST; - DriverEntry->LoadedImage->DeviceHandle = DeviceHandle; - - DriverEntry->SmmLoadedImage.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; - DriverEntry->SmmLoadedImage.ParentHandle = gSmmCorePrivate->SmmIplImageHandle; - DriverEntry->SmmLoadedImage.SystemTable = gST; - DriverEntry->SmmLoadedImage.DeviceHandle = DeviceHandle; - - // - // Make an EfiBootServicesData buffer copy of FilePath - // - Status = gBS->AllocatePool (EfiBootServicesData, GetDevicePathSize (FilePath), (VOID **)&DriverEntry->LoadedImage->FilePath); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - SmmFreePages (DstBuffer, PageCount); - return Status; - } - CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath)); - - DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer; - DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize; - DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode; - DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData; - - // - // Make a buffer copy of FilePath - // - Status = SmmAllocatePool (EfiRuntimeServicesData, GetDevicePathSize(FilePath), (VOID **)&DriverEntry->SmmLoadedImage.FilePath); - if (EFI_ERROR (Status)) { - if (Buffer != NULL) { - gBS->FreePool (Buffer); - } - gBS->FreePool (DriverEntry->LoadedImage->FilePath); - SmmFreePages (DstBuffer, PageCount); - return Status; - } - CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize(FilePath)); - - DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer; - DriverEntry->SmmLoadedImage.ImageSize = ImageContext.ImageSize; - DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode; - DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData; - - // - // Create a new image handle in the UEFI handle database for the SMM Driver - // - DriverEntry->ImageHandle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &DriverEntry->ImageHandle, - &gEfiLoadedImageProtocolGuid, DriverEntry->LoadedImage, - NULL - ); - - // - // Create a new image handle in the SMM handle database for the SMM Driver - // - DriverEntry->SmmImageHandle = NULL; - Status = SmmInstallProtocolInterface ( - &DriverEntry->SmmImageHandle, - &gEfiLoadedImageProtocolGuid, - EFI_NATIVE_INTERFACE, - &DriverEntry->SmmLoadedImage - ); - - PERF_START (DriverEntry->ImageHandle, "LoadImage:", NULL, Tick); - PERF_END (DriverEntry->ImageHandle, "LoadImage:", NULL, 0); - - // - // Print the load address and the PDB file name if it is available - // - - DEBUG_CODE_BEGIN (); - - UINTN Index; - UINTN StartIndex; - CHAR8 EfiFileName[256]; - - - DEBUG ((DEBUG_INFO | DEBUG_LOAD, - "Loading SMM driver at 0x%11p EntryPoint=0x%11p ", - (VOID *)(UINTN) ImageContext.ImageAddress, - FUNCTION_ENTRY_POINT (ImageContext.EntryPoint))); - - - // - // Print Module Name by Pdb file path. - // Windows and Unix style file path are all trimmed correctly. - // - if (ImageContext.PdbPointer != NULL) { - StartIndex = 0; - for (Index = 0; ImageContext.PdbPointer[Index] != 0; Index++) { - if ((ImageContext.PdbPointer[Index] == '\\') || (ImageContext.PdbPointer[Index] == '/')) { - StartIndex = Index + 1; - } - } - // - // Copy the PDB file name to our temporary string, and replace .pdb with .efi - // The PDB file name is limited in the range of 0~255. - // If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary. - // - for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) { - EfiFileName[Index] = ImageContext.PdbPointer[Index + StartIndex]; - if (EfiFileName[Index] == 0) { - EfiFileName[Index] = '.'; - } - if (EfiFileName[Index] == '.') { - EfiFileName[Index + 1] = 'e'; - EfiFileName[Index + 2] = 'f'; - EfiFileName[Index + 3] = 'i'; - EfiFileName[Index + 4] = 0; - break; - } - } - - if (Index == sizeof (EfiFileName) - 4) { - EfiFileName[Index] = 0; - } - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex])); - } - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n")); - - DEBUG_CODE_END (); - - // - // Free buffer allocated by Fv->ReadSection. - // - // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection - // used the UEFI Boot Services AllocatePool() function - // - Status = gBS->FreePool(Buffer); - if (!EFI_ERROR (Status) && EFI_ERROR (SecurityStatus)) { - Status = SecurityStatus; - } - return Status; -} - -/** - Preprocess dependency expression and update DriverEntry to reflect the - state of Before and After dependencies. If DriverEntry->Before - or DriverEntry->After is set it will never be cleared. - - @param DriverEntry DriverEntry element to update . - - @retval EFI_SUCCESS It always works. - -**/ -EFI_STATUS -SmmPreProcessDepex ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry - ) -{ - UINT8 *Iterator; - - Iterator = DriverEntry->Depex; - DriverEntry->Dependent = TRUE; - - if (*Iterator == EFI_DEP_BEFORE) { - DriverEntry->Before = TRUE; - } else if (*Iterator == EFI_DEP_AFTER) { - DriverEntry->After = TRUE; - } - - if (DriverEntry->Before || DriverEntry->After) { - CopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID)); - } - - return EFI_SUCCESS; -} - -/** - Read Depex and pre-process the Depex for Before and After. If Section Extraction - protocol returns an error via ReadSection defer the reading of the Depex. - - @param DriverEntry Driver to work on. - - @retval EFI_SUCCESS Depex read and preprossesed - @retval EFI_PROTOCOL_ERROR The section extraction protocol returned an error - and Depex reading needs to be retried. - @retval Error DEPEX not found. - -**/ -EFI_STATUS -SmmGetDepexSectionAndPreProccess ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry - ) -{ - EFI_STATUS Status; - EFI_SECTION_TYPE SectionType; - UINT32 AuthenticationStatus; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - - Fv = DriverEntry->Fv; - - // - // Grab Depex info, it will never be free'ed. - // (Note: DriverEntry->Depex is in DXE memory) - // - SectionType = EFI_SECTION_SMM_DEPEX; - Status = Fv->ReadSection ( - DriverEntry->Fv, - &DriverEntry->FileName, - SectionType, - 0, - &DriverEntry->Depex, - (UINTN *)&DriverEntry->DepexSize, - &AuthenticationStatus - ); - if (EFI_ERROR (Status)) { - if (Status == EFI_PROTOCOL_ERROR) { - // - // The section extraction protocol failed so set protocol error flag - // - DriverEntry->DepexProtocolError = TRUE; - } else { - // - // If no Depex assume depend on all architectural protocols - // - DriverEntry->Depex = NULL; - DriverEntry->Dependent = TRUE; - DriverEntry->DepexProtocolError = FALSE; - } - } else { - // - // Set Before and After state information based on Depex - // Driver will be put in Dependent state - // - SmmPreProcessDepex (DriverEntry); - DriverEntry->DepexProtocolError = FALSE; - } - - return Status; -} - -/** - This is the main Dispatcher for SMM and it exits when there are no more - drivers to run. Drain the mScheduledQueue and load and start a PE - image for each driver. Search the mDiscoveredList to see if any driver can - be placed on the mScheduledQueue. If no drivers are placed on the - mScheduledQueue exit the function. - - @retval EFI_SUCCESS All of the SMM Drivers that could be dispatched - have been run and the SMM Entry Point has been - registered. - @retval EFI_NOT_READY The SMM Driver that registered the SMM Entry Point - was just dispatched. - @retval EFI_NOT_FOUND There are no SMM Drivers available to be dispatched. - @retval EFI_ALREADY_STARTED The SMM Dispatcher is already running - -**/ -EFI_STATUS -SmmDispatcher ( - VOID - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - EFI_SMM_DRIVER_ENTRY *DriverEntry; - BOOLEAN ReadyToRun; - BOOLEAN PreviousSmmEntryPointRegistered; - - if (!gRequestDispatch) { - return EFI_NOT_FOUND; - } - - if (gDispatcherRunning) { - // - // If the dispatcher is running don't let it be restarted. - // - return EFI_ALREADY_STARTED; - } - - gDispatcherRunning = TRUE; - - do { - // - // Drain the Scheduled Queue - // - while (!IsListEmpty (&mScheduledQueue)) { - DriverEntry = CR ( - mScheduledQueue.ForwardLink, - EFI_SMM_DRIVER_ENTRY, - ScheduledLink, - EFI_SMM_DRIVER_ENTRY_SIGNATURE - ); - - // - // Load the SMM Driver image into memory. If the Driver was transitioned from - // Untrused to Scheduled it would have already been loaded so we may need to - // skip the LoadImage - // - if (DriverEntry->ImageHandle == NULL) { - Status = SmmLoadImage (DriverEntry); - - // - // Update the driver state to reflect that it's been loaded - // - if (EFI_ERROR (Status)) { - // - // The SMM Driver could not be loaded, and do not attempt to load or start it again. - // Take driver from Scheduled to Initialized. - // - DriverEntry->Initialized = TRUE; - DriverEntry->Scheduled = FALSE; - RemoveEntryList (&DriverEntry->ScheduledLink); - - // - // If it's an error don't try the StartImage - // - continue; - } - } - - DriverEntry->Scheduled = FALSE; - DriverEntry->Initialized = TRUE; - RemoveEntryList (&DriverEntry->ScheduledLink); - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_BEGIN, - &DriverEntry->ImageHandle, - sizeof (DriverEntry->ImageHandle) - ); - - // - // Cache state of SmmEntryPointRegistered before calling entry point - // - PreviousSmmEntryPointRegistered = gSmmCorePrivate->SmmEntryPointRegistered; - - // - // For each SMM driver, pass NULL as ImageHandle - // - RegisterSmramProfileImage (DriverEntry, TRUE); - PERF_START (DriverEntry->ImageHandle, "StartImage:", NULL, 0); - Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST); - PERF_END (DriverEntry->ImageHandle, "StartImage:", NULL, 0); - if (EFI_ERROR(Status)){ - UnregisterSmramProfileImage (DriverEntry, TRUE); - SmmFreePages(DriverEntry->ImageBuffer, DriverEntry->NumberOfPage); - // - // Uninstall LoadedImage - // - Status = gBS->UninstallProtocolInterface ( - DriverEntry->ImageHandle, - &gEfiLoadedImageProtocolGuid, - DriverEntry->LoadedImage - ); - if (!EFI_ERROR (Status)) { - if (DriverEntry->LoadedImage->FilePath != NULL) { - gBS->FreePool (DriverEntry->LoadedImage->FilePath); - } - gBS->FreePool (DriverEntry->LoadedImage); - } - Status = SmmUninstallProtocolInterface ( - DriverEntry->SmmImageHandle, - &gEfiLoadedImageProtocolGuid, - &DriverEntry->SmmLoadedImage - ); - if (!EFI_ERROR(Status)) { - if (DriverEntry->SmmLoadedImage.FilePath != NULL) { - SmmFreePool (DriverEntry->SmmLoadedImage.FilePath); - } - } - } - - REPORT_STATUS_CODE_WITH_EXTENDED_DATA ( - EFI_PROGRESS_CODE, - EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_END, - &DriverEntry->ImageHandle, - sizeof (DriverEntry->ImageHandle) - ); - - if (!PreviousSmmEntryPointRegistered && gSmmCorePrivate->SmmEntryPointRegistered) { - // - // Return immediately if the SMM Entry Point was registered by the SMM - // Driver that was just dispatched. The SMM IPL will reinvoke the SMM - // Core Dispatcher. This is required so SMM Mode may be enabled as soon - // as all the dependent SMM Drivers for SMM Mode have been dispatched. - // Once the SMM Entry Point has been registered, then SMM Mode will be - // used. - // - gRequestDispatch = TRUE; - gDispatcherRunning = FALSE; - return EFI_NOT_READY; - } - } - - // - // Search DriverList for items to place on Scheduled Queue - // - ReadyToRun = FALSE; - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE); - - if (DriverEntry->DepexProtocolError){ - // - // If Section Extraction Protocol did not let the Depex be read before retry the read - // - Status = SmmGetDepexSectionAndPreProccess (DriverEntry); - } - - if (DriverEntry->Dependent) { - if (SmmIsSchedulable (DriverEntry)) { - SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); - ReadyToRun = TRUE; - } - } - } - } while (ReadyToRun); - - // - // If there is no more SMM driver to dispatch, stop the dispatch request - // - gRequestDispatch = FALSE; - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE); - - if (!DriverEntry->Initialized){ - // - // We have SMM driver pending to dispatch - // - gRequestDispatch = TRUE; - break; - } - } - - gDispatcherRunning = FALSE; - - return EFI_SUCCESS; -} - -/** - Insert InsertedDriverEntry onto the mScheduledQueue. To do this you - must add any driver with a before dependency on InsertedDriverEntry first. - You do this by recursively calling this routine. After all the Befores are - processed you can add InsertedDriverEntry to the mScheduledQueue. - Then you can add any driver with an After dependency on InsertedDriverEntry - by recursively calling this routine. - - @param InsertedDriverEntry The driver to insert on the ScheduledLink Queue - -**/ -VOID -SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter ( - IN EFI_SMM_DRIVER_ENTRY *InsertedDriverEntry - ) -{ - LIST_ENTRY *Link; - EFI_SMM_DRIVER_ENTRY *DriverEntry; - - // - // Process Before Dependency - // - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE); - if (DriverEntry->Before && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) { - DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - DEBUG ((DEBUG_DISPATCH, " BEFORE FFS(%g) = ", &DriverEntry->BeforeAfterGuid)); - if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) { - // - // Recursively process BEFORE - // - DEBUG ((DEBUG_DISPATCH, "TRUE\n END\n RESULT = TRUE\n")); - SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); - } else { - DEBUG ((DEBUG_DISPATCH, "FALSE\n END\n RESULT = FALSE\n")); - } - } - } - - // - // Convert driver from Dependent to Scheduled state - // - - InsertedDriverEntry->Dependent = FALSE; - InsertedDriverEntry->Scheduled = TRUE; - InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink); - - - // - // Process After Dependency - // - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE); - if (DriverEntry->After && DriverEntry->Dependent && DriverEntry != InsertedDriverEntry) { - DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - DEBUG ((DEBUG_DISPATCH, " AFTER FFS(%g) = ", &DriverEntry->BeforeAfterGuid)); - if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) { - // - // Recursively process AFTER - // - DEBUG ((DEBUG_DISPATCH, "TRUE\n END\n RESULT = TRUE\n")); - SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry); - } else { - DEBUG ((DEBUG_DISPATCH, "FALSE\n END\n RESULT = FALSE\n")); - } - } - } -} - -/** - Return TRUE if the Fv has been processed, FALSE if not. - - @param FvHandle The handle of a FV that's being tested - - @retval TRUE Fv protocol on FvHandle has been processed - @retval FALSE Fv protocol on FvHandle has not yet been - processed - -**/ -BOOLEAN -FvHasBeenProcessed ( - IN EFI_HANDLE FvHandle - ) -{ - LIST_ENTRY *Link; - KNOWN_HANDLE *KnownHandle; - - for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) { - KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE); - if (KnownHandle->Handle == FvHandle) { - return TRUE; - } - } - return FALSE; -} - -/** - Remember that Fv protocol on FvHandle has had it's drivers placed on the - mDiscoveredList. This fucntion adds entries on the mFvHandleList. Items are - never removed/freed from the mFvHandleList. - - @param FvHandle The handle of a FV that has been processed - -**/ -VOID -FvIsBeingProcesssed ( - IN EFI_HANDLE FvHandle - ) -{ - KNOWN_HANDLE *KnownHandle; - - KnownHandle = AllocatePool (sizeof (KNOWN_HANDLE)); - ASSERT (KnownHandle != NULL); - - KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE; - KnownHandle->Handle = FvHandle; - InsertTailList (&mFvHandleList, &KnownHandle->Link); -} - -/** - Convert FvHandle and DriverName into an EFI device path - - @param Fv Fv protocol, needed to read Depex info out of - FLASH. - @param FvHandle Handle for Fv, needed in the - EFI_SMM_DRIVER_ENTRY so that the PE image can be - read out of the FV at a later time. - @param DriverName Name of driver to add to mDiscoveredList. - - @return Pointer to device path constructed from FvHandle and DriverName - -**/ -EFI_DEVICE_PATH_PROTOCOL * -SmmFvToDevicePath ( - IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, - IN EFI_HANDLE FvHandle, - IN EFI_GUID *DriverName - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *FvDevicePath; - EFI_DEVICE_PATH_PROTOCOL *FileNameDevicePath; - - // - // Remember the device path of the FV - // - Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath); - if (EFI_ERROR (Status)) { - FileNameDevicePath = NULL; - } else { - // - // Build a device path to the file in the FV to pass into gBS->LoadImage - // - EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName); - SetDevicePathEndNode (&mFvDevicePath.End); - - // - // Note: FileNameDevicePath is in DXE memory - // - FileNameDevicePath = AppendDevicePath ( - FvDevicePath, - (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath - ); - } - return FileNameDevicePath; -} - -/** - Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry, - and initilize any state variables. Read the Depex from the FV and store it - in DriverEntry. Pre-process the Depex to set the Before and After state. - The Discovered list is never free'ed and contains booleans that represent the - other possible SMM driver states. - - @param Fv Fv protocol, needed to read Depex info out of - FLASH. - @param FvHandle Handle for Fv, needed in the - EFI_SMM_DRIVER_ENTRY so that the PE image can be - read out of the FV at a later time. - @param DriverName Name of driver to add to mDiscoveredList. - - @retval EFI_SUCCESS If driver was added to the mDiscoveredList. - @retval EFI_ALREADY_STARTED The driver has already been started. Only one - DriverName may be active in the system at any one - time. - -**/ -EFI_STATUS -SmmAddToDriverList ( - IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, - IN EFI_HANDLE FvHandle, - IN EFI_GUID *DriverName - ) -{ - EFI_SMM_DRIVER_ENTRY *DriverEntry; - - // - // Create the Driver Entry for the list. ZeroPool initializes lots of variables to - // NULL or FALSE. - // - DriverEntry = AllocateZeroPool (sizeof (EFI_SMM_DRIVER_ENTRY)); - ASSERT (DriverEntry != NULL); - - DriverEntry->Signature = EFI_SMM_DRIVER_ENTRY_SIGNATURE; - CopyGuid (&DriverEntry->FileName, DriverName); - DriverEntry->FvHandle = FvHandle; - DriverEntry->Fv = Fv; - DriverEntry->FvFileDevicePath = SmmFvToDevicePath (Fv, FvHandle, DriverName); - - SmmGetDepexSectionAndPreProccess (DriverEntry); - - InsertTailList (&mDiscoveredList, &DriverEntry->Link); - gRequestDispatch = TRUE; - - return EFI_SUCCESS; -} - -/** - This function is the main entry point for an SMM handler dispatch - or communicate-based callback. - - Event notification that is fired every time a FV dispatch protocol is added. - More than one protocol may have been added when this event is fired, so you - must loop on SmmLocateHandle () to see how many protocols were added and - do the following to each FV: - If the Fv has already been processed, skip it. If the Fv has not been - processed then mark it as being processed, as we are about to process it. - Read the Fv and add any driver in the Fv to the mDiscoveredList.The - mDiscoveredList is never free'ed and contains variables that define - the other states the SMM driver transitions to.. - While you are at it read the A Priori file into memory. - Place drivers in the A Priori list onto the mScheduledQueue. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmDriverDispatchHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - EFI_STATUS GetNextFileStatus; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - EFI_DEVICE_PATH_PROTOCOL *FvDevicePath; - EFI_HANDLE FvHandle; - EFI_GUID NameGuid; - UINTN Key; - EFI_FV_FILETYPE Type; - EFI_FV_FILE_ATTRIBUTES Attributes; - UINTN Size; - EFI_SMM_DRIVER_ENTRY *DriverEntry; - EFI_GUID *AprioriFile; - UINTN AprioriEntryCount; - UINTN HandleIndex; - UINTN SmmTypeIndex; - UINTN AprioriIndex; - LIST_ENTRY *Link; - UINT32 AuthenticationStatus; - UINTN SizeOfBuffer; - - HandleBuffer = NULL; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiFirmwareVolume2ProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { - FvHandle = HandleBuffer[HandleIndex]; - - if (FvHasBeenProcessed (FvHandle)) { - // - // This Fv has already been processed so lets skip it! - // - continue; - } - - // - // Since we are about to process this Fv mark it as processed. - // - FvIsBeingProcesssed (FvHandle); - - Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv); - if (EFI_ERROR (Status)) { - // - // FvHandle must have a Firmware Volume2 Protocol thus we should never get here. - // - ASSERT (FALSE); - continue; - } - - Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath); - if (EFI_ERROR (Status)) { - // - // The Firmware volume doesn't have device path, can't be dispatched. - // - continue; - } - - // - // Discover Drivers in FV and add them to the Discovered Driver List. - // Process EFI_FV_FILETYPE_SMM type and then EFI_FV_FILETYPE_COMBINED_SMM_DXE - // EFI_FV_FILETYPE_SMM_CORE is processed to produce a Loaded Image protocol for the core - // - for (SmmTypeIndex = 0; SmmTypeIndex < sizeof (mSmmFileTypes)/sizeof (EFI_FV_FILETYPE); SmmTypeIndex++) { - // - // Initialize the search key - // - Key = 0; - do { - Type = mSmmFileTypes[SmmTypeIndex]; - GetNextFileStatus = Fv->GetNextFile ( - Fv, - &Key, - &Type, - &NameGuid, - &Attributes, - &Size - ); - if (!EFI_ERROR (GetNextFileStatus)) { - if (Type == EFI_FV_FILETYPE_SMM_CORE) { - // - // If this is the SMM core fill in it's DevicePath & DeviceHandle - // - if (mSmmCoreLoadedImage->FilePath == NULL) { - // - // Maybe one special FV contains only one SMM_CORE module, so its device path must - // be initialized completely. - // - EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid); - SetDevicePathEndNode (&mFvDevicePath.End); - - // - // Make an EfiBootServicesData buffer copy of FilePath - // - Status = gBS->AllocatePool ( - EfiBootServicesData, - GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath), - (VOID **)&mSmmCoreLoadedImage->FilePath - ); - ASSERT_EFI_ERROR (Status); - CopyMem (mSmmCoreLoadedImage->FilePath, &mFvDevicePath, GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath)); - - mSmmCoreLoadedImage->DeviceHandle = FvHandle; - } - if (mSmmCoreDriverEntry->SmmLoadedImage.FilePath == NULL) { - // - // Maybe one special FV contains only one SMM_CORE module, so its device path must - // be initialized completely. - // - EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid); - SetDevicePathEndNode (&mFvDevicePath.End); - - // - // Make a buffer copy FilePath - // - Status = SmmAllocatePool ( - EfiRuntimeServicesData, - GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath), - (VOID **)&mSmmCoreDriverEntry->SmmLoadedImage.FilePath - ); - ASSERT_EFI_ERROR (Status); - CopyMem (mSmmCoreDriverEntry->SmmLoadedImage.FilePath, &mFvDevicePath, GetDevicePathSize((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath)); - - mSmmCoreDriverEntry->SmmLoadedImage.DeviceHandle = FvHandle; - } - } else { - SmmAddToDriverList (Fv, FvHandle, &NameGuid); - } - } - } while (!EFI_ERROR (GetNextFileStatus)); - } - - // - // Read the array of GUIDs from the Apriori file if it is present in the firmware volume - // (Note: AprioriFile is in DXE memory) - // - AprioriFile = NULL; - Status = Fv->ReadSection ( - Fv, - &gAprioriGuid, - EFI_SECTION_RAW, - 0, - (VOID **)&AprioriFile, - &SizeOfBuffer, - &AuthenticationStatus - ); - if (!EFI_ERROR (Status)) { - AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID); - } else { - AprioriEntryCount = 0; - } - - // - // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes - // drivers not in the current FV and these must be skipped since the a priori list - // is only valid for the FV that it resided in. - // - - for (AprioriIndex = 0; AprioriIndex < AprioriEntryCount; AprioriIndex++) { - for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE); - if (CompareGuid (&DriverEntry->FileName, &AprioriFile[AprioriIndex]) && - (FvHandle == DriverEntry->FvHandle)) { - DriverEntry->Dependent = FALSE; - DriverEntry->Scheduled = TRUE; - InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink); - DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName)); - DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (Apriori)\n")); - break; - } - } - } - - // - // Free data allocated by Fv->ReadSection () - // - // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection - // used the UEFI Boot Services AllocatePool() function - // - gBS->FreePool (AprioriFile); - } - - // - // Execute the SMM Dispatcher on any newly discovered FVs and previously - // discovered SMM drivers that have been discovered but not dispatched. - // - Status = SmmDispatcher (); - - // - // Check to see if CommBuffer and CommBufferSize are valid - // - if (CommBuffer != NULL && CommBufferSize != NULL) { - if (*CommBufferSize > 0) { - if (Status == EFI_NOT_READY) { - // - // If a the SMM Core Entry Point was just registered, then set flag to - // request the SMM Dispatcher to be restarted. - // - *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_RESTART; - } else if (!EFI_ERROR (Status)) { - // - // Set the flag to show that the SMM Dispatcher executed without errors - // - *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_SUCCESS; - } else { - // - // Set the flag to show that the SMM Dispatcher encountered an error - // - *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_ERROR; - } - } - } - - return EFI_SUCCESS; -} - -/** - Traverse the discovered list for any drivers that were discovered but not loaded - because the dependency experessions evaluated to false. - -**/ -VOID -SmmDisplayDiscoveredNotDispatched ( - VOID - ) -{ - LIST_ENTRY *Link; - EFI_SMM_DRIVER_ENTRY *DriverEntry; - - for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) { - DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE); - if (DriverEntry->Dependent) { - DEBUG ((DEBUG_LOAD, "SMM Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName)); - } - } -} diff --git a/MdeModulePkg/Core/PiSmmCore/Handle.c b/MdeModulePkg/Core/PiSmmCore/Handle.c deleted file mode 100644 index 9cedb2aeb5..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/Handle.c +++ /dev/null @@ -1,532 +0,0 @@ -/** @file - SMM handle & protocol handling. - - Copyright (c) 2009 - 2010, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -// -// mProtocolDatabase - A list of all protocols in the system. (simple list for now) -// gHandleList - A list of all the handles in the system -// -LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase); -LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList); - -/** - Check whether a handle is a valid EFI_HANDLE - - @param UserHandle The handle to check - - @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE. - @retval EFI_SUCCESS The handle is valid EFI_HANDLE. - -**/ -EFI_STATUS -SmmValidateHandle ( - IN EFI_HANDLE UserHandle - ) -{ - IHANDLE *Handle; - - Handle = (IHANDLE *)UserHandle; - if (Handle == NULL) { - return EFI_INVALID_PARAMETER; - } - if (Handle->Signature != EFI_HANDLE_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - return EFI_SUCCESS; -} - -/** - Finds the protocol entry for the requested protocol. - - @param Protocol The ID of the protocol - @param Create Create a new entry if not found - - @return Protocol entry - -**/ -PROTOCOL_ENTRY * -SmmFindProtocolEntry ( - IN EFI_GUID *Protocol, - IN BOOLEAN Create - ) -{ - LIST_ENTRY *Link; - PROTOCOL_ENTRY *Item; - PROTOCOL_ENTRY *ProtEntry; - - // - // Search the database for the matching GUID - // - - ProtEntry = NULL; - for (Link = mProtocolDatabase.ForwardLink; - Link != &mProtocolDatabase; - Link = Link->ForwardLink) { - - Item = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE); - if (CompareGuid (&Item->ProtocolID, Protocol)) { - // - // This is the protocol entry - // - ProtEntry = Item; - break; - } - } - - // - // If the protocol entry was not found and Create is TRUE, then - // allocate a new entry - // - if ((ProtEntry == NULL) && Create) { - ProtEntry = AllocatePool (sizeof(PROTOCOL_ENTRY)); - if (ProtEntry != NULL) { - // - // Initialize new protocol entry structure - // - ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE; - CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol); - InitializeListHead (&ProtEntry->Protocols); - InitializeListHead (&ProtEntry->Notify); - - // - // Add it to protocol database - // - InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries); - } - } - return ProtEntry; -} - -/** - Finds the protocol instance for the requested handle and protocol. - Note: This function doesn't do parameters checking, it's caller's responsibility - to pass in valid parameters. - - @param Handle The handle to search the protocol on - @param Protocol GUID of the protocol - @param Interface The interface for the protocol being searched - - @return Protocol instance (NULL: Not found) - -**/ -PROTOCOL_INTERFACE * -SmmFindProtocolInterface ( - IN IHANDLE *Handle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ) -{ - PROTOCOL_INTERFACE *Prot; - PROTOCOL_ENTRY *ProtEntry; - LIST_ENTRY *Link; - - Prot = NULL; - - // - // Lookup the protocol entry for this protocol ID - // - ProtEntry = SmmFindProtocolEntry (Protocol, FALSE); - if (ProtEntry != NULL) { - // - // Look at each protocol interface for any matches - // - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link=Link->ForwardLink) { - // - // If this protocol interface matches, remove it - // - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - if (Prot->Interface == Interface && Prot->Protocol == ProtEntry) { - break; - } - Prot = NULL; - } - } - return Prot; -} - -/** - Wrapper function to SmmInstallProtocolInterfaceNotify. This is the public API which - Calls the private one which contains a BOOLEAN parameter for notifications - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - - @return Status code - -**/ -EFI_STATUS -EFIAPI -SmmInstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface - ) -{ - return SmmInstallProtocolInterfaceNotify ( - UserHandle, - Protocol, - InterfaceType, - Interface, - TRUE - ); -} - -/** - Installs a protocol interface into the boot services environment. - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - @param Notify indicates whether notify the notification list - for this protocol - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SUCCESS Protocol interface successfully installed - -**/ -EFI_STATUS -SmmInstallProtocolInterfaceNotify ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface, - IN BOOLEAN Notify - ) -{ - PROTOCOL_INTERFACE *Prot; - PROTOCOL_ENTRY *ProtEntry; - IHANDLE *Handle; - EFI_STATUS Status; - VOID *ExistingInterface; - - // - // returns EFI_INVALID_PARAMETER if InterfaceType is invalid. - // Also added check for invalid UserHandle and Protocol pointers. - // - if (UserHandle == NULL || Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (InterfaceType != EFI_NATIVE_INTERFACE) { - return EFI_INVALID_PARAMETER; - } - - // - // Print debug message - // - DEBUG((DEBUG_LOAD | DEBUG_INFO, "SmmInstallProtocolInterface: %g %p\n", Protocol, Interface)); - - Status = EFI_OUT_OF_RESOURCES; - Prot = NULL; - Handle = NULL; - - if (*UserHandle != NULL) { - Status = SmmHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface); - if (!EFI_ERROR (Status)) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Lookup the Protocol Entry for the requested protocol - // - ProtEntry = SmmFindProtocolEntry (Protocol, TRUE); - if (ProtEntry == NULL) { - goto Done; - } - - // - // Allocate a new protocol interface structure - // - Prot = AllocateZeroPool (sizeof(PROTOCOL_INTERFACE)); - if (Prot == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - // - // If caller didn't supply a handle, allocate a new one - // - Handle = (IHANDLE *)*UserHandle; - if (Handle == NULL) { - Handle = AllocateZeroPool (sizeof(IHANDLE)); - if (Handle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Done; - } - - // - // Initialize new handler structure - // - Handle->Signature = EFI_HANDLE_SIGNATURE; - InitializeListHead (&Handle->Protocols); - - // - // Add this handle to the list global list of all handles - // in the system - // - InsertTailList (&gHandleList, &Handle->AllHandles); - } - - Status = SmmValidateHandle (Handle); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Each interface that is added must be unique - // - ASSERT (SmmFindProtocolInterface (Handle, Protocol, Interface) == NULL); - - // - // Initialize the protocol interface structure - // - Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE; - Prot->Handle = Handle; - Prot->Protocol = ProtEntry; - Prot->Interface = Interface; - - // - // Add this protocol interface to the head of the supported - // protocol list for this handle - // - InsertHeadList (&Handle->Protocols, &Prot->Link); - - // - // Add this protocol interface to the tail of the - // protocol entry - // - InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol); - - // - // Notify the notification list for this protocol - // - if (Notify) { - SmmNotifyProtocol (Prot); - } - Status = EFI_SUCCESS; - -Done: - if (!EFI_ERROR (Status)) { - // - // Return the new handle back to the caller - // - *UserHandle = Handle; - } else { - // - // There was an error, clean up - // - if (Prot != NULL) { - FreePool (Prot); - } - } - return Status; -} - -/** - Uninstalls all instances of a protocol:interfacer from a handle. - If the last protocol interface is remove from the handle, the - handle is freed. - - @param UserHandle The handle to remove the protocol handler from - @param Protocol The protocol, of protocol:interface, to remove - @param Interface The interface, of protocol:interface, to remove - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Protocol interface successfully uninstalled. - -**/ -EFI_STATUS -EFIAPI -SmmUninstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ) -{ - EFI_STATUS Status; - IHANDLE *Handle; - PROTOCOL_INTERFACE *Prot; - - // - // Check that Protocol is valid - // - if (Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check that UserHandle is a valid handle - // - Status = SmmValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Check that Protocol exists on UserHandle, and Interface matches the interface in the database - // - Prot = SmmFindProtocolInterface (UserHandle, Protocol, Interface); - if (Prot == NULL) { - return EFI_NOT_FOUND; - } - - // - // Remove the protocol interface from the protocol - // - Status = EFI_NOT_FOUND; - Handle = (IHANDLE *)UserHandle; - Prot = SmmRemoveInterfaceFromProtocol (Handle, Protocol, Interface); - - if (Prot != NULL) { - // - // Remove the protocol interface from the handle - // - RemoveEntryList (&Prot->Link); - - // - // Free the memory - // - Prot->Signature = 0; - FreePool (Prot); - Status = EFI_SUCCESS; - } - - // - // If there are no more handlers for the handle, free the handle - // - if (IsListEmpty (&Handle->Protocols)) { - Handle->Signature = 0; - RemoveEntryList (&Handle->AllHandles); - FreePool (Handle); - } - return Status; -} - -/** - Locate a certain GUID protocol interface in a Handle's protocols. - - @param UserHandle The handle to obtain the protocol interface on - @param Protocol The GUID of the protocol - - @return The requested protocol interface for the handle - -**/ -PROTOCOL_INTERFACE * -SmmGetProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol - ) -{ - EFI_STATUS Status; - PROTOCOL_ENTRY *ProtEntry; - PROTOCOL_INTERFACE *Prot; - IHANDLE *Handle; - LIST_ENTRY *Link; - - Status = SmmValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return NULL; - } - - Handle = (IHANDLE *)UserHandle; - - // - // Look at each protocol interface for a match - // - for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { - Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); - ProtEntry = Prot->Protocol; - if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) { - return Prot; - } - } - return NULL; -} - -/** - Queries a handle to determine if it supports a specified protocol. - - @param UserHandle The handle being queried. - @param Protocol The published unique identifier of the protocol. - @param Interface Supplies the address where a pointer to the - corresponding Protocol Interface is returned. - - @retval EFI_SUCCESS The interface information for the specified protocol was returned. - @retval EFI_UNSUPPORTED The device does not support the specified protocol. - @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.. - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_INVALID_PARAMETER Interface is NULL. - -**/ -EFI_STATUS -EFIAPI -SmmHandleProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - PROTOCOL_INTERFACE *Prot; - - // - // Check for invalid Protocol - // - if (Protocol == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check for invalid Interface - // - if (Interface == NULL) { - return EFI_INVALID_PARAMETER; - } else { - *Interface = NULL; - } - - // - // Check for invalid UserHandle - // - Status = SmmValidateHandle (UserHandle); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Look at each protocol interface for a match - // - Prot = SmmGetProtocolInterface (UserHandle, Protocol); - if (Prot == NULL) { - return EFI_UNSUPPORTED; - } - - // - // This is the protocol interface entry for this protocol - // - *Interface = Prot->Interface; - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/PiSmmCore/InstallConfigurationTable.c b/MdeModulePkg/Core/PiSmmCore/InstallConfigurationTable.c deleted file mode 100644 index b2f6769c10..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/InstallConfigurationTable.c +++ /dev/null @@ -1,161 +0,0 @@ -/** @file - System Management System Table Services SmmInstallConfigurationTable service - - Copyright (c) 2009 - 2010, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -#define CONFIG_TABLE_SIZE_INCREASED 0x10 - -UINTN mSmmSystemTableAllocateSize = 0; - -/** - The SmmInstallConfigurationTable() function is used to maintain the list - of configuration tables that are stored in the System Management System - Table. The list is stored as an array of (GUID, Pointer) pairs. The list - must be allocated from pool memory with PoolType set to EfiRuntimeServicesData. - - @param SystemTable A pointer to the SMM System Table (SMST). - @param Guid A pointer to the GUID for the entry to add, update, or remove. - @param Table A pointer to the buffer of the table to add. - @param TableSize The size of the table to install. - - @retval EFI_SUCCESS The (Guid, Table) pair was added, updated, or removed. - @retval EFI_INVALID_PARAMETER Guid is not valid. - @retval EFI_NOT_FOUND An attempt was made to delete a non-existent entry. - @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation. - -**/ -EFI_STATUS -EFIAPI -SmmInstallConfigurationTable ( - IN CONST EFI_SMM_SYSTEM_TABLE2 *SystemTable, - IN CONST EFI_GUID *Guid, - IN VOID *Table, - IN UINTN TableSize - ) -{ - UINTN Index; - EFI_CONFIGURATION_TABLE *ConfigurationTable; - - // - // If Guid is NULL, then this operation cannot be performed - // - if (Guid == NULL) { - return EFI_INVALID_PARAMETER; - } - - ConfigurationTable = gSmmCoreSmst.SmmConfigurationTable; - - // - // Search all the table for an entry that matches Guid - // - for (Index = 0; Index < gSmmCoreSmst.NumberOfTableEntries; Index++) { - if (CompareGuid (Guid, &(ConfigurationTable[Index].VendorGuid))) { - break; - } - } - - if (Index < gSmmCoreSmst.NumberOfTableEntries) { - // - // A match was found, so this is either a modify or a delete operation - // - if (Table != NULL) { - // - // If Table is not NULL, then this is a modify operation. - // Modify the table enty and return. - // - ConfigurationTable[Index].VendorTable = Table; - return EFI_SUCCESS; - } - - // - // A match was found and Table is NULL, so this is a delete operation. - // - gSmmCoreSmst.NumberOfTableEntries--; - - // - // Copy over deleted entry - // - CopyMem ( - &(ConfigurationTable[Index]), - &(ConfigurationTable[Index + 1]), - (gSmmCoreSmst.NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE) - ); - - } else { - // - // No matching GUIDs were found, so this is an add operation. - // - if (Table == NULL) { - // - // If Table is NULL on an add operation, then return an error. - // - return EFI_NOT_FOUND; - } - - // - // Assume that Index == gSmmCoreSmst.NumberOfTableEntries - // - if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSmmSystemTableAllocateSize) { - // - // Allocate a table with one additional entry. - // - mSmmSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE)); - ConfigurationTable = AllocatePool (mSmmSystemTableAllocateSize); - if (ConfigurationTable == NULL) { - // - // If a new table could not be allocated, then return an error. - // - return EFI_OUT_OF_RESOURCES; - } - - if (gSmmCoreSmst.SmmConfigurationTable != NULL) { - // - // Copy the old table to the new table. - // - CopyMem ( - ConfigurationTable, - gSmmCoreSmst.SmmConfigurationTable, - Index * sizeof (EFI_CONFIGURATION_TABLE) - ); - - // - // Free Old Table - // - FreePool (gSmmCoreSmst.SmmConfigurationTable); - } - - // - // Update System Table - // - gSmmCoreSmst.SmmConfigurationTable = ConfigurationTable; - } - - // - // Fill in the new entry - // - CopyGuid ((VOID *)&ConfigurationTable[Index].VendorGuid, Guid); - ConfigurationTable[Index].VendorTable = Table; - - // - // This is an add operation, so increment the number of table entries - // - gSmmCoreSmst.NumberOfTableEntries++; - } - - // - // CRC-32 field is ignorable for SMM System Table and should be set to zero - // - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/PiSmmCore/Locate.c b/MdeModulePkg/Core/PiSmmCore/Locate.c deleted file mode 100644 index a7220bae86..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/Locate.c +++ /dev/null @@ -1,499 +0,0 @@ -/** @file - Locate handle functions - - Copyright (c) 2009 - 2010, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -// -// ProtocolRequest - Last LocateHandle request ID -// -UINTN mEfiLocateHandleRequest = 0; - -// -// Internal prototypes -// - -typedef struct { - EFI_GUID *Protocol; - VOID *SearchKey; - LIST_ENTRY *Position; - PROTOCOL_ENTRY *ProtEntry; -} LOCATE_POSITION; - -typedef -IHANDLE * -(* CORE_GET_NEXT) ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ); - -/** - Routine to get the next Handle, when you are searching for all handles. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -SmmGetNextLocateAllHandles ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - - // - // Next handle - // - Position->Position = Position->Position->ForwardLink; - - // - // If not at the end of the list, get the handle - // - Handle = NULL; - *Interface = NULL; - if (Position->Position != &gHandleList) { - Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); - } - return Handle; -} - -/** - Routine to get the next Handle, when you are searching for register protocol - notifies. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -SmmGetNextLocateByRegisterNotify ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - PROTOCOL_NOTIFY *ProtNotify; - PROTOCOL_INTERFACE *Prot; - LIST_ENTRY *Link; - - Handle = NULL; - *Interface = NULL; - ProtNotify = Position->SearchKey; - - // - // If this is the first request, get the next handle - // - if (ProtNotify != NULL) { - ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE); - Position->SearchKey = NULL; - - // - // If not at the end of the list, get the next handle - // - Link = ProtNotify->Position->ForwardLink; - if (Link != &ProtNotify->Protocol->Protocols) { - Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); - Handle = Prot->Handle; - *Interface = Prot->Interface; - } - } - return Handle; -} - -/** - Routine to get the next Handle, when you are searching for a given protocol. - - @param Position Information about which Handle to seach for. - @param Interface Return the interface structure for the matching - protocol. - - @return An pointer to IHANDLE if the next Position is not the end of the list. - Otherwise,NULL is returned. - -**/ -IHANDLE * -SmmGetNextLocateByProtocol ( - IN OUT LOCATE_POSITION *Position, - OUT VOID **Interface - ) -{ - IHANDLE *Handle; - LIST_ENTRY *Link; - PROTOCOL_INTERFACE *Prot; - - Handle = NULL; - *Interface = NULL; - for (; ;) { - // - // Next entry - // - Link = Position->Position->ForwardLink; - Position->Position = Link; - - // - // If not at the end, return the handle - // - if (Link == &Position->ProtEntry->Protocols) { - Handle = NULL; - break; - } - - // - // Get the handle - // - Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); - Handle = Prot->Handle; - *Interface = Prot->Interface; - - // - // If this handle has not been returned this request, then - // return it now - // - if (Handle->LocateRequest != mEfiLocateHandleRequest) { - Handle->LocateRequest = mEfiLocateHandleRequest; - break; - } - } - return Handle; -} - -/** - Return the first Protocol Interface that matches the Protocol GUID. If - Registration is pasased in return a Protocol Instance that was just add - to the system. If Retistration is NULL return the first Protocol Interface - you find. - - @param Protocol The protocol to search for - @param Registration Optional Registration Key returned from - RegisterProtocolNotify() - @param Interface Return the Protocol interface (instance). - - @retval EFI_SUCCESS If a valid Interface is returned - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Protocol interface not found - -**/ -EFI_STATUS -EFIAPI -SmmLocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *Registration OPTIONAL, - OUT VOID **Interface - ) -{ - EFI_STATUS Status; - LOCATE_POSITION Position; - PROTOCOL_NOTIFY *ProtNotify; - IHANDLE *Handle; - - if (Interface == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Protocol == NULL) { - return EFI_NOT_FOUND; - } - - *Interface = NULL; - Status = EFI_SUCCESS; - - // - // Set initial position - // - Position.Protocol = Protocol; - Position.SearchKey = Registration; - Position.Position = &gHandleList; - - mEfiLocateHandleRequest += 1; - - if (Registration == NULL) { - // - // Look up the protocol entry and set the head pointer - // - Position.ProtEntry = SmmFindProtocolEntry (Protocol, FALSE); - if (Position.ProtEntry == NULL) { - return EFI_NOT_FOUND; - } - Position.Position = &Position.ProtEntry->Protocols; - - Handle = SmmGetNextLocateByProtocol (&Position, Interface); - } else { - Handle = SmmGetNextLocateByRegisterNotify (&Position, Interface); - } - - if (Handle == NULL) { - Status = EFI_NOT_FOUND; - } else if (Registration != NULL) { - // - // If this is a search by register notify and a handle was - // returned, update the register notification position - // - ProtNotify = Registration; - ProtNotify->Position = ProtNotify->Position->ForwardLink; - } - - return Status; -} - -/** - Locates the requested handle(s) and returns them in Buffer. - - @param SearchType The type of search to perform to locate the - handles - @param Protocol The protocol to search for - @param SearchKey Dependant on SearchType - @param BufferSize On input the size of Buffer. On output the - size of data returned. - @param Buffer The buffer to return the results in - - @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is - returned in BufferSize. - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully found the requested handle(s) and - returns them in Buffer. - -**/ -EFI_STATUS -EFIAPI -SmmLocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ) -{ - EFI_STATUS Status; - LOCATE_POSITION Position; - PROTOCOL_NOTIFY *ProtNotify; - CORE_GET_NEXT GetNext; - UINTN ResultSize; - IHANDLE *Handle; - IHANDLE **ResultBuffer; - VOID *Interface; - - if (BufferSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((*BufferSize > 0) && (Buffer == NULL)) { - return EFI_INVALID_PARAMETER; - } - - GetNext = NULL; - - // - // Set initial position - // - Position.Protocol = Protocol; - Position.SearchKey = SearchKey; - Position.Position = &gHandleList; - - ResultSize = 0; - ResultBuffer = (IHANDLE **) Buffer; - Status = EFI_SUCCESS; - - // - // Get the search function based on type - // - switch (SearchType) { - case AllHandles: - GetNext = SmmGetNextLocateAllHandles; - break; - - case ByRegisterNotify: - GetNext = SmmGetNextLocateByRegisterNotify; - // - // Must have SearchKey for locate ByRegisterNotify - // - if (SearchKey == NULL) { - Status = EFI_INVALID_PARAMETER; - } - break; - - case ByProtocol: - GetNext = SmmGetNextLocateByProtocol; - if (Protocol == NULL) { - Status = EFI_INVALID_PARAMETER; - break; - } - // - // Look up the protocol entry and set the head pointer - // - Position.ProtEntry = SmmFindProtocolEntry (Protocol, FALSE); - if (Position.ProtEntry == NULL) { - Status = EFI_NOT_FOUND; - break; - } - Position.Position = &Position.ProtEntry->Protocols; - break; - - default: - Status = EFI_INVALID_PARAMETER; - break; - } - - if (EFI_ERROR(Status)) { - return Status; - } - - // - // Enumerate out the matching handles - // - mEfiLocateHandleRequest += 1; - for (; ;) { - // - // Get the next handle. If no more handles, stop - // - Handle = GetNext (&Position, &Interface); - if (NULL == Handle) { - break; - } - - // - // Increase the resulting buffer size, and if this handle - // fits return it - // - ResultSize += sizeof(Handle); - if (ResultSize <= *BufferSize) { - *ResultBuffer = Handle; - ResultBuffer += 1; - } - } - - // - // If the result is a zero length buffer, then there were no - // matching handles - // - if (ResultSize == 0) { - Status = EFI_NOT_FOUND; - } else { - // - // Return the resulting buffer size. If it's larger than what - // was passed, then set the error code - // - if (ResultSize > *BufferSize) { - Status = EFI_BUFFER_TOO_SMALL; - } - - *BufferSize = ResultSize; - - if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) { - ASSERT (SearchKey != NULL); - // - // If this is a search by register notify and a handle was - // returned, update the register notification position - // - ProtNotify = SearchKey; - ProtNotify->Position = ProtNotify->Position->ForwardLink; - } - } - - return Status; -} - -/** - Function returns an array of handles that support the requested protocol - in a buffer allocated from pool. This is a version of SmmLocateHandle() - that allocates a buffer for the caller. - - @param SearchType Specifies which handle(s) are to be returned. - @param Protocol Provides the protocol to search by. This - parameter is only valid for SearchType - ByProtocol. - @param SearchKey Supplies the search key depending on the - SearchType. - @param NumberHandles The number of handles returned in Buffer. - @param Buffer A pointer to the buffer to return the requested - array of handles that support Protocol. - - @retval EFI_SUCCESS The result array of handles was returned. - @retval EFI_NOT_FOUND No handles match the search. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - matching results. - @retval EFI_INVALID_PARAMETER One or more parameters are not valid. - -**/ -EFI_STATUS -EFIAPI -SmmLocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ) -{ - EFI_STATUS Status; - UINTN BufferSize; - - if (NumberHandles == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - BufferSize = 0; - *NumberHandles = 0; - *Buffer = NULL; - Status = SmmLocateHandle ( - SearchType, - Protocol, - SearchKey, - &BufferSize, - *Buffer - ); - // - // LocateHandleBuffer() returns incorrect status code if SearchType is - // invalid. - // - // Add code to correctly handle expected errors from SmmLocateHandle(). - // - if (EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL) { - if (Status != EFI_INVALID_PARAMETER) { - Status = EFI_NOT_FOUND; - } - return Status; - } - - *Buffer = AllocatePool (BufferSize); - if (*Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = SmmLocateHandle ( - SearchType, - Protocol, - SearchKey, - &BufferSize, - *Buffer - ); - - *NumberHandles = BufferSize / sizeof(EFI_HANDLE); - if (EFI_ERROR(Status)) { - *NumberHandles = 0; - } - - return Status; -} diff --git a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c b/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c deleted file mode 100644 index e3c505ef18..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/MemoryAttributesTable.c +++ /dev/null @@ -1,1520 +0,0 @@ -/** @file - PI SMM MemoryAttributes support - -Copyright (c) 2016, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "PiSmmCore.h" - -#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ - ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) - -#define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I','P','R','C') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS CodeSegmentBase; - UINT64 CodeSegmentSize; -} IMAGE_PROPERTIES_RECORD_CODE_SECTION; - -#define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D') - -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - EFI_PHYSICAL_ADDRESS ImageBase; - UINT64 ImageSize; - UINTN CodeSegmentCount; - LIST_ENTRY CodeSegmentList; -} IMAGE_PROPERTIES_RECORD; - -#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D') - -typedef struct { - UINT32 Signature; - UINTN ImageRecordCount; - UINTN CodeSegmentCountMax; - LIST_ENTRY ImageRecordList; -} IMAGE_PROPERTIES_PRIVATE_DATA; - -IMAGE_PROPERTIES_PRIVATE_DATA mImagePropertiesPrivateData = { - IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE, - 0, - 0, - INITIALIZE_LIST_HEAD_VARIABLE (mImagePropertiesPrivateData.ImageRecordList) -}; - -#define EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA BIT0 - -UINT64 mMemoryProtectionAttribute = EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA; - -// -// Below functions are for MemoryMap -// - -/** - Converts a number of EFI_PAGEs to a size in bytes. - - NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only. - - @param[in] Pages The number of EFI_PAGES. - - @return The number of bytes associated with the number of EFI_PAGEs specified - by Pages. -**/ -STATIC -UINT64 -EfiPagesToSize ( - IN UINT64 Pages - ) -{ - return LShiftU64 (Pages, EFI_PAGE_SHIFT); -} - -/** - Converts a size, in bytes, to a number of EFI_PAGESs. - - NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only. - - @param[in] Size A size in bytes. - - @return The number of EFI_PAGESs associated with the number of bytes specified - by Size. - -**/ -STATIC -UINT64 -EfiSizeToPages ( - IN UINT64 Size - ) -{ - return RShiftU64 (Size, EFI_PAGE_SHIFT) + ((((UINTN)Size) & EFI_PAGE_MASK) ? 1 : 0); -} - -/** - Check the consistency of Smm memory attributes table. - - @param[in] MemoryAttributesTable PI SMM memory attributes table -**/ -VOID -SmmMemoryAttributesTableConsistencyCheck ( - IN EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN MemoryMapEntryCount; - UINTN DescriptorSize; - UINTN Index; - UINT64 Address; - - Address = 0; - MemoryMapEntryCount = MemoryAttributesTable->NumberOfEntries; - DescriptorSize = MemoryAttributesTable->DescriptorSize; - MemoryMap = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1); - for (Index = 0; Index < MemoryMapEntryCount; Index++) { - if (Address != 0) { - ASSERT (Address == MemoryMap->PhysicalStart); - } - Address = MemoryMap->PhysicalStart + EfiPagesToSize(MemoryMap->NumberOfPages); - MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize); - } -} - -/** - Sort memory map entries based upon PhysicalStart, from low to high. - - @param[in,out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer. - @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -SortMemoryMap ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - EFI_MEMORY_DESCRIPTOR TempMemoryMap; - - MemoryMapEntry = MemoryMap; - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); - while (MemoryMapEntry < MemoryMapEnd) { - while (NextMemoryMapEntry < MemoryMapEnd) { - if (MemoryMapEntry->PhysicalStart > NextMemoryMapEntry->PhysicalStart) { - CopyMem (&TempMemoryMap, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - CopyMem (MemoryMapEntry, NextMemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - CopyMem (NextMemoryMapEntry, &TempMemoryMap, sizeof(EFI_MEMORY_DESCRIPTOR)); - } - - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - } - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - } - - return ; -} - -/** - Merge continous memory map entries whose have same attributes. - - @param[in, out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the current memory map. On output, - it is the size of new memory map after merge. - @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -MergeMemoryMap ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN OUT UINTN *MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - UINT64 MemoryBlockLength; - EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; - - MemoryMapEntry = MemoryMap; - NewMemoryMapEntry = MemoryMap; - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + *MemoryMapSize); - while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR)); - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - - do { - MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages)); - if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && - (MemoryMapEntry->Type == NextMemoryMapEntry->Type) && - (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) && - ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) { - MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; - if (NewMemoryMapEntry != MemoryMapEntry) { - NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; - } - - NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - continue; - } else { - MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); - break; - } - } while (TRUE); - - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize); - } - - *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap; - - return ; -} - -/** - Enforce memory map attributes. - This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP. - - @param[in, out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer. - @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -EnforceMemoryMapAttribute ( - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; - EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; - - MemoryMapEntry = MemoryMap; - MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) MemoryMap + MemoryMapSize); - while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { - if (MemoryMapEntry->Attribute != 0) { - // It is PE image, the attribute is already set. - } else { - switch (MemoryMapEntry->Type) { - case EfiRuntimeServicesCode: - MemoryMapEntry->Attribute = EFI_MEMORY_RO; - break; - case EfiRuntimeServicesData: - default: - MemoryMapEntry->Attribute |= EFI_MEMORY_XP; - break; - } - } - MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); - } - - return ; -} - -/** - Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length]. - - @param[in] Buffer Start Address - @param[in] Length Address length - - @return first image record covered by [buffer, length] -**/ -STATIC -IMAGE_PROPERTIES_RECORD * -GetImageRecordByAddress ( - IN EFI_PHYSICAL_ADDRESS Buffer, - IN UINT64 Length - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *ImageRecordList; - - ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; - - for (ImageRecordLink = ImageRecordList->ForwardLink; - ImageRecordLink != ImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if ((Buffer <= ImageRecord->ImageBase) && - (Buffer + Length >= ImageRecord->ImageBase + ImageRecord->ImageSize)) { - return ImageRecord; - } - } - - return NULL; -} - -/** - Set the memory map to new entries, according to one old entry, - based upon PE code section and data section in image record - - @param[in] ImageRecord An image record whose [ImageBase, ImageSize] covered - by old memory map entry. - @param[in, out] NewRecord A pointer to several new memory map entries. - The caller gurantee the buffer size be 1 + - (SplitRecordCount * DescriptorSize) calculated - below. - @param[in] OldRecord A pointer to one old memory map entry. - @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -UINTN -SetNewRecord ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord, - IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, - IN EFI_MEMORY_DESCRIPTOR *OldRecord, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR TempRecord; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - UINTN NewRecordCount; - UINT64 PhysicalEnd; - UINT64 ImageEnd; - - CopyMem (&TempRecord, OldRecord, sizeof(EFI_MEMORY_DESCRIPTOR)); - PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages); - NewRecordCount = 0; - - // - // Always create a new entry for non-PE image record - // - if (ImageRecord->ImageBase > TempRecord.PhysicalStart) { - NewRecord->Type = TempRecord.Type; - NewRecord->PhysicalStart = TempRecord.PhysicalStart; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages(ImageRecord->ImageBase - TempRecord.PhysicalStart); - NewRecord->Attribute = TempRecord.Attribute; - NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount ++; - TempRecord.PhysicalStart = ImageRecord->ImageBase; - TempRecord.NumberOfPages = EfiSizeToPages(PhysicalEnd - TempRecord.PhysicalStart); - } - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - - if (TempRecord.PhysicalStart <= ImageRecordCodeSection->CodeSegmentBase) { - // - // DATA - // - NewRecord->Type = EfiRuntimeServicesData; - NewRecord->PhysicalStart = TempRecord.PhysicalStart; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentBase - NewRecord->PhysicalStart); - NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP; - if (NewRecord->NumberOfPages != 0) { - NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount ++; - } - - // - // CODE - // - NewRecord->Type = EfiRuntimeServicesCode; - NewRecord->PhysicalStart = ImageRecordCodeSection->CodeSegmentBase; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize); - NewRecord->Attribute = (TempRecord.Attribute & (~EFI_MEMORY_XP)) | EFI_MEMORY_RO; - if (NewRecord->NumberOfPages != 0) { - NewRecord = NEXT_MEMORY_DESCRIPTOR (NewRecord, DescriptorSize); - NewRecordCount ++; - } - - TempRecord.PhysicalStart = ImageRecordCodeSection->CodeSegmentBase + EfiPagesToSize (EfiSizeToPages(ImageRecordCodeSection->CodeSegmentSize)); - TempRecord.NumberOfPages = EfiSizeToPages(PhysicalEnd - TempRecord.PhysicalStart); - if (TempRecord.NumberOfPages == 0) { - break; - } - } - } - - ImageEnd = ImageRecord->ImageBase + ImageRecord->ImageSize; - - // - // Final DATA - // - if (TempRecord.PhysicalStart < ImageEnd) { - NewRecord->Type = EfiRuntimeServicesData; - NewRecord->PhysicalStart = TempRecord.PhysicalStart; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = EfiSizeToPages (ImageEnd - TempRecord.PhysicalStart); - NewRecord->Attribute = TempRecord.Attribute | EFI_MEMORY_XP; - NewRecordCount ++; - } - - return NewRecordCount; -} - -/** - Return the max number of new splitted entries, according to one old entry, - based upon PE code section and data section. - - @param[in] OldRecord A pointer to one old memory map entry. - - @retval 0 no entry need to be splitted. - @return the max number of new splitted entries -**/ -STATIC -UINTN -GetMaxSplitRecordCount ( - IN EFI_MEMORY_DESCRIPTOR *OldRecord - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - UINTN SplitRecordCount; - UINT64 PhysicalStart; - UINT64 PhysicalEnd; - - SplitRecordCount = 0; - PhysicalStart = OldRecord->PhysicalStart; - PhysicalEnd = OldRecord->PhysicalStart + EfiPagesToSize(OldRecord->NumberOfPages); - - do { - ImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart); - if (ImageRecord == NULL) { - break; - } - SplitRecordCount += (2 * ImageRecord->CodeSegmentCount + 2); - PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; - } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); - - return SplitRecordCount; -} - -/** - Split the memory map to new entries, according to one old entry, - based upon PE code section and data section. - - @param[in] OldRecord A pointer to one old memory map entry. - @param[in, out] NewRecord A pointer to several new memory map entries. - The caller gurantee the buffer size be 1 + - (SplitRecordCount * DescriptorSize) calculated - below. - @param[in] MaxSplitRecordCount The max number of splitted entries - @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. - - @retval 0 no entry is splitted. - @return the real number of splitted record. -**/ -STATIC -UINTN -SplitRecord ( - IN EFI_MEMORY_DESCRIPTOR *OldRecord, - IN OUT EFI_MEMORY_DESCRIPTOR *NewRecord, - IN UINTN MaxSplitRecordCount, - IN UINTN DescriptorSize - ) -{ - EFI_MEMORY_DESCRIPTOR TempRecord; - IMAGE_PROPERTIES_RECORD *ImageRecord; - IMAGE_PROPERTIES_RECORD *NewImageRecord; - UINT64 PhysicalStart; - UINT64 PhysicalEnd; - UINTN NewRecordCount; - UINTN TotalNewRecordCount; - - if (MaxSplitRecordCount == 0) { - CopyMem (NewRecord, OldRecord, DescriptorSize); - return 0; - } - - TotalNewRecordCount = 0; - - // - // Override previous record - // - CopyMem (&TempRecord, OldRecord, sizeof(EFI_MEMORY_DESCRIPTOR)); - PhysicalStart = TempRecord.PhysicalStart; - PhysicalEnd = TempRecord.PhysicalStart + EfiPagesToSize(TempRecord.NumberOfPages); - - ImageRecord = NULL; - do { - NewImageRecord = GetImageRecordByAddress (PhysicalStart, PhysicalEnd - PhysicalStart); - if (NewImageRecord == NULL) { - // - // No more image covered by this range, stop - // - if (PhysicalEnd > PhysicalStart) { - // - // Always create a new entry for non-PE image record - // - NewRecord->Type = TempRecord.Type; - NewRecord->PhysicalStart = TempRecord.PhysicalStart; - NewRecord->VirtualStart = 0; - NewRecord->NumberOfPages = TempRecord.NumberOfPages; - NewRecord->Attribute = TempRecord.Attribute; - TotalNewRecordCount ++; - } - break; - } - ImageRecord = NewImageRecord; - - // - // Set new record - // - NewRecordCount = SetNewRecord (ImageRecord, NewRecord, &TempRecord, DescriptorSize); - TotalNewRecordCount += NewRecordCount; - NewRecord = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)NewRecord + NewRecordCount * DescriptorSize); - - // - // Update PhysicalStart, in order to exclude the image buffer already splitted. - // - PhysicalStart = ImageRecord->ImageBase + ImageRecord->ImageSize; - TempRecord.PhysicalStart = PhysicalStart; - TempRecord.NumberOfPages = EfiSizeToPages (PhysicalEnd - PhysicalStart); - } while ((ImageRecord != NULL) && (PhysicalStart < PhysicalEnd)); - - return TotalNewRecordCount - 1; -} - -/** - Split the original memory map, and add more entries to describe PE code section and data section. - This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP. - This function will merge entries with same attributes finally. - - NOTE: It assumes PE code/data section are page aligned. - NOTE: It assumes enough entry is prepared for new memory map. - - Split table: - +---------------+ - | Record X | - +---------------+ - | Record RtCode | - +---------------+ - | Record Y | - +---------------+ - ==> - +---------------+ - | Record X | - +---------------+ - | Record RtCode | - +---------------+ ---- - | Record RtData | | - +---------------+ | - | Record RtCode | |-> PE/COFF1 - +---------------+ | - | Record RtData | | - +---------------+ ---- - | Record RtCode | - +---------------+ ---- - | Record RtData | | - +---------------+ | - | Record RtCode | |-> PE/COFF2 - +---------------+ | - | Record RtData | | - +---------------+ ---- - | Record RtCode | - +---------------+ - | Record Y | - +---------------+ - - @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - old MemoryMap before split. The actual buffer - size of MemoryMap is MemoryMapSize + - (AdditionalRecordCount * DescriptorSize) calculated - below. On output, it is the size of new MemoryMap - after split. - @param[in, out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. -**/ -STATIC -VOID -SplitTable ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - IN UINTN DescriptorSize - ) -{ - INTN IndexOld; - INTN IndexNew; - UINTN MaxSplitRecordCount; - UINTN RealSplitRecordCount; - UINTN TotalSplitRecordCount; - UINTN AdditionalRecordCount; - - AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount; - - TotalSplitRecordCount = 0; - // - // Let old record point to end of valid MemoryMap buffer. - // - IndexOld = ((*MemoryMapSize) / DescriptorSize) - 1; - // - // Let new record point to end of full MemoryMap buffer. - // - IndexNew = ((*MemoryMapSize) / DescriptorSize) - 1 + AdditionalRecordCount; - for (; IndexOld >= 0; IndexOld--) { - MaxSplitRecordCount = GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize)); - // - // Split this MemoryMap record - // - IndexNew -= MaxSplitRecordCount; - RealSplitRecordCount = SplitRecord ( - (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexOld * DescriptorSize), - (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + IndexNew * DescriptorSize), - MaxSplitRecordCount, - DescriptorSize - ); - // - // Adjust IndexNew according to real split. - // - if (MaxSplitRecordCount != RealSplitRecordCount) { - CopyMem ( - ((UINT8 *)MemoryMap + (IndexNew + MaxSplitRecordCount - RealSplitRecordCount) * DescriptorSize), - ((UINT8 *)MemoryMap + IndexNew * DescriptorSize), - (RealSplitRecordCount + 1) * DescriptorSize - ); - } - IndexNew = IndexNew + MaxSplitRecordCount - RealSplitRecordCount; - TotalSplitRecordCount += RealSplitRecordCount; - IndexNew --; - } - // - // Move all records to the beginning. - // - CopyMem ( - MemoryMap, - (UINT8 *)MemoryMap + (AdditionalRecordCount - TotalSplitRecordCount) * DescriptorSize, - (*MemoryMapSize) + TotalSplitRecordCount * DescriptorSize - ); - - *MemoryMapSize = (*MemoryMapSize) + DescriptorSize * TotalSplitRecordCount; - - // - // Sort from low to high (Just in case) - // - SortMemoryMap (MemoryMap, *MemoryMapSize, DescriptorSize); - - // - // Set RuntimeData to XP - // - EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, DescriptorSize); - - // - // Merge same type to save entry size - // - MergeMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize); - - return ; -} - -/** - This function for GetMemoryMap() with memory attributes table. - - It calls original GetMemoryMap() to get the original memory map information. Then - plus the additional memory map entries for PE Code/Data seperation. - - @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param[in, out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[out] MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param[out] DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param[out] DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -STATIC -EFI_STATUS -EFIAPI -SmmCoreGetMemoryMapMemoryAttributesTable ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ) -{ - EFI_STATUS Status; - UINTN OldMemoryMapSize; - UINTN AdditionalRecordCount; - - // - // If PE code/data is not aligned, just return. - // - if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { - return SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); - } - - if (MemoryMapSize == NULL) { - return EFI_INVALID_PARAMETER; - } - - AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 2) * mImagePropertiesPrivateData.ImageRecordCount; - - OldMemoryMapSize = *MemoryMapSize; - Status = SmmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); - if (Status == EFI_BUFFER_TOO_SMALL) { - *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount; - } else if (Status == EFI_SUCCESS) { - if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) { - *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount; - // - // Need update status to buffer too small - // - Status = EFI_BUFFER_TOO_SMALL; - } else { - // - // Split PE code/data - // - ASSERT(MemoryMap != NULL); - SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize); - } - } - - return Status; -} - -// -// Below functions are for ImageRecord -// - -/** - Set MemoryProtectionAttribute according to PE/COFF image section alignment. - - @param[in] SectionAlignment PE/COFF section alignment -**/ -STATIC -VOID -SetMemoryAttributesTableSectionAlignment ( - IN UINT32 SectionAlignment - ) -{ - if (((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) && - ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) != 0)) { - DEBUG ((DEBUG_VERBOSE, "SMM SetMemoryAttributesTableSectionAlignment - Clear\n")); - mMemoryProtectionAttribute &= ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); - } -} - -/** - Swap two code sections in image record. - - @param[in] FirstImageRecordCodeSection first code section in image record - @param[in] SecondImageRecordCodeSection second code section in image record -**/ -STATIC -VOID -SwapImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *FirstImageRecordCodeSection, - IN IMAGE_PROPERTIES_RECORD_CODE_SECTION *SecondImageRecordCodeSection - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection; - - TempImageRecordCodeSection.CodeSegmentBase = FirstImageRecordCodeSection->CodeSegmentBase; - TempImageRecordCodeSection.CodeSegmentSize = FirstImageRecordCodeSection->CodeSegmentSize; - - FirstImageRecordCodeSection->CodeSegmentBase = SecondImageRecordCodeSection->CodeSegmentBase; - FirstImageRecordCodeSection->CodeSegmentSize = SecondImageRecordCodeSection->CodeSegmentSize; - - SecondImageRecordCodeSection->CodeSegmentBase = TempImageRecordCodeSection.CodeSegmentBase; - SecondImageRecordCodeSection->CodeSegmentSize = TempImageRecordCodeSection.CodeSegmentSize; -} - -/** - Sort code section in image record, based upon CodeSegmentBase from low to high. - - @param[in] ImageRecord image record to be sorted -**/ -STATIC -VOID -SortImageRecordCodeSection ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *NextImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *NextImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - while (NextImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - NextImageRecordCodeSection = CR ( - NextImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - if (ImageRecordCodeSection->CodeSegmentBase > NextImageRecordCodeSection->CodeSegmentBase) { - SwapImageRecordCodeSection (ImageRecordCodeSection, NextImageRecordCodeSection); - } - NextImageRecordCodeSectionLink = NextImageRecordCodeSectionLink->ForwardLink; - } - - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - NextImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - } -} - -/** - Check if code section in image record is valid. - - @param[in] ImageRecord image record to be checked - - @retval TRUE image record is valid - @retval FALSE image record is invalid -**/ -STATIC -BOOLEAN -IsImageRecordCodeSectionValid ( - IN IMAGE_PROPERTIES_RECORD *ImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *LastImageRecordCodeSection; - LIST_ENTRY *ImageRecordCodeSectionLink; - LIST_ENTRY *ImageRecordCodeSectionEndLink; - LIST_ENTRY *ImageRecordCodeSectionList; - - DEBUG ((DEBUG_VERBOSE, "SMM ImageCode SegmentCount - 0x%x\n", ImageRecord->CodeSegmentCount)); - - ImageRecordCodeSectionList = &ImageRecord->CodeSegmentList; - - ImageRecordCodeSectionLink = ImageRecordCodeSectionList->ForwardLink; - ImageRecordCodeSectionEndLink = ImageRecordCodeSectionList; - LastImageRecordCodeSection = NULL; - while (ImageRecordCodeSectionLink != ImageRecordCodeSectionEndLink) { - ImageRecordCodeSection = CR ( - ImageRecordCodeSectionLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - if (ImageRecordCodeSection->CodeSegmentSize == 0) { - return FALSE; - } - if (ImageRecordCodeSection->CodeSegmentBase < ImageRecord->ImageBase) { - return FALSE; - } - if (ImageRecordCodeSection->CodeSegmentBase >= MAX_ADDRESS - ImageRecordCodeSection->CodeSegmentSize) { - return FALSE; - } - if ((ImageRecordCodeSection->CodeSegmentBase + ImageRecordCodeSection->CodeSegmentSize) > (ImageRecord->ImageBase + ImageRecord->ImageSize)) { - return FALSE; - } - if (LastImageRecordCodeSection != NULL) { - if ((LastImageRecordCodeSection->CodeSegmentBase + LastImageRecordCodeSection->CodeSegmentSize) > ImageRecordCodeSection->CodeSegmentBase) { - return FALSE; - } - } - - LastImageRecordCodeSection = ImageRecordCodeSection; - ImageRecordCodeSectionLink = ImageRecordCodeSectionLink->ForwardLink; - } - - return TRUE; -} - -/** - Swap two image records. - - @param[in] FirstImageRecord first image record. - @param[in] SecondImageRecord second image record. -**/ -STATIC -VOID -SwapImageRecord ( - IN IMAGE_PROPERTIES_RECORD *FirstImageRecord, - IN IMAGE_PROPERTIES_RECORD *SecondImageRecord - ) -{ - IMAGE_PROPERTIES_RECORD TempImageRecord; - - TempImageRecord.ImageBase = FirstImageRecord->ImageBase; - TempImageRecord.ImageSize = FirstImageRecord->ImageSize; - TempImageRecord.CodeSegmentCount = FirstImageRecord->CodeSegmentCount; - - FirstImageRecord->ImageBase = SecondImageRecord->ImageBase; - FirstImageRecord->ImageSize = SecondImageRecord->ImageSize; - FirstImageRecord->CodeSegmentCount = SecondImageRecord->CodeSegmentCount; - - SecondImageRecord->ImageBase = TempImageRecord.ImageBase; - SecondImageRecord->ImageSize = TempImageRecord.ImageSize; - SecondImageRecord->CodeSegmentCount = TempImageRecord.CodeSegmentCount; - - SwapListEntries (&FirstImageRecord->CodeSegmentList, &SecondImageRecord->CodeSegmentList); -} - -/** - Sort image record based upon the ImageBase from low to high. -**/ -STATIC -VOID -SortImageRecord ( - VOID - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - IMAGE_PROPERTIES_RECORD *NextImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *NextImageRecordLink; - LIST_ENTRY *ImageRecordEndLink; - LIST_ENTRY *ImageRecordList; - - ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; - - ImageRecordLink = ImageRecordList->ForwardLink; - NextImageRecordLink = ImageRecordLink->ForwardLink; - ImageRecordEndLink = ImageRecordList; - while (ImageRecordLink != ImageRecordEndLink) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - while (NextImageRecordLink != ImageRecordEndLink) { - NextImageRecord = CR ( - NextImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - if (ImageRecord->ImageBase > NextImageRecord->ImageBase) { - SwapImageRecord (ImageRecord, NextImageRecord); - } - NextImageRecordLink = NextImageRecordLink->ForwardLink; - } - - ImageRecordLink = ImageRecordLink->ForwardLink; - NextImageRecordLink = ImageRecordLink->ForwardLink; - } -} - -/** - Dump image record. -**/ -STATIC -VOID -DumpImageRecord ( - VOID - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *ImageRecordList; - UINTN Index; - - ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; - - for (ImageRecordLink = ImageRecordList->ForwardLink, Index= 0; - ImageRecordLink != ImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink, Index++) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - DEBUG ((DEBUG_VERBOSE, "SMM Image[%d]: 0x%016lx - 0x%016lx\n", Index, ImageRecord->ImageBase, ImageRecord->ImageSize)); - } -} - -/** - Insert image record. - - @param[in] DriverEntry Driver information -**/ -VOID -SmmInsertImageRecord ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry - ) -{ - VOID *ImageAddress; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT32 PeCoffHeaderOffset; - UINT32 SectionAlignment; - EFI_IMAGE_SECTION_HEADER *Section; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - UINT8 *Name; - UINTN Index; - IMAGE_PROPERTIES_RECORD *ImageRecord; - CHAR8 *PdbPointer; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - UINT16 Magic; - - DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%x\n", DriverEntry)); - DEBUG ((DEBUG_VERBOSE, "SMM InsertImageRecord - 0x%016lx - 0x%08x\n", DriverEntry->ImageBuffer, DriverEntry->NumberOfPage)); - - ImageRecord = AllocatePool (sizeof(*ImageRecord)); - if (ImageRecord == NULL) { - return ; - } - ImageRecord->Signature = IMAGE_PROPERTIES_RECORD_SIGNATURE; - - DEBUG ((DEBUG_VERBOSE, "SMM ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); - - // - // Step 1: record whole region - // - ImageRecord->ImageBase = DriverEntry->ImageBuffer; - ImageRecord->ImageSize = EfiPagesToSize(DriverEntry->NumberOfPage); - - ImageAddress = (VOID *)(UINTN)DriverEntry->ImageBuffer; - - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_VERBOSE, "SMM Image - %a\n", PdbPointer)); - } - - // - // Check PE/COFF image - // - DosHdr = (EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress; - PeCoffHeaderOffset = 0; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - PeCoffHeaderOffset = DosHdr->e_lfanew; - } - - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINT8 *) (UINTN) ImageAddress + PeCoffHeaderOffset); - if (Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - DEBUG ((DEBUG_VERBOSE, "SMM Hdr.Pe32->Signature invalid - 0x%x\n", Hdr.Pe32->Signature)); - goto Finish; - } - - // - // Get SectionAlignment - // - if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - // - // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value - // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the - // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - } else { - // - // Get the magic value from the PE/COFF Optional Header - // - Magic = Hdr.Pe32->OptionalHeader.Magic; - } - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment; - } else { - SectionAlignment = Hdr.Pe32Plus->OptionalHeader.SectionAlignment; - } - - SetMemoryAttributesTableSectionAlignment (SectionAlignment); - if ((SectionAlignment & (RUNTIME_PAGE_ALLOCATION_GRANULARITY - 1)) != 0) { - DEBUG ((DEBUG_WARN, "SMM !!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n", - SectionAlignment, RUNTIME_PAGE_ALLOCATION_GRANULARITY >> 10)); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_WARN, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); - } - goto Finish; - } - - Section = (EFI_IMAGE_SECTION_HEADER *) ( - (UINT8 *) (UINTN) ImageAddress + - PeCoffHeaderOffset + - sizeof(UINT32) + - sizeof(EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); - ImageRecord->CodeSegmentCount = 0; - InitializeListHead (&ImageRecord->CodeSegmentList); - for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) { - Name = Section[Index].Name; - DEBUG (( - DEBUG_VERBOSE, - "SMM Section - '%c%c%c%c%c%c%c%c'\n", - Name[0], - Name[1], - Name[2], - Name[3], - Name[4], - Name[5], - Name[6], - Name[7] - )); - - if ((Section[Index].Characteristics & EFI_IMAGE_SCN_CNT_CODE) != 0) { - DEBUG ((DEBUG_VERBOSE, "SMM VirtualSize - 0x%08x\n", Section[Index].Misc.VirtualSize)); - DEBUG ((DEBUG_VERBOSE, "SMM VirtualAddress - 0x%08x\n", Section[Index].VirtualAddress)); - DEBUG ((DEBUG_VERBOSE, "SMM SizeOfRawData - 0x%08x\n", Section[Index].SizeOfRawData)); - DEBUG ((DEBUG_VERBOSE, "SMM PointerToRawData - 0x%08x\n", Section[Index].PointerToRawData)); - DEBUG ((DEBUG_VERBOSE, "SMM PointerToRelocations - 0x%08x\n", Section[Index].PointerToRelocations)); - DEBUG ((DEBUG_VERBOSE, "SMM PointerToLinenumbers - 0x%08x\n", Section[Index].PointerToLinenumbers)); - DEBUG ((DEBUG_VERBOSE, "SMM NumberOfRelocations - 0x%08x\n", Section[Index].NumberOfRelocations)); - DEBUG ((DEBUG_VERBOSE, "SMM NumberOfLinenumbers - 0x%08x\n", Section[Index].NumberOfLinenumbers)); - DEBUG ((DEBUG_VERBOSE, "SMM Characteristics - 0x%08x\n", Section[Index].Characteristics)); - - // - // Step 2: record code section - // - ImageRecordCodeSection = AllocatePool (sizeof(*ImageRecordCodeSection)); - if (ImageRecordCodeSection == NULL) { - return ; - } - ImageRecordCodeSection->Signature = IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE; - - ImageRecordCodeSection->CodeSegmentBase = (UINTN)ImageAddress + Section[Index].VirtualAddress; - ImageRecordCodeSection->CodeSegmentSize = Section[Index].SizeOfRawData; - - DEBUG ((DEBUG_VERBOSE, "SMM ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection->CodeSegmentBase, ImageRecordCodeSection->CodeSegmentSize)); - - InsertTailList (&ImageRecord->CodeSegmentList, &ImageRecordCodeSection->Link); - ImageRecord->CodeSegmentCount++; - } - } - - if (ImageRecord->CodeSegmentCount == 0) { - SetMemoryAttributesTableSectionAlignment (1); - DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n")); - PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageAddress); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); - } - goto Finish; - } - - // - // Final - // - SortImageRecordCodeSection (ImageRecord); - // - // Check overlap all section in ImageBase/Size - // - if (!IsImageRecordCodeSectionValid (ImageRecord)) { - DEBUG ((DEBUG_ERROR, "SMM IsImageRecordCodeSectionValid - FAIL\n")); - goto Finish; - } - - InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link); - mImagePropertiesPrivateData.ImageRecordCount++; - - SortImageRecord (); - - if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) { - mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount; - } - -Finish: - return ; -} - -/** - Find image record according to image base and size. - - @param[in] ImageBase Base of PE image - @param[in] ImageSize Size of PE image - - @return image record -**/ -STATIC -IMAGE_PROPERTIES_RECORD * -FindImageRecord ( - IN EFI_PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *ImageRecordLink; - LIST_ENTRY *ImageRecordList; - - ImageRecordList = &mImagePropertiesPrivateData.ImageRecordList; - - for (ImageRecordLink = ImageRecordList->ForwardLink; - ImageRecordLink != ImageRecordList; - ImageRecordLink = ImageRecordLink->ForwardLink) { - ImageRecord = CR ( - ImageRecordLink, - IMAGE_PROPERTIES_RECORD, - Link, - IMAGE_PROPERTIES_RECORD_SIGNATURE - ); - - if ((ImageBase == ImageRecord->ImageBase) && - (ImageSize == ImageRecord->ImageSize)) { - return ImageRecord; - } - } - - return NULL; -} - -/** - Remove Image record. - - @param[in] DriverEntry Driver information -**/ -VOID -SmmRemoveImageRecord ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry - ) -{ - IMAGE_PROPERTIES_RECORD *ImageRecord; - LIST_ENTRY *CodeSegmentListHead; - IMAGE_PROPERTIES_RECORD_CODE_SECTION *ImageRecordCodeSection; - - DEBUG ((DEBUG_VERBOSE, "SMM RemoveImageRecord - 0x%x\n", DriverEntry)); - DEBUG ((DEBUG_VERBOSE, "SMM RemoveImageRecord - 0x%016lx - 0x%016lx\n", DriverEntry->ImageBuffer, DriverEntry->NumberOfPage)); - - ImageRecord = FindImageRecord (DriverEntry->ImageBuffer, EfiPagesToSize(DriverEntry->NumberOfPage)); - if (ImageRecord == NULL) { - DEBUG ((DEBUG_ERROR, "SMM !!!!!!!! ImageRecord not found !!!!!!!!\n")); - return ; - } - - CodeSegmentListHead = &ImageRecord->CodeSegmentList; - while (!IsListEmpty (CodeSegmentListHead)) { - ImageRecordCodeSection = CR ( - CodeSegmentListHead->ForwardLink, - IMAGE_PROPERTIES_RECORD_CODE_SECTION, - Link, - IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE - ); - RemoveEntryList (&ImageRecordCodeSection->Link); - FreePool (ImageRecordCodeSection); - } - - RemoveEntryList (&ImageRecord->Link); - FreePool (ImageRecord); - mImagePropertiesPrivateData.ImageRecordCount--; -} - -/** - Publish MemoryAttributesTable to SMM configuration table. -**/ -VOID -PublishMemoryAttributesTable ( - VOID - ) -{ - UINTN MemoryMapSize; - EFI_MEMORY_DESCRIPTOR *MemoryMap; - UINTN MapKey; - UINTN DescriptorSize; - UINT32 DescriptorVersion; - UINTN Index; - EFI_STATUS Status; - UINTN RuntimeEntryCount; - EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; - UINTN MemoryAttributesTableSize; - - MemoryMapSize = 0; - MemoryMap = NULL; - Status = SmmCoreGetMemoryMapMemoryAttributesTable ( - &MemoryMapSize, - MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion - ); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - do { - DEBUG ((DEBUG_INFO, "MemoryMapSize - 0x%x\n", MemoryMapSize)); - MemoryMap = AllocatePool (MemoryMapSize); - ASSERT (MemoryMap != NULL); - DEBUG ((DEBUG_INFO, "MemoryMap - 0x%x\n", MemoryMap)); - - Status = SmmCoreGetMemoryMapMemoryAttributesTable ( - &MemoryMapSize, - MemoryMap, - &MapKey, - &DescriptorSize, - &DescriptorVersion - ); - if (EFI_ERROR (Status)) { - FreePool (MemoryMap); - } - } while (Status == EFI_BUFFER_TOO_SMALL); - - // - // Allocate MemoryAttributesTable - // - RuntimeEntryCount = MemoryMapSize/DescriptorSize; - MemoryAttributesTableSize = sizeof(EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount; - MemoryAttributesTable = AllocatePool (sizeof(EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount); - ASSERT (MemoryAttributesTable != NULL); - MemoryAttributesTable->Version = EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE_VERSION; - MemoryAttributesTable->NumberOfEntries = (UINT32)RuntimeEntryCount; - MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize; - MemoryAttributesTable->Reserved = 0; - DEBUG ((DEBUG_INFO, "MemoryAttributesTable:\n")); - DEBUG ((DEBUG_INFO, " Version - 0x%08x\n", MemoryAttributesTable->Version)); - DEBUG ((DEBUG_INFO, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); - DEBUG ((DEBUG_INFO, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize)); - MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1); - for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) { - CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize); - DEBUG ((DEBUG_INFO, "Entry (0x%x)\n", MemoryAttributesEntry)); - DEBUG ((DEBUG_INFO, " Type - 0x%x\n", MemoryAttributesEntry->Type)); - DEBUG ((DEBUG_INFO, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart)); - DEBUG ((DEBUG_INFO, " VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart)); - DEBUG ((DEBUG_INFO, " NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages)); - DEBUG ((DEBUG_INFO, " Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute)); - MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR(MemoryAttributesEntry, DescriptorSize); - - MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize); - } - - Status = gSmst->SmmInstallConfigurationTable (gSmst, &gEdkiiPiSmmMemoryAttributesTableGuid, MemoryAttributesTable, MemoryAttributesTableSize); - ASSERT_EFI_ERROR (Status); -} - -/** - This function returns if image is inside SMRAM. - - @param[in] LoadedImage LoadedImage protocol instance for an image. - - @retval TRUE the image is inside SMRAM. - @retval FALSE the image is outside SMRAM. -**/ -BOOLEAN -IsImageInsideSmram ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage - ) -{ - UINTN Index; - - for (Index = 0; Index < mFullSmramRangeCount; Index++) { - if ((mFullSmramRanges[Index].PhysicalStart <= (UINTN)LoadedImage->ImageBase)&& - (mFullSmramRanges[Index].PhysicalStart + mFullSmramRanges[Index].PhysicalSize >= (UINTN)LoadedImage->ImageBase + LoadedImage->ImageSize)) { - return TRUE; - } - } - - return FALSE; -} - -/** - This function installs all SMM image record information. -**/ -VOID -SmmInstallImageRecord ( - VOID - ) -{ - EFI_STATUS Status; - UINTN NoHandles; - EFI_HANDLE *HandleBuffer; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - UINTN Index; - EFI_SMM_DRIVER_ENTRY DriverEntry; - - Status = SmmLocateHandleBuffer ( - ByProtocol, - &gEfiLoadedImageProtocolGuid, - NULL, - &NoHandles, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return ; - } - - for (Index = 0; Index < NoHandles; Index++) { - Status = gSmst->SmmHandleProtocol ( - HandleBuffer[Index], - &gEfiLoadedImageProtocolGuid, - (VOID **)&LoadedImage - ); - if (EFI_ERROR (Status)) { - continue; - } - DEBUG ((DEBUG_VERBOSE, "LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize)); - { - VOID *PdbPointer; - PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase); - if (PdbPointer != NULL) { - DEBUG ((DEBUG_VERBOSE, "(%a) ", PdbPointer)); - } - } - DEBUG ((DEBUG_VERBOSE, "\n")); - ZeroMem (&DriverEntry, sizeof(DriverEntry)); - DriverEntry.ImageBuffer = (UINTN)LoadedImage->ImageBase; - DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES((UINTN)LoadedImage->ImageSize); - SmmInsertImageRecord (&DriverEntry); - } - - FreePool (HandleBuffer); -} - -/** - Install MemoryAttributesTable. - - @param[in] Protocol Points to the protocol's unique identifier. - @param[in] Interface Points to the interface instance. - @param[in] Handle The handle on which the interface was installed. - - @retval EFI_SUCCESS Notification runs successfully. -**/ -EFI_STATUS -EFIAPI -SmmInstallMemoryAttributesTable ( - IN CONST EFI_GUID *Protocol, - IN VOID *Interface, - IN EFI_HANDLE Handle - ) -{ - SmmInstallImageRecord (); - - DEBUG ((DEBUG_INFO, "SMM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute)); - if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { - return EFI_SUCCESS; - } - - DEBUG ((DEBUG_VERBOSE, "SMM Total Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); - DEBUG ((DEBUG_VERBOSE, "SMM Dump ImageRecord:\n")); - DumpImageRecord (); - - PublishMemoryAttributesTable (); - - return EFI_SUCCESS; -} - -/** - Initialize MemoryAttributesTable support. -**/ -VOID -EFIAPI -SmmCoreInitializeMemoryAttributesTable ( - VOID - ) -{ - EFI_STATUS Status; - VOID *Registration; - - Status = gSmst->SmmRegisterProtocolNotify ( - &gEfiSmmEndOfDxeProtocolGuid, - SmmInstallMemoryAttributesTable, - &Registration - ); - ASSERT_EFI_ERROR (Status); - - return ; -} diff --git a/MdeModulePkg/Core/PiSmmCore/Notify.c b/MdeModulePkg/Core/PiSmmCore/Notify.c deleted file mode 100644 index 0054fe66aa..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/Notify.c +++ /dev/null @@ -1,202 +0,0 @@ -/** @file - Support functions for UEFI protocol notification infrastructure. - - Copyright (c) 2009 - 2015, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -/** - Signal event for every protocol in protocol entry. - - @param Prot Protocol interface - -**/ -VOID -SmmNotifyProtocol ( - IN PROTOCOL_INTERFACE *Prot - ) -{ - PROTOCOL_ENTRY *ProtEntry; - PROTOCOL_NOTIFY *ProtNotify; - LIST_ENTRY *Link; - - ProtEntry = Prot->Protocol; - for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) { - ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); - ProtNotify->Function (&ProtEntry->ProtocolID, Prot->Interface, Prot->Handle); - } -} - -/** - Removes Protocol from the protocol list (but not the handle list). - - @param Handle The handle to remove protocol on. - @param Protocol GUID of the protocol to be moved - @param Interface The interface of the protocol - - @return Protocol Entry - -**/ -PROTOCOL_INTERFACE * -SmmRemoveInterfaceFromProtocol ( - IN IHANDLE *Handle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ) -{ - PROTOCOL_INTERFACE *Prot; - PROTOCOL_NOTIFY *ProtNotify; - PROTOCOL_ENTRY *ProtEntry; - LIST_ENTRY *Link; - - Prot = SmmFindProtocolInterface (Handle, Protocol, Interface); - if (Prot != NULL) { - - ProtEntry = Prot->Protocol; - - // - // If there's a protocol notify location pointing to this entry, back it up one - // - for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) { - ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); - - if (ProtNotify->Position == &Prot->ByProtocol) { - ProtNotify->Position = Prot->ByProtocol.BackLink; - } - } - - // - // Remove the protocol interface entry - // - RemoveEntryList (&Prot->ByProtocol); - } - - return Prot; -} - -/** - Add a new protocol notification record for the request protocol. - - @param Protocol The requested protocol to add the notify - registration - @param Function Points to the notification function - @param Registration Returns the registration record - - @retval EFI_SUCCESS Successfully returned the registration record - that has been added or unhooked - @retval EFI_INVALID_PARAMETER Protocol is NULL or Registration is NULL - @retval EFI_OUT_OF_RESOURCES Not enough memory resource to finish the request - @retval EFI_NOT_FOUND If the registration is not found when Function == NULL - -**/ -EFI_STATUS -EFIAPI -SmmRegisterProtocolNotify ( - IN CONST EFI_GUID *Protocol, - IN EFI_SMM_NOTIFY_FN Function, - OUT VOID **Registration - ) -{ - PROTOCOL_ENTRY *ProtEntry; - PROTOCOL_NOTIFY *ProtNotify; - LIST_ENTRY *Link; - EFI_STATUS Status; - - if (Protocol == NULL || Registration == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (Function == NULL) { - // - // Get the protocol entry per Protocol - // - ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, FALSE); - if (ProtEntry != NULL) { - ProtNotify = (PROTOCOL_NOTIFY * )*Registration; - for (Link = ProtEntry->Notify.ForwardLink; - Link != &ProtEntry->Notify; - Link = Link->ForwardLink) { - // - // Compare the notification record - // - if (ProtNotify == (CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE))){ - // - // If Registration is an existing registration, then unhook it - // - ProtNotify->Signature = 0; - RemoveEntryList (&ProtNotify->Link); - FreePool (ProtNotify); - return EFI_SUCCESS; - } - } - } - // - // If the registration is not found - // - return EFI_NOT_FOUND; - } - - ProtNotify = NULL; - - // - // Get the protocol entry to add the notification too - // - ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, TRUE); - if (ProtEntry != NULL) { - // - // Find whether notification already exist - // - for (Link = ProtEntry->Notify.ForwardLink; - Link != &ProtEntry->Notify; - Link = Link->ForwardLink) { - - ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); - if (CompareGuid (&ProtNotify->Protocol->ProtocolID, Protocol) && - (ProtNotify->Function == Function)) { - - // - // Notification already exist - // - *Registration = ProtNotify; - - return EFI_SUCCESS; - } - } - - // - // Allocate a new notification record - // - ProtNotify = AllocatePool (sizeof(PROTOCOL_NOTIFY)); - if (ProtNotify != NULL) { - ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE; - ProtNotify->Protocol = ProtEntry; - ProtNotify->Function = Function; - // - // Start at the ending - // - ProtNotify->Position = ProtEntry->Protocols.BackLink; - - InsertTailList (&ProtEntry->Notify, &ProtNotify->Link); - } - } - - // - // Done. If we have a protocol notify entry, then return it. - // Otherwise, we must have run out of resources trying to add one - // - Status = EFI_OUT_OF_RESOURCES; - if (ProtNotify != NULL) { - *Registration = ProtNotify; - Status = EFI_SUCCESS; - } - return Status; -} diff --git a/MdeModulePkg/Core/PiSmmCore/Page.c b/MdeModulePkg/Core/PiSmmCore/Page.c deleted file mode 100644 index 4154c2e6a1..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/Page.c +++ /dev/null @@ -1,1121 +0,0 @@ -/** @file - SMM Memory page management functions. - - Copyright (c) 2009 - 2016, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" -#include - -#define TRUNCATE_TO_PAGES(a) ((a) >> EFI_PAGE_SHIFT) - -LIST_ENTRY mSmmMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (mSmmMemoryMap); - -// -// For GetMemoryMap() -// - -#define MEMORY_MAP_SIGNATURE SIGNATURE_32('m','m','a','p') -typedef struct { - UINTN Signature; - LIST_ENTRY Link; - - BOOLEAN FromStack; - EFI_MEMORY_TYPE Type; - UINT64 Start; - UINT64 End; - -} MEMORY_MAP; - -LIST_ENTRY gMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (gMemoryMap); - - -#define MAX_MAP_DEPTH 6 - -/// -/// mMapDepth - depth of new descriptor stack -/// -UINTN mMapDepth = 0; -/// -/// mMapStack - space to use as temp storage to build new map descriptors -/// -MEMORY_MAP mMapStack[MAX_MAP_DEPTH]; -UINTN mFreeMapStack = 0; -/// -/// This list maintain the free memory map list -/// -LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemoryMapEntryList); - -/** - Allocates pages from the memory map. - - @param[in] Type The type of allocation to perform. - @param[in] MemoryType The type of memory to turn the allocated pages - into. - @param[in] NumberOfPages The number of pages to allocate. - @param[out] Memory A pointer to receive the base allocated memory - address. - @param[in] AddRegion If this memory is new added region. - - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -SmmInternalAllocatePagesEx ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory, - IN BOOLEAN AddRegion - ); - -/** - Internal function. Deque a descriptor entry from the mFreeMemoryMapEntryList. - If the list is emtry, then allocate a new page to refuel the list. - Please Note this algorithm to allocate the memory map descriptor has a property - that the memory allocated for memory entries always grows, and will never really be freed. - - @return The Memory map descriptor dequed from the mFreeMemoryMapEntryList - -**/ -MEMORY_MAP * -AllocateMemoryMapEntry ( - VOID - ) -{ - EFI_PHYSICAL_ADDRESS Mem; - EFI_STATUS Status; - MEMORY_MAP* FreeDescriptorEntries; - MEMORY_MAP* Entry; - UINTN Index; - - //DEBUG((DEBUG_INFO, "AllocateMemoryMapEntry\n")); - - if (IsListEmpty (&mFreeMemoryMapEntryList)) { - //DEBUG((DEBUG_INFO, "mFreeMemoryMapEntryList is empty\n")); - // - // The list is empty, to allocate one page to refuel the list - // - Status = SmmInternalAllocatePagesEx ( - AllocateAnyPages, - EfiRuntimeServicesData, - EFI_SIZE_TO_PAGES (RUNTIME_PAGE_ALLOCATION_GRANULARITY), - &Mem, - TRUE - ); - ASSERT_EFI_ERROR (Status); - if(!EFI_ERROR (Status)) { - FreeDescriptorEntries = (MEMORY_MAP *)(UINTN)Mem; - //DEBUG((DEBUG_INFO, "New FreeDescriptorEntries - 0x%x\n", FreeDescriptorEntries)); - // - // Enque the free memmory map entries into the list - // - for (Index = 0; Index< RUNTIME_PAGE_ALLOCATION_GRANULARITY / sizeof(MEMORY_MAP); Index++) { - FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE; - InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link); - } - } else { - return NULL; - } - } - // - // dequeue the first descriptor from the list - // - Entry = CR (mFreeMemoryMapEntryList.ForwardLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - RemoveEntryList (&Entry->Link); - - return Entry; -} - - -/** - Internal function. Moves any memory descriptors that are on the - temporary descriptor stack to heap. - -**/ -VOID -CoreFreeMemoryMapStack ( - VOID - ) -{ - MEMORY_MAP *Entry; - - // - // If already freeing the map stack, then return - // - if (mFreeMapStack != 0) { - ASSERT (FALSE); - return ; - } - - // - // Move the temporary memory descriptor stack into pool - // - mFreeMapStack += 1; - - while (mMapDepth != 0) { - // - // Deque an memory map entry from mFreeMemoryMapEntryList - // - Entry = AllocateMemoryMapEntry (); - ASSERT (Entry); - - // - // Update to proper entry - // - mMapDepth -= 1; - - if (mMapStack[mMapDepth].Link.ForwardLink != NULL) { - - CopyMem (Entry , &mMapStack[mMapDepth], sizeof (MEMORY_MAP)); - Entry->FromStack = FALSE; - - // - // Move this entry to general memory - // - InsertTailList (&mMapStack[mMapDepth].Link, &Entry->Link); - RemoveEntryList (&mMapStack[mMapDepth].Link); - mMapStack[mMapDepth].Link.ForwardLink = NULL; - } - } - - mFreeMapStack -= 1; -} - -/** - Insert new entry from memory map. - - @param[in] Link The old memory map entry to be linked. - @param[in] Start The start address of new memory map entry. - @param[in] End The end address of new memory map entry. - @param[in] Type The type of new memory map entry. - @param[in] Next If new entry is inserted to the next of old entry. - @param[in] AddRegion If this memory is new added region. -**/ -VOID -InsertNewEntry ( - IN LIST_ENTRY *Link, - IN UINT64 Start, - IN UINT64 End, - IN EFI_MEMORY_TYPE Type, - IN BOOLEAN Next, - IN BOOLEAN AddRegion - ) -{ - MEMORY_MAP *Entry; - - Entry = &mMapStack[mMapDepth]; - mMapDepth += 1; - ASSERT (mMapDepth < MAX_MAP_DEPTH); - Entry->FromStack = TRUE; - - Entry->Signature = MEMORY_MAP_SIGNATURE; - Entry->Type = Type; - Entry->Start = Start; - Entry->End = End; - if (Next) { - InsertHeadList (Link, &Entry->Link); - } else { - InsertTailList (Link, &Entry->Link); - } -} - -/** - Remove old entry from memory map. - - @param[in] Entry Memory map entry to be removed. -**/ -VOID -RemoveOldEntry ( - IN MEMORY_MAP *Entry - ) -{ - RemoveEntryList (&Entry->Link); - if (!Entry->FromStack) { - InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link); - } -} - -/** - Update SMM memory map entry. - - @param[in] Type The type of allocation to perform. - @param[in] Memory The base of memory address. - @param[in] NumberOfPages The number of pages to allocate. - @param[in] AddRegion If this memory is new added region. -**/ -VOID -ConvertSmmMemoryMapEntry ( - IN EFI_MEMORY_TYPE Type, - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages, - IN BOOLEAN AddRegion - ) -{ - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - MEMORY_MAP *NextEntry; - LIST_ENTRY *NextLink; - MEMORY_MAP *PreviousEntry; - LIST_ENTRY *PreviousLink; - EFI_PHYSICAL_ADDRESS Start; - EFI_PHYSICAL_ADDRESS End; - - Start = Memory; - End = Memory + EFI_PAGES_TO_SIZE(NumberOfPages) - 1; - - // - // Exclude memory region - // - Link = gMemoryMap.ForwardLink; - while (Link != &gMemoryMap) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - Link = Link->ForwardLink; - - // - // --------------------------------------------------- - // | +----------+ +------+ +------+ +------+ | - // ---|gMemoryMep|---|Entry1|---|Entry2|---|Entry3|--- - // +----------+ ^ +------+ +------+ +------+ - // | - // +------+ - // |EntryX| - // +------+ - // - if (Entry->Start > End) { - if ((Entry->Start == End + 1) && (Entry->Type == Type)) { - Entry->Start = Start; - return ; - } - InsertNewEntry ( - &Entry->Link, - Start, - End, - Type, - FALSE, - AddRegion - ); - return ; - } - - if ((Entry->Start <= Start) && (Entry->End >= End)) { - if (Entry->Type != Type) { - if (Entry->Start < Start) { - // - // --------------------------------------------------- - // | +----------+ +------+ +------+ +------+ | - // ---|gMemoryMep|---|Entry1|---|EntryX|---|Entry3|--- - // +----------+ +------+ ^ +------+ +------+ - // | - // +------+ - // |EntryA| - // +------+ - // - InsertNewEntry ( - &Entry->Link, - Entry->Start, - Start - 1, - Entry->Type, - FALSE, - AddRegion - ); - } - if (Entry->End > End) { - // - // --------------------------------------------------- - // | +----------+ +------+ +------+ +------+ | - // ---|gMemoryMep|---|Entry1|---|EntryX|---|Entry3|--- - // +----------+ +------+ +------+ ^ +------+ - // | - // +------+ - // |EntryZ| - // +------+ - // - InsertNewEntry ( - &Entry->Link, - End + 1, - Entry->End, - Entry->Type, - TRUE, - AddRegion - ); - } - // - // Update this node - // - Entry->Start = Start; - Entry->End = End; - Entry->Type = Type; - - // - // Check adjacent - // - NextLink = Entry->Link.ForwardLink; - if (NextLink != &gMemoryMap) { - NextEntry = CR (NextLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - // - // --------------------------------------------------- - // | +----------+ +------+ +-----------------+ | - // ---|gMemoryMep|---|Entry1|---|EntryX Entry3|--- - // +----------+ +------+ +-----------------+ - // - if ((Entry->Type == NextEntry->Type) && (Entry->End + 1 == NextEntry->Start)) { - Entry->End = NextEntry->End; - RemoveOldEntry (NextEntry); - } - } - PreviousLink = Entry->Link.BackLink; - if (PreviousLink != &gMemoryMap) { - PreviousEntry = CR (PreviousLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - // - // --------------------------------------------------- - // | +----------+ +-----------------+ +------+ | - // ---|gMemoryMep|---|Entry1 EntryX|---|Entry3|--- - // +----------+ +-----------------+ +------+ - // - if ((PreviousEntry->Type == Entry->Type) && (PreviousEntry->End + 1 == Entry->Start)) { - PreviousEntry->End = Entry->End; - RemoveOldEntry (Entry); - } - } - } - return ; - } - } - - // - // --------------------------------------------------- - // | +----------+ +------+ +------+ +------+ | - // ---|gMemoryMep|---|Entry1|---|Entry2|---|Entry3|--- - // +----------+ +------+ +------+ +------+ ^ - // | - // +------+ - // |EntryX| - // +------+ - // - Link = gMemoryMap.BackLink; - if (Link != &gMemoryMap) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - if ((Entry->End + 1 == Start) && (Entry->Type == Type)) { - Entry->End = End; - return ; - } - } - InsertNewEntry ( - &gMemoryMap, - Start, - End, - Type, - FALSE, - AddRegion - ); - return ; -} - -/** - Return the count of Smm memory map entry. - - @return The count of Smm memory map entry. -**/ -UINTN -GetSmmMemoryMapEntryCount ( - VOID - ) -{ - LIST_ENTRY *Link; - UINTN Count; - - Count = 0; - Link = gMemoryMap.ForwardLink; - while (Link != &gMemoryMap) { - Link = Link->ForwardLink; - Count++; - } - return Count; -} - -/** - Dump Smm memory map entry. -**/ -VOID -DumpSmmMemoryMapEntry ( - VOID - ) -{ - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - EFI_PHYSICAL_ADDRESS Last; - - Last = 0; - DEBUG ((DEBUG_INFO, "DumpSmmMemoryMapEntry:\n")); - Link = gMemoryMap.ForwardLink; - while (Link != &gMemoryMap) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - Link = Link->ForwardLink; - - if ((Last != 0) && (Last != (UINT64)-1)) { - if (Last + 1 != Entry->Start) { - Last = (UINT64)-1; - } else { - Last = Entry->End; - } - } else if (Last == 0) { - Last = Entry->End; - } - - DEBUG ((DEBUG_INFO, "Entry (Link - 0x%x)\n", &Entry->Link)); - DEBUG ((DEBUG_INFO, " Signature - 0x%x\n", Entry->Signature)); - DEBUG ((DEBUG_INFO, " Link.ForwardLink - 0x%x\n", Entry->Link.ForwardLink)); - DEBUG ((DEBUG_INFO, " Link.BackLink - 0x%x\n", Entry->Link.BackLink)); - DEBUG ((DEBUG_INFO, " Type - 0x%x\n", Entry->Type)); - DEBUG ((DEBUG_INFO, " Start - 0x%016lx\n", Entry->Start)); - DEBUG ((DEBUG_INFO, " End - 0x%016lx\n", Entry->End)); - } - - ASSERT (Last != (UINT64)-1); -} - -/** - Dump Smm memory map. -**/ -VOID -DumpSmmMemoryMap ( - VOID - ) -{ - LIST_ENTRY *Node; - FREE_PAGE_LIST *Pages; - - DEBUG ((DEBUG_INFO, "DumpSmmMemoryMap\n")); - - Pages = NULL; - Node = mSmmMemoryMap.ForwardLink; - while (Node != &mSmmMemoryMap) { - Pages = BASE_CR (Node, FREE_PAGE_LIST, Link); - DEBUG ((DEBUG_INFO, "Pages - 0x%x\n", Pages)); - DEBUG ((DEBUG_INFO, "Pages->NumberOfPages - 0x%x\n", Pages->NumberOfPages)); - Node = Node->ForwardLink; - } -} - -/** - Check if a Smm base~length is in Smm memory map. - - @param[in] Base The base address of Smm memory to be checked. - @param[in] Length THe length of Smm memory to be checked. - - @retval TRUE Smm base~length is in smm memory map. - @retval FALSE Smm base~length is in smm memory map. -**/ -BOOLEAN -SmmMemoryMapConsistencyCheckRange ( - IN EFI_PHYSICAL_ADDRESS Base, - IN UINTN Length - ) -{ - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - BOOLEAN Result; - - Result = FALSE; - Link = gMemoryMap.ForwardLink; - while (Link != &gMemoryMap) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - Link = Link->ForwardLink; - - if (Entry->Type != EfiConventionalMemory) { - continue; - } - if (Entry->Start == Base && Entry->End == Base + Length - 1) { - Result = TRUE; - break; - } - } - - return Result; -} - -/** - Check the consistency of Smm memory map. -**/ -VOID -SmmMemoryMapConsistencyCheck ( - VOID - ) -{ - LIST_ENTRY *Node; - FREE_PAGE_LIST *Pages; - BOOLEAN Result; - - Pages = NULL; - Node = mSmmMemoryMap.ForwardLink; - while (Node != &mSmmMemoryMap) { - Pages = BASE_CR (Node, FREE_PAGE_LIST, Link); - Result = SmmMemoryMapConsistencyCheckRange ((EFI_PHYSICAL_ADDRESS)(UINTN)Pages, (UINTN)EFI_PAGES_TO_SIZE(Pages->NumberOfPages)); - ASSERT (Result); - Node = Node->ForwardLink; - } -} - -/** - Internal Function. Allocate n pages from given free page node. - - @param Pages The free page node. - @param NumberOfPages Number of pages to be allocated. - @param MaxAddress Request to allocate memory below this address. - - @return Memory address of allocated pages. - -**/ -UINTN -InternalAllocPagesOnOneNode ( - IN OUT FREE_PAGE_LIST *Pages, - IN UINTN NumberOfPages, - IN UINTN MaxAddress - ) -{ - UINTN Top; - UINTN Bottom; - FREE_PAGE_LIST *Node; - - Top = TRUNCATE_TO_PAGES (MaxAddress + 1 - (UINTN)Pages); - if (Top > Pages->NumberOfPages) { - Top = Pages->NumberOfPages; - } - Bottom = Top - NumberOfPages; - - if (Top < Pages->NumberOfPages) { - Node = (FREE_PAGE_LIST*)((UINTN)Pages + EFI_PAGES_TO_SIZE (Top)); - Node->NumberOfPages = Pages->NumberOfPages - Top; - InsertHeadList (&Pages->Link, &Node->Link); - } - - if (Bottom > 0) { - Pages->NumberOfPages = Bottom; - } else { - RemoveEntryList (&Pages->Link); - } - - return (UINTN)Pages + EFI_PAGES_TO_SIZE (Bottom); -} - -/** - Internal Function. Allocate n pages from free page list below MaxAddress. - - @param FreePageList The free page node. - @param NumberOfPages Number of pages to be allocated. - @param MaxAddress Request to allocate memory below this address. - - @return Memory address of allocated pages. - -**/ -UINTN -InternalAllocMaxAddress ( - IN OUT LIST_ENTRY *FreePageList, - IN UINTN NumberOfPages, - IN UINTN MaxAddress - ) -{ - LIST_ENTRY *Node; - FREE_PAGE_LIST *Pages; - - for (Node = FreePageList->BackLink; Node != FreePageList; Node = Node->BackLink) { - Pages = BASE_CR (Node, FREE_PAGE_LIST, Link); - if (Pages->NumberOfPages >= NumberOfPages && - (UINTN)Pages + EFI_PAGES_TO_SIZE (NumberOfPages) - 1 <= MaxAddress) { - return InternalAllocPagesOnOneNode (Pages, NumberOfPages, MaxAddress); - } - } - return (UINTN)(-1); -} - -/** - Internal Function. Allocate n pages from free page list at given address. - - @param FreePageList The free page node. - @param NumberOfPages Number of pages to be allocated. - @param MaxAddress Request to allocate memory below this address. - - @return Memory address of allocated pages. - -**/ -UINTN -InternalAllocAddress ( - IN OUT LIST_ENTRY *FreePageList, - IN UINTN NumberOfPages, - IN UINTN Address - ) -{ - UINTN EndAddress; - LIST_ENTRY *Node; - FREE_PAGE_LIST *Pages; - - if ((Address & EFI_PAGE_MASK) != 0) { - return ~Address; - } - - EndAddress = Address + EFI_PAGES_TO_SIZE (NumberOfPages); - for (Node = FreePageList->BackLink; Node!= FreePageList; Node = Node->BackLink) { - Pages = BASE_CR (Node, FREE_PAGE_LIST, Link); - if ((UINTN)Pages <= Address) { - if ((UINTN)Pages + EFI_PAGES_TO_SIZE (Pages->NumberOfPages) < EndAddress) { - break; - } - return InternalAllocPagesOnOneNode (Pages, NumberOfPages, EndAddress); - } - } - return ~Address; -} - -/** - Allocates pages from the memory map. - - @param[in] Type The type of allocation to perform. - @param[in] MemoryType The type of memory to turn the allocated pages - into. - @param[in] NumberOfPages The number of pages to allocate. - @param[out] Memory A pointer to receive the base allocated memory - address. - @param[in] AddRegion If this memory is new added region. - - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -SmmInternalAllocatePagesEx ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory, - IN BOOLEAN AddRegion - ) -{ - UINTN RequestedAddress; - - if (MemoryType != EfiRuntimeServicesCode && - MemoryType != EfiRuntimeServicesData) { - return EFI_INVALID_PARAMETER; - } - - if (NumberOfPages > TRUNCATE_TO_PAGES ((UINTN)-1) + 1) { - return EFI_OUT_OF_RESOURCES; - } - - // - // We don't track memory type in SMM - // - RequestedAddress = (UINTN)*Memory; - switch (Type) { - case AllocateAnyPages: - RequestedAddress = (UINTN)(-1); - case AllocateMaxAddress: - *Memory = InternalAllocMaxAddress ( - &mSmmMemoryMap, - NumberOfPages, - RequestedAddress - ); - if (*Memory == (UINTN)-1) { - return EFI_OUT_OF_RESOURCES; - } - break; - case AllocateAddress: - *Memory = InternalAllocAddress ( - &mSmmMemoryMap, - NumberOfPages, - RequestedAddress - ); - if (*Memory != RequestedAddress) { - return EFI_NOT_FOUND; - } - break; - default: - return EFI_INVALID_PARAMETER; - } - - // - // Update SmmMemoryMap here. - // - ConvertSmmMemoryMapEntry (MemoryType, *Memory, NumberOfPages, AddRegion); - if (!AddRegion) { - CoreFreeMemoryMapStack(); - } - - return EFI_SUCCESS; -} - -/** - Allocates pages from the memory map. - - @param[in] Type The type of allocation to perform. - @param[in] MemoryType The type of memory to turn the allocated pages - into. - @param[in] NumberOfPages The number of pages to allocate. - @param[out] Memory A pointer to receive the base allocated memory - address. - - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmInternalAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory - ) -{ - return SmmInternalAllocatePagesEx (Type, MemoryType, NumberOfPages, Memory, FALSE); -} - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform. - @param MemoryType The type of memory to turn the allocated pages - into. - @param NumberOfPages The number of pages to allocate. - @param Memory A pointer to receive the base allocated memory - address. - - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory - ) -{ - EFI_STATUS Status; - - Status = SmmInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory); - if (!EFI_ERROR (Status)) { - SmmCoreUpdateProfile ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), - MemoryProfileActionAllocatePages, - MemoryType, - EFI_PAGES_TO_SIZE (NumberOfPages), - (VOID *) (UINTN) *Memory, - NULL - ); - } - return Status; -} - -/** - Internal Function. Merge two adjacent nodes. - - @param First The first of two nodes to merge. - - @return Pointer to node after merge (if success) or pointer to next node (if fail). - -**/ -FREE_PAGE_LIST * -InternalMergeNodes ( - IN FREE_PAGE_LIST *First - ) -{ - FREE_PAGE_LIST *Next; - - Next = BASE_CR (First->Link.ForwardLink, FREE_PAGE_LIST, Link); - ASSERT ( - TRUNCATE_TO_PAGES ((UINTN)Next - (UINTN)First) >= First->NumberOfPages); - - if (TRUNCATE_TO_PAGES ((UINTN)Next - (UINTN)First) == First->NumberOfPages) { - First->NumberOfPages += Next->NumberOfPages; - RemoveEntryList (&Next->Link); - Next = First; - } - return Next; -} - -/** - Frees previous allocated pages. - - @param[in] Memory Base address of memory being freed. - @param[in] NumberOfPages The number of pages to free. - @param[in] AddRegion If this memory is new added region. - - @retval EFI_NOT_FOUND Could not find the entry that covers the range. - @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. - @return EFI_SUCCESS Pages successfully freed. - -**/ -EFI_STATUS -SmmInternalFreePagesEx ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages, - IN BOOLEAN AddRegion - ) -{ - LIST_ENTRY *Node; - FREE_PAGE_LIST *Pages; - - if (((Memory & EFI_PAGE_MASK) != 0) || (Memory == 0) || (NumberOfPages == 0)) { - return EFI_INVALID_PARAMETER; - } - - Pages = NULL; - Node = mSmmMemoryMap.ForwardLink; - while (Node != &mSmmMemoryMap) { - Pages = BASE_CR (Node, FREE_PAGE_LIST, Link); - if (Memory < (UINTN)Pages) { - break; - } - Node = Node->ForwardLink; - } - - if (Node != &mSmmMemoryMap && - Memory + EFI_PAGES_TO_SIZE (NumberOfPages) > (UINTN)Pages) { - return EFI_INVALID_PARAMETER; - } - - if (Node->BackLink != &mSmmMemoryMap) { - Pages = BASE_CR (Node->BackLink, FREE_PAGE_LIST, Link); - if ((UINTN)Pages + EFI_PAGES_TO_SIZE (Pages->NumberOfPages) > Memory) { - return EFI_INVALID_PARAMETER; - } - } - - Pages = (FREE_PAGE_LIST*)(UINTN)Memory; - Pages->NumberOfPages = NumberOfPages; - InsertTailList (Node, &Pages->Link); - - if (Pages->Link.BackLink != &mSmmMemoryMap) { - Pages = InternalMergeNodes ( - BASE_CR (Pages->Link.BackLink, FREE_PAGE_LIST, Link) - ); - } - - if (Node != &mSmmMemoryMap) { - InternalMergeNodes (Pages); - } - - // - // Update SmmMemoryMap here. - // - ConvertSmmMemoryMapEntry (EfiConventionalMemory, Memory, NumberOfPages, AddRegion); - if (!AddRegion) { - CoreFreeMemoryMapStack(); - } - - return EFI_SUCCESS; -} - -/** - Frees previous allocated pages. - - @param[in] Memory Base address of memory being freed. - @param[in] NumberOfPages The number of pages to free. - - @retval EFI_NOT_FOUND Could not find the entry that covers the range. - @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. - @return EFI_SUCCESS Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmInternalFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ) -{ - return SmmInternalFreePagesEx (Memory, NumberOfPages, FALSE); -} - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed. - @param NumberOfPages The number of pages to free. - - @retval EFI_NOT_FOUND Could not find the entry that covers the range. - @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. - @return EFI_SUCCESS Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ) -{ - EFI_STATUS Status; - - Status = SmmInternalFreePages (Memory, NumberOfPages); - if (!EFI_ERROR (Status)) { - SmmCoreUpdateProfile ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), - MemoryProfileActionFreePages, - EfiMaxMemoryType, - EFI_PAGES_TO_SIZE (NumberOfPages), - (VOID *) (UINTN) Memory, - NULL - ); - } - return Status; -} - -/** - Add free SMRAM region for use by memory service. - - @param MemBase Base address of memory region. - @param MemLength Length of the memory region. - @param Type Memory type. - @param Attributes Memory region state. - -**/ -VOID -SmmAddMemoryRegion ( - IN EFI_PHYSICAL_ADDRESS MemBase, - IN UINT64 MemLength, - IN EFI_MEMORY_TYPE Type, - IN UINT64 Attributes - ) -{ - UINTN AlignedMemBase; - - // - // Add EfiRuntimeServicesData for memory regions that is already allocated, needs testing, or needs ECC initialization - // - if ((Attributes & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { - Type = EfiRuntimeServicesData; - } else { - Type = EfiConventionalMemory; - } - - DEBUG ((DEBUG_INFO, "SmmAddMemoryRegion\n")); - DEBUG ((DEBUG_INFO, " MemBase - 0x%lx\n", MemBase)); - DEBUG ((DEBUG_INFO, " MemLength - 0x%lx\n", MemLength)); - DEBUG ((DEBUG_INFO, " Type - 0x%x\n", Type)); - DEBUG ((DEBUG_INFO, " Attributes - 0x%lx\n", Attributes)); - - // - // Align range on an EFI_PAGE_SIZE boundary - // - AlignedMemBase = (UINTN)(MemBase + EFI_PAGE_MASK) & ~EFI_PAGE_MASK; - MemLength -= AlignedMemBase - MemBase; - if (Type == EfiConventionalMemory) { - SmmInternalFreePagesEx (AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength), TRUE); - } else { - ConvertSmmMemoryMapEntry (EfiRuntimeServicesData, AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength), TRUE); - } - - CoreFreeMemoryMapStack (); -} - -/** - This function returns a copy of the current memory map. The map is an array of - memory descriptors, each of which describes a contiguous block of memory. - - @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param[in, out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[out] MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param[out] DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param[out] DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -SmmCoreGetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ) -{ - UINTN Count; - LIST_ENTRY *Link; - MEMORY_MAP *Entry; - UINTN Size; - UINTN BufferSize; - - Size = sizeof (EFI_MEMORY_DESCRIPTOR); - - // - // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will - // prevent people from having pointer math bugs in their code. - // now you have to use *DescriptorSize to make things work. - // - Size += sizeof(UINT64) - (Size % sizeof (UINT64)); - - if (DescriptorSize != NULL) { - *DescriptorSize = Size; - } - - if (DescriptorVersion != NULL) { - *DescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION; - } - - Count = GetSmmMemoryMapEntryCount (); - BufferSize = Size * Count; - if (*MemoryMapSize < BufferSize) { - *MemoryMapSize = BufferSize; - return EFI_BUFFER_TOO_SMALL; - } - - *MemoryMapSize = BufferSize; - if (MemoryMap == NULL) { - return EFI_INVALID_PARAMETER; - } - - ZeroMem (MemoryMap, BufferSize); - Link = gMemoryMap.ForwardLink; - while (Link != &gMemoryMap) { - Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); - Link = Link->ForwardLink; - - MemoryMap->Type = Entry->Type; - MemoryMap->PhysicalStart = Entry->Start; - MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT); - - MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, Size); - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c deleted file mode 100644 index 9e4390e15a..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c +++ /dev/null @@ -1,686 +0,0 @@ -/** @file - SMM Core Main Entry Point - - Copyright (c) 2009 - 2017, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -// -// Physical pointer to private structure shared between SMM IPL and the SMM Core -// -SMM_CORE_PRIVATE_DATA *gSmmCorePrivate; - -// -// SMM Core global variable for SMM System Table. Only accessed as a physical structure in SMRAM. -// -EFI_SMM_SYSTEM_TABLE2 gSmmCoreSmst = { - { - SMM_SMST_SIGNATURE, - EFI_SMM_SYSTEM_TABLE2_REVISION, - sizeof (gSmmCoreSmst.Hdr) - }, - NULL, // SmmFirmwareVendor - 0, // SmmFirmwareRevision - SmmInstallConfigurationTable, - { - { - (EFI_SMM_CPU_IO2) SmmEfiNotAvailableYetArg5, // SmmMemRead - (EFI_SMM_CPU_IO2) SmmEfiNotAvailableYetArg5 // SmmMemWrite - }, - { - (EFI_SMM_CPU_IO2) SmmEfiNotAvailableYetArg5, // SmmIoRead - (EFI_SMM_CPU_IO2) SmmEfiNotAvailableYetArg5 // SmmIoWrite - } - }, - SmmAllocatePool, - SmmFreePool, - SmmAllocatePages, - SmmFreePages, - NULL, // SmmStartupThisAp - 0, // CurrentlyExecutingCpu - 0, // NumberOfCpus - NULL, // CpuSaveStateSize - NULL, // CpuSaveState - 0, // NumberOfTableEntries - NULL, // SmmConfigurationTable - SmmInstallProtocolInterface, - SmmUninstallProtocolInterface, - SmmHandleProtocol, - SmmRegisterProtocolNotify, - SmmLocateHandle, - SmmLocateProtocol, - SmiManage, - SmiHandlerRegister, - SmiHandlerUnRegister -}; - -// -// Flag to determine if the platform has performed a legacy boot. -// If this flag is TRUE, then the runtime code and runtime data associated with the -// SMM IPL are converted to free memory, so the SMM Core must guarantee that is -// does not touch of the code/data associated with the SMM IPL if this flag is TRUE. -// -BOOLEAN mInLegacyBoot = FALSE; - -// -// Table of SMI Handlers that are registered by the SMM Core when it is initialized -// -SMM_CORE_SMI_HANDLERS mSmmCoreSmiHandlers[] = { - { SmmDriverDispatchHandler, &gEfiEventDxeDispatchGuid, NULL, TRUE }, - { SmmReadyToLockHandler, &gEfiDxeSmmReadyToLockProtocolGuid, NULL, TRUE }, - { SmmLegacyBootHandler, &gEfiEventLegacyBootGuid, NULL, FALSE }, - { SmmExitBootServicesHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE }, - { SmmReadyToBootHandler, &gEfiEventReadyToBootGuid, NULL, FALSE }, - { SmmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, TRUE }, - { NULL, NULL, NULL, FALSE } -}; - -UINTN mFullSmramRangeCount; -EFI_SMRAM_DESCRIPTOR *mFullSmramRanges; - -EFI_SMM_DRIVER_ENTRY *mSmmCoreDriverEntry; - -EFI_LOADED_IMAGE_PROTOCOL *mSmmCoreLoadedImage; - -/** - Place holder function until all the SMM System Table Service are available. - - Note: This function is only used by SMRAM invocation. It is never used by DXE invocation. - - @param Arg1 Undefined - @param Arg2 Undefined - @param Arg3 Undefined - @param Arg4 Undefined - @param Arg5 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -SmmEfiNotAvailableYetArg5 ( - UINTN Arg1, - UINTN Arg2, - UINTN Arg3, - UINTN Arg4, - UINTN Arg5 - ) -{ - // - // This function should never be executed. If it does, then the architectural protocols - // have not been designed correctly. - // - return EFI_NOT_AVAILABLE_YET; -} - -/** - Software SMI handler that is called when a Legacy Boot event is signalled. The SMM - Core uses this signal to know that a Legacy Boot has been performed and that - gSmmCorePrivate that is shared between the UEFI and SMM execution environments can - not be accessed from SMM anymore since that structure is considered free memory by - a legacy OS. Then the SMM Core also install SMM Legacy Boot protocol to notify SMM - driver that system enter legacy boot. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmLegacyBootHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_HANDLE SmmHandle; - - // - // Install SMM Legacy Boot protocol. - // - SmmHandle = NULL; - Status = SmmInstallProtocolInterface ( - &SmmHandle, - &gEdkiiSmmLegacyBootProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - - mInLegacyBoot = TRUE; - - SmiHandlerUnRegister (DispatchHandle); - - return Status; -} - -/** - Software SMI handler that is called when an Exit Boot Services event is signalled. - Then the SMM Core also install SMM Exit Boot Services protocol to notify SMM driver - that system enter exit boot services. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmExitBootServicesHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_HANDLE SmmHandle; - - // - // Install SMM Exit Boot Services protocol. - // - SmmHandle = NULL; - Status = SmmInstallProtocolInterface ( - &SmmHandle, - &gEdkiiSmmExitBootServicesProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - - SmiHandlerUnRegister (DispatchHandle); - - return Status; -} - -/** - Software SMI handler that is called when an Ready To Boot event is signalled. - Then the SMM Core also install SMM Ready To Boot protocol to notify SMM driver - that system enter ready to boot. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmReadyToBootHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_HANDLE SmmHandle; - - // - // Install SMM Ready To Boot protocol. - // - SmmHandle = NULL; - Status = SmmInstallProtocolInterface ( - &SmmHandle, - &gEdkiiSmmReadyToBootProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - - SmiHandlerUnRegister (DispatchHandle); - - return Status; -} - -/** - Software SMI handler that is called when the DxeSmmReadyToLock protocol is added - or if gEfiEventReadyToBootGuid is signalled. This function unregisters the - Software SMIs that are nor required after SMRAM is locked and installs the - SMM Ready To Lock Protocol so SMM Drivers are informed that SMRAM is about - to be locked. It also verifies the SMM CPU I/O 2 Protocol has been installed - and NULLs gBS and gST because they can not longer be used after SMRAM is locked. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmReadyToLockHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - EFI_STATUS Status; - UINTN Index; - EFI_HANDLE SmmHandle; - VOID *Interface; - - // - // Unregister SMI Handlers that are no required after the SMM driver dispatch is stopped - // - for (Index = 0; mSmmCoreSmiHandlers[Index].HandlerType != NULL; Index++) { - if (mSmmCoreSmiHandlers[Index].UnRegister) { - SmiHandlerUnRegister (mSmmCoreSmiHandlers[Index].DispatchHandle); - } - } - - // - // Install SMM Ready to lock protocol - // - SmmHandle = NULL; - Status = SmmInstallProtocolInterface ( - &SmmHandle, - &gEfiSmmReadyToLockProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - - // - // Make sure SMM CPU I/O 2 Procol has been installed into the handle database - // - Status = SmmLocateProtocol (&gEfiSmmCpuIo2ProtocolGuid, NULL, &Interface); - - // - // Print a message on a debug build if the SMM CPU I/O 2 Protocol is not installed - // - DEBUG_CODE_BEGIN (); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "\nSMM: SmmCpuIo Arch Protocol not present!!\n")); - } - DEBUG_CODE_END (); - - // - // Assert if the CPU I/O 2 Protocol is not installed - // - ASSERT_EFI_ERROR (Status); - - // - // Display any drivers that were not dispatched because dependency expression - // evaluated to false if this is a debug build - // - DEBUG_CODE_BEGIN (); - SmmDisplayDiscoveredNotDispatched (); - DEBUG_CODE_END (); - - // - // Not allowed to use gST or gBS after lock - // - gST = NULL; - gBS = NULL; - - SmramProfileReadyToLock (); - - return Status; -} - -/** - Software SMI handler that is called when the EndOfDxe event is signalled. - This function installs the SMM EndOfDxe Protocol so SMM Drivers are informed that - platform code will invoke 3rd part code. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmEndOfDxeHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_HANDLE SmmHandle; - - DEBUG ((EFI_D_INFO, "SmmEndOfDxeHandler\n")); - // - // Install SMM EndOfDxe protocol - // - SmmHandle = NULL; - Status = SmmInstallProtocolInterface ( - &SmmHandle, - &gEfiSmmEndOfDxeProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - return Status; -} - -/** - Determine if two buffers overlap in memory. - - @param[in] Buff1 Pointer to first buffer - @param[in] Size1 Size of Buff1 - @param[in] Buff2 Pointer to second buffer - @param[in] Size2 Size of Buff2 - - @retval TRUE Buffers overlap in memory. - @retval FALSE Buffer doesn't overlap. - -**/ -BOOLEAN -InternalIsBufferOverlapped ( - IN UINT8 *Buff1, - IN UINTN Size1, - IN UINT8 *Buff2, - IN UINTN Size2 - ) -{ - // - // If buff1's end is less than the start of buff2, then it's ok. - // Also, if buff1's start is beyond buff2's end, then it's ok. - // - if (((Buff1 + Size1) <= Buff2) || (Buff1 >= (Buff2 + Size2))) { - return FALSE; - } - - return TRUE; -} - -/** - The main entry point to SMM Foundation. - - Note: This function is only used by SMRAM invocation. It is never used by DXE invocation. - - @param SmmEntryContext Processor information and functionality - needed by SMM Foundation. - -**/ -VOID -EFIAPI -SmmEntryPoint ( - IN CONST EFI_SMM_ENTRY_CONTEXT *SmmEntryContext -) -{ - EFI_STATUS Status; - EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader; - BOOLEAN InLegacyBoot; - BOOLEAN IsOverlapped; - VOID *CommunicationBuffer; - UINTN BufferSize; - - PERF_START (NULL, "SMM", NULL, 0) ; - - // - // Update SMST with contents of the SmmEntryContext structure - // - gSmmCoreSmst.SmmStartupThisAp = SmmEntryContext->SmmStartupThisAp; - gSmmCoreSmst.CurrentlyExecutingCpu = SmmEntryContext->CurrentlyExecutingCpu; - gSmmCoreSmst.NumberOfCpus = SmmEntryContext->NumberOfCpus; - gSmmCoreSmst.CpuSaveStateSize = SmmEntryContext->CpuSaveStateSize; - gSmmCoreSmst.CpuSaveState = SmmEntryContext->CpuSaveState; - - // - // Call platform hook before Smm Dispatch - // - PlatformHookBeforeSmmDispatch (); - - // - // If a legacy boot has occured, then make sure gSmmCorePrivate is not accessed - // - InLegacyBoot = mInLegacyBoot; - if (!InLegacyBoot) { - // - // Mark the InSmm flag as TRUE, it will be used by SmmBase2 protocol - // - gSmmCorePrivate->InSmm = TRUE; - - // - // Check to see if this is a Synchronous SMI sent through the SMM Communication - // Protocol or an Asynchronous SMI - // - CommunicationBuffer = gSmmCorePrivate->CommunicationBuffer; - BufferSize = gSmmCorePrivate->BufferSize; - if (CommunicationBuffer != NULL) { - // - // Synchronous SMI for SMM Core or request from Communicate protocol - // - IsOverlapped = InternalIsBufferOverlapped ( - (UINT8 *) CommunicationBuffer, - BufferSize, - (UINT8 *) gSmmCorePrivate, - sizeof (*gSmmCorePrivate) - ); - if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicationBuffer, BufferSize) || IsOverlapped) { - // - // If CommunicationBuffer is not in valid address scope, - // or there is overlap between gSmmCorePrivate and CommunicationBuffer, - // return EFI_INVALID_PARAMETER - // - gSmmCorePrivate->CommunicationBuffer = NULL; - gSmmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER; - } else { - CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommunicationBuffer; - BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data); - Status = SmiManage ( - &CommunicateHeader->HeaderGuid, - NULL, - CommunicateHeader->Data, - &BufferSize - ); - // - // Update CommunicationBuffer, BufferSize and ReturnStatus - // Communicate service finished, reset the pointer to CommBuffer to NULL - // - gSmmCorePrivate->BufferSize = BufferSize + OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data); - gSmmCorePrivate->CommunicationBuffer = NULL; - gSmmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; - } - } - } - - // - // Process Asynchronous SMI sources - // - SmiManage (NULL, NULL, NULL, NULL); - - // - // Call platform hook after Smm Dispatch - // - PlatformHookAfterSmmDispatch (); - - // - // If a legacy boot has occured, then make sure gSmmCorePrivate is not accessed - // - if (!InLegacyBoot) { - // - // Clear the InSmm flag as we are going to leave SMM - // - gSmmCorePrivate->InSmm = FALSE; - } - - PERF_END (NULL, "SMM", NULL, 0) ; -} - -/** - Install LoadedImage protocol for SMM Core. -**/ -VOID -SmmCoreInstallLoadedImage ( - VOID - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - - // - // Allocate a Loaded Image Protocol in EfiBootServicesData - // - Status = gBS->AllocatePool (EfiBootServicesData, sizeof(EFI_LOADED_IMAGE_PROTOCOL), (VOID **)&mSmmCoreLoadedImage); - ASSERT_EFI_ERROR (Status); - - ZeroMem (mSmmCoreLoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL)); - // - // Fill in the remaining fields of the Loaded Image Protocol instance. - // Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed. - // - mSmmCoreLoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; - mSmmCoreLoadedImage->ParentHandle = gSmmCorePrivate->SmmIplImageHandle; - mSmmCoreLoadedImage->SystemTable = gST; - - mSmmCoreLoadedImage->ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase; - mSmmCoreLoadedImage->ImageSize = gSmmCorePrivate->PiSmmCoreImageSize; - mSmmCoreLoadedImage->ImageCodeType = EfiRuntimeServicesCode; - mSmmCoreLoadedImage->ImageDataType = EfiRuntimeServicesData; - - // - // Create a new image handle in the UEFI handle database for the SMM Driver - // - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiLoadedImageProtocolGuid, mSmmCoreLoadedImage, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Allocate a Loaded Image Protocol in SMM - // - Status = SmmAllocatePool (EfiRuntimeServicesData, sizeof(EFI_SMM_DRIVER_ENTRY), (VOID **)&mSmmCoreDriverEntry); - ASSERT_EFI_ERROR(Status); - - ZeroMem (mSmmCoreDriverEntry, sizeof(EFI_SMM_DRIVER_ENTRY)); - // - // Fill in the remaining fields of the Loaded Image Protocol instance. - // - mSmmCoreDriverEntry->Signature = EFI_SMM_DRIVER_ENTRY_SIGNATURE; - mSmmCoreDriverEntry->SmmLoadedImage.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; - mSmmCoreDriverEntry->SmmLoadedImage.ParentHandle = gSmmCorePrivate->SmmIplImageHandle; - mSmmCoreDriverEntry->SmmLoadedImage.SystemTable = gST; - - mSmmCoreDriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)gSmmCorePrivate->PiSmmCoreImageBase; - mSmmCoreDriverEntry->SmmLoadedImage.ImageSize = gSmmCorePrivate->PiSmmCoreImageSize; - mSmmCoreDriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode; - mSmmCoreDriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData; - - mSmmCoreDriverEntry->ImageEntryPoint = gSmmCorePrivate->PiSmmCoreEntryPoint; - mSmmCoreDriverEntry->ImageBuffer = gSmmCorePrivate->PiSmmCoreImageBase; - mSmmCoreDriverEntry->NumberOfPage = EFI_SIZE_TO_PAGES((UINTN)gSmmCorePrivate->PiSmmCoreImageSize); - - // - // Create a new image handle in the SMM handle database for the SMM Driver - // - mSmmCoreDriverEntry->SmmImageHandle = NULL; - Status = SmmInstallProtocolInterface ( - &mSmmCoreDriverEntry->SmmImageHandle, - &gEfiLoadedImageProtocolGuid, - EFI_NATIVE_INTERFACE, - &mSmmCoreDriverEntry->SmmLoadedImage - ); - ASSERT_EFI_ERROR(Status); - - return ; -} - -/** - The Entry Point for SMM Core - - Install DXE Protocols and reload SMM Core into SMRAM and register SMM Core - EntryPoint on the SMI vector. - - Note: This function is called for both DXE invocation and SMRAM invocation. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval Other Some error occurred when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -SmmMain ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - UINTN Index; - - // - // Get SMM Core Private context passed in from SMM IPL in ImageHandle. - // - gSmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle; - - // - // Fill in SMRAM physical address for the SMM Services Table and the SMM Entry Point. - // - gSmmCorePrivate->Smst = &gSmmCoreSmst; - gSmmCorePrivate->SmmEntryPoint = SmmEntryPoint; - - // - // No need to initialize memory service. - // It is done in constructor of PiSmmCoreMemoryAllocationLib(), - // so that the library linked with PiSmmCore can use AllocatePool() in constuctor. - // - - SmramProfileInit (); - - // - // Copy FullSmramRanges to SMRAM - // - mFullSmramRangeCount = gSmmCorePrivate->SmramRangeCount; - mFullSmramRanges = AllocatePool (mFullSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR)); - ASSERT (mFullSmramRanges != NULL); - CopyMem (mFullSmramRanges, gSmmCorePrivate->SmramRanges, mFullSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR)); - - // - // Register all SMI Handlers required by the SMM Core - // - for (Index = 0; mSmmCoreSmiHandlers[Index].HandlerType != NULL; Index++) { - Status = SmiHandlerRegister ( - mSmmCoreSmiHandlers[Index].Handler, - mSmmCoreSmiHandlers[Index].HandlerType, - &mSmmCoreSmiHandlers[Index].DispatchHandle - ); - ASSERT_EFI_ERROR (Status); - } - - RegisterSmramProfileHandler (); - SmramProfileInstallProtocol (); - - SmmCoreInstallLoadedImage (); - - SmmCoreInitializeMemoryAttributesTable (); - - SmmCoreInitializeSmiHandlerProfile (); - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h deleted file mode 100644 index c12805a2dd..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.h +++ /dev/null @@ -1,1218 +0,0 @@ -/** @file - The internal header file includes the common header files, defines - internal structure and functions used by SmmCore module. - - Copyright (c) 2009 - 2017, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _SMM_CORE_H_ -#define _SMM_CORE_H_ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "PiSmmCorePrivateData.h" - -// -// Used to build a table of SMI Handlers that the SMM Core registers -// -typedef struct { - EFI_SMM_HANDLER_ENTRY_POINT2 Handler; - EFI_GUID *HandlerType; - EFI_HANDLE DispatchHandle; - BOOLEAN UnRegister; -} SMM_CORE_SMI_HANDLERS; - -// -// SMM_HANDLER - used for each SMM handler -// - -#define SMI_ENTRY_SIGNATURE SIGNATURE_32('s','m','i','e') - - typedef struct { - UINTN Signature; - LIST_ENTRY AllEntries; // All entries - - EFI_GUID HandlerType; // Type of interrupt - LIST_ENTRY SmiHandlers; // All handlers -} SMI_ENTRY; - -#define SMI_HANDLER_SIGNATURE SIGNATURE_32('s','m','i','h') - - typedef struct { - UINTN Signature; - LIST_ENTRY Link; // Link on SMI_ENTRY.SmiHandlers - EFI_SMM_HANDLER_ENTRY_POINT2 Handler; // The smm handler's entry point - UINTN CallerAddr; // The address of caller who register the SMI handler. - SMI_ENTRY *SmiEntry; - VOID *Context; // for profile - UINTN ContextSize; // for profile -} SMI_HANDLER; - -// -// Structure for recording the state of an SMM Driver -// -#define EFI_SMM_DRIVER_ENTRY_SIGNATURE SIGNATURE_32('s', 'd','r','v') - -typedef struct { - UINTN Signature; - LIST_ENTRY Link; // mDriverList - - LIST_ENTRY ScheduledLink; // mScheduledQueue - - EFI_HANDLE FvHandle; - EFI_GUID FileName; - EFI_DEVICE_PATH_PROTOCOL *FvFileDevicePath; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - - VOID *Depex; - UINTN DepexSize; - - BOOLEAN Before; - BOOLEAN After; - EFI_GUID BeforeAfterGuid; - - BOOLEAN Dependent; - BOOLEAN Scheduled; - BOOLEAN Initialized; - BOOLEAN DepexProtocolError; - - EFI_HANDLE ImageHandle; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - // - // Image EntryPoint in SMRAM - // - PHYSICAL_ADDRESS ImageEntryPoint; - // - // Image Buffer in SMRAM - // - PHYSICAL_ADDRESS ImageBuffer; - // - // Image Page Number - // - UINTN NumberOfPage; - EFI_HANDLE SmmImageHandle; - EFI_LOADED_IMAGE_PROTOCOL SmmLoadedImage; -} EFI_SMM_DRIVER_ENTRY; - -#define EFI_HANDLE_SIGNATURE SIGNATURE_32('h','n','d','l') - -/// -/// IHANDLE - contains a list of protocol handles -/// -typedef struct { - UINTN Signature; - /// All handles list of IHANDLE - LIST_ENTRY AllHandles; - /// List of PROTOCOL_INTERFACE's for this handle - LIST_ENTRY Protocols; - UINTN LocateRequest; -} IHANDLE; - -#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE) - -#define PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('p','r','t','e') - -/// -/// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol -/// database. Each handler that supports this protocol is listed, along -/// with a list of registered notifies. -/// -typedef struct { - UINTN Signature; - /// Link Entry inserted to mProtocolDatabase - LIST_ENTRY AllEntries; - /// ID of the protocol - EFI_GUID ProtocolID; - /// All protocol interfaces - LIST_ENTRY Protocols; - /// Registerd notification handlers - LIST_ENTRY Notify; -} PROTOCOL_ENTRY; - -#define PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('p','i','f','c') - -/// -/// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked -/// with a protocol interface structure -/// -typedef struct { - UINTN Signature; - /// Link on IHANDLE.Protocols - LIST_ENTRY Link; - /// Back pointer - IHANDLE *Handle; - /// Link on PROTOCOL_ENTRY.Protocols - LIST_ENTRY ByProtocol; - /// The protocol ID - PROTOCOL_ENTRY *Protocol; - /// The interface value - VOID *Interface; -} PROTOCOL_INTERFACE; - -#define PROTOCOL_NOTIFY_SIGNATURE SIGNATURE_32('p','r','t','n') - -/// -/// PROTOCOL_NOTIFY - used for each register notification for a protocol -/// -typedef struct { - UINTN Signature; - PROTOCOL_ENTRY *Protocol; - /// All notifications for this protocol - LIST_ENTRY Link; - /// Notification function - EFI_SMM_NOTIFY_FN Function; - /// Last position notified - LIST_ENTRY *Position; -} PROTOCOL_NOTIFY; - -// -// SMM Core Global Variables -// -extern SMM_CORE_PRIVATE_DATA *gSmmCorePrivate; -extern EFI_SMM_SYSTEM_TABLE2 gSmmCoreSmst; -extern LIST_ENTRY gHandleList; -extern EFI_PHYSICAL_ADDRESS gLoadModuleAtFixAddressSmramBase; - -/** - Called to initialize the memory service. - - @param SmramRangeCount Number of SMRAM Regions - @param SmramRanges Pointer to SMRAM Descriptors - -**/ -VOID -SmmInitializeMemoryServices ( - IN UINTN SmramRangeCount, - IN EFI_SMRAM_DESCRIPTOR *SmramRanges - ); - -/** - The SmmInstallConfigurationTable() function is used to maintain the list - of configuration tables that are stored in the System Management System - Table. The list is stored as an array of (GUID, Pointer) pairs. The list - must be allocated from pool memory with PoolType set to EfiRuntimeServicesData. - - @param SystemTable A pointer to the SMM System Table (SMST). - @param Guid A pointer to the GUID for the entry to add, update, or remove. - @param Table A pointer to the buffer of the table to add. - @param TableSize The size of the table to install. - - @retval EFI_SUCCESS The (Guid, Table) pair was added, updated, or removed. - @retval EFI_INVALID_PARAMETER Guid is not valid. - @retval EFI_NOT_FOUND An attempt was made to delete a non-existent entry. - @retval EFI_OUT_OF_RESOURCES There is not enough memory available to complete the operation. - -**/ -EFI_STATUS -EFIAPI -SmmInstallConfigurationTable ( - IN CONST EFI_SMM_SYSTEM_TABLE2 *SystemTable, - IN CONST EFI_GUID *Guid, - IN VOID *Table, - IN UINTN TableSize - ); - -/** - Wrapper function to SmmInstallProtocolInterfaceNotify. This is the public API which - Calls the private one which contains a BOOLEAN parameter for notifications - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - - @return Status code - -**/ -EFI_STATUS -EFIAPI -SmmInstallProtocolInterface ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface - ); - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform - @param MemoryType The type of memory to turn the allocated pages - into - @param NumberOfPages The number of pages to allocate - @param Memory A pointer to receive the base allocated memory - address - - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory - ); - -/** - Allocates pages from the memory map. - - @param Type The type of allocation to perform - @param MemoryType The type of memory to turn the allocated pages - into - @param NumberOfPages The number of pages to allocate - @param Memory A pointer to receive the base allocated memory - address - - @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. - @retval EFI_NOT_FOUND Could not allocate pages match the requirement. - @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. - @retval EFI_SUCCESS Pages successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmInternalAllocatePages ( - IN EFI_ALLOCATE_TYPE Type, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory - ); - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed - @param NumberOfPages The number of pages to free - - @retval EFI_NOT_FOUND Could not find the entry that covers the range - @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. - @return EFI_SUCCESS Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - -/** - Frees previous allocated pages. - - @param Memory Base address of memory being freed - @param NumberOfPages The number of pages to free - - @retval EFI_NOT_FOUND Could not find the entry that covers the range - @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. - @return EFI_SUCCESS Pages successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmInternalFreePages ( - IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages - ); - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate - @param Size The amount of pool to allocate - @param Buffer The address to return a pointer to the allocated - pool - - @retval EFI_INVALID_PARAMETER PoolType not valid - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmInternalAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmFreePool ( - IN VOID *Buffer - ); - -/** - Frees pool. - - @param Buffer The allocated pool entry to free - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmInternalFreePool ( - IN VOID *Buffer - ); - -/** - Installs a protocol interface into the boot services environment. - - @param UserHandle The handle to install the protocol handler on, - or NULL if a new handle is to be allocated - @param Protocol The protocol to add to the handle - @param InterfaceType Indicates whether Interface is supplied in - native form. - @param Interface The interface for the protocol being added - @param Notify indicates whether notify the notification list - for this protocol - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate - @retval EFI_SUCCESS Protocol interface successfully installed - -**/ -EFI_STATUS -SmmInstallProtocolInterfaceNotify ( - IN OUT EFI_HANDLE *UserHandle, - IN EFI_GUID *Protocol, - IN EFI_INTERFACE_TYPE InterfaceType, - IN VOID *Interface, - IN BOOLEAN Notify - ); - -/** - Uninstalls all instances of a protocol:interfacer from a handle. - If the last protocol interface is remove from the handle, the - handle is freed. - - @param UserHandle The handle to remove the protocol handler from - @param Protocol The protocol, of protocol:interface, to remove - @param Interface The interface, of protocol:interface, to remove - - @retval EFI_INVALID_PARAMETER Protocol is NULL. - @retval EFI_SUCCESS Protocol interface successfully uninstalled. - -**/ -EFI_STATUS -EFIAPI -SmmUninstallProtocolInterface ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ); - -/** - Queries a handle to determine if it supports a specified protocol. - - @param UserHandle The handle being queried. - @param Protocol The published unique identifier of the protocol. - @param Interface Supplies the address where a pointer to the - corresponding Protocol Interface is returned. - - @return The requested protocol interface for the handle - -**/ -EFI_STATUS -EFIAPI -SmmHandleProtocol ( - IN EFI_HANDLE UserHandle, - IN EFI_GUID *Protocol, - OUT VOID **Interface - ); - -/** - Add a new protocol notification record for the request protocol. - - @param Protocol The requested protocol to add the notify - registration - @param Function Points to the notification function - @param Registration Returns the registration record - - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully returned the registration record - that has been added - -**/ -EFI_STATUS -EFIAPI -SmmRegisterProtocolNotify ( - IN CONST EFI_GUID *Protocol, - IN EFI_SMM_NOTIFY_FN Function, - OUT VOID **Registration - ); - -/** - Locates the requested handle(s) and returns them in Buffer. - - @param SearchType The type of search to perform to locate the - handles - @param Protocol The protocol to search for - @param SearchKey Dependant on SearchType - @param BufferSize On input the size of Buffer. On output the - size of data returned. - @param Buffer The buffer to return the results in - - @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is - returned in BufferSize. - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_SUCCESS Successfully found the requested handle(s) and - returns them in Buffer. - -**/ -EFI_STATUS -EFIAPI -SmmLocateHandle ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *BufferSize, - OUT EFI_HANDLE *Buffer - ); - -/** - Return the first Protocol Interface that matches the Protocol GUID. If - Registration is pasased in return a Protocol Instance that was just add - to the system. If Retistration is NULL return the first Protocol Interface - you find. - - @param Protocol The protocol to search for - @param Registration Optional Registration Key returned from - RegisterProtocolNotify() - @param Interface Return the Protocol interface (instance). - - @retval EFI_SUCCESS If a valid Interface is returned - @retval EFI_INVALID_PARAMETER Invalid parameter - @retval EFI_NOT_FOUND Protocol interface not found - -**/ -EFI_STATUS -EFIAPI -SmmLocateProtocol ( - IN EFI_GUID *Protocol, - IN VOID *Registration OPTIONAL, - OUT VOID **Interface - ); - -/** - Function returns an array of handles that support the requested protocol - in a buffer allocated from pool. This is a version of SmmLocateHandle() - that allocates a buffer for the caller. - - @param SearchType Specifies which handle(s) are to be returned. - @param Protocol Provides the protocol to search by. This - parameter is only valid for SearchType - ByProtocol. - @param SearchKey Supplies the search key depending on the - SearchType. - @param NumberHandles The number of handles returned in Buffer. - @param Buffer A pointer to the buffer to return the requested - array of handles that support Protocol. - - @retval EFI_SUCCESS The result array of handles was returned. - @retval EFI_NOT_FOUND No handles match the search. - @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the - matching results. - @retval EFI_INVALID_PARAMETER One or more paramters are not valid. - -**/ -EFI_STATUS -EFIAPI -SmmLocateHandleBuffer ( - IN EFI_LOCATE_SEARCH_TYPE SearchType, - IN EFI_GUID *Protocol OPTIONAL, - IN VOID *SearchKey OPTIONAL, - IN OUT UINTN *NumberHandles, - OUT EFI_HANDLE **Buffer - ); - -/** - Manage SMI of a particular type. - - @param HandlerType Points to the handler type or NULL for root SMI handlers. - @param Context Points to an optional context buffer. - @param CommBuffer Points to the optional communication buffer. - @param CommBufferSize Points to the size of the optional communication buffer. - - @retval EFI_SUCCESS Interrupt source was processed successfully but not quiesced. - @retval EFI_INTERRUPT_PENDING One or more SMI sources could not be quiesced. - @retval EFI_WARN_INTERRUPT_SOURCE_PENDING Interrupt source was not handled or quiesced. - @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED Interrupt source was handled and quiesced. - -**/ -EFI_STATUS -EFIAPI -SmiManage ( - IN CONST EFI_GUID *HandlerType, - IN CONST VOID *Context OPTIONAL, - IN OUT VOID *CommBuffer OPTIONAL, - IN OUT UINTN *CommBufferSize OPTIONAL - ); - -/** - Registers a handler to execute within SMM. - - @param Handler Handler service funtion pointer. - @param HandlerType Points to the handler type or NULL for root SMI handlers. - @param DispatchHandle On return, contains a unique handle which can be used to later unregister the handler function. - - @retval EFI_SUCCESS Handler register success. - @retval EFI_INVALID_PARAMETER Handler or DispatchHandle is NULL. - -**/ -EFI_STATUS -EFIAPI -SmiHandlerRegister ( - IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler, - IN CONST EFI_GUID *HandlerType OPTIONAL, - OUT EFI_HANDLE *DispatchHandle - ); - -/** - Unregister a handler in SMM. - - @param DispatchHandle The handle that was specified when the handler was registered. - - @retval EFI_SUCCESS Handler function was successfully unregistered. - @retval EFI_INVALID_PARAMETER DispatchHandle does not refer to a valid handle. - -**/ -EFI_STATUS -EFIAPI -SmiHandlerUnRegister ( - IN EFI_HANDLE DispatchHandle - ); - -/** - This function is the main entry point for an SMM handler dispatch - or communicate-based callback. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmDriverDispatchHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ); - -/** - This function is the main entry point for an SMM handler dispatch - or communicate-based callback. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmLegacyBootHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ); - -/** - This function is the main entry point for an SMM handler dispatch - or communicate-based callback. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmReadyToLockHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ); - -/** - This function is the main entry point for an SMM handler dispatch - or communicate-based callback. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmEndOfDxeHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ); - -/** - This function is the main entry point for an SMM handler dispatch - or communicate-based callback. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmExitBootServicesHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ); - -/** - This function is the main entry point for an SMM handler dispatch - or communicate-based callback. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @return Status Code - -**/ -EFI_STATUS -EFIAPI -SmmReadyToBootHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context, OPTIONAL - IN OUT VOID *CommBuffer, OPTIONAL - IN OUT UINTN *CommBufferSize OPTIONAL - ); - -/** - Place holder function until all the SMM System Table Service are available. - - @param Arg1 Undefined - @param Arg2 Undefined - @param Arg3 Undefined - @param Arg4 Undefined - @param Arg5 Undefined - - @return EFI_NOT_AVAILABLE_YET - -**/ -EFI_STATUS -EFIAPI -SmmEfiNotAvailableYetArg5 ( - UINTN Arg1, - UINTN Arg2, - UINTN Arg3, - UINTN Arg4, - UINTN Arg5 - ); - -// -//Functions used during debug buils -// - -/** - Traverse the discovered list for any drivers that were discovered but not loaded - because the dependency experessions evaluated to false. - -**/ -VOID -SmmDisplayDiscoveredNotDispatched ( - VOID - ); - -/** - Add free SMRAM region for use by memory service. - - @param MemBase Base address of memory region. - @param MemLength Length of the memory region. - @param Type Memory type. - @param Attributes Memory region state. - -**/ -VOID -SmmAddMemoryRegion ( - IN EFI_PHYSICAL_ADDRESS MemBase, - IN UINT64 MemLength, - IN EFI_MEMORY_TYPE Type, - IN UINT64 Attributes - ); - -/** - Finds the protocol entry for the requested protocol. - - @param Protocol The ID of the protocol - @param Create Create a new entry if not found - - @return Protocol entry - -**/ -PROTOCOL_ENTRY * -SmmFindProtocolEntry ( - IN EFI_GUID *Protocol, - IN BOOLEAN Create - ); - -/** - Signal event for every protocol in protocol entry. - - @param Prot Protocol interface - -**/ -VOID -SmmNotifyProtocol ( - IN PROTOCOL_INTERFACE *Prot - ); - -/** - Finds the protocol instance for the requested handle and protocol. - Note: This function doesn't do parameters checking, it's caller's responsibility - to pass in valid parameters. - - @param Handle The handle to search the protocol on - @param Protocol GUID of the protocol - @param Interface The interface for the protocol being searched - - @return Protocol instance (NULL: Not found) - -**/ -PROTOCOL_INTERFACE * -SmmFindProtocolInterface ( - IN IHANDLE *Handle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ); - -/** - Removes Protocol from the protocol list (but not the handle list). - - @param Handle The handle to remove protocol on. - @param Protocol GUID of the protocol to be moved - @param Interface The interface of the protocol - - @return Protocol Entry - -**/ -PROTOCOL_INTERFACE * -SmmRemoveInterfaceFromProtocol ( - IN IHANDLE *Handle, - IN EFI_GUID *Protocol, - IN VOID *Interface - ); - -/** - This is the POSTFIX version of the dependency evaluator. This code does - not need to handle Before or After, as it is not valid to call this - routine in this case. POSTFIX means all the math is done on top of the stack. - - @param DriverEntry DriverEntry element to update. - - @retval TRUE If driver is ready to run. - @retval FALSE If driver is not ready to run or some fatal error - was found. - -**/ -BOOLEAN -SmmIsSchedulable ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry - ); - -// -// SmramProfile -// - -/** - Initialize SMRAM profile. - -**/ -VOID -SmramProfileInit ( - VOID - ); - -/** - Install SMRAM profile protocol. - -**/ -VOID -SmramProfileInstallProtocol ( - VOID - ); - -/** - Register SMM image to SMRAM profile. - - @param DriverEntry SMM image info. - @param RegisterToDxe Register image to DXE. - - @return EFI_SUCCESS Register successfully. - @return EFI_UNSUPPORTED Memory profile unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCES No enough resource for this register. - -**/ -EFI_STATUS -RegisterSmramProfileImage ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry, - IN BOOLEAN RegisterToDxe - ); - -/** - Unregister image from SMRAM profile. - - @param DriverEntry SMM image info. - @param UnregisterToDxe Unregister image from DXE. - - @return EFI_SUCCESS Unregister successfully. - @return EFI_UNSUPPORTED Memory profile unsupported, - or memory profile for the image is not required. - @return EFI_NOT_FOUND The image is not found. - -**/ -EFI_STATUS -UnregisterSmramProfileImage ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry, - IN BOOLEAN UnregisterToDxe - ); - -/** - Update SMRAM profile information. - - @param CallerAddress Address of caller who call Allocate or Free. - @param Action This Allocate or Free action. - @param MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param Size Buffer size. - @param Buffer Buffer address. - @param ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -SmmCoreUpdateProfile ( - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, // Valid for AllocatePages/AllocatePool - IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ); - -/** - Register SMRAM profile handler. - -**/ -VOID -RegisterSmramProfileHandler ( - VOID - ); - -/** - SMRAM profile ready to lock callback function. - -**/ -VOID -SmramProfileReadyToLock ( - VOID - ); - -/** - Initialize MemoryAttributes support. -**/ -VOID -EFIAPI -SmmCoreInitializeMemoryAttributesTable ( - VOID - ); - -/** - This function returns a copy of the current memory map. The map is an array of - memory descriptors, each of which describes a contiguous block of memory. - - @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the - MemoryMap buffer. On input, this is the size of - the buffer allocated by the caller. On output, - it is the size of the buffer returned by the - firmware if the buffer was large enough, or the - size of the buffer needed to contain the map if - the buffer was too small. - @param[in, out] MemoryMap A pointer to the buffer in which firmware places - the current memory map. - @param[out] MapKey A pointer to the location in which firmware - returns the key for the current memory map. - @param[out] DescriptorSize A pointer to the location in which firmware - returns the size, in bytes, of an individual - EFI_MEMORY_DESCRIPTOR. - @param[out] DescriptorVersion A pointer to the location in which firmware - returns the version number associated with the - EFI_MEMORY_DESCRIPTOR. - - @retval EFI_SUCCESS The memory map was returned in the MemoryMap - buffer. - @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current - buffer size needed to hold the memory map is - returned in MemoryMapSize. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -SmmCoreGetMemoryMap ( - IN OUT UINTN *MemoryMapSize, - IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, - OUT UINTN *MapKey, - OUT UINTN *DescriptorSize, - OUT UINT32 *DescriptorVersion - ); - -/** - Initialize SmiHandler profile feature. -**/ -VOID -SmmCoreInitializeSmiHandlerProfile ( - VOID - ); - -/** - This function is called by SmmChildDispatcher module to report - a new SMI handler is registered, to SmmCore. - - @param This The protocol instance - @param HandlerGuid The GUID to identify the type of the handler. - For the SmmChildDispatch protocol, the HandlerGuid - must be the GUID of SmmChildDispatch protocol. - @param Handler The SMI handler. - @param CallerAddress The address of the module who registers the SMI handler. - @param Context The context of the SMI handler. - For the SmmChildDispatch protocol, the Context - must match the one defined for SmmChildDispatch protocol. - @param ContextSize The size of the context in bytes. - For the SmmChildDispatch protocol, the Context - must match the one defined for SmmChildDispatch protocol. - - @retval EFI_SUCCESS The information is recorded. - @retval EFI_OUT_OF_RESOURCES There is no enough resource to record the information. -**/ -EFI_STATUS -EFIAPI -SmiHandlerProfileRegisterHandler ( - IN SMI_HANDLER_PROFILE_PROTOCOL *This, - IN EFI_GUID *HandlerGuid, - IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler, - IN PHYSICAL_ADDRESS CallerAddress, - IN VOID *Context, OPTIONAL - IN UINTN ContextSize OPTIONAL - ); - -/** - This function is called by SmmChildDispatcher module to report - an existing SMI handler is unregistered, to SmmCore. - - @param This The protocol instance - @param HandlerGuid The GUID to identify the type of the handler. - For the SmmChildDispatch protocol, the HandlerGuid - must be the GUID of SmmChildDispatch protocol. - @param Handler The SMI handler. - @param Context The context of the SMI handler. - If it is NOT NULL, it will be used to check what is registered. - @param ContextSize The size of the context in bytes. - If Context is NOT NULL, it will be used to check what is registered. - - @retval EFI_SUCCESS The original record is removed. - @retval EFI_NOT_FOUND There is no record for the HandlerGuid and handler. -**/ -EFI_STATUS -EFIAPI -SmiHandlerProfileUnregisterHandler ( - IN SMI_HANDLER_PROFILE_PROTOCOL *This, - IN EFI_GUID *HandlerGuid, - IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler, - IN VOID *Context, OPTIONAL - IN UINTN ContextSize OPTIONAL - ); - -extern UINTN mFullSmramRangeCount; -extern EFI_SMRAM_DESCRIPTOR *mFullSmramRanges; - -extern EFI_SMM_DRIVER_ENTRY *mSmmCoreDriverEntry; - -extern EFI_LOADED_IMAGE_PROTOCOL *mSmmCoreLoadedImage; - -// -// Page management -// - -typedef struct { - LIST_ENTRY Link; - UINTN NumberOfPages; -} FREE_PAGE_LIST; - -extern LIST_ENTRY mSmmMemoryMap; - -// -// Pool management -// - -// -// MIN_POOL_SHIFT must not be less than 5 -// -#define MIN_POOL_SHIFT 6 -#define MIN_POOL_SIZE (1 << MIN_POOL_SHIFT) - -// -// MAX_POOL_SHIFT must not be less than EFI_PAGE_SHIFT - 1 -// -#define MAX_POOL_SHIFT (EFI_PAGE_SHIFT - 1) -#define MAX_POOL_SIZE (1 << MAX_POOL_SHIFT) - -// -// MAX_POOL_INDEX are calculated by maximum and minimum pool sizes -// -#define MAX_POOL_INDEX (MAX_POOL_SHIFT - MIN_POOL_SHIFT + 1) - -typedef struct { - UINTN Size; - BOOLEAN Available; - EFI_MEMORY_TYPE Type; -} POOL_HEADER; - -typedef struct { - POOL_HEADER Header; - LIST_ENTRY Link; -} FREE_POOL_HEADER; - -typedef enum { - SmmPoolTypeCode, - SmmPoolTypeData, - SmmPoolTypeMax, -} SMM_POOL_TYPE; - -extern LIST_ENTRY mSmmPoolLists[SmmPoolTypeMax][MAX_POOL_INDEX]; - -#endif diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf deleted file mode 100644 index 95e34bd683..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf +++ /dev/null @@ -1,120 +0,0 @@ -## @file -# This module provide an SMM CIS compliant implementation of SMM Core. -# -# Copyright (c) 2009 - 2017, 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 -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = PiSmmCore - MODULE_UNI_FILE = PiSmmCore.uni - FILE_GUID = E94F54CD-81EB-47ed-AEC3-856F5DC157A9 - MODULE_TYPE = SMM_CORE - VERSION_STRING = 1.0 - PI_SPECIFICATION_VERSION = 0x0001000A - ENTRY_POINT = SmmMain - -# VALID_ARCHITECTURES = IA32 X64 - -[Sources] - PiSmmCore.c - PiSmmCore.h - PiSmmCorePrivateData.h - Page.c - Pool.c - Handle.c - Locate.c - Notify.c - Dependency.c - Dispatcher.c - Smi.c - InstallConfigurationTable.c - SmramProfileRecord.c - MemoryAttributesTable.c - SmiHandlerProfile.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - BaseLib - BaseMemoryLib - PeCoffLib - PeCoffGetEntryPointLib - CacheMaintenanceLib - DebugLib - ReportStatusCodeLib - DevicePathLib - UefiLib - UefiBootServicesTableLib - MemoryAllocationLib - PcdLib - SmmCorePlatformHookLib - PerformanceLib - TimerLib - HobLib - SmmMemLib - DxeServicesLib - -[Protocols] - gEfiDxeSmmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister - gEfiSmmReadyToLockProtocolGuid ## PRODUCES - gEfiSmmCpuIo2ProtocolGuid ## CONSUMES - gEfiFirmwareVolume2ProtocolGuid ## CONSUMES - gEfiSmmEndOfDxeProtocolGuid ## PRODUCES - gEfiSecurityArchProtocolGuid ## SOMETIMES_CONSUMES - gEfiSecurity2ArchProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadedImageProtocolGuid ## PRODUCES - gEfiDevicePathProtocolGuid ## CONSUMES - gEdkiiSmmExitBootServicesProtocolGuid ## SOMETIMES_PRODUCES - gEdkiiSmmLegacyBootProtocolGuid ## SOMETIMES_PRODUCES - gEdkiiSmmReadyToBootProtocolGuid ## PRODUCES - - gEfiSmmSwDispatch2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiSmmSxDispatch2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiSmmPowerButtonDispatch2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiSmmStandbyButtonDispatch2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiSmmPeriodicTimerDispatch2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiSmmGpiDispatch2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiSmmIoTrapDispatch2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiSmmUsbDispatch2ProtocolGuid ## SOMETIMES_CONSUMES - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileDriverPath ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask ## CONSUMES - -[Guids] - gAprioriGuid ## SOMETIMES_CONSUMES ## File - gEfiEventDxeDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister - gEfiEventLegacyBootGuid ## PRODUCES ## GUID # SmiHandlerRegister - gEfiEventExitBootServicesGuid ## PRODUCES ## GUID # SmiHandlerRegister - gEfiEventReadyToBootGuid ## PRODUCES ## GUID # SmiHandlerRegister - gEfiEndOfDxeEventGroupGuid ## PRODUCES ## GUID # SmiHandlerRegister - ## SOMETIMES_CONSUMES ## GUID # Locate protocol - ## SOMETIMES_PRODUCES ## GUID # SmiHandlerRegister - gEdkiiMemoryProfileGuid - ## SOMETIMES_PRODUCES ## GUID # Install protocol - gEdkiiSmmMemoryProfileGuid - gEdkiiPiSmmMemoryAttributesTableGuid ## SOMETIMES_PRODUCES ## SystemTable - ## SOMETIMES_CONSUMES ## SystemTable - gLoadFixedAddressConfigurationTableGuid - ## SOMETIMES_PRODUCES ## GUID # Install protocol - ## SOMETIMES_PRODUCES ## GUID # SmiHandlerRegister - gSmiHandlerProfileGuid - -[UserExtensions.TianoCore."ExtraFiles"] - PiSmmCoreExtra.uni diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.uni b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.uni deleted file mode 100644 index 5b02e71e07..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.uni +++ /dev/null @@ -1,21 +0,0 @@ -// /** @file -// This module provide an SMM CIS compliant implementation of SMM Core. -// -// This module provide an SMM CIS compliant implementation of SMM Core. -// -// Copyright (c) 2009 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Provides an SMM CIS compliant implementation of SMM Core" - -#string STR_MODULE_DESCRIPTION #language en-US "This module provide an SMM CIS compliant implementation of SMM Core." - diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCoreExtra.uni b/MdeModulePkg/Core/PiSmmCore/PiSmmCoreExtra.uni deleted file mode 100644 index c1ed17534c..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCoreExtra.uni +++ /dev/null @@ -1,19 +0,0 @@ -// /** @file -// PiSmmCore Localized Strings and Content -// -// Copyright (c) 2013 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Core SMM Services Driver" - - diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h b/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h deleted file mode 100644 index 8aec7a6568..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h +++ /dev/null @@ -1,125 +0,0 @@ -/** @file - The internal header file that declared a data structure that is shared - between the SMM IPL and the SMM Core. - - Copyright (c) 2009 - 2015, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _PI_SMM_CORE_PRIVATE_DATA_H_ -#define _PI_SMM_CORE_PRIVATE_DATA_H_ - -/// -/// Define values for the communications buffer used when gEfiEventDxeDispatchGuid is -/// event signaled. This event is signaled by the DXE Core each time the DXE Core -/// dispatcher has completed its work. When this event is signaled, the SMM Core -/// if notified, so the SMM Core can dispatch SMM drivers. If COMM_BUFFER_SMM_DISPATCH_ERROR -/// is returned in the communication buffer, then an error occurred dispatching SMM -/// Drivers. If COMM_BUFFER_SMM_DISPATCH_SUCCESS is returned, then the SMM Core -/// dispatched all the drivers it could. If COMM_BUFFER_SMM_DISPATCH_RESTART is -/// returned, then the SMM Core just dispatched the SMM Driver that registered -/// the SMM Entry Point enabling the use of SMM Mode. In this case, the SMM Core -/// should be notified again to dispatch more SMM Drivers using SMM Mode. -/// -#define COMM_BUFFER_SMM_DISPATCH_ERROR 0x00 -#define COMM_BUFFER_SMM_DISPATCH_SUCCESS 0x01 -#define COMM_BUFFER_SMM_DISPATCH_RESTART 0x02 - -/// -/// Signature for the private structure shared between the SMM IPL and the SMM Core -/// -#define SMM_CORE_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'm', 'm', 'c') - -/// -/// Private structure that is used to share information between the SMM IPL and -/// the SMM Core. This structure is allocated from memory of type EfiRuntimeServicesData. -/// Since runtime memory types are converted to available memory when a legacy boot -/// is performed, the SMM Core must not access any fields of this structure if a legacy -/// boot is performed. As a result, the SMM IPL must create an event notification -/// for the Legacy Boot event and notify the SMM Core that a legacy boot is being -/// performed. The SMM Core can then use this information to filter accesses to -/// thos structure. -/// -typedef struct { - UINTN Signature; - - /// - /// The ImageHandle passed into the entry point of the SMM IPL. This ImageHandle - /// is used by the SMM Core to fill in the ParentImageHandle field of the Loaded - /// Image Protocol for each SMM Driver that is dispatched by the SMM Core. - /// - EFI_HANDLE SmmIplImageHandle; - - /// - /// The number of SMRAM ranges passed from the SMM IPL to the SMM Core. The SMM - /// Core uses these ranges of SMRAM to initialize the SMM Core memory manager. - /// - UINTN SmramRangeCount; - - /// - /// A table of SMRAM ranges passed from the SMM IPL to the SMM Core. The SMM - /// Core uses these ranges of SMRAM to initialize the SMM Core memory manager. - /// - EFI_SMRAM_DESCRIPTOR *SmramRanges; - - /// - /// The SMM Foundation Entry Point. The SMM Core fills in this field when the - /// SMM Core is initialized. The SMM IPL is responsbile for registering this entry - /// point with the SMM Configuration Protocol. The SMM Configuration Protocol may - /// not be available at the time the SMM IPL and SMM Core are started, so the SMM IPL - /// sets up a protocol notification on the SMM Configuration Protocol and registers - /// the SMM Foundation Entry Point as soon as the SMM Configuration Protocol is - /// available. - /// - EFI_SMM_ENTRY_POINT SmmEntryPoint; - - /// - /// Boolean flag set to TRUE while an SMI is being processed by the SMM Core. - /// - BOOLEAN SmmEntryPointRegistered; - - /// - /// Boolean flag set to TRUE while an SMI is being processed by the SMM Core. - /// - BOOLEAN InSmm; - - /// - /// This field is set by the SMM Core then the SMM Core is initialized. This field is - /// used by the SMM Base 2 Protocol and SMM Communication Protocol implementations in - /// the SMM IPL. - /// - EFI_SMM_SYSTEM_TABLE2 *Smst; - - /// - /// This field is used by the SMM Communicatioon Protocol to pass a buffer into - /// a software SMI handler and for the software SMI handler to pass a buffer back to - /// the caller of the SMM Communication Protocol. - /// - VOID *CommunicationBuffer; - - /// - /// This field is used by the SMM Communicatioon Protocol to pass the size of a buffer, - /// in bytes, into a software SMI handler and for the software SMI handler to pass the - /// size, in bytes, of a buffer back to the caller of the SMM Communication Protocol. - /// - UINTN BufferSize; - - /// - /// This field is used by the SMM Communication Protocol to pass the return status from - /// a software SMI handler back to the caller of the SMM Communication Protocol. - /// - EFI_STATUS ReturnStatus; - - EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase; - UINT64 PiSmmCoreImageSize; - EFI_PHYSICAL_ADDRESS PiSmmCoreEntryPoint; -} SMM_CORE_PRIVATE_DATA; - -#endif diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c deleted file mode 100644 index feb846ee9e..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ /dev/null @@ -1,1745 +0,0 @@ -/** @file - SMM IPL that produces SMM related runtime protocols and load the SMM Core into SMRAM - - Copyright (c) 2009 - 2017, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "PiSmmCorePrivateData.h" - -// -// Function prototypes from produced protocols -// - -/** - Indicate whether the driver is currently executing in the SMM Initialization phase. - - @param This The EFI_SMM_BASE2_PROTOCOL instance. - @param InSmram Pointer to a Boolean which, on return, indicates that the driver is currently executing - inside of SMRAM (TRUE) or outside of SMRAM (FALSE). - - @retval EFI_INVALID_PARAMETER InSmram was NULL. - @retval EFI_SUCCESS The call returned successfully. - -**/ -EFI_STATUS -EFIAPI -SmmBase2InSmram ( - IN CONST EFI_SMM_BASE2_PROTOCOL *This, - OUT BOOLEAN *InSmram - ); - -/** - Retrieves the location of the System Management System Table (SMST). - - @param This The EFI_SMM_BASE2_PROTOCOL instance. - @param Smst On return, points to a pointer to the System Management Service Table (SMST). - - @retval EFI_INVALID_PARAMETER Smst or This was invalid. - @retval EFI_SUCCESS The memory was returned to the system. - @retval EFI_UNSUPPORTED Not in SMM. - -**/ -EFI_STATUS -EFIAPI -SmmBase2GetSmstLocation ( - IN CONST EFI_SMM_BASE2_PROTOCOL *This, - OUT EFI_SMM_SYSTEM_TABLE2 **Smst - ); - -/** - Communicates with a registered handler. - - This function provides a service to send and receive messages from a registered - UEFI service. This function is part of the SMM Communication Protocol that may - be called in physical mode prior to SetVirtualAddressMap() and in virtual mode - after SetVirtualAddressMap(). - - @param[in] This The EFI_SMM_COMMUNICATION_PROTOCOL instance. - @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. - @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data - being returned. Zero if the handler does not wish to reply with any data. - - @retval EFI_SUCCESS The message was successfully posted. - @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. -**/ -EFI_STATUS -EFIAPI -SmmCommunicationCommunicate ( - IN CONST EFI_SMM_COMMUNICATION_PROTOCOL *This, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommSize - ); - -/** - Event notification that is fired every time a gEfiSmmConfigurationProtocol installs. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplSmmConfigurationEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Event notification that is fired every time a DxeSmmReadyToLock protocol is added - or if gEfiEventReadyToBootGuid is signalled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplReadyToLockEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Event notification that is fired when DxeDispatch Event Group is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplDxeDispatchEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Event notification that is fired when a GUIDed Event Group is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplGuidedEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Event notification that is fired when EndOfDxe Event Group is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplEndOfDxeEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. - - This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. - It convers pointer to new virtual address. - - @param Event Event whose notification function is being invoked. - @param Context Pointer to the notification function's context. - -**/ -VOID -EFIAPI -SmmIplSetVirtualAddressNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -// -// Data structure used to declare a table of protocol notifications and event -// notifications required by the SMM IPL -// -typedef struct { - BOOLEAN Protocol; - BOOLEAN CloseOnLock; - EFI_GUID *Guid; - EFI_EVENT_NOTIFY NotifyFunction; - VOID *NotifyContext; - EFI_TPL NotifyTpl; - EFI_EVENT Event; -} SMM_IPL_EVENT_NOTIFICATION; - -// -// Handle to install the SMM Base2 Protocol and the SMM Communication Protocol -// -EFI_HANDLE mSmmIplHandle = NULL; - -// -// SMM Base 2 Protocol instance -// -EFI_SMM_BASE2_PROTOCOL mSmmBase2 = { - SmmBase2InSmram, - SmmBase2GetSmstLocation -}; - -// -// SMM Communication Protocol instance -// -EFI_SMM_COMMUNICATION_PROTOCOL mSmmCommunication = { - SmmCommunicationCommunicate -}; - -// -// SMM Core Private Data structure that contains the data shared between -// the SMM IPL and the SMM Core. -// -SMM_CORE_PRIVATE_DATA mSmmCorePrivateData = { - SMM_CORE_PRIVATE_DATA_SIGNATURE, // Signature - NULL, // SmmIplImageHandle - 0, // SmramRangeCount - NULL, // SmramRanges - NULL, // SmmEntryPoint - FALSE, // SmmEntryPointRegistered - FALSE, // InSmm - NULL, // Smst - NULL, // CommunicationBuffer - 0, // BufferSize - EFI_SUCCESS // ReturnStatus -}; - -// -// Global pointer used to access mSmmCorePrivateData from outside and inside SMM -// -SMM_CORE_PRIVATE_DATA *gSmmCorePrivate = &mSmmCorePrivateData; - -// -// SMM IPL global variables -// -EFI_SMM_CONTROL2_PROTOCOL *mSmmControl2; -EFI_SMM_ACCESS2_PROTOCOL *mSmmAccess; -EFI_SMRAM_DESCRIPTOR *mCurrentSmramRange; -BOOLEAN mSmmLocked = FALSE; -BOOLEAN mEndOfDxe = FALSE; -EFI_PHYSICAL_ADDRESS mSmramCacheBase; -UINT64 mSmramCacheSize; - -EFI_SMM_COMMUNICATE_HEADER mCommunicateHeader; - -// -// Table of Protocol notification and GUIDed Event notifications that the SMM IPL requires -// -SMM_IPL_EVENT_NOTIFICATION mSmmIplEvents[] = { - // - // Declare protocol notification on the SMM Configuration protocol. When this notification is established, - // the associated event is immediately signalled, so the notification function will be executed and the - // SMM Configuration Protocol will be found if it is already in the handle database. - // - { TRUE, FALSE, &gEfiSmmConfigurationProtocolGuid, SmmIplSmmConfigurationEventNotify, &gEfiSmmConfigurationProtocolGuid, TPL_NOTIFY, NULL }, - // - // Declare protocol notification on DxeSmmReadyToLock protocols. When this notification is established, - // the associated event is immediately signalled, so the notification function will be executed and the - // DXE SMM Ready To Lock Protocol will be found if it is already in the handle database. - // - { TRUE, TRUE, &gEfiDxeSmmReadyToLockProtocolGuid, SmmIplReadyToLockEventNotify, &gEfiDxeSmmReadyToLockProtocolGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on EndOfDxe event. When this notification is established, - // the associated event is immediately signalled, so the notification function will be executed and the - // SMM End Of Dxe Protocol will be found if it is already in the handle database. - // - { FALSE, TRUE, &gEfiEndOfDxeEventGroupGuid, SmmIplGuidedEventNotify, &gEfiEndOfDxeEventGroupGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on EndOfDxe event. This is used to set EndOfDxe event signaled flag. - // - { FALSE, TRUE, &gEfiEndOfDxeEventGroupGuid, SmmIplEndOfDxeEventNotify, &gEfiEndOfDxeEventGroupGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on the DXE Dispatch Event Group. This event is signaled by the DXE Core - // each time the DXE Core dispatcher has completed its work. When this event is signalled, the SMM Core - // if notified, so the SMM Core can dispatch SMM drivers. - // - { FALSE, TRUE, &gEfiEventDxeDispatchGuid, SmmIplDxeDispatchEventNotify, &gEfiEventDxeDispatchGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on Ready To Boot Event Group. This is an extra event notification that is - // used to make sure SMRAM is locked before any boot options are processed. - // - { FALSE, TRUE, &gEfiEventReadyToBootGuid, SmmIplReadyToLockEventNotify, &gEfiEventReadyToBootGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on Legacy Boot Event Group. This is used to inform the SMM Core that the platform - // is performing a legacy boot operation, and that the UEFI environment is no longer available and the SMM Core - // must guarantee that it does not access any UEFI related structures outside of SMRAM. - // It is also to inform the SMM Core to notify SMM driver that system enter legacy boot. - // - { FALSE, FALSE, &gEfiEventLegacyBootGuid, SmmIplGuidedEventNotify, &gEfiEventLegacyBootGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on Exit Boot Services Event Group. This is used to inform the SMM Core - // to notify SMM driver that system enter exit boot services. - // - { FALSE, FALSE, &gEfiEventExitBootServicesGuid, SmmIplGuidedEventNotify, &gEfiEventExitBootServicesGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on Ready To Boot Event Group. This is used to inform the SMM Core - // to notify SMM driver that system enter ready to boot. - // - { FALSE, FALSE, &gEfiEventReadyToBootGuid, SmmIplGuidedEventNotify, &gEfiEventReadyToBootGuid, TPL_CALLBACK, NULL }, - // - // Declare event notification on SetVirtualAddressMap() Event Group. This is used to convert gSmmCorePrivate - // and mSmmControl2 from physical addresses to virtual addresses. - // - { FALSE, FALSE, &gEfiEventVirtualAddressChangeGuid, SmmIplSetVirtualAddressNotify, NULL, TPL_CALLBACK, NULL }, - // - // Terminate the table of event notifications - // - { FALSE, FALSE, NULL, NULL, NULL, TPL_CALLBACK, NULL } -}; - -/** - Find the maximum SMRAM cache range that covers the range specified by SmramRange. - - This function searches and joins all adjacent ranges of SmramRange into a range to be cached. - - @param SmramRange The SMRAM range to search from. - @param SmramCacheBase The returned cache range base. - @param SmramCacheSize The returned cache range size. - -**/ -VOID -GetSmramCacheRange ( - IN EFI_SMRAM_DESCRIPTOR *SmramRange, - OUT EFI_PHYSICAL_ADDRESS *SmramCacheBase, - OUT UINT64 *SmramCacheSize - ) -{ - UINTN Index; - EFI_PHYSICAL_ADDRESS RangeCpuStart; - UINT64 RangePhysicalSize; - BOOLEAN FoundAjacentRange; - - *SmramCacheBase = SmramRange->CpuStart; - *SmramCacheSize = SmramRange->PhysicalSize; - - do { - FoundAjacentRange = FALSE; - for (Index = 0; Index < gSmmCorePrivate->SmramRangeCount; Index++) { - RangeCpuStart = gSmmCorePrivate->SmramRanges[Index].CpuStart; - RangePhysicalSize = gSmmCorePrivate->SmramRanges[Index].PhysicalSize; - if (RangeCpuStart < *SmramCacheBase && *SmramCacheBase == (RangeCpuStart + RangePhysicalSize)) { - *SmramCacheBase = RangeCpuStart; - *SmramCacheSize += RangePhysicalSize; - FoundAjacentRange = TRUE; - } else if ((*SmramCacheBase + *SmramCacheSize) == RangeCpuStart && RangePhysicalSize > 0) { - *SmramCacheSize += RangePhysicalSize; - FoundAjacentRange = TRUE; - } - } - } while (FoundAjacentRange); - -} - -/** - Indicate whether the driver is currently executing in the SMM Initialization phase. - - @param This The EFI_SMM_BASE2_PROTOCOL instance. - @param InSmram Pointer to a Boolean which, on return, indicates that the driver is currently executing - inside of SMRAM (TRUE) or outside of SMRAM (FALSE). - - @retval EFI_INVALID_PARAMETER InSmram was NULL. - @retval EFI_SUCCESS The call returned successfully. - -**/ -EFI_STATUS -EFIAPI -SmmBase2InSmram ( - IN CONST EFI_SMM_BASE2_PROTOCOL *This, - OUT BOOLEAN *InSmram - ) -{ - if (InSmram == NULL) { - return EFI_INVALID_PARAMETER; - } - - *InSmram = gSmmCorePrivate->InSmm; - - return EFI_SUCCESS; -} - -/** - Retrieves the location of the System Management System Table (SMST). - - @param This The EFI_SMM_BASE2_PROTOCOL instance. - @param Smst On return, points to a pointer to the System Management Service Table (SMST). - - @retval EFI_INVALID_PARAMETER Smst or This was invalid. - @retval EFI_SUCCESS The memory was returned to the system. - @retval EFI_UNSUPPORTED Not in SMM. - -**/ -EFI_STATUS -EFIAPI -SmmBase2GetSmstLocation ( - IN CONST EFI_SMM_BASE2_PROTOCOL *This, - OUT EFI_SMM_SYSTEM_TABLE2 **Smst - ) -{ - if ((This == NULL) ||(Smst == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (!gSmmCorePrivate->InSmm) { - return EFI_UNSUPPORTED; - } - - *Smst = gSmmCorePrivate->Smst; - - return EFI_SUCCESS; -} - -/** - Communicates with a registered handler. - - This function provides a service to send and receive messages from a registered - UEFI service. This function is part of the SMM Communication Protocol that may - be called in physical mode prior to SetVirtualAddressMap() and in virtual mode - after SetVirtualAddressMap(). - - @param[in] This The EFI_SMM_COMMUNICATION_PROTOCOL instance. - @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. - @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data - being returned. Zero if the handler does not wish to reply with any data. - - @retval EFI_SUCCESS The message was successfully posted. - @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. -**/ -EFI_STATUS -EFIAPI -SmmCommunicationCommunicate ( - IN CONST EFI_SMM_COMMUNICATION_PROTOCOL *This, - IN OUT VOID *CommBuffer, - IN OUT UINTN *CommSize - ) -{ - EFI_STATUS Status; - EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader; - BOOLEAN OldInSmm; - - // - // Check parameters - // - if ((CommBuffer == NULL) || (CommSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // CommSize must hold HeaderGuid and MessageLength - // - if (*CommSize < OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) { - return EFI_INVALID_PARAMETER; - } - - // - // If not already in SMM, then generate a Software SMI - // - if (!gSmmCorePrivate->InSmm && gSmmCorePrivate->SmmEntryPointRegistered) { - // - // Put arguments for Software SMI in gSmmCorePrivate - // - gSmmCorePrivate->CommunicationBuffer = CommBuffer; - gSmmCorePrivate->BufferSize = *CommSize; - - // - // Generate Software SMI - // - Status = mSmmControl2->Trigger (mSmmControl2, NULL, NULL, FALSE, 0); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Return status from software SMI - // - *CommSize = gSmmCorePrivate->BufferSize; - return gSmmCorePrivate->ReturnStatus; - } - - // - // If we are in SMM, then the execution mode must be physical, which means that - // OS established virtual addresses can not be used. If SetVirtualAddressMap() - // has been called, then a direct invocation of the Software SMI is not - // not allowed so return EFI_INVALID_PARAMETER. - // - if (EfiGoneVirtual()) { - return EFI_INVALID_PARAMETER; - } - - // - // If we are not in SMM, don't allow call SmiManage() directly when SMRAM is closed or locked. - // - if ((!gSmmCorePrivate->InSmm) && (!mSmmAccess->OpenState || mSmmAccess->LockState)) { - return EFI_INVALID_PARAMETER; - } - - // - // Save current InSmm state and set InSmm state to TRUE - // - OldInSmm = gSmmCorePrivate->InSmm; - gSmmCorePrivate->InSmm = TRUE; - - // - // Before SetVirtualAddressMap(), we are in SMM or SMRAM is open and unlocked, call SmiManage() directly. - // - CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommBuffer; - *CommSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data); - Status = gSmmCorePrivate->Smst->SmiManage ( - &CommunicateHeader->HeaderGuid, - NULL, - CommunicateHeader->Data, - CommSize - ); - - // - // Update CommunicationBuffer, BufferSize and ReturnStatus - // Communicate service finished, reset the pointer to CommBuffer to NULL - // - *CommSize += OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data); - - // - // Restore original InSmm state - // - gSmmCorePrivate->InSmm = OldInSmm; - - return (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND; -} - -/** - Event notification that is fired when GUIDed Event Group is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplGuidedEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - UINTN Size; - - // - // Use Guid to initialize EFI_SMM_COMMUNICATE_HEADER structure - // - CopyGuid (&mCommunicateHeader.HeaderGuid, (EFI_GUID *)Context); - mCommunicateHeader.MessageLength = 1; - mCommunicateHeader.Data[0] = 0; - - // - // Generate the Software SMI and return the result - // - Size = sizeof (mCommunicateHeader); - SmmCommunicationCommunicate (&mSmmCommunication, &mCommunicateHeader, &Size); -} - -/** - Event notification that is fired when EndOfDxe Event Group is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplEndOfDxeEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - mEndOfDxe = TRUE; -} - -/** - Event notification that is fired when DxeDispatch Event Group is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplDxeDispatchEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - UINTN Size; - EFI_STATUS Status; - - // - // Keep calling the SMM Core Dispatcher until there is no request to restart it. - // - while (TRUE) { - // - // Use Guid to initialize EFI_SMM_COMMUNICATE_HEADER structure - // Clear the buffer passed into the Software SMI. This buffer will return - // the status of the SMM Core Dispatcher. - // - CopyGuid (&mCommunicateHeader.HeaderGuid, (EFI_GUID *)Context); - mCommunicateHeader.MessageLength = 1; - mCommunicateHeader.Data[0] = 0; - - // - // Generate the Software SMI and return the result - // - Size = sizeof (mCommunicateHeader); - SmmCommunicationCommunicate (&mSmmCommunication, &mCommunicateHeader, &Size); - - // - // Return if there is no request to restart the SMM Core Dispatcher - // - if (mCommunicateHeader.Data[0] != COMM_BUFFER_SMM_DISPATCH_RESTART) { - return; - } - - // - // Attempt to reset SMRAM cacheability to UC - // Assume CPU AP is available at this time - // - Status = gDS->SetMemorySpaceAttributes( - mSmramCacheBase, - mSmramCacheSize, - EFI_MEMORY_UC - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "SMM IPL failed to reset SMRAM window to EFI_MEMORY_UC\n")); - } - - // - // Close all SMRAM ranges to protect SMRAM - // - Status = mSmmAccess->Close (mSmmAccess); - ASSERT_EFI_ERROR (Status); - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "SMM IPL closed SMRAM window\n")); - } -} - -/** - Event notification that is fired every time a gEfiSmmConfigurationProtocol installs. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplSmmConfigurationEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - EFI_SMM_CONFIGURATION_PROTOCOL *SmmConfiguration; - - // - // Make sure this notification is for this handler - // - Status = gBS->LocateProtocol (Context, NULL, (VOID **)&SmmConfiguration); - if (EFI_ERROR (Status)) { - return; - } - - // - // Register the SMM Entry Point provided by the SMM Core with the SMM COnfiguration protocol - // - Status = SmmConfiguration->RegisterSmmEntry (SmmConfiguration, gSmmCorePrivate->SmmEntryPoint); - ASSERT_EFI_ERROR (Status); - - // - // Set flag to indicate that the SMM Entry Point has been registered which - // means that SMIs are now fully operational. - // - gSmmCorePrivate->SmmEntryPointRegistered = TRUE; - - // - // Print debug message showing SMM Core entry point address. - // - DEBUG ((DEBUG_INFO, "SMM IPL registered SMM Entry Point address %p\n", (VOID *)(UINTN)gSmmCorePrivate->SmmEntryPoint)); -} - -/** - Event notification that is fired every time a DxeSmmReadyToLock protocol is added - or if gEfiEventReadyToBootGuid is signaled. - - @param Event The Event that is being processed, not used. - @param Context Event Context, not used. - -**/ -VOID -EFIAPI -SmmIplReadyToLockEventNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - VOID *Interface; - UINTN Index; - - // - // See if we are already locked - // - if (mSmmLocked) { - return; - } - - // - // Make sure this notification is for this handler - // - if (CompareGuid ((EFI_GUID *)Context, &gEfiDxeSmmReadyToLockProtocolGuid)) { - Status = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, &Interface); - if (EFI_ERROR (Status)) { - return; - } - } else { - // - // If SMM is not locked yet and we got here from gEfiEventReadyToBootGuid being - // signaled, then gEfiDxeSmmReadyToLockProtocolGuid was not installed as expected. - // Print a warning on debug builds. - // - DEBUG ((DEBUG_WARN, "SMM IPL! DXE SMM Ready To Lock Protocol not installed before Ready To Boot signal\n")); - } - - if (!mEndOfDxe) { - DEBUG ((DEBUG_ERROR, "EndOfDxe Event must be signaled before DxeSmmReadyToLock Protocol installation!\n")); - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED, - (EFI_SOFTWARE_SMM_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE) - ); - ASSERT (FALSE); - } - - // - // Lock the SMRAM (Note: Locking SMRAM may not be supported on all platforms) - // - mSmmAccess->Lock (mSmmAccess); - - // - // Close protocol and event notification events that do not apply after the - // DXE SMM Ready To Lock Protocol has been installed or the Ready To Boot - // event has been signalled. - // - for (Index = 0; mSmmIplEvents[Index].NotifyFunction != NULL; Index++) { - if (mSmmIplEvents[Index].CloseOnLock) { - gBS->CloseEvent (mSmmIplEvents[Index].Event); - } - } - - // - // Inform SMM Core that the DxeSmmReadyToLock protocol was installed - // - SmmIplGuidedEventNotify (Event, (VOID *)&gEfiDxeSmmReadyToLockProtocolGuid); - - // - // Print debug message that the SMRAM window is now locked. - // - DEBUG ((DEBUG_INFO, "SMM IPL locked SMRAM window\n")); - - // - // Set flag so this operation will not be performed again - // - mSmmLocked = TRUE; -} - -/** - Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. - - This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. - It convers pointer to new virtual address. - - @param Event Event whose notification function is being invoked. - @param Context Pointer to the notification function's context. - -**/ -VOID -EFIAPI -SmmIplSetVirtualAddressNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EfiConvertPointer (0x0, (VOID **)&mSmmControl2); -} - -/** - Get the fixed loading address from image header assigned by build tool. This function only be called - when Loading module at Fixed address feature enabled. - - @param ImageContext Pointer to the image context structure that describes the PE/COFF - image that needs to be examined by this function. - @retval EFI_SUCCESS An fixed loading address is assigned to this image by build tools . - @retval EFI_NOT_FOUND The image has no assigned fixed loading address. -**/ -EFI_STATUS -GetPeCoffImageFixLoadingAssignedAddress( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - UINTN SectionHeaderOffset; - EFI_STATUS Status; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_PHYSICAL_ADDRESS FixLoadingAddress; - UINT16 Index; - UINTN Size; - UINT16 NumberOfSections; - EFI_PHYSICAL_ADDRESS SmramBase; - UINT64 SmmCodeSize; - UINT64 ValueInSectionHeader; - // - // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber - // - SmmCodeSize = EFI_PAGES_TO_SIZE (PcdGet32(PcdLoadFixAddressSmmCodePageNumber)); - - FixLoadingAddress = 0; - Status = EFI_NOT_FOUND; - SmramBase = mCurrentSmramRange->CpuStart; - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8* )ImageContext->Handle + ImageContext->PeCoffHeaderOffset); - SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader; - NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections; - - // - // Get base address from the first section header that doesn't point to code section. - // - for (Index = 0; Index < NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EFI_NOT_FOUND; - - if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - // - // Build tool saves the offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields in the - // first section header that doesn't point to code section in image header. And there is an assumption that when the - // feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers - // fields should NOT be Zero, or else, these 2 fields should be set to Zero - // - ValueInSectionHeader = ReadUnaligned64((UINT64*)&SectionHeader.PointerToRelocations); - if (ValueInSectionHeader != 0) { - // - // Found first section header that doesn't point to code section in which build tool saves the - // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields - // - FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(SmramBase + (INT64)ValueInSectionHeader); - - if (SmramBase + SmmCodeSize > FixLoadingAddress && SmramBase <= FixLoadingAddress) { - // - // The assigned address is valid. Return the specified loading address - // - ImageContext->ImageAddress = FixLoadingAddress; - Status = EFI_SUCCESS; - } - } - break; - } - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status)); - return Status; -} -/** - Load the SMM Core image into SMRAM and executes the SMM Core from SMRAM. - - @param[in, out] SmramRange Descriptor for the range of SMRAM to reload the - currently executing image, the rang of SMRAM to - hold SMM Core will be excluded. - @param[in, out] SmramRangeSmmCore Descriptor for the range of SMRAM to hold SMM Core. - - @param[in] Context Context to pass into SMM Core - - @return EFI_STATUS - -**/ -EFI_STATUS -ExecuteSmmCoreFromSmram ( - IN OUT EFI_SMRAM_DESCRIPTOR *SmramRange, - IN OUT EFI_SMRAM_DESCRIPTOR *SmramRangeSmmCore, - IN VOID *Context - ) -{ - EFI_STATUS Status; - VOID *SourceBuffer; - UINTN SourceSize; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN PageCount; - EFI_IMAGE_ENTRY_POINT EntryPoint; - - // - // Search all Firmware Volumes for a PE/COFF image in a file of type SMM_CORE - // - Status = GetSectionFromAnyFvByFileType ( - EFI_FV_FILETYPE_SMM_CORE, - 0, - EFI_SECTION_PE32, - 0, - &SourceBuffer, - &SourceSize - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Initilize ImageContext - // - ImageContext.Handle = SourceBuffer; - ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory; - - // - // Get information about the image being loaded - // - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - return Status; - } - // - // if Loading module at Fixed Address feature is enabled, the SMM core driver will be loaded to - // the address assigned by build tool. - // - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { - // - // Get the fixed loading address assigned by Build tool - // - Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext); - if (!EFI_ERROR (Status)) { - // - // Since the memory range to load SMM CORE will be cut out in SMM core, so no need to allocate and free this range - // - PageCount = 0; - // - // Reserved Smram Region for SmmCore is not used, and remove it from SmramRangeCount. - // - gSmmCorePrivate->SmramRangeCount --; - } else { - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR: Loading module at fixed address at address failed\n")); - // - // Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR - // specified by SmramRange - // - PageCount = (UINTN)EFI_SIZE_TO_PAGES((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); - - ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0); - ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); - - SmramRange->PhysicalSize -= EFI_PAGES_TO_SIZE (PageCount); - SmramRangeSmmCore->CpuStart = SmramRange->CpuStart + SmramRange->PhysicalSize; - SmramRangeSmmCore->PhysicalStart = SmramRange->PhysicalStart + SmramRange->PhysicalSize; - SmramRangeSmmCore->RegionState = SmramRange->RegionState | EFI_ALLOCATED; - SmramRangeSmmCore->PhysicalSize = EFI_PAGES_TO_SIZE (PageCount); - - // - // Align buffer on section boundary - // - ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart; - } - } else { - // - // Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR - // specified by SmramRange - // - PageCount = (UINTN)EFI_SIZE_TO_PAGES((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); - - ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0); - ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount)); - - SmramRange->PhysicalSize -= EFI_PAGES_TO_SIZE (PageCount); - SmramRangeSmmCore->CpuStart = SmramRange->CpuStart + SmramRange->PhysicalSize; - SmramRangeSmmCore->PhysicalStart = SmramRange->PhysicalStart + SmramRange->PhysicalSize; - SmramRangeSmmCore->RegionState = SmramRange->RegionState | EFI_ALLOCATED; - SmramRangeSmmCore->PhysicalSize = EFI_PAGES_TO_SIZE (PageCount); - - // - // Align buffer on section boundary - // - ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart; - } - - ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; - ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); - - // - // Print debug message showing SMM Core load address. - // - DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.ImageAddress)); - - // - // Load the image to our new buffer - // - Status = PeCoffLoaderLoadImage (&ImageContext); - if (!EFI_ERROR (Status)) { - // - // Relocate the image in our new buffer - // - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (!EFI_ERROR (Status)) { - // - // Flush the instruction cache so the image data are written before we execute it - // - InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize); - - // - // Print debug message showing SMM Core entry point address. - // - DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.EntryPoint)); - - gSmmCorePrivate->PiSmmCoreImageBase = ImageContext.ImageAddress; - gSmmCorePrivate->PiSmmCoreImageSize = ImageContext.ImageSize; - DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase)); - DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageSize)); - - gSmmCorePrivate->PiSmmCoreEntryPoint = ImageContext.EntryPoint; - - // - // Execute image - // - EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)ImageContext.EntryPoint; - Status = EntryPoint ((EFI_HANDLE)Context, gST); - } - } - - // - // Always free memory allocted by GetFileBufferByFilePath () - // - FreePool (SourceBuffer); - - return Status; -} - -/** - SMM split SMRAM entry. - - @param[in, out] RangeToCompare Pointer to EFI_SMRAM_DESCRIPTOR to compare. - @param[in, out] ReservedRangeToCompare Pointer to EFI_SMM_RESERVED_SMRAM_REGION to compare. - @param[out] Ranges Output pointer to hold split EFI_SMRAM_DESCRIPTOR entry. - @param[in, out] RangeCount Pointer to range count. - @param[out] ReservedRanges Output pointer to hold split EFI_SMM_RESERVED_SMRAM_REGION entry. - @param[in, out] ReservedRangeCount Pointer to reserved range count. - @param[out] FinalRanges Output pointer to hold split final EFI_SMRAM_DESCRIPTOR entry - that no need to be split anymore. - @param[in, out] FinalRangeCount Pointer to final range count. - -**/ -VOID -SmmSplitSmramEntry ( - IN OUT EFI_SMRAM_DESCRIPTOR *RangeToCompare, - IN OUT EFI_SMM_RESERVED_SMRAM_REGION *ReservedRangeToCompare, - OUT EFI_SMRAM_DESCRIPTOR *Ranges, - IN OUT UINTN *RangeCount, - OUT EFI_SMM_RESERVED_SMRAM_REGION *ReservedRanges, - IN OUT UINTN *ReservedRangeCount, - OUT EFI_SMRAM_DESCRIPTOR *FinalRanges, - IN OUT UINTN *FinalRangeCount - ) -{ - UINT64 RangeToCompareEnd; - UINT64 ReservedRangeToCompareEnd; - - RangeToCompareEnd = RangeToCompare->CpuStart + RangeToCompare->PhysicalSize; - ReservedRangeToCompareEnd = ReservedRangeToCompare->SmramReservedStart + ReservedRangeToCompare->SmramReservedSize; - - if ((RangeToCompare->CpuStart >= ReservedRangeToCompare->SmramReservedStart) && - (RangeToCompare->CpuStart < ReservedRangeToCompareEnd)) { - if (RangeToCompareEnd < ReservedRangeToCompareEnd) { - // - // RangeToCompare ReservedRangeToCompare - // ---- ---- -------------------------------------- - // | | | | -> 1. ReservedRangeToCompare - // ---- | | |--| -------------------------------------- - // | | | | | | - // | | | | | | -> 2. FinalRanges[*FinalRangeCount] and increment *FinalRangeCount - // | | | | | | RangeToCompare->PhysicalSize = 0 - // ---- | | |--| -------------------------------------- - // | | | | -> 3. ReservedRanges[*ReservedRangeCount] and increment *ReservedRangeCount - // ---- ---- -------------------------------------- - // - - // - // 1. Update ReservedRangeToCompare. - // - ReservedRangeToCompare->SmramReservedSize = RangeToCompare->CpuStart - ReservedRangeToCompare->SmramReservedStart; - // - // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount. - // Zero RangeToCompare->PhysicalSize. - // - FinalRanges[*FinalRangeCount].CpuStart = RangeToCompare->CpuStart; - FinalRanges[*FinalRangeCount].PhysicalStart = RangeToCompare->PhysicalStart; - FinalRanges[*FinalRangeCount].RegionState = RangeToCompare->RegionState | EFI_ALLOCATED; - FinalRanges[*FinalRangeCount].PhysicalSize = RangeToCompare->PhysicalSize; - *FinalRangeCount += 1; - RangeToCompare->PhysicalSize = 0; - // - // 3. Update ReservedRanges[*ReservedRangeCount] and increment *ReservedRangeCount. - // - ReservedRanges[*ReservedRangeCount].SmramReservedStart = FinalRanges[*FinalRangeCount - 1].CpuStart + FinalRanges[*FinalRangeCount - 1].PhysicalSize; - ReservedRanges[*ReservedRangeCount].SmramReservedSize = ReservedRangeToCompareEnd - RangeToCompareEnd; - *ReservedRangeCount += 1; - } else { - // - // RangeToCompare ReservedRangeToCompare - // ---- ---- -------------------------------------- - // | | | | -> 1. ReservedRangeToCompare - // ---- | | |--| -------------------------------------- - // | | | | | | - // | | | | | | -> 2. FinalRanges[*FinalRangeCount] and increment *FinalRangeCount - // | | | | | | - // | | ---- |--| -------------------------------------- - // | | | | -> 3. RangeToCompare - // ---- ---- -------------------------------------- - // - - // - // 1. Update ReservedRangeToCompare. - // - ReservedRangeToCompare->SmramReservedSize = RangeToCompare->CpuStart - ReservedRangeToCompare->SmramReservedStart; - // - // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount. - // - FinalRanges[*FinalRangeCount].CpuStart = RangeToCompare->CpuStart; - FinalRanges[*FinalRangeCount].PhysicalStart = RangeToCompare->PhysicalStart; - FinalRanges[*FinalRangeCount].RegionState = RangeToCompare->RegionState | EFI_ALLOCATED; - FinalRanges[*FinalRangeCount].PhysicalSize = ReservedRangeToCompareEnd - RangeToCompare->CpuStart; - *FinalRangeCount += 1; - // - // 3. Update RangeToCompare. - // - RangeToCompare->CpuStart += FinalRanges[*FinalRangeCount - 1].PhysicalSize; - RangeToCompare->PhysicalStart += FinalRanges[*FinalRangeCount - 1].PhysicalSize; - RangeToCompare->PhysicalSize -= FinalRanges[*FinalRangeCount - 1].PhysicalSize; - } - } else if ((ReservedRangeToCompare->SmramReservedStart >= RangeToCompare->CpuStart) && - (ReservedRangeToCompare->SmramReservedStart < RangeToCompareEnd)) { - if (ReservedRangeToCompareEnd < RangeToCompareEnd) { - // - // RangeToCompare ReservedRangeToCompare - // ---- ---- -------------------------------------- - // | | | | -> 1. RangeToCompare - // | | ---- |--| -------------------------------------- - // | | | | | | - // | | | | | | -> 2. FinalRanges[*FinalRangeCount] and increment *FinalRangeCount - // | | | | | | ReservedRangeToCompare->SmramReservedSize = 0 - // | | ---- |--| -------------------------------------- - // | | | | -> 3. Ranges[*RangeCount] and increment *RangeCount - // ---- ---- -------------------------------------- - // - - // - // 1. Update RangeToCompare. - // - RangeToCompare->PhysicalSize = ReservedRangeToCompare->SmramReservedStart - RangeToCompare->CpuStart; - // - // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount. - // ReservedRangeToCompare->SmramReservedSize = 0 - // - FinalRanges[*FinalRangeCount].CpuStart = ReservedRangeToCompare->SmramReservedStart; - FinalRanges[*FinalRangeCount].PhysicalStart = RangeToCompare->PhysicalStart + RangeToCompare->PhysicalSize; - FinalRanges[*FinalRangeCount].RegionState = RangeToCompare->RegionState | EFI_ALLOCATED; - FinalRanges[*FinalRangeCount].PhysicalSize = ReservedRangeToCompare->SmramReservedSize; - *FinalRangeCount += 1; - ReservedRangeToCompare->SmramReservedSize = 0; - // - // 3. Update Ranges[*RangeCount] and increment *RangeCount. - // - Ranges[*RangeCount].CpuStart = FinalRanges[*FinalRangeCount - 1].CpuStart + FinalRanges[*FinalRangeCount - 1].PhysicalSize; - Ranges[*RangeCount].PhysicalStart = FinalRanges[*FinalRangeCount - 1].PhysicalStart + FinalRanges[*FinalRangeCount - 1].PhysicalSize; - Ranges[*RangeCount].RegionState = RangeToCompare->RegionState; - Ranges[*RangeCount].PhysicalSize = RangeToCompareEnd - ReservedRangeToCompareEnd; - *RangeCount += 1; - } else { - // - // RangeToCompare ReservedRangeToCompare - // ---- ---- -------------------------------------- - // | | | | -> 1. RangeToCompare - // | | ---- |--| -------------------------------------- - // | | | | | | - // | | | | | | -> 2. FinalRanges[*FinalRangeCount] and increment *FinalRangeCount - // | | | | | | - // ---- | | |--| -------------------------------------- - // | | | | -> 3. ReservedRangeToCompare - // ---- ---- -------------------------------------- - // - - // - // 1. Update RangeToCompare. - // - RangeToCompare->PhysicalSize = ReservedRangeToCompare->SmramReservedStart - RangeToCompare->CpuStart; - // - // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount. - // ReservedRangeToCompare->SmramReservedSize = 0 - // - FinalRanges[*FinalRangeCount].CpuStart = ReservedRangeToCompare->SmramReservedStart; - FinalRanges[*FinalRangeCount].PhysicalStart = RangeToCompare->PhysicalStart + RangeToCompare->PhysicalSize; - FinalRanges[*FinalRangeCount].RegionState = RangeToCompare->RegionState | EFI_ALLOCATED; - FinalRanges[*FinalRangeCount].PhysicalSize = RangeToCompareEnd - ReservedRangeToCompare->SmramReservedStart; - *FinalRangeCount += 1; - // - // 3. Update ReservedRangeToCompare. - // - ReservedRangeToCompare->SmramReservedStart += FinalRanges[*FinalRangeCount - 1].PhysicalSize; - ReservedRangeToCompare->SmramReservedSize -= FinalRanges[*FinalRangeCount - 1].PhysicalSize; - } - } -} - -/** - Returns if SMRAM range and SMRAM reserved range are overlapped. - - @param[in] RangeToCompare Pointer to EFI_SMRAM_DESCRIPTOR to compare. - @param[in] ReservedRangeToCompare Pointer to EFI_SMM_RESERVED_SMRAM_REGION to compare. - - @retval TRUE There is overlap. - @retval FALSE There is no overlap. - -**/ -BOOLEAN -SmmIsSmramOverlap ( - IN EFI_SMRAM_DESCRIPTOR *RangeToCompare, - IN EFI_SMM_RESERVED_SMRAM_REGION *ReservedRangeToCompare - ) -{ - UINT64 RangeToCompareEnd; - UINT64 ReservedRangeToCompareEnd; - - RangeToCompareEnd = RangeToCompare->CpuStart + RangeToCompare->PhysicalSize; - ReservedRangeToCompareEnd = ReservedRangeToCompare->SmramReservedStart + ReservedRangeToCompare->SmramReservedSize; - - if ((RangeToCompare->CpuStart >= ReservedRangeToCompare->SmramReservedStart) && - (RangeToCompare->CpuStart < ReservedRangeToCompareEnd)) { - return TRUE; - } else if ((ReservedRangeToCompare->SmramReservedStart >= RangeToCompare->CpuStart) && - (ReservedRangeToCompare->SmramReservedStart < RangeToCompareEnd)) { - return TRUE; - } - return FALSE; -} - -/** - Get full SMRAM ranges. - - It will get SMRAM ranges from SmmAccess protocol and SMRAM reserved ranges from - SmmConfiguration protocol, split the entries if there is overlap between them. - It will also reserve one entry for SMM core. - - @param[out] FullSmramRangeCount Output pointer to full SMRAM range count. - - @return Pointer to full SMRAM ranges. - -**/ -EFI_SMRAM_DESCRIPTOR * -GetFullSmramRanges ( - OUT UINTN *FullSmramRangeCount - ) -{ - EFI_STATUS Status; - EFI_SMM_CONFIGURATION_PROTOCOL *SmmConfiguration; - UINTN Size; - UINTN Index; - UINTN Index2; - EFI_SMRAM_DESCRIPTOR *FullSmramRanges; - UINTN TempSmramRangeCount; - UINTN AdditionSmramRangeCount; - EFI_SMRAM_DESCRIPTOR *TempSmramRanges; - UINTN SmramRangeCount; - EFI_SMRAM_DESCRIPTOR *SmramRanges; - UINTN SmramReservedCount; - EFI_SMM_RESERVED_SMRAM_REGION *SmramReservedRanges; - UINTN MaxCount; - BOOLEAN Rescan; - - // - // Get SMM Configuration Protocol if it is present. - // - SmmConfiguration = NULL; - Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, (VOID **) &SmmConfiguration); - - // - // Get SMRAM information. - // - Size = 0; - Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, NULL); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR); - - // - // Get SMRAM reserved region count. - // - SmramReservedCount = 0; - if (SmmConfiguration != NULL) { - while (SmmConfiguration->SmramReservedRegions[SmramReservedCount].SmramReservedSize != 0) { - SmramReservedCount++; - } - } - - // - // Reserve one entry for SMM Core in the full SMRAM ranges. - // - AdditionSmramRangeCount = 1; - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { - // - // Reserve two entries for all SMM drivers and SMM Core in the full SMRAM ranges. - // - AdditionSmramRangeCount = 2; - } - - if (SmramReservedCount == 0) { - // - // No reserved SMRAM entry from SMM Configuration Protocol. - // - *FullSmramRangeCount = SmramRangeCount + AdditionSmramRangeCount; - Size = (*FullSmramRangeCount) * sizeof (EFI_SMRAM_DESCRIPTOR); - FullSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocateZeroPool (Size); - ASSERT (FullSmramRanges != NULL); - - Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, FullSmramRanges); - ASSERT_EFI_ERROR (Status); - - return FullSmramRanges; - } - - // - // Why MaxCount = X + 2 * Y? - // Take Y = 1 as example below, Y > 1 case is just the iteration of Y = 1. - // - // X = 1 Y = 1 MaxCount = 3 = 1 + 2 * 1 - // ---- ---- - // | | ---- |--| - // | | | | -> | | - // | | ---- |--| - // ---- ---- - // - // X = 2 Y = 1 MaxCount = 4 = 2 + 2 * 1 - // ---- ---- - // | | | | - // | | ---- |--| - // | | | | | | - // |--| | | -> |--| - // | | | | | | - // | | ---- |--| - // | | | | - // ---- ---- - // - // X = 3 Y = 1 MaxCount = 5 = 3 + 2 * 1 - // ---- ---- - // | | | | - // | | ---- |--| - // |--| | | |--| - // | | | | -> | | - // |--| | | |--| - // | | ---- |--| - // | | | | - // ---- ---- - // - // ...... - // - MaxCount = SmramRangeCount + 2 * SmramReservedCount; - - Size = MaxCount * sizeof (EFI_SMM_RESERVED_SMRAM_REGION); - SmramReservedRanges = (EFI_SMM_RESERVED_SMRAM_REGION *) AllocatePool (Size); - ASSERT (SmramReservedRanges != NULL); - for (Index = 0; Index < SmramReservedCount; Index++) { - CopyMem (&SmramReservedRanges[Index], &SmmConfiguration->SmramReservedRegions[Index], sizeof (EFI_SMM_RESERVED_SMRAM_REGION)); - } - - Size = MaxCount * sizeof (EFI_SMRAM_DESCRIPTOR); - TempSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size); - ASSERT (TempSmramRanges != NULL); - TempSmramRangeCount = 0; - - SmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size); - ASSERT (SmramRanges != NULL); - Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, SmramRanges); - ASSERT_EFI_ERROR (Status); - - do { - Rescan = FALSE; - for (Index = 0; (Index < SmramRangeCount) && !Rescan; Index++) { - // - // Skip zero size entry. - // - if (SmramRanges[Index].PhysicalSize != 0) { - for (Index2 = 0; (Index2 < SmramReservedCount) && !Rescan; Index2++) { - // - // Skip zero size entry. - // - if (SmramReservedRanges[Index2].SmramReservedSize != 0) { - if (SmmIsSmramOverlap ( - &SmramRanges[Index], - &SmramReservedRanges[Index2] - )) { - // - // There is overlap, need to split entry and then rescan. - // - SmmSplitSmramEntry ( - &SmramRanges[Index], - &SmramReservedRanges[Index2], - SmramRanges, - &SmramRangeCount, - SmramReservedRanges, - &SmramReservedCount, - TempSmramRanges, - &TempSmramRangeCount - ); - Rescan = TRUE; - } - } - } - if (!Rescan) { - // - // No any overlap, copy the entry to the temp SMRAM ranges. - // Zero SmramRanges[Index].PhysicalSize = 0; - // - CopyMem (&TempSmramRanges[TempSmramRangeCount++], &SmramRanges[Index], sizeof (EFI_SMRAM_DESCRIPTOR)); - SmramRanges[Index].PhysicalSize = 0; - } - } - } - } while (Rescan); - ASSERT (TempSmramRangeCount <= MaxCount); - - // - // Sort the entries - // - FullSmramRanges = AllocateZeroPool ((TempSmramRangeCount + AdditionSmramRangeCount) * sizeof (EFI_SMRAM_DESCRIPTOR)); - ASSERT (FullSmramRanges != NULL); - *FullSmramRangeCount = 0; - do { - for (Index = 0; Index < TempSmramRangeCount; Index++) { - if (TempSmramRanges[Index].PhysicalSize != 0) { - break; - } - } - ASSERT (Index < TempSmramRangeCount); - for (Index2 = 0; Index2 < TempSmramRangeCount; Index2++) { - if ((Index2 != Index) && (TempSmramRanges[Index2].PhysicalSize != 0) && (TempSmramRanges[Index2].CpuStart < TempSmramRanges[Index].CpuStart)) { - Index = Index2; - } - } - CopyMem (&FullSmramRanges[*FullSmramRangeCount], &TempSmramRanges[Index], sizeof (EFI_SMRAM_DESCRIPTOR)); - *FullSmramRangeCount += 1; - TempSmramRanges[Index].PhysicalSize = 0; - } while (*FullSmramRangeCount < TempSmramRangeCount); - ASSERT (*FullSmramRangeCount == TempSmramRangeCount); - *FullSmramRangeCount += AdditionSmramRangeCount; - - FreePool (SmramRanges); - FreePool (SmramReservedRanges); - FreePool (TempSmramRanges); - - return FullSmramRanges; -} - -/** - The Entry Point for SMM IPL - - Load SMM Core into SMRAM, register SMM Core entry point for SMIs, install - SMM Base 2 Protocol and SMM Communication Protocol, and register for the - critical events required to coordinate between DXE and SMM environments. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval Other Some error occurred when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -SmmIplEntry ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT64 MaxSize; - VOID *Registration; - UINT64 SmmCodeSize; - EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE *LMFAConfigurationTable; - EFI_CPU_ARCH_PROTOCOL *CpuArch; - EFI_STATUS SetAttrStatus; - EFI_SMRAM_DESCRIPTOR *SmramRangeSmmDriver; - - // - // Fill in the image handle of the SMM IPL so the SMM Core can use this as the - // ParentImageHandle field of the Load Image Protocol for all SMM Drivers loaded - // by the SMM Core - // - mSmmCorePrivateData.SmmIplImageHandle = ImageHandle; - - // - // Get SMM Access Protocol - // - Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&mSmmAccess); - ASSERT_EFI_ERROR (Status); - - // - // Get SMM Control2 Protocol - // - Status = gBS->LocateProtocol (&gEfiSmmControl2ProtocolGuid, NULL, (VOID **)&mSmmControl2); - ASSERT_EFI_ERROR (Status); - - gSmmCorePrivate->SmramRanges = GetFullSmramRanges (&gSmmCorePrivate->SmramRangeCount); - - // - // Open all SMRAM ranges - // - Status = mSmmAccess->Open (mSmmAccess); - ASSERT_EFI_ERROR (Status); - - // - // Print debug message that the SMRAM window is now open. - // - DEBUG ((DEBUG_INFO, "SMM IPL opened SMRAM window\n")); - - // - // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size - // - mCurrentSmramRange = NULL; - for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < gSmmCorePrivate->SmramRangeCount; Index++) { - // - // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization - // - if ((gSmmCorePrivate->SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { - continue; - } - - if (gSmmCorePrivate->SmramRanges[Index].CpuStart >= BASE_1MB) { - if ((gSmmCorePrivate->SmramRanges[Index].CpuStart + gSmmCorePrivate->SmramRanges[Index].PhysicalSize - 1) <= MAX_ADDRESS) { - if (gSmmCorePrivate->SmramRanges[Index].PhysicalSize >= MaxSize) { - MaxSize = gSmmCorePrivate->SmramRanges[Index].PhysicalSize; - mCurrentSmramRange = &gSmmCorePrivate->SmramRanges[Index]; - } - } - } - } - - if (mCurrentSmramRange != NULL) { - // - // Print debug message showing SMRAM window that will be used by SMM IPL and SMM Core - // - DEBUG ((DEBUG_INFO, "SMM IPL found SMRAM window %p - %p\n", - (VOID *)(UINTN)mCurrentSmramRange->CpuStart, - (VOID *)(UINTN)(mCurrentSmramRange->CpuStart + mCurrentSmramRange->PhysicalSize - 1) - )); - - GetSmramCacheRange (mCurrentSmramRange, &mSmramCacheBase, &mSmramCacheSize); - // - // If CPU AP is present, attempt to set SMRAM cacheability to WB - // Note that it is expected that cacheability of SMRAM has been set to WB if CPU AP - // is not available here. - // - CpuArch = NULL; - Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&CpuArch); - if (!EFI_ERROR (Status)) { - Status = gDS->SetMemorySpaceAttributes( - mSmramCacheBase, - mSmramCacheSize, - EFI_MEMORY_WB - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_WARN, "SMM IPL failed to set SMRAM window to EFI_MEMORY_WB\n")); - } - } - // - // if Loading module at Fixed Address feature is enabled, save the SMRAM base to Load - // Modules At Fixed Address Configuration Table. - // - if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { - // - // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber - // - SmmCodeSize = LShiftU64 (PcdGet32(PcdLoadFixAddressSmmCodePageNumber), EFI_PAGE_SHIFT); - // - // The SMRAM available memory is assumed to be larger than SmmCodeSize - // - ASSERT (mCurrentSmramRange->PhysicalSize > SmmCodeSize); - // - // Retrieve Load modules At fixed address configuration table and save the SMRAM base. - // - Status = EfiGetSystemConfigurationTable ( - &gLoadFixedAddressConfigurationTableGuid, - (VOID **) &LMFAConfigurationTable - ); - if (!EFI_ERROR (Status) && LMFAConfigurationTable != NULL) { - LMFAConfigurationTable->SmramBase = mCurrentSmramRange->CpuStart; - // - // Print the SMRAM base - // - DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: TSEG BASE is %x. \n", LMFAConfigurationTable->SmramBase)); - } - - // - // Fill the Smram range for all SMM code - // - SmramRangeSmmDriver = &gSmmCorePrivate->SmramRanges[gSmmCorePrivate->SmramRangeCount - 2]; - SmramRangeSmmDriver->CpuStart = mCurrentSmramRange->CpuStart; - SmramRangeSmmDriver->PhysicalStart = mCurrentSmramRange->PhysicalStart; - SmramRangeSmmDriver->RegionState = mCurrentSmramRange->RegionState | EFI_ALLOCATED; - SmramRangeSmmDriver->PhysicalSize = SmmCodeSize; - - mCurrentSmramRange->PhysicalSize -= SmmCodeSize; - mCurrentSmramRange->CpuStart = mCurrentSmramRange->CpuStart + SmmCodeSize; - mCurrentSmramRange->PhysicalStart = mCurrentSmramRange->PhysicalStart + SmmCodeSize; - } - // - // Load SMM Core into SMRAM and execute it from SMRAM - // - Status = ExecuteSmmCoreFromSmram ( - mCurrentSmramRange, - &gSmmCorePrivate->SmramRanges[gSmmCorePrivate->SmramRangeCount - 1], - gSmmCorePrivate - ); - if (EFI_ERROR (Status)) { - // - // Print error message that the SMM Core failed to be loaded and executed. - // - DEBUG ((DEBUG_ERROR, "SMM IPL could not load and execute SMM Core from SMRAM\n")); - - // - // Attempt to reset SMRAM cacheability to UC - // - if (CpuArch != NULL) { - SetAttrStatus = gDS->SetMemorySpaceAttributes( - mSmramCacheBase, - mSmramCacheSize, - EFI_MEMORY_UC - ); - if (EFI_ERROR (SetAttrStatus)) { - DEBUG ((DEBUG_WARN, "SMM IPL failed to reset SMRAM window to EFI_MEMORY_UC\n")); - } - } - } - } else { - // - // Print error message that there are not enough SMRAM resources to load the SMM Core. - // - DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n")); - } - - // - // If the SMM Core could not be loaded then close SMRAM window, free allocated - // resources, and return an error so SMM IPL will be unloaded. - // - if (mCurrentSmramRange == NULL || EFI_ERROR (Status)) { - // - // Close all SMRAM ranges - // - Status = mSmmAccess->Close (mSmmAccess); - ASSERT_EFI_ERROR (Status); - - // - // Print debug message that the SMRAM window is now closed. - // - DEBUG ((DEBUG_INFO, "SMM IPL closed SMRAM window\n")); - - // - // Free all allocated resources - // - FreePool (gSmmCorePrivate->SmramRanges); - - return EFI_UNSUPPORTED; - } - - // - // Install SMM Base2 Protocol and SMM Communication Protocol - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &mSmmIplHandle, - &gEfiSmmBase2ProtocolGuid, &mSmmBase2, - &gEfiSmmCommunicationProtocolGuid, &mSmmCommunication, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Create the set of protocol and event notififcations that the SMM IPL requires - // - for (Index = 0; mSmmIplEvents[Index].NotifyFunction != NULL; Index++) { - if (mSmmIplEvents[Index].Protocol) { - mSmmIplEvents[Index].Event = EfiCreateProtocolNotifyEvent ( - mSmmIplEvents[Index].Guid, - mSmmIplEvents[Index].NotifyTpl, - mSmmIplEvents[Index].NotifyFunction, - mSmmIplEvents[Index].NotifyContext, - &Registration - ); - } else { - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - mSmmIplEvents[Index].NotifyTpl, - mSmmIplEvents[Index].NotifyFunction, - mSmmIplEvents[Index].NotifyContext, - mSmmIplEvents[Index].Guid, - &mSmmIplEvents[Index].Event - ); - ASSERT_EFI_ERROR (Status); - } - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf deleted file mode 100644 index 07a765b5d2..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf +++ /dev/null @@ -1,95 +0,0 @@ -## @file -# This module provide an SMM CIS compliant implementation of SMM IPL. -# -# Copyright (c) 2009 - 2016, 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 -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = PiSmmIpl - MODULE_UNI_FILE = PiSmmIpl.uni - FILE_GUID = 2FA2A6DA-11D5-4dc3-999A-749648B03C56 - MODULE_TYPE = DXE_RUNTIME_DRIVER - VERSION_STRING = 1.0 - PI_SPECIFICATION_VERSION = 0x0001000A - ENTRY_POINT = SmmIplEntry - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - PiSmmIpl.c - PiSmmCorePrivateData.h - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - BaseLib - BaseMemoryLib - PeCoffLib - CacheMaintenanceLib - MemoryAllocationLib - DebugLib - UefiBootServicesTableLib - DxeServicesTableLib - UefiLib - UefiRuntimeLib - DxeServicesLib - PcdLib - ReportStatusCodeLib - -[Protocols] - gEfiSmmBase2ProtocolGuid ## PRODUCES - gEfiSmmCommunicationProtocolGuid ## PRODUCES - gEfiSmmAccess2ProtocolGuid ## CONSUMES - ## NOTIFY - ## CONSUMES - gEfiSmmConfigurationProtocolGuid - gEfiSmmControl2ProtocolGuid ## CONSUMES - ## NOTIFY - ## SOMETIMES_CONSUMES - ## UNDEFINED # Used to do smm communcation - gEfiDxeSmmReadyToLockProtocolGuid - gEfiCpuArchProtocolGuid ## SOMETIMES_CONSUMES - -[Guids] - ## CONSUMES ## Event - ## PRODUCES ## UNDEFINED # Used to do smm communcation - gEfiEventDxeDispatchGuid - gEfiEventReadyToBootGuid ## CONSUMES ## Event - ## SOMETIMES_CONSUMES ## Event - ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communcation - gEfiEventLegacyBootGuid - ## SOMETIMES_CONSUMES ## Event - ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communcation - gEfiEventExitBootServicesGuid - ## SOMETIMES_CONSUMES ## Event - ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communcation - gEfiEventReadyToBootGuid - gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event - gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event - gLoadFixedAddressConfigurationTableGuid ## SOMETIMES_CONSUMES ## SystemTable - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES - -[Depex] - gEfiSmmAccess2ProtocolGuid AND gEfiSmmControl2ProtocolGuid - -[UserExtensions.TianoCore."ExtraFiles"] - PiSmmIplExtra.uni diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.uni b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.uni deleted file mode 100644 index edb3e236d9..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.uni +++ /dev/null @@ -1,21 +0,0 @@ -// /** @file -// This module provide an SMM CIS compliant implementation of SMM IPL. -// -// This module provide an SMM CIS compliant implementation of SMM IPL. -// -// Copyright (c) 2009 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Provides an SMM CIS compliant implementation of SMM IPL" - -#string STR_MODULE_DESCRIPTION #language en-US "This module provide an SMM CIS compliant implementation of SMM IPL." - diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIplExtra.uni b/MdeModulePkg/Core/PiSmmCore/PiSmmIplExtra.uni deleted file mode 100644 index 98410d8f0f..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIplExtra.uni +++ /dev/null @@ -1,19 +0,0 @@ -// /** @file -// PiSmmIpl Localized Strings and Content -// -// Copyright (c) 2013 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Core SMM Services Initial Program Loader" - - diff --git a/MdeModulePkg/Core/PiSmmCore/Pool.c b/MdeModulePkg/Core/PiSmmCore/Pool.c deleted file mode 100644 index f734b3f72d..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/Pool.c +++ /dev/null @@ -1,365 +0,0 @@ -/** @file - SMM Memory pool management functions. - - Copyright (c) 2009 - 2016, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -LIST_ENTRY mSmmPoolLists[SmmPoolTypeMax][MAX_POOL_INDEX]; -// -// To cache the SMRAM base since when Loading modules At fixed address feature is enabled, -// all module is assigned an offset relative the SMRAM base in build time. -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS gLoadModuleAtFixAddressSmramBase = 0; - -/** - Convert a UEFI memory type to SMM pool type. - - @param[in] MemoryType Type of pool to allocate. - - @return SMM pool type -**/ -SMM_POOL_TYPE -UefiMemoryTypeToSmmPoolType ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - ASSERT ((MemoryType == EfiRuntimeServicesCode) || (MemoryType == EfiRuntimeServicesData)); - switch (MemoryType) { - case EfiRuntimeServicesCode: - return SmmPoolTypeCode; - case EfiRuntimeServicesData: - return SmmPoolTypeData; - default: - return SmmPoolTypeMax; - } -} - - -/** - Called to initialize the memory service. - - @param SmramRangeCount Number of SMRAM Regions - @param SmramRanges Pointer to SMRAM Descriptors - -**/ -VOID -SmmInitializeMemoryServices ( - IN UINTN SmramRangeCount, - IN EFI_SMRAM_DESCRIPTOR *SmramRanges - ) -{ - UINTN Index; - EFI_STATUS Status; - UINTN SmmPoolTypeIndex; - EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE *LMFAConfigurationTable; - - // - // Initialize Pool list - // - for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { - for (Index = 0; Index < ARRAY_SIZE (mSmmPoolLists[SmmPoolTypeIndex]); Index++) { - InitializeListHead (&mSmmPoolLists[SmmPoolTypeIndex][Index]); - } - } - - Status = EfiGetSystemConfigurationTable ( - &gLoadFixedAddressConfigurationTableGuid, - (VOID **) &LMFAConfigurationTable - ); - if (!EFI_ERROR (Status) && LMFAConfigurationTable != NULL) { - gLoadModuleAtFixAddressSmramBase = LMFAConfigurationTable->SmramBase; - } - - // - // Add Free SMRAM regions - // Need add Free memory at first, to let gSmmMemoryMap record data - // - for (Index = 0; Index < SmramRangeCount; Index++) { - if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { - continue; - } - SmmAddMemoryRegion ( - SmramRanges[Index].CpuStart, - SmramRanges[Index].PhysicalSize, - EfiConventionalMemory, - SmramRanges[Index].RegionState - ); - } - - // - // Add the allocated SMRAM regions - // - for (Index = 0; Index < SmramRangeCount; Index++) { - if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) == 0) { - continue; - } - SmmAddMemoryRegion ( - SmramRanges[Index].CpuStart, - SmramRanges[Index].PhysicalSize, - EfiConventionalMemory, - SmramRanges[Index].RegionState - ); - } - -} - -/** - Internal Function. Allocate a pool by specified PoolIndex. - - @param PoolType Type of pool to allocate. - @param PoolIndex Index which indicate the Pool size. - @param FreePoolHdr The returned Free pool. - - @retval EFI_OUT_OF_RESOURCES Allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -InternalAllocPoolByIndex ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN PoolIndex, - OUT FREE_POOL_HEADER **FreePoolHdr - ) -{ - EFI_STATUS Status; - FREE_POOL_HEADER *Hdr; - EFI_PHYSICAL_ADDRESS Address; - SMM_POOL_TYPE SmmPoolType; - - SmmPoolType = UefiMemoryTypeToSmmPoolType(PoolType); - - ASSERT (PoolIndex <= MAX_POOL_INDEX); - Status = EFI_SUCCESS; - Hdr = NULL; - if (PoolIndex == MAX_POOL_INDEX) { - Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - Hdr = (FREE_POOL_HEADER *) (UINTN) Address; - } else if (!IsListEmpty (&mSmmPoolLists[SmmPoolType][PoolIndex])) { - Hdr = BASE_CR (GetFirstNode (&mSmmPoolLists[SmmPoolType][PoolIndex]), FREE_POOL_HEADER, Link); - RemoveEntryList (&Hdr->Link); - } else { - Status = InternalAllocPoolByIndex (PoolType, PoolIndex + 1, &Hdr); - if (!EFI_ERROR (Status)) { - Hdr->Header.Size >>= 1; - Hdr->Header.Available = TRUE; - Hdr->Header.Type = PoolType; - InsertHeadList (&mSmmPoolLists[SmmPoolType][PoolIndex], &Hdr->Link); - Hdr = (FREE_POOL_HEADER*)((UINT8*)Hdr + Hdr->Header.Size); - } - } - - if (!EFI_ERROR (Status)) { - Hdr->Header.Size = MIN_POOL_SIZE << PoolIndex; - Hdr->Header.Available = FALSE; - Hdr->Header.Type = PoolType; - } - - *FreePoolHdr = Hdr; - return Status; -} - -/** - Internal Function. Free a pool by specified PoolIndex. - - @param FreePoolHdr The pool to free. - - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -InternalFreePoolByIndex ( - IN FREE_POOL_HEADER *FreePoolHdr - ) -{ - UINTN PoolIndex; - SMM_POOL_TYPE SmmPoolType; - - ASSERT ((FreePoolHdr->Header.Size & (FreePoolHdr->Header.Size - 1)) == 0); - ASSERT (((UINTN)FreePoolHdr & (FreePoolHdr->Header.Size - 1)) == 0); - ASSERT (FreePoolHdr->Header.Size >= MIN_POOL_SIZE); - - SmmPoolType = UefiMemoryTypeToSmmPoolType(FreePoolHdr->Header.Type); - - PoolIndex = (UINTN) (HighBitSet32 ((UINT32)FreePoolHdr->Header.Size) - MIN_POOL_SHIFT); - FreePoolHdr->Header.Available = TRUE; - ASSERT (PoolIndex < MAX_POOL_INDEX); - InsertHeadList (&mSmmPoolLists[SmmPoolType][PoolIndex], &FreePoolHdr->Link); - return EFI_SUCCESS; -} - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate. - @param Size The amount of pool to allocate. - @param Buffer The address to return a pointer to the allocated - pool. - - @retval EFI_INVALID_PARAMETER PoolType not valid. - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmInternalAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ) -{ - POOL_HEADER *PoolHdr; - FREE_POOL_HEADER *FreePoolHdr; - EFI_STATUS Status; - EFI_PHYSICAL_ADDRESS Address; - UINTN PoolIndex; - - if (PoolType != EfiRuntimeServicesCode && - PoolType != EfiRuntimeServicesData) { - return EFI_INVALID_PARAMETER; - } - - Size += sizeof (*PoolHdr); - if (Size > MAX_POOL_SIZE) { - Size = EFI_SIZE_TO_PAGES (Size); - Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, Size, &Address); - if (EFI_ERROR (Status)) { - return Status; - } - - PoolHdr = (POOL_HEADER*)(UINTN)Address; - PoolHdr->Size = EFI_PAGES_TO_SIZE (Size); - PoolHdr->Available = FALSE; - PoolHdr->Type = PoolType; - *Buffer = PoolHdr + 1; - return Status; - } - - Size = (Size + MIN_POOL_SIZE - 1) >> MIN_POOL_SHIFT; - PoolIndex = (UINTN) HighBitSet32 ((UINT32)Size); - if ((Size & (Size - 1)) != 0) { - PoolIndex++; - } - - Status = InternalAllocPoolByIndex (PoolType, PoolIndex, &FreePoolHdr); - if (!EFI_ERROR(Status)) { - *Buffer = &FreePoolHdr->Header + 1; - } - return Status; -} - -/** - Allocate pool of a particular type. - - @param PoolType Type of pool to allocate. - @param Size The amount of pool to allocate. - @param Buffer The address to return a pointer to the allocated - pool. - - @retval EFI_INVALID_PARAMETER PoolType not valid. - @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. - @retval EFI_SUCCESS Pool successfully allocated. - -**/ -EFI_STATUS -EFIAPI -SmmAllocatePool ( - IN EFI_MEMORY_TYPE PoolType, - IN UINTN Size, - OUT VOID **Buffer - ) -{ - EFI_STATUS Status; - - Status = SmmInternalAllocatePool (PoolType, Size, Buffer); - if (!EFI_ERROR (Status)) { - SmmCoreUpdateProfile ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), - MemoryProfileActionAllocatePool, - PoolType, - Size, - *Buffer, - NULL - ); - } - return Status; -} - -/** - Frees pool. - - @param Buffer The allocated pool entry to free. - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmInternalFreePool ( - IN VOID *Buffer - ) -{ - FREE_POOL_HEADER *FreePoolHdr; - - if (Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - FreePoolHdr = (FREE_POOL_HEADER*)((POOL_HEADER*)Buffer - 1); - ASSERT (!FreePoolHdr->Header.Available); - - if (FreePoolHdr->Header.Size > MAX_POOL_SIZE) { - ASSERT (((UINTN)FreePoolHdr & EFI_PAGE_MASK) == 0); - ASSERT ((FreePoolHdr->Header.Size & EFI_PAGE_MASK) == 0); - return SmmInternalFreePages ( - (EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr, - EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size) - ); - } - return InternalFreePoolByIndex (FreePoolHdr); -} - -/** - Frees pool. - - @param Buffer The allocated pool entry to free. - - @retval EFI_INVALID_PARAMETER Buffer is not a valid value. - @retval EFI_SUCCESS Pool successfully freed. - -**/ -EFI_STATUS -EFIAPI -SmmFreePool ( - IN VOID *Buffer - ) -{ - EFI_STATUS Status; - - Status = SmmInternalFreePool (Buffer); - if (!EFI_ERROR (Status)) { - SmmCoreUpdateProfile ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), - MemoryProfileActionFreePool, - EfiMaxMemoryType, - 0, - Buffer, - NULL - ); - } - return Status; -} diff --git a/MdeModulePkg/Core/PiSmmCore/Smi.c b/MdeModulePkg/Core/PiSmmCore/Smi.c deleted file mode 100644 index ad483a1877..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/Smi.c +++ /dev/null @@ -1,312 +0,0 @@ -/** @file - SMI management. - - Copyright (c) 2009 - 2017, 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 - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -LIST_ENTRY mSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mSmiEntryList); - -SMI_ENTRY mRootSmiEntry = { - SMI_ENTRY_SIGNATURE, - INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntry.AllEntries), - {0}, - INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntry.SmiHandlers), -}; - -/** - Finds the SMI entry for the requested handler type. - - @param HandlerType The type of the interrupt - @param Create Create a new entry if not found - - @return SMI entry - -**/ -SMI_ENTRY * -EFIAPI -SmmCoreFindSmiEntry ( - IN EFI_GUID *HandlerType, - IN BOOLEAN Create - ) -{ - LIST_ENTRY *Link; - SMI_ENTRY *Item; - SMI_ENTRY *SmiEntry; - - // - // Search the SMI entry list for the matching GUID - // - SmiEntry = NULL; - for (Link = mSmiEntryList.ForwardLink; - Link != &mSmiEntryList; - Link = Link->ForwardLink) { - - Item = CR (Link, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE); - if (CompareGuid (&Item->HandlerType, HandlerType)) { - // - // This is the SMI entry - // - SmiEntry = Item; - break; - } - } - - // - // If the protocol entry was not found and Create is TRUE, then - // allocate a new entry - // - if ((SmiEntry == NULL) && Create) { - SmiEntry = AllocatePool (sizeof(SMI_ENTRY)); - if (SmiEntry != NULL) { - // - // Initialize new SMI entry structure - // - SmiEntry->Signature = SMI_ENTRY_SIGNATURE; - CopyGuid ((VOID *)&SmiEntry->HandlerType, HandlerType); - InitializeListHead (&SmiEntry->SmiHandlers); - - // - // Add it to SMI entry list - // - InsertTailList (&mSmiEntryList, &SmiEntry->AllEntries); - } - } - return SmiEntry; -} - -/** - Manage SMI of a particular type. - - @param HandlerType Points to the handler type or NULL for root SMI handlers. - @param Context Points to an optional context buffer. - @param CommBuffer Points to the optional communication buffer. - @param CommBufferSize Points to the size of the optional communication buffer. - - @retval EFI_WARN_INTERRUPT_SOURCE_PENDING Interrupt source was processed successfully but not quiesced. - @retval EFI_INTERRUPT_PENDING One or more SMI sources could not be quiesced. - @retval EFI_NOT_FOUND Interrupt source was not handled or quiesced. - @retval EFI_SUCCESS Interrupt source was handled and quiesced. - -**/ -EFI_STATUS -EFIAPI -SmiManage ( - IN CONST EFI_GUID *HandlerType, - IN CONST VOID *Context OPTIONAL, - IN OUT VOID *CommBuffer OPTIONAL, - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - LIST_ENTRY *Link; - LIST_ENTRY *Head; - SMI_ENTRY *SmiEntry; - SMI_HANDLER *SmiHandler; - BOOLEAN SuccessReturn; - EFI_STATUS Status; - - Status = EFI_NOT_FOUND; - SuccessReturn = FALSE; - if (HandlerType == NULL) { - // - // Root SMI handler - // - SmiEntry = &mRootSmiEntry; - } else { - // - // Non-root SMI handler - // - SmiEntry = SmmCoreFindSmiEntry ((EFI_GUID *) HandlerType, FALSE); - if (SmiEntry == NULL) { - // - // There is no handler registered for this interrupt source - // - return Status; - } - } - Head = &SmiEntry->SmiHandlers; - - for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) { - SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE); - - Status = SmiHandler->Handler ( - (EFI_HANDLE) SmiHandler, - Context, - CommBuffer, - CommBufferSize - ); - - switch (Status) { - case EFI_INTERRUPT_PENDING: - // - // If a handler returns EFI_INTERRUPT_PENDING and HandlerType is not NULL then - // no additional handlers will be processed and EFI_INTERRUPT_PENDING will be returned. - // - if (HandlerType != NULL) { - return EFI_INTERRUPT_PENDING; - } - break; - - case EFI_SUCCESS: - // - // If at least one of the handlers returns EFI_SUCCESS then the function will return - // EFI_SUCCESS. If a handler returns EFI_SUCCESS and HandlerType is not NULL then no - // additional handlers will be processed. - // - if (HandlerType != NULL) { - return EFI_SUCCESS; - } - SuccessReturn = TRUE; - break; - - case EFI_WARN_INTERRUPT_SOURCE_QUIESCED: - // - // If at least one of the handlers returns EFI_WARN_INTERRUPT_SOURCE_QUIESCED - // then the function will return EFI_SUCCESS. - // - SuccessReturn = TRUE; - break; - - case EFI_WARN_INTERRUPT_SOURCE_PENDING: - // - // If all the handlers returned EFI_WARN_INTERRUPT_SOURCE_PENDING - // then EFI_WARN_INTERRUPT_SOURCE_PENDING will be returned. - // - break; - - default: - // - // Unexpected status code returned. - // - ASSERT (FALSE); - break; - } - } - - if (SuccessReturn) { - Status = EFI_SUCCESS; - } - - return Status; -} - -/** - Registers a handler to execute within SMM. - - @param Handler Handler service funtion pointer. - @param HandlerType Points to the handler type or NULL for root SMI handlers. - @param DispatchHandle On return, contains a unique handle which can be used to later unregister the handler function. - - @retval EFI_SUCCESS Handler register success. - @retval EFI_INVALID_PARAMETER Handler or DispatchHandle is NULL. - -**/ -EFI_STATUS -EFIAPI -SmiHandlerRegister ( - IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler, - IN CONST EFI_GUID *HandlerType OPTIONAL, - OUT EFI_HANDLE *DispatchHandle - ) -{ - SMI_HANDLER *SmiHandler; - SMI_ENTRY *SmiEntry; - LIST_ENTRY *List; - - if (Handler == NULL || DispatchHandle == NULL) { - return EFI_INVALID_PARAMETER; - } - - SmiHandler = AllocateZeroPool (sizeof (SMI_HANDLER)); - if (SmiHandler == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - SmiHandler->Signature = SMI_HANDLER_SIGNATURE; - SmiHandler->Handler = Handler; - SmiHandler->CallerAddr = (UINTN)RETURN_ADDRESS (0); - - if (HandlerType == NULL) { - // - // This is root SMI handler - // - SmiEntry = &mRootSmiEntry; - } else { - // - // None root SMI handler - // - SmiEntry = SmmCoreFindSmiEntry ((EFI_GUID *) HandlerType, TRUE); - if (SmiEntry == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - List = &SmiEntry->SmiHandlers; - - SmiHandler->SmiEntry = SmiEntry; - InsertTailList (List, &SmiHandler->Link); - - *DispatchHandle = (EFI_HANDLE) SmiHandler; - - return EFI_SUCCESS; -} - -/** - Unregister a handler in SMM. - - @param DispatchHandle The handle that was specified when the handler was registered. - - @retval EFI_SUCCESS Handler function was successfully unregistered. - @retval EFI_INVALID_PARAMETER DispatchHandle does not refer to a valid handle. - -**/ -EFI_STATUS -EFIAPI -SmiHandlerUnRegister ( - IN EFI_HANDLE DispatchHandle - ) -{ - SMI_HANDLER *SmiHandler; - SMI_ENTRY *SmiEntry; - - SmiHandler = (SMI_HANDLER *) DispatchHandle; - - if (SmiHandler == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (SmiHandler->Signature != SMI_HANDLER_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - - SmiEntry = SmiHandler->SmiEntry; - - RemoveEntryList (&SmiHandler->Link); - FreePool (SmiHandler); - - if (SmiEntry == NULL) { - // - // This is root SMI handler - // - return EFI_SUCCESS; - } - - if (IsListEmpty (&SmiEntry->SmiHandlers)) { - // - // No handler registered for this interrupt now, remove the SMI_ENTRY - // - RemoveEntryList (&SmiEntry->AllEntries); - - FreePool (SmiEntry); - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c b/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c deleted file mode 100644 index ad3b54ace4..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/SmiHandlerProfile.c +++ /dev/null @@ -1,1327 +0,0 @@ -/** @file - SMI handler profile support. - -Copyright (c) 2017, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "PiSmmCore.h" - -typedef struct { - EFI_GUID FileGuid; - UINTN ImageRef; - UINTN EntryPoint; - UINTN ImageBase; - UINTN ImageSize; - UINTN PdbStringSize; - CHAR8 *PdbString; -} IMAGE_STRUCT; - -/** - Register SMI handler profile handler. -**/ -VOID -RegisterSmiHandlerProfileHandler( - VOID - ); - -/** - Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded - into system memory with the PE/COFF Loader Library functions. - - Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry - point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then - return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. - If Pe32Data is NULL, then ASSERT(). - If EntryPoint is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - @param EntryPoint The pointer to entry point to the PE/COFF image to return. - - @retval RETURN_SUCCESS EntryPoint was returned. - @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. - -**/ -RETURN_STATUS -InternalPeCoffGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint - ); - -extern LIST_ENTRY mSmiEntryList; -extern LIST_ENTRY mHardwareSmiEntryList; -extern SMI_ENTRY mRootSmiEntry; - -extern SMI_HANDLER_PROFILE_PROTOCOL mSmiHandlerProfile; - -GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mHardwareSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mHardwareSmiEntryList); - -GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mRootSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiEntryList); - -GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY *mSmmCoreRootSmiEntryList = &mRootSmiEntryList; -GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY *mSmmCoreSmiEntryList = &mSmiEntryList; -GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY *mSmmCoreHardwareSmiEntryList = &mHardwareSmiEntryList; - -GLOBAL_REMOVE_IF_UNREFERENCED IMAGE_STRUCT *mImageStruct; -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mImageStructCountMax; -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mImageStructCount; - -GLOBAL_REMOVE_IF_UNREFERENCED VOID *mSmiHandlerProfileDatabase; -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmiHandlerProfileDatabaseSize; - -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmImageDatabaseSize; -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmRootSmiDatabaseSize; -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmSmiDatabaseSize; -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmmHardwareSmiDatabaseSize; - -GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmiHandlerProfileRecordingStatus; - -GLOBAL_REMOVE_IF_UNREFERENCED SMI_HANDLER_PROFILE_PROTOCOL mSmiHandlerProfile = { - SmiHandlerProfileRegisterHandler, - SmiHandlerProfileUnregisterHandler, -}; - -/** - This function dump raw data. - - @param Data raw data - @param Size raw data size -**/ -VOID -InternalDumpData ( - IN UINT8 *Data, - IN UINTN Size - ) -{ - UINTN Index; - for (Index = 0; Index < Size; Index++) { - DEBUG ((DEBUG_INFO, "%02x ", (UINTN)Data[Index])); - } -} - -/** - Get GUID name for an image. - - @param[in] LoadedImage LoadedImage protocol. - @param[out] Guid Guid of the FFS -**/ -VOID -GetDriverGuid ( - IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, - OUT EFI_GUID *Guid - ) -{ - EFI_GUID *FileName; - - FileName = NULL; - if ((DevicePathType(LoadedImage->FilePath) == MEDIA_DEVICE_PATH) && - (DevicePathSubType(LoadedImage->FilePath) == MEDIA_PIWG_FW_FILE_DP)) { - FileName = &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath)->FvFileName; - } - if (FileName != NULL) { - CopyGuid(Guid, FileName); - } else { - ZeroMem(Guid, sizeof(EFI_GUID)); - } -} - -/** - Add image structure. - - @param ImageBase image base - @param ImageSize image size - @param EntryPoint image entry point - @param Guid FFS GUID of the image - @param PdbString image PDB string -**/ -VOID -AddImageStruct( - IN UINTN ImageBase, - IN UINTN ImageSize, - IN UINTN EntryPoint, - IN EFI_GUID *Guid, - IN CHAR8 *PdbString - ) -{ - UINTN PdbStringSize; - - if (mImageStructCount >= mImageStructCountMax) { - ASSERT(FALSE); - return; - } - - CopyGuid(&mImageStruct[mImageStructCount].FileGuid, Guid); - mImageStruct[mImageStructCount].ImageRef = mImageStructCount; - mImageStruct[mImageStructCount].ImageBase = ImageBase; - mImageStruct[mImageStructCount].ImageSize = ImageSize; - mImageStruct[mImageStructCount].EntryPoint = EntryPoint; - if (PdbString != NULL) { - PdbStringSize = AsciiStrSize(PdbString); - mImageStruct[mImageStructCount].PdbString = AllocateCopyPool (PdbStringSize, PdbString); - if (mImageStruct[mImageStructCount].PdbString != NULL) { - mImageStruct[mImageStructCount].PdbStringSize = PdbStringSize; - } - } - - mImageStructCount++; -} - -/** - return an image structure based upon image address. - - @param Address image address - - @return image structure -**/ -IMAGE_STRUCT * -AddressToImageStruct( - IN UINTN Address - ) -{ - UINTN Index; - - for (Index = 0; Index < mImageStructCount; Index++) { - if ((Address >= mImageStruct[Index].ImageBase) && - (Address < mImageStruct[Index].ImageBase + mImageStruct[Index].ImageSize)) { - return &mImageStruct[Index]; - } - } - return NULL; -} - -/** - return an image reference index based upon image address. - - @param Address image address - - @return image reference index -**/ -UINTN -AddressToImageRef( - IN UINTN Address - ) -{ - IMAGE_STRUCT *ImageStruct; - - ImageStruct = AddressToImageStruct(Address); - if (ImageStruct != NULL) { - return ImageStruct->ImageRef; - } - return (UINTN)-1; -} - -/** - Collect SMM image information based upon loaded image protocol. -**/ -VOID -GetSmmLoadedImage( - VOID - ) -{ - EFI_STATUS Status; - UINTN NoHandles; - UINTN HandleBufferSize; - EFI_HANDLE *HandleBuffer; - UINTN Index; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - CHAR16 *PathStr; - EFI_SMM_DRIVER_ENTRY *LoadedImagePrivate; - UINTN EntryPoint; - VOID *EntryPointInImage; - EFI_GUID Guid; - CHAR8 *PdbString; - UINTN RealImageBase; - - HandleBufferSize = 0; - HandleBuffer = NULL; - Status = gSmst->SmmLocateHandle( - ByProtocol, - &gEfiLoadedImageProtocolGuid, - NULL, - &HandleBufferSize, - HandleBuffer - ); - if (Status != EFI_BUFFER_TOO_SMALL) { - return; - } - HandleBuffer = AllocateZeroPool (HandleBufferSize); - if (HandleBuffer == NULL) { - return; - } - Status = gSmst->SmmLocateHandle( - ByProtocol, - &gEfiLoadedImageProtocolGuid, - NULL, - &HandleBufferSize, - HandleBuffer - ); - if (EFI_ERROR(Status)) { - return; - } - - NoHandles = HandleBufferSize/sizeof(EFI_HANDLE); - mImageStructCountMax = NoHandles; - mImageStruct = AllocateZeroPool(mImageStructCountMax * sizeof(IMAGE_STRUCT)); - if (mImageStruct == NULL) { - goto Done; - } - - for (Index = 0; Index < NoHandles; Index++) { - Status = gSmst->SmmHandleProtocol( - HandleBuffer[Index], - &gEfiLoadedImageProtocolGuid, - (VOID **)&LoadedImage - ); - if (EFI_ERROR(Status)) { - continue; - } - PathStr = ConvertDevicePathToText(LoadedImage->FilePath, TRUE, TRUE); - GetDriverGuid(LoadedImage, &Guid); - DEBUG ((DEBUG_INFO, "Image: %g ", &Guid)); - - EntryPoint = 0; - LoadedImagePrivate = BASE_CR(LoadedImage, EFI_SMM_DRIVER_ENTRY, SmmLoadedImage); - RealImageBase = (UINTN)LoadedImage->ImageBase; - if (LoadedImagePrivate->Signature == EFI_SMM_DRIVER_ENTRY_SIGNATURE) { - EntryPoint = (UINTN)LoadedImagePrivate->ImageEntryPoint; - if ((EntryPoint != 0) && ((EntryPoint < (UINTN)LoadedImage->ImageBase) || (EntryPoint >= ((UINTN)LoadedImage->ImageBase + (UINTN)LoadedImage->ImageSize)))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageBuffer here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint(LoadedImage->ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR(Status); - RealImageBase = (UINTN)LoadedImage->ImageBase + EntryPoint - (UINTN)EntryPointInImage; - } - } - DEBUG ((DEBUG_INFO, "(0x%x - 0x%x", RealImageBase, (UINTN)LoadedImage->ImageSize)); - if (EntryPoint != 0) { - DEBUG ((DEBUG_INFO, ", EntryPoint:0x%x", EntryPoint)); - } - DEBUG ((DEBUG_INFO, ")\n")); - - if (RealImageBase != 0) { - PdbString = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) RealImageBase); - DEBUG ((DEBUG_INFO, " pdb - %a\n", PdbString)); - } else { - PdbString = NULL; - } - DEBUG ((DEBUG_INFO, " (%s)\n", PathStr)); - - AddImageStruct((UINTN)RealImageBase, (UINTN)LoadedImage->ImageSize, EntryPoint, &Guid, PdbString); - } - -Done: - FreePool(HandleBuffer); - return; -} - -/** - Dump SMI child context. - - @param HandlerType the handler type - @param Context the handler context - @param ContextSize the handler context size -**/ -VOID -DumpSmiChildContext ( - IN EFI_GUID *HandlerType, - IN VOID *Context, - IN UINTN ContextSize - ) -{ - if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) { - DEBUG ((DEBUG_INFO, " SwSmi - 0x%x\n", ((EFI_SMM_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue)); - } else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) { - DEBUG ((DEBUG_INFO, " SxType - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type)); - DEBUG ((DEBUG_INFO, " SxPhase - 0x%x\n", ((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase)); - } else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) { - DEBUG ((DEBUG_INFO, " PowerButtonPhase - 0x%x\n", ((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase)); - } else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) { - DEBUG ((DEBUG_INFO, " StandbyButtonPhase - 0x%x\n", ((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase)); - } else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) { - DEBUG ((DEBUG_INFO, " PeriodicTimerPeriod - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period)); - DEBUG ((DEBUG_INFO, " PeriodicTimerSmiTickInterval - %ld\n", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval)); - } else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) { - DEBUG ((DEBUG_INFO, " GpiNum - 0x%lx\n", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum)); - } else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) { - DEBUG ((DEBUG_INFO, " IoTrapAddress - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address)); - DEBUG ((DEBUG_INFO, " IoTrapLength - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length)); - DEBUG ((DEBUG_INFO, " IoTrapType - 0x%x\n", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type)); - } else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) { - DEBUG ((DEBUG_INFO, " UsbType - 0x%x\n", ((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type)); - DEBUG ((DEBUG_INFO, " UsbDevicePath - %s\n", ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE))); - } else { - DEBUG ((DEBUG_INFO, " Context - ")); - InternalDumpData (Context, ContextSize); - DEBUG ((DEBUG_INFO, "\n")); - } -} - -/** - Dump all SMI handlers associated with SmiEntry. - - @param SmiEntry SMI entry. -**/ -VOID -DumpSmiHandlerOnSmiEntry( - IN SMI_ENTRY *SmiEntry - ) -{ - LIST_ENTRY *ListEntry; - SMI_HANDLER *SmiHandler; - IMAGE_STRUCT *ImageStruct; - - ListEntry = &SmiEntry->SmiHandlers; - for (ListEntry = ListEntry->ForwardLink; - ListEntry != &SmiEntry->SmiHandlers; - ListEntry = ListEntry->ForwardLink) { - SmiHandler = CR(ListEntry, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE); - ImageStruct = AddressToImageStruct((UINTN)SmiHandler->Handler); - if (ImageStruct != NULL) { - DEBUG ((DEBUG_INFO, " Module - %g", &ImageStruct->FileGuid)); - } - if ((ImageStruct != NULL) && (ImageStruct->PdbString[0] != 0)) { - DEBUG ((DEBUG_INFO, " (Pdb - %a)", ImageStruct->PdbString)); - } - DEBUG ((DEBUG_INFO, "\n")); - if (SmiHandler->ContextSize != 0) { - DumpSmiChildContext (&SmiEntry->HandlerType, SmiHandler->Context, SmiHandler->ContextSize); - } - DEBUG ((DEBUG_INFO, " Handler - 0x%x", SmiHandler->Handler)); - if (ImageStruct != NULL) { - DEBUG ((DEBUG_INFO, " <== RVA - 0x%x", (UINTN)SmiHandler->Handler - ImageStruct->ImageBase)); - } - DEBUG ((DEBUG_INFO, "\n")); - DEBUG ((DEBUG_INFO, " CallerAddr - 0x%x", SmiHandler->CallerAddr)); - if (ImageStruct != NULL) { - DEBUG ((DEBUG_INFO, " <== RVA - 0x%x", SmiHandler->CallerAddr - ImageStruct->ImageBase)); - } - DEBUG ((DEBUG_INFO, "\n")); - } - - return; -} - -/** - Dump all SMI entry on the list. - - @param SmiEntryList a list of SMI entry. -**/ -VOID -DumpSmiEntryList( - IN LIST_ENTRY *SmiEntryList - ) -{ - LIST_ENTRY *ListEntry; - SMI_ENTRY *SmiEntry; - - ListEntry = SmiEntryList; - for (ListEntry = ListEntry->ForwardLink; - ListEntry != SmiEntryList; - ListEntry = ListEntry->ForwardLink) { - SmiEntry = CR(ListEntry, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE); - DEBUG ((DEBUG_INFO, "SmiEntry - %g\n", &SmiEntry->HandlerType)); - DumpSmiHandlerOnSmiEntry(SmiEntry); - } - - return; -} - -/** - SMM Ready To Lock event notification handler. - - This function collects all SMM image information and build SmiHandleProfile database, - and register SmiHandlerProfile SMI handler. - - @param[in] Protocol Points to the protocol's unique identifier. - @param[in] Interface Points to the interface instance. - @param[in] Handle The handle on which the interface was installed. - - @retval EFI_SUCCESS Notification handler runs successfully. -**/ -EFI_STATUS -EFIAPI -SmmReadyToLockInSmiHandlerProfile ( - IN CONST EFI_GUID *Protocol, - IN VOID *Interface, - IN EFI_HANDLE Handle - ) -{ - // - // Dump all image - // - DEBUG ((DEBUG_INFO, "##################\n")); - DEBUG ((DEBUG_INFO, "# IMAGE DATABASE #\n")); - DEBUG ((DEBUG_INFO, "##################\n")); - GetSmmLoadedImage (); - DEBUG ((DEBUG_INFO, "\n")); - - // - // Dump SMI Handler - // - DEBUG ((DEBUG_INFO, "########################\n")); - DEBUG ((DEBUG_INFO, "# SMI Handler DATABASE #\n")); - DEBUG ((DEBUG_INFO, "########################\n")); - - DEBUG ((DEBUG_INFO, "# 1. ROOT SMI Handler #\n")); - DEBUG_CODE ( - DumpSmiEntryList(mSmmCoreRootSmiEntryList); - ); - - DEBUG ((DEBUG_INFO, "# 2. GUID SMI Handler #\n")); - DEBUG_CODE ( - DumpSmiEntryList(mSmmCoreSmiEntryList); - ); - - DEBUG ((DEBUG_INFO, "# 3. Hardware SMI Handler #\n")); - DEBUG_CODE ( - DumpSmiEntryList(mSmmCoreHardwareSmiEntryList); - ); - - DEBUG ((DEBUG_INFO, "\n")); - - RegisterSmiHandlerProfileHandler(); - - if (mImageStruct != NULL) { - FreePool(mImageStruct); - } - - return EFI_SUCCESS; -} - -/** - returns SMM image data base size. - - @return SMM image data base size. -**/ -UINTN -GetSmmImageDatabaseSize( - VOID - ) -{ - UINTN Size; - UINTN Index; - - Size = (sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE)) * mImageStructCount; - for (Index = 0; Index < mImageStructCount; Index++) { - Size += mImageStruct[Index].PdbStringSize; - } - return Size; -} - -/** - returns all SMI handlers' size associated with SmiEntry. - - @param SmiEntry SMI entry. - - @return all SMI handlers' size associated with SmiEntry. -**/ -UINTN -GetSmmSmiHandlerSizeOnSmiEntry( - IN SMI_ENTRY *SmiEntry - ) -{ - LIST_ENTRY *ListEntry; - SMI_HANDLER *SmiHandler; - UINTN Size; - - Size = 0; - ListEntry = &SmiEntry->SmiHandlers; - for (ListEntry = ListEntry->ForwardLink; - ListEntry != &SmiEntry->SmiHandlers; - ListEntry = ListEntry->ForwardLink) { - SmiHandler = CR(ListEntry, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE); - Size += sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE) + SmiHandler->ContextSize; - } - - return Size; -} - -/** - return all SMI handler database size on the SMI entry list. - - @param SmiEntryList a list of SMI entry. - - @return all SMI handler database size on the SMI entry list. -**/ -UINTN -GetSmmSmiDatabaseSize( - IN LIST_ENTRY *SmiEntryList - ) -{ - LIST_ENTRY *ListEntry; - SMI_ENTRY *SmiEntry; - UINTN Size; - - Size = 0; - ListEntry = SmiEntryList; - for (ListEntry = ListEntry->ForwardLink; - ListEntry != SmiEntryList; - ListEntry = ListEntry->ForwardLink) { - SmiEntry = CR(ListEntry, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE); - Size += sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE); - Size += GetSmmSmiHandlerSizeOnSmiEntry(SmiEntry); - } - return Size; -} - -/** - return SMI handler profile database size. - - @return SMI handler profile database size. -**/ -UINTN -GetSmiHandlerProfileDatabaseSize ( - VOID - ) -{ - mSmmImageDatabaseSize = GetSmmImageDatabaseSize(); - mSmmRootSmiDatabaseSize = GetSmmSmiDatabaseSize(mSmmCoreRootSmiEntryList); - mSmmSmiDatabaseSize = GetSmmSmiDatabaseSize(mSmmCoreSmiEntryList); - mSmmHardwareSmiDatabaseSize = GetSmmSmiDatabaseSize(mSmmCoreHardwareSmiEntryList); - - return mSmmImageDatabaseSize + mSmmSmiDatabaseSize + mSmmRootSmiDatabaseSize + mSmmHardwareSmiDatabaseSize; -} - -/** - get SMM image database. - - @param Data The buffer to hold SMM image database - @param ExpectedSize The expected size of the SMM image database - - @return SMM image data base size. -**/ -UINTN -GetSmmImageDatabaseData ( - IN OUT VOID *Data, - IN UINTN ExpectedSize - ) -{ - SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct; - UINTN Size; - UINTN Index; - - ImageStruct = Data; - Size = 0; - for (Index = 0; Index < mImageStructCount; Index++) { - if (Size >= ExpectedSize) { - return 0; - } - if (sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE) + mImageStruct[Index].PdbStringSize > ExpectedSize - Size) { - return 0; - } - ImageStruct->Header.Signature = SMM_CORE_IMAGE_DATABASE_SIGNATURE; - ImageStruct->Header.Length = (UINT32)(sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE) + mImageStruct[Index].PdbStringSize); - ImageStruct->Header.Revision = SMM_CORE_IMAGE_DATABASE_REVISION; - CopyGuid(&ImageStruct->FileGuid, &mImageStruct[Index].FileGuid); - ImageStruct->ImageRef = mImageStruct[Index].ImageRef; - ImageStruct->EntryPoint = mImageStruct[Index].EntryPoint; - ImageStruct->ImageBase = mImageStruct[Index].ImageBase; - ImageStruct->ImageSize = mImageStruct[Index].ImageSize; - ImageStruct->PdbStringOffset = sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE); - CopyMem ((VOID *)((UINTN)ImageStruct + ImageStruct->PdbStringOffset), mImageStruct[Index].PdbString, mImageStruct[Index].PdbStringSize); - ImageStruct = (SMM_CORE_IMAGE_DATABASE_STRUCTURE *)((UINTN)ImageStruct + ImageStruct->Header.Length); - Size += sizeof(SMM_CORE_IMAGE_DATABASE_STRUCTURE) + mImageStruct[Index].PdbStringSize; - } - - if (ExpectedSize != Size) { - return 0; - } - return Size; -} - -/** - get all SMI handler data associated with SmiEntry. - - @param SmiEntry SMI entry. - @param Data The buffer to hold all SMI handler data - @param MaxSize The max size of the SMM image database - @param Count The count of the SMI handler. - - @return SMM image data base size. -**/ -UINTN -GetSmmSmiHandlerDataOnSmiEntry( - IN SMI_ENTRY *SmiEntry, - IN OUT VOID *Data, - IN UINTN MaxSize, - OUT UINTN *Count - ) -{ - SMM_CORE_SMI_HANDLER_STRUCTURE *SmiHandlerStruct; - LIST_ENTRY *ListEntry; - SMI_HANDLER *SmiHandler; - UINTN Size; - - SmiHandlerStruct = Data; - Size = 0; - *Count = 0; - ListEntry = &SmiEntry->SmiHandlers; - for (ListEntry = ListEntry->ForwardLink; - ListEntry != &SmiEntry->SmiHandlers; - ListEntry = ListEntry->ForwardLink) { - SmiHandler = CR(ListEntry, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE); - if (Size >= MaxSize) { - *Count = 0; - return 0; - } - if (sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE) + SmiHandler->ContextSize > MaxSize - Size) { - *Count = 0; - return 0; - } - SmiHandlerStruct->Length = (UINT32)(sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE) + SmiHandler->ContextSize); - SmiHandlerStruct->CallerAddr = (UINTN)SmiHandler->CallerAddr; - SmiHandlerStruct->Handler = (UINTN)SmiHandler->Handler; - SmiHandlerStruct->ImageRef = AddressToImageRef((UINTN)SmiHandler->Handler); - SmiHandlerStruct->ContextBufferSize = (UINT32)SmiHandler->ContextSize; - if (SmiHandler->ContextSize != 0) { - SmiHandlerStruct->ContextBufferOffset = sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE); - CopyMem ((UINT8 *)SmiHandlerStruct + SmiHandlerStruct->ContextBufferOffset, SmiHandler->Context, SmiHandler->ContextSize); - } else { - SmiHandlerStruct->ContextBufferOffset = 0; - } - Size += sizeof(SMM_CORE_SMI_HANDLER_STRUCTURE) + SmiHandler->ContextSize; - SmiHandlerStruct = (SMM_CORE_SMI_HANDLER_STRUCTURE *)((UINTN)SmiHandlerStruct + SmiHandlerStruct->Length); - *Count = *Count + 1; - } - - return Size; -} - -/** - get all SMI handler database on the SMI entry list. - - @param SmiEntryList a list of SMI entry. - @param HandlerCategory The handler category - @param Data The buffer to hold all SMI handler database - @param ExpectedSize The expected size of the SMM image database - - @return all SMI database size on the SMI entry list. -**/ -UINTN -GetSmmSmiDatabaseData( - IN LIST_ENTRY *SmiEntryList, - IN UINT32 HandlerCategory, - IN OUT VOID *Data, - IN UINTN ExpectedSize - ) -{ - SMM_CORE_SMI_DATABASE_STRUCTURE *SmiStruct; - LIST_ENTRY *ListEntry; - SMI_ENTRY *SmiEntry; - UINTN Size; - UINTN SmiHandlerSize; - UINTN SmiHandlerCount; - - SmiStruct = Data; - Size = 0; - ListEntry = SmiEntryList; - for (ListEntry = ListEntry->ForwardLink; - ListEntry != SmiEntryList; - ListEntry = ListEntry->ForwardLink) { - SmiEntry = CR(ListEntry, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE); - if (Size >= ExpectedSize) { - return 0; - } - if (sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE) > ExpectedSize - Size) { - return 0; - } - - SmiStruct->Header.Signature = SMM_CORE_SMI_DATABASE_SIGNATURE; - SmiStruct->Header.Length = sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE); - SmiStruct->Header.Revision = SMM_CORE_SMI_DATABASE_REVISION; - SmiStruct->HandlerCategory = HandlerCategory; - CopyGuid(&SmiStruct->HandlerType, &SmiEntry->HandlerType); - Size += sizeof(SMM_CORE_SMI_DATABASE_STRUCTURE); - SmiHandlerSize = GetSmmSmiHandlerDataOnSmiEntry(SmiEntry, (UINT8 *)SmiStruct + SmiStruct->Header.Length, ExpectedSize - Size, &SmiHandlerCount); - SmiStruct->HandlerCount = SmiHandlerCount; - Size += SmiHandlerSize; - SmiStruct->Header.Length += (UINT32)SmiHandlerSize; - SmiStruct = (VOID *)((UINTN)SmiStruct + SmiStruct->Header.Length); - } - if (ExpectedSize != Size) { - return 0; - } - return Size; -} - -/** - Get SMI handler profile database. - - @param Data the buffer to hold SMI handler profile database - - @retval EFI_SUCCESS the database is got. - @retval EFI_INVALID_PARAMETER the database size mismatch. -**/ -EFI_STATUS -GetSmiHandlerProfileDatabaseData( - IN OUT VOID *Data - ) -{ - UINTN SmmImageDatabaseSize; - UINTN SmmSmiDatabaseSize; - UINTN SmmRootSmiDatabaseSize; - UINTN SmmHardwareSmiDatabaseSize; - - DEBUG((DEBUG_VERBOSE, "GetSmiHandlerProfileDatabaseData\n")); - SmmImageDatabaseSize = GetSmmImageDatabaseData(Data, mSmmImageDatabaseSize); - if (SmmImageDatabaseSize != mSmmImageDatabaseSize) { - DEBUG((DEBUG_ERROR, "GetSmiHandlerProfileDatabaseData - SmmImageDatabaseSize mismatch!\n")); - return EFI_INVALID_PARAMETER; - } - SmmRootSmiDatabaseSize = GetSmmSmiDatabaseData(mSmmCoreRootSmiEntryList, SmmCoreSmiHandlerCategoryRootHandler, (UINT8 *)Data + SmmImageDatabaseSize, mSmmRootSmiDatabaseSize); - if (SmmRootSmiDatabaseSize != mSmmRootSmiDatabaseSize) { - DEBUG((DEBUG_ERROR, "GetSmiHandlerProfileDatabaseData - SmmRootSmiDatabaseSize mismatch!\n")); - return EFI_INVALID_PARAMETER; - } - SmmSmiDatabaseSize = GetSmmSmiDatabaseData(mSmmCoreSmiEntryList, SmmCoreSmiHandlerCategoryGuidHandler, (UINT8 *)Data + SmmImageDatabaseSize + mSmmRootSmiDatabaseSize, mSmmSmiDatabaseSize); - if (SmmSmiDatabaseSize != mSmmSmiDatabaseSize) { - DEBUG((DEBUG_ERROR, "GetSmiHandlerProfileDatabaseData - SmmSmiDatabaseSize mismatch!\n")); - return EFI_INVALID_PARAMETER; - } - SmmHardwareSmiDatabaseSize = GetSmmSmiDatabaseData(mSmmCoreHardwareSmiEntryList, SmmCoreSmiHandlerCategoryHardwareHandler, (UINT8 *)Data + SmmImageDatabaseSize + SmmRootSmiDatabaseSize + SmmSmiDatabaseSize, mSmmHardwareSmiDatabaseSize); - if (SmmHardwareSmiDatabaseSize != mSmmHardwareSmiDatabaseSize) { - DEBUG((DEBUG_ERROR, "GetSmiHandlerProfileDatabaseData - SmmHardwareSmiDatabaseSize mismatch!\n")); - return EFI_INVALID_PARAMETER; - } - - return EFI_SUCCESS; -} - -/** - build SMI handler profile database. -**/ -VOID -BuildSmiHandlerProfileDatabase( - VOID - ) -{ - EFI_STATUS Status; - mSmiHandlerProfileDatabaseSize = GetSmiHandlerProfileDatabaseSize(); - mSmiHandlerProfileDatabase = AllocatePool(mSmiHandlerProfileDatabaseSize); - if (mSmiHandlerProfileDatabase == NULL) { - return; - } - Status = GetSmiHandlerProfileDatabaseData(mSmiHandlerProfileDatabase); - if (EFI_ERROR(Status)) { - FreePool(mSmiHandlerProfileDatabase); - mSmiHandlerProfileDatabase = NULL; - } -} - -/** - Copy SMI handler profile data. - - @param DataBuffer The buffer to hold SMI handler profile data. - @param DataSize On input, data buffer size. - On output, actual data buffer size copied. - @param DataOffset On input, data buffer offset to copy. - On output, next time data buffer offset to copy. - -**/ -VOID -SmiHandlerProfileCopyData( - OUT VOID *DataBuffer, - IN OUT UINT64 *DataSize, - IN OUT UINT64 *DataOffset - ) -{ - if (*DataOffset >= mSmiHandlerProfileDatabaseSize) { - *DataOffset = mSmiHandlerProfileDatabaseSize; - return; - } - if (mSmiHandlerProfileDatabaseSize - *DataOffset < *DataSize) { - *DataSize = mSmiHandlerProfileDatabaseSize - *DataOffset; - } - - CopyMem( - DataBuffer, - (UINT8 *)mSmiHandlerProfileDatabase + *DataOffset, - (UINTN)*DataSize - ); - *DataOffset = *DataOffset + *DataSize; -} - -/** - SMI handler profile handler to get info. - - @param SmiHandlerProfileParameterGetInfo The parameter of SMI handler profile get info. - -**/ -VOID -SmiHandlerProfileHandlerGetInfo( - IN SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *SmiHandlerProfileParameterGetInfo - ) -{ - BOOLEAN SmiHandlerProfileRecordingStatus; - - SmiHandlerProfileRecordingStatus = mSmiHandlerProfileRecordingStatus; - mSmiHandlerProfileRecordingStatus = FALSE; - - SmiHandlerProfileParameterGetInfo->DataSize = mSmiHandlerProfileDatabaseSize; - SmiHandlerProfileParameterGetInfo->Header.ReturnStatus = 0; - - mSmiHandlerProfileRecordingStatus = SmiHandlerProfileRecordingStatus; -} - -/** - SMI handler profile handler to get data by offset. - - @param SmiHandlerProfileParameterGetDataByOffset The parameter of SMI handler profile get data by offset. - -**/ -VOID -SmiHandlerProfileHandlerGetDataByOffset( - IN SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *SmiHandlerProfileParameterGetDataByOffset - ) -{ - SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET SmiHandlerProfileGetDataByOffset; - BOOLEAN SmiHandlerProfileRecordingStatus; - - SmiHandlerProfileRecordingStatus = mSmiHandlerProfileRecordingStatus; - mSmiHandlerProfileRecordingStatus = FALSE; - - CopyMem(&SmiHandlerProfileGetDataByOffset, SmiHandlerProfileParameterGetDataByOffset, sizeof(SmiHandlerProfileGetDataByOffset)); - - // - // Sanity check - // - if (!SmmIsBufferOutsideSmmValid((UINTN)SmiHandlerProfileGetDataByOffset.DataBuffer, (UINTN)SmiHandlerProfileGetDataByOffset.DataSize)) { - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandlerGetDataByOffset: SMI handler profile get data in SMRAM or overflow!\n")); - SmiHandlerProfileParameterGetDataByOffset->Header.ReturnStatus = (UINT64)(INT64)(INTN)EFI_ACCESS_DENIED; - goto Done; - } - - SmiHandlerProfileCopyData((VOID *)(UINTN)SmiHandlerProfileGetDataByOffset.DataBuffer, &SmiHandlerProfileGetDataByOffset.DataSize, &SmiHandlerProfileGetDataByOffset.DataOffset); - CopyMem(SmiHandlerProfileParameterGetDataByOffset, &SmiHandlerProfileGetDataByOffset, sizeof(SmiHandlerProfileGetDataByOffset)); - SmiHandlerProfileParameterGetDataByOffset->Header.ReturnStatus = 0; - -Done: - mSmiHandlerProfileRecordingStatus = SmiHandlerProfileRecordingStatus; -} - -/** - Dispatch function for a Software SMI handler. - - Caution: This function may receive untrusted input. - Communicate buffer and buffer size are external input, so this function will do basic validation. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the - handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @retval EFI_SUCCESS Command is handled successfully. -**/ -EFI_STATUS -EFIAPI -SmiHandlerProfileHandler( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context OPTIONAL, - IN OUT VOID *CommBuffer OPTIONAL, - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - SMI_HANDLER_PROFILE_PARAMETER_HEADER *SmiHandlerProfileParameterHeader; - UINTN TempCommBufferSize; - - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandler Enter\n")); - - if (mSmiHandlerProfileDatabase == NULL) { - return EFI_SUCCESS; - } - - // - // If input is invalid, stop processing this SMI - // - if (CommBuffer == NULL || CommBufferSize == NULL) { - return EFI_SUCCESS; - } - - TempCommBufferSize = *CommBufferSize; - - if (TempCommBufferSize < sizeof(SMI_HANDLER_PROFILE_PARAMETER_HEADER)) { - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - - if (!SmmIsBufferOutsideSmmValid((UINTN)CommBuffer, TempCommBufferSize)) { - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandler: SMM communication buffer in SMRAM or overflow!\n")); - return EFI_SUCCESS; - } - - SmiHandlerProfileParameterHeader = (SMI_HANDLER_PROFILE_PARAMETER_HEADER *)((UINTN)CommBuffer); - SmiHandlerProfileParameterHeader->ReturnStatus = (UINT64)-1; - - switch (SmiHandlerProfileParameterHeader->Command) { - case SMI_HANDLER_PROFILE_COMMAND_GET_INFO: - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandlerGetInfo\n")); - if (TempCommBufferSize != sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_INFO)) { - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - SmiHandlerProfileHandlerGetInfo((SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *)(UINTN)CommBuffer); - break; - case SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET: - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandlerGetDataByOffset\n")); - if (TempCommBufferSize != sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET)) { - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - SmiHandlerProfileHandlerGetDataByOffset((SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *)(UINTN)CommBuffer); - break; - default: - break; - } - - DEBUG((DEBUG_ERROR, "SmiHandlerProfileHandler Exit\n")); - - return EFI_SUCCESS; -} - -/** - Register SMI handler profile handler. -**/ -VOID -RegisterSmiHandlerProfileHandler ( - VOID - ) -{ - EFI_STATUS Status; - EFI_HANDLE DispatchHandle; - - Status = gSmst->SmiHandlerRegister ( - SmiHandlerProfileHandler, - &gSmiHandlerProfileGuid, - &DispatchHandle - ); - ASSERT_EFI_ERROR (Status); - - BuildSmiHandlerProfileDatabase(); -} - -/** - Finds the SMI entry for the requested handler type. - - @param HandlerType The type of the interrupt - @param Create Create a new entry if not found - - @return SMI entry -**/ -SMI_ENTRY * -SmmCoreFindHardwareSmiEntry ( - IN EFI_GUID *HandlerType, - IN BOOLEAN Create - ) -{ - LIST_ENTRY *Link; - SMI_ENTRY *Item; - SMI_ENTRY *SmiEntry; - - // - // Search the SMI entry list for the matching GUID - // - SmiEntry = NULL; - for (Link = mHardwareSmiEntryList.ForwardLink; - Link != &mHardwareSmiEntryList; - Link = Link->ForwardLink) { - - Item = CR (Link, SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE); - if (CompareGuid (&Item->HandlerType, HandlerType)) { - // - // This is the SMI entry - // - SmiEntry = Item; - break; - } - } - - // - // If the protocol entry was not found and Create is TRUE, then - // allocate a new entry - // - if ((SmiEntry == NULL) && Create) { - SmiEntry = AllocatePool (sizeof(SMI_ENTRY)); - if (SmiEntry != NULL) { - // - // Initialize new SMI entry structure - // - SmiEntry->Signature = SMI_ENTRY_SIGNATURE; - CopyGuid ((VOID *)&SmiEntry->HandlerType, HandlerType); - InitializeListHead (&SmiEntry->SmiHandlers); - - // - // Add it to SMI entry list - // - InsertTailList (&mHardwareSmiEntryList, &SmiEntry->AllEntries); - } - } - return SmiEntry; -} - -/** - Convert EFI_SMM_USB_REGISTER_CONTEXT to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT. - - @param UsbContext A pointer to EFI_SMM_USB_REGISTER_CONTEXT - @param UsbContextSize The size of EFI_SMM_USB_REGISTER_CONTEXT in bytes - @param SmiHandlerUsbContextSize The size of SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT in bytes - - @return SmiHandlerUsbContext A pointer to SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT -**/ -SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT * -ConvertSmiHandlerUsbContext ( - IN EFI_SMM_USB_REGISTER_CONTEXT *UsbContext, - IN UINTN UsbContextSize, - OUT UINTN *SmiHandlerUsbContextSize - ) -{ - UINTN DevicePathSize; - SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *SmiHandlerUsbContext; - - ASSERT (UsbContextSize == sizeof(EFI_SMM_USB_REGISTER_CONTEXT)); - - DevicePathSize = GetDevicePathSize (UsbContext->Device); - SmiHandlerUsbContext = AllocatePool (sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT) + DevicePathSize); - if (SmiHandlerUsbContext == NULL) { - *SmiHandlerUsbContextSize = 0; - return NULL; - } - SmiHandlerUsbContext->Type = UsbContext->Type; - SmiHandlerUsbContext->DevicePathSize = (UINT32)DevicePathSize; - CopyMem (SmiHandlerUsbContext + 1, UsbContext->Device, DevicePathSize); - *SmiHandlerUsbContextSize = sizeof (SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT) + DevicePathSize; - return SmiHandlerUsbContext; -} - -/** - This function is called by SmmChildDispatcher module to report - a new SMI handler is registered, to SmmCore. - - @param This The protocol instance - @param HandlerGuid The GUID to identify the type of the handler. - For the SmmChildDispatch protocol, the HandlerGuid - must be the GUID of SmmChildDispatch protocol. - @param Handler The SMI handler. - @param CallerAddress The address of the module who registers the SMI handler. - @param Context The context of the SMI handler. - For the SmmChildDispatch protocol, the Context - must match the one defined for SmmChildDispatch protocol. - @param ContextSize The size of the context in bytes. - For the SmmChildDispatch protocol, the Context - must match the one defined for SmmChildDispatch protocol. - - @retval EFI_SUCCESS The information is recorded. - @retval EFI_OUT_OF_RESOURCES There is no enough resource to record the information. -**/ -EFI_STATUS -EFIAPI -SmiHandlerProfileRegisterHandler ( - IN SMI_HANDLER_PROFILE_PROTOCOL *This, - IN EFI_GUID *HandlerGuid, - IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler, - IN PHYSICAL_ADDRESS CallerAddress, - IN VOID *Context, OPTIONAL - IN UINTN ContextSize OPTIONAL - ) -{ - SMI_HANDLER *SmiHandler; - SMI_ENTRY *SmiEntry; - LIST_ENTRY *List; - - if (((ContextSize == 0) && (Context != NULL)) || - ((ContextSize != 0) && (Context == NULL))) { - return EFI_INVALID_PARAMETER; - } - - SmiHandler = AllocateZeroPool (sizeof (SMI_HANDLER)); - if (SmiHandler == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - SmiHandler->Signature = SMI_HANDLER_SIGNATURE; - SmiHandler->Handler = Handler; - SmiHandler->CallerAddr = (UINTN)CallerAddress; - SmiHandler->Context = Context; - SmiHandler->ContextSize = ContextSize; - - if (Context != NULL) { - if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) { - SmiHandler->Context = ConvertSmiHandlerUsbContext (Context, ContextSize, &SmiHandler->ContextSize); - } else { - SmiHandler->Context = AllocateCopyPool (ContextSize, Context); - } - } - if (SmiHandler->Context == NULL) { - SmiHandler->ContextSize = 0; - } - - SmiEntry = SmmCoreFindHardwareSmiEntry (HandlerGuid, TRUE); - if (SmiEntry == NULL) { - if (SmiHandler->Context != NULL) { - FreePool (SmiHandler->Context); - } - FreePool (SmiHandler); - return EFI_OUT_OF_RESOURCES; - } - - List = &SmiEntry->SmiHandlers; - - SmiHandler->SmiEntry = SmiEntry; - InsertTailList (List, &SmiHandler->Link); - - return EFI_SUCCESS; -} - -/** - This function is called by SmmChildDispatcher module to report - an existing SMI handler is unregistered, to SmmCore. - - @param This The protocol instance - @param HandlerGuid The GUID to identify the type of the handler. - For the SmmChildDispatch protocol, the HandlerGuid - must be the GUID of SmmChildDispatch protocol. - @param Handler The SMI handler. - @param Context The context of the SMI handler. - If it is NOT NULL, it will be used to check what is registered. - @param ContextSize The size of the context in bytes. - If Context is NOT NULL, it will be used to check what is registered. - - @retval EFI_SUCCESS The original record is removed. - @retval EFI_NOT_FOUND There is no record for the HandlerGuid and handler. -**/ -EFI_STATUS -EFIAPI -SmiHandlerProfileUnregisterHandler ( - IN SMI_HANDLER_PROFILE_PROTOCOL *This, - IN EFI_GUID *HandlerGuid, - IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler, - IN VOID *Context, OPTIONAL - IN UINTN ContextSize OPTIONAL - ) -{ - LIST_ENTRY *Link; - LIST_ENTRY *Head; - SMI_HANDLER *SmiHandler; - SMI_ENTRY *SmiEntry; - SMI_HANDLER *TargetSmiHandler; - VOID *SearchContext; - UINTN SearchContextSize; - - if (((ContextSize == 0) && (Context != NULL)) || - ((ContextSize != 0) && (Context == NULL))) { - return EFI_INVALID_PARAMETER; - } - - SmiEntry = SmmCoreFindHardwareSmiEntry (HandlerGuid, FALSE); - if (SmiEntry == NULL) { - return EFI_NOT_FOUND; - } - - SearchContext = Context; - SearchContextSize = ContextSize; - if (Context != NULL) { - if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) { - SearchContext = ConvertSmiHandlerUsbContext (Context, ContextSize, &SearchContextSize); - } - } - - TargetSmiHandler = NULL; - Head = &SmiEntry->SmiHandlers; - for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) { - SmiHandler = CR (Link, SMI_HANDLER, Link, SMI_HANDLER_SIGNATURE); - if (SmiHandler->Handler == Handler) { - if ((SearchContext == NULL) || - ((SearchContextSize == SmiHandler->ContextSize) && (CompareMem (SearchContext, SmiHandler->Context, SearchContextSize) == 0))) { - TargetSmiHandler = SmiHandler; - break; - } - } - } - - if (SearchContext != NULL) { - if (CompareGuid (HandlerGuid, &gEfiSmmUsbDispatch2ProtocolGuid)) { - FreePool (SearchContext); - } - } - - if (TargetSmiHandler == NULL) { - return EFI_NOT_FOUND; - } - SmiHandler = TargetSmiHandler; - - RemoveEntryList (&SmiHandler->Link); - if (SmiHandler->Context != NULL) { - FreePool (SmiHandler->Context); - } - FreePool (SmiHandler); - - if (IsListEmpty (&SmiEntry->SmiHandlers)) { - RemoveEntryList (&SmiEntry->AllEntries); - FreePool (SmiEntry); - } - - return EFI_SUCCESS; -} - -/** - Initialize SmiHandler profile feature. -**/ -VOID -SmmCoreInitializeSmiHandlerProfile ( - VOID - ) -{ - EFI_STATUS Status; - VOID *Registration; - EFI_HANDLE Handle; - - if ((PcdGet8 (PcdSmiHandlerProfilePropertyMask) & 0x1) != 0) { - InsertTailList (&mRootSmiEntryList, &mRootSmiEntry.AllEntries); - - Status = gSmst->SmmRegisterProtocolNotify ( - &gEfiSmmReadyToLockProtocolGuid, - SmmReadyToLockInSmiHandlerProfile, - &Registration - ); - ASSERT_EFI_ERROR (Status); - - Handle = NULL; - Status = gSmst->SmmInstallProtocolInterface ( - &Handle, - &gSmiHandlerProfileGuid, - EFI_NATIVE_INTERFACE, - &mSmiHandlerProfile - ); - ASSERT_EFI_ERROR (Status); - } -} - diff --git a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c b/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c deleted file mode 100644 index 410e0836fd..0000000000 --- a/MdeModulePkg/Core/PiSmmCore/SmramProfileRecord.c +++ /dev/null @@ -1,2852 +0,0 @@ -/** @file - Support routines for SMRAM profile. - - Copyright (c) 2014 - 2017, 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 - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "PiSmmCore.h" - -#define IS_SMRAM_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT1) != 0) -#define IS_UEFI_MEMORY_PROFILE_ENABLED ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT0) != 0) - -#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \ - ((ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))) - -typedef struct { - UINT32 Signature; - MEMORY_PROFILE_CONTEXT Context; - LIST_ENTRY *DriverInfoList; -} MEMORY_PROFILE_CONTEXT_DATA; - -typedef struct { - UINT32 Signature; - MEMORY_PROFILE_DRIVER_INFO DriverInfo; - LIST_ENTRY *AllocInfoList; - CHAR8 *PdbString; - LIST_ENTRY Link; -} MEMORY_PROFILE_DRIVER_INFO_DATA; - -typedef struct { - UINT32 Signature; - MEMORY_PROFILE_ALLOC_INFO AllocInfo; - CHAR8 *ActionString; - LIST_ENTRY Link; -} MEMORY_PROFILE_ALLOC_INFO_DATA; - -// -// When free memory less than 4 pages, dump it. -// -#define SMRAM_INFO_DUMP_PAGE_THRESHOLD 4 - -GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_FREE_MEMORY mSmramFreeMemory = { - { - MEMORY_PROFILE_FREE_MEMORY_SIGNATURE, - sizeof (MEMORY_PROFILE_FREE_MEMORY), - MEMORY_PROFILE_FREE_MEMORY_REVISION - }, - 0, - 0 -}; - -GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY mImageQueue = INITIALIZE_LIST_HEAD_VARIABLE (mImageQueue); -GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA mSmramProfileContext = { - MEMORY_PROFILE_CONTEXT_SIGNATURE, - { - { - MEMORY_PROFILE_CONTEXT_SIGNATURE, - sizeof (MEMORY_PROFILE_CONTEXT), - MEMORY_PROFILE_CONTEXT_REVISION - }, - 0, - 0, - {0}, - {0}, - 0, - 0, - 0 - }, - &mImageQueue, -}; -GLOBAL_REMOVE_IF_UNREFERENCED MEMORY_PROFILE_CONTEXT_DATA *mSmramProfileContextPtr = NULL; - -GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmramReadyToLock; -GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmramProfileGettingStatus = FALSE; -GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSmramProfileRecordingEnable = MEMORY_PROFILE_RECORDING_DISABLE; -GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_PROTOCOL *mSmramProfileDriverPath; -GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSmramProfileDriverPathSize; - -/** - Dump SMRAM infromation. - -**/ -VOID -DumpSmramInfo ( - VOID - ); - -/** - Get memory profile data. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer. - On return, points to the size of the data returned in ProfileBuffer. - @param[out] ProfileBuffer Profile buffer. - - @return EFI_SUCCESS Get the memory profile data successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data. - ProfileSize is updated with the size required. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolGetData ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN OUT UINT64 *ProfileSize, - OUT VOID *ProfileBuffer - ); - -/** - Register image to memory profile. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in] FilePath File path of the image. - @param[in] ImageBase Image base address. - @param[in] ImageSize Image size. - @param[in] FileType File type of the image. - - @return EFI_SUCCESS Register successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCE No enough resource for this register. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolRegisterImage ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN EFI_FV_FILETYPE FileType - ); - -/** - Unregister image from memory profile. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in] FilePath File path of the image. - @param[in] ImageBase Image base address. - @param[in] ImageSize Image size. - - @return EFI_SUCCESS Unregister successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_NOT_FOUND The image is not found. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolUnregisterImage ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize - ); - -/** - Get memory profile recording state. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[out] RecordingState Recording state. - - @return EFI_SUCCESS Memory profile recording state is returned. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_INVALID_PARAMETER RecordingState is NULL. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolGetRecordingState ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - OUT BOOLEAN *RecordingState - ); - -/** - Set memory profile recording state. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in] RecordingState Recording state. - - @return EFI_SUCCESS Set memory profile recording state successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolSetRecordingState ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN BOOLEAN RecordingState - ); - -/** - Record memory profile of multilevel caller. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in] CallerAddress Address of caller. - @param[in] Action Memory profile action. - @param[in] MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param[in] Buffer Buffer address. - @param[in] Size Buffer size. - @param[in] ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolRecord ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN VOID *Buffer, - IN UINTN Size, - IN CHAR8 *ActionString OPTIONAL - ); - -GLOBAL_REMOVE_IF_UNREFERENCED EDKII_SMM_MEMORY_PROFILE_PROTOCOL mSmmProfileProtocol = { - SmramProfileProtocolGetData, - SmramProfileProtocolRegisterImage, - SmramProfileProtocolUnregisterImage, - SmramProfileProtocolGetRecordingState, - SmramProfileProtocolSetRecordingState, - SmramProfileProtocolRecord, -}; - -/** - Return SMRAM profile context. - - @return SMRAM profile context. - -**/ -MEMORY_PROFILE_CONTEXT_DATA * -GetSmramProfileContext ( - VOID - ) -{ - return mSmramProfileContextPtr; -} - -/** - Retrieves the magic value from the PE/COFF header. - - @param Hdr The buffer in which to return the PE32, PE32+, or TE header. - - @return EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - Image is PE32 - @return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - Image is PE32+ - -**/ -UINT16 -InternalPeCoffGetPeHeaderMagicValue ( - IN EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr - ) -{ - // - // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value - // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the - // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC - // then override the returned value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC - // - if (Hdr.Pe32->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64 && Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - return EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - } - // - // Return the magic value from the PC/COFF Optional Header - // - return Hdr.Pe32->OptionalHeader.Magic; -} - -/** - Retrieves and returns the Subsystem of a PE/COFF image that has been loaded into system memory. - If Pe32Data is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - - @return The Subsystem of the PE/COFF image. - -**/ -UINT16 -InternalPeCoffGetSubsystem ( - IN VOID *Pe32Data - ) -{ - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_DOS_HEADER *DosHdr; - UINT16 Magic; - - ASSERT (Pe32Data != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data; - } - - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - return Hdr.Te->Subsystem; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - Magic = InternalPeCoffGetPeHeaderMagicValue (Hdr); - if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - return Hdr.Pe32->OptionalHeader.Subsystem; - } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - return Hdr.Pe32Plus->OptionalHeader.Subsystem; - } - } - - return 0x0000; -} - -/** - Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded - into system memory with the PE/COFF Loader Library functions. - - Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry - point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then - return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. - If Pe32Data is NULL, then ASSERT(). - If EntryPoint is NULL, then ASSERT(). - - @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. - @param EntryPoint The pointer to entry point to the PE/COFF image to return. - - @retval RETURN_SUCCESS EntryPoint was returned. - @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. - -**/ -RETURN_STATUS -InternalPeCoffGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - - ASSERT (Pe32Data != NULL); - ASSERT (EntryPoint != NULL); - - DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) ((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) Pe32Data; - } - - // - // Calculate the entry point relative to the start of the image. - // AddressOfEntryPoint is common for PE32 & PE32+ - // - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); - return RETURN_SUCCESS; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (Hdr.Pe32->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff)); - return RETURN_SUCCESS; - } - - return RETURN_UNSUPPORTED; -} - -/** - Build driver info. - - @param ContextData Memory profile context. - @param FileName File name of the image. - @param ImageBase Image base address. - @param ImageSize Image size. - @param EntryPoint Entry point of the image. - @param ImageSubsystem Image subsystem of the image. - @param FileType File type of the image. - - @return Pointer to memory profile driver info. - -**/ -MEMORY_PROFILE_DRIVER_INFO_DATA * -BuildDriverInfo ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, - IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN PHYSICAL_ADDRESS EntryPoint, - IN UINT16 ImageSubsystem, - IN EFI_FV_FILETYPE FileType - ) -{ - EFI_STATUS Status; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - VOID *EntryPointInImage; - CHAR8 *PdbString; - UINTN PdbSize; - UINTN PdbOccupiedSize; - - PdbSize = 0; - PdbOccupiedSize = 0; - PdbString = NULL; - if (ImageBase != 0) { - PdbString = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageBase); - if (PdbString != NULL) { - PdbSize = AsciiStrSize (PdbString); - PdbOccupiedSize = GET_OCCUPIED_SIZE (PdbSize, sizeof (UINT64)); - } - } - - // - // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action. - // - Status = SmmInternalAllocatePool ( - EfiRuntimeServicesData, - sizeof (*DriverInfoData) + sizeof (LIST_ENTRY) + PdbSize, - (VOID **) &DriverInfoData - ); - if (EFI_ERROR (Status)) { - return NULL; - } - ASSERT (DriverInfoData != NULL); - - ZeroMem (DriverInfoData, sizeof (*DriverInfoData)); - - DriverInfo = &DriverInfoData->DriverInfo; - DriverInfoData->Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE; - DriverInfo->Header.Signature = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE; - DriverInfo->Header.Length = (UINT16) (sizeof (MEMORY_PROFILE_DRIVER_INFO) + PdbOccupiedSize); - DriverInfo->Header.Revision = MEMORY_PROFILE_DRIVER_INFO_REVISION; - if (FileName != NULL) { - CopyMem (&DriverInfo->FileName, FileName, sizeof (EFI_GUID)); - } - DriverInfo->ImageBase = ImageBase; - DriverInfo->ImageSize = ImageSize; - DriverInfo->EntryPoint = EntryPoint; - DriverInfo->ImageSubsystem = ImageSubsystem; - if ((EntryPoint != 0) && ((EntryPoint < ImageBase) || (EntryPoint >= (ImageBase + ImageSize)))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageBuffer here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageBase, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverInfo->ImageBase = ImageBase + EntryPoint - (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage; - } - DriverInfo->FileType = FileType; - DriverInfoData->AllocInfoList = (LIST_ENTRY *) (DriverInfoData + 1); - InitializeListHead (DriverInfoData->AllocInfoList); - DriverInfo->CurrentUsage = 0; - DriverInfo->PeakUsage = 0; - DriverInfo->AllocRecordCount = 0; - if (PdbSize != 0) { - DriverInfo->PdbStringOffset = (UINT16) sizeof (MEMORY_PROFILE_DRIVER_INFO); - DriverInfoData->PdbString = (CHAR8 *) (DriverInfoData->AllocInfoList + 1); - CopyMem (DriverInfoData->PdbString, PdbString, PdbSize); - } else { - DriverInfo->PdbStringOffset = 0; - DriverInfoData->PdbString = NULL; - } - - InsertTailList (ContextData->DriverInfoList, &DriverInfoData->Link); - ContextData->Context.ImageCount ++; - ContextData->Context.TotalImageSize += DriverInfo->ImageSize; - - return DriverInfoData; -} - -/** - Register image to DXE. - - @param FileName File name of the image. - @param ImageBase Image base address. - @param ImageSize Image size. - @param FileType File type of the image. - -**/ -VOID -RegisterImageToDxe ( - IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN EFI_FV_FILETYPE FileType - ) -{ - EFI_STATUS Status; - EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; - UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)]; - - if (IS_UEFI_MEMORY_PROFILE_ENABLED) { - - FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer; - Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **) &ProfileProtocol); - if (!EFI_ERROR (Status)) { - EfiInitializeFwVolDevicepathNode (FilePath, FileName); - SetDevicePathEndNode (FilePath + 1); - - Status = ProfileProtocol->RegisterImage ( - ProfileProtocol, - (EFI_DEVICE_PATH_PROTOCOL *) FilePath, - ImageBase, - ImageSize, - FileType - ); - } - } -} - -/** - Unregister image from DXE. - - @param FileName File name of the image. - @param ImageBase Image base address. - @param ImageSize Image size. - -**/ -VOID -UnregisterImageFromDxe ( - IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize - ) -{ - EFI_STATUS Status; - EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; - UINT8 TempBuffer[sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof (EFI_DEVICE_PATH_PROTOCOL)]; - - if (IS_UEFI_MEMORY_PROFILE_ENABLED) { - - FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)TempBuffer; - Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID *) &ProfileProtocol); - if (!EFI_ERROR (Status)) { - EfiInitializeFwVolDevicepathNode (FilePath, FileName); - SetDevicePathEndNode (FilePath + 1); - - Status = ProfileProtocol->UnregisterImage ( - ProfileProtocol, - (EFI_DEVICE_PATH_PROTOCOL *) FilePath, - ImageBase, - ImageSize - ); - } - } -} - -/** - Return if record for this driver is needed.. - - @param DriverFilePath Driver file path. - - @retval TRUE Record for this driver is needed. - @retval FALSE Record for this driver is not needed. - -**/ -BOOLEAN -NeedRecordThisDriver ( - IN EFI_DEVICE_PATH_PROTOCOL *DriverFilePath - ) -{ - EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance; - UINTN DevicePathSize; - UINTN FilePathSize; - - if (!IsDevicePathValid (mSmramProfileDriverPath, mSmramProfileDriverPathSize)) { - // - // Invalid Device Path means record all. - // - return TRUE; - } - - // - // Record FilePath without end node. - // - FilePathSize = GetDevicePathSize (DriverFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL); - - DevicePathInstance = mSmramProfileDriverPath; - do { - // - // Find End node (it might be END_ENTIRE or END_INSTANCE) - // - TmpDevicePath = DevicePathInstance; - while (!IsDevicePathEndType (TmpDevicePath)) { - TmpDevicePath = NextDevicePathNode (TmpDevicePath); - } - - // - // Do not compare END node - // - DevicePathSize = (UINTN)TmpDevicePath - (UINTN)DevicePathInstance; - if ((FilePathSize == DevicePathSize) && - (CompareMem (DriverFilePath, DevicePathInstance, DevicePathSize) == 0)) { - return TRUE; - } - - // - // Get next instance - // - DevicePathInstance = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)DevicePathInstance + DevicePathSize + DevicePathNodeLength(TmpDevicePath)); - } while (DevicePathSubType (TmpDevicePath) != END_ENTIRE_DEVICE_PATH_SUBTYPE); - - return FALSE; -} - -/** - Register SMM Core to SMRAM profile. - - @param ContextData SMRAM profile context. - - @retval TRUE Register success. - @retval FALSE Register fail. - -**/ -BOOLEAN -RegisterSmmCore ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData - ) -{ - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - PHYSICAL_ADDRESS ImageBase; - UINT8 TempBuffer[sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH_PROTOCOL)]; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; - - FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempBuffer; - EfiInitializeFwVolDevicepathNode (FilePath, &gEfiCallerIdGuid); - SetDevicePathEndNode (FilePath + 1); - - if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *) FilePath)) { - return FALSE; - } - - ImageBase = gSmmCorePrivate->PiSmmCoreImageBase; - DriverInfoData = BuildDriverInfo ( - ContextData, - &gEfiCallerIdGuid, - ImageBase, - gSmmCorePrivate->PiSmmCoreImageSize, - gSmmCorePrivate->PiSmmCoreEntryPoint, - InternalPeCoffGetSubsystem ((VOID *) (UINTN) ImageBase), - EFI_FV_FILETYPE_SMM_CORE - ); - if (DriverInfoData == NULL) { - return FALSE; - } - - return TRUE; -} - -/** - Initialize SMRAM profile. - -**/ -VOID -SmramProfileInit ( - VOID - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *SmramProfileContext; - - RegisterImageToDxe ( - &gEfiCallerIdGuid, - gSmmCorePrivate->PiSmmCoreImageBase, - gSmmCorePrivate->PiSmmCoreImageSize, - EFI_FV_FILETYPE_SMM_CORE - ); - - if (!IS_SMRAM_PROFILE_ENABLED) { - return; - } - - SmramProfileContext = GetSmramProfileContext (); - if (SmramProfileContext != NULL) { - return; - } - - mSmramProfileGettingStatus = FALSE; - if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT7) != 0) { - mSmramProfileRecordingEnable = MEMORY_PROFILE_RECORDING_DISABLE; - } else { - mSmramProfileRecordingEnable = MEMORY_PROFILE_RECORDING_ENABLE; - } - mSmramProfileDriverPathSize = PcdGetSize (PcdMemoryProfileDriverPath); - mSmramProfileDriverPath = AllocateCopyPool (mSmramProfileDriverPathSize, PcdGetPtr (PcdMemoryProfileDriverPath)); - mSmramProfileContextPtr = &mSmramProfileContext; - - RegisterSmmCore (&mSmramProfileContext); - - DEBUG ((EFI_D_INFO, "SmramProfileInit SmramProfileContext - 0x%x\n", &mSmramProfileContext)); -} - -/** - Install SMRAM profile protocol. - -**/ -VOID -SmramProfileInstallProtocol ( - VOID - ) -{ - EFI_HANDLE Handle; - EFI_STATUS Status; - - if (!IS_SMRAM_PROFILE_ENABLED) { - return; - } - - Handle = NULL; - Status = SmmInstallProtocolInterface ( - &Handle, - &gEdkiiSmmMemoryProfileGuid, - EFI_NATIVE_INTERFACE, - &mSmmProfileProtocol - ); - ASSERT_EFI_ERROR (Status); -} - -/** - Get the GUID file name from the file path. - - @param FilePath File path. - - @return The GUID file name from the file path. - -**/ -EFI_GUID * -GetFileNameFromFilePath ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath - ) -{ - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *ThisFilePath; - EFI_GUID *FileName; - - FileName = NULL; - if (FilePath != NULL) { - ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) FilePath; - while (!IsDevicePathEnd (ThisFilePath)) { - FileName = EfiGetNameGuidFromFwVolDevicePathNode (ThisFilePath); - if (FileName != NULL) { - break; - } - ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) NextDevicePathNode (ThisFilePath); - } - } - - return FileName; -} - -/** - Register SMM image to SMRAM profile. - - @param DriverEntry SMM image info. - @param RegisterToDxe Register image to DXE. - - @return EFI_SUCCESS Register successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCES No enough resource for this register. - -**/ -EFI_STATUS -RegisterSmramProfileImage ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry, - IN BOOLEAN RegisterToDxe - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - UINT8 TempBuffer[sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH_PROTOCOL)]; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; - - if (RegisterToDxe) { - RegisterImageToDxe ( - &DriverEntry->FileName, - DriverEntry->ImageBuffer, - EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage), - EFI_FV_FILETYPE_SMM - ); - } - - if (!IS_SMRAM_PROFILE_ENABLED) { - return EFI_UNSUPPORTED; - } - - FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempBuffer; - EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName); - SetDevicePathEndNode (FilePath + 1); - - if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *) FilePath)) { - return EFI_UNSUPPORTED; - } - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - DriverInfoData = BuildDriverInfo ( - ContextData, - &DriverEntry->FileName, - DriverEntry->ImageBuffer, - EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage), - DriverEntry->ImageEntryPoint, - InternalPeCoffGetSubsystem ((VOID *) (UINTN) DriverEntry->ImageBuffer), - EFI_FV_FILETYPE_SMM - ); - if (DriverInfoData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} - -/** - Search image from memory profile. - - @param ContextData Memory profile context. - @param FileName Image file name. - @param Address Image Address. - - @return Pointer to memory profile driver info. - -**/ -MEMORY_PROFILE_DRIVER_INFO_DATA * -GetMemoryProfileDriverInfoByFileNameAndAddress ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, - IN EFI_GUID *FileName, - IN PHYSICAL_ADDRESS Address - ) -{ - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - LIST_ENTRY *DriverLink; - LIST_ENTRY *DriverInfoList; - - DriverInfoList = ContextData->DriverInfoList; - - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - DriverInfo = &DriverInfoData->DriverInfo; - if ((CompareGuid (&DriverInfo->FileName, FileName)) && - (Address >= DriverInfo->ImageBase) && - (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) { - return DriverInfoData; - } - } - - return NULL; -} - -/** - Search image from memory profile. - It will return image, if (Address >= ImageBuffer) AND (Address < ImageBuffer + ImageSize) - - @param ContextData Memory profile context. - @param Address Image or Function address. - - @return Pointer to memory profile driver info. - -**/ -MEMORY_PROFILE_DRIVER_INFO_DATA * -GetMemoryProfileDriverInfoFromAddress ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData, - IN PHYSICAL_ADDRESS Address - ) -{ - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - LIST_ENTRY *DriverLink; - LIST_ENTRY *DriverInfoList; - - DriverInfoList = ContextData->DriverInfoList; - - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - DriverInfo = &DriverInfoData->DriverInfo; - if ((Address >= DriverInfo->ImageBase) && - (Address < (DriverInfo->ImageBase + DriverInfo->ImageSize))) { - return DriverInfoData; - } - } - - return NULL; -} - -/** - Unregister image from SMRAM profile. - - @param DriverEntry SMM image info. - @param UnregisterFromDxe Unregister image from DXE. - - @return EFI_SUCCESS Unregister successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_NOT_FOUND The image is not found. - -**/ -EFI_STATUS -UnregisterSmramProfileImage ( - IN EFI_SMM_DRIVER_ENTRY *DriverEntry, - IN BOOLEAN UnregisterFromDxe - ) -{ - EFI_STATUS Status; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - EFI_GUID *FileName; - PHYSICAL_ADDRESS ImageAddress; - VOID *EntryPointInImage; - UINT8 TempBuffer[sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH) + sizeof(EFI_DEVICE_PATH_PROTOCOL)]; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FilePath; - - if (UnregisterFromDxe) { - UnregisterImageFromDxe ( - &DriverEntry->FileName, - DriverEntry->ImageBuffer, - EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage) - ); - } - - if (!IS_SMRAM_PROFILE_ENABLED) { - return EFI_UNSUPPORTED; - } - - FilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) TempBuffer; - EfiInitializeFwVolDevicepathNode (FilePath, &DriverEntry->FileName); - SetDevicePathEndNode (FilePath + 1); - - if (!NeedRecordThisDriver ((EFI_DEVICE_PATH_PROTOCOL *) FilePath)) { - return EFI_UNSUPPORTED; - } - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - DriverInfoData = NULL; - FileName = &DriverEntry->FileName; - ImageAddress = DriverEntry->ImageBuffer; - if ((DriverEntry->ImageEntryPoint < ImageAddress) || (DriverEntry->ImageEntryPoint >= (ImageAddress + EFI_PAGES_TO_SIZE (DriverEntry->NumberOfPage)))) { - // - // If the EntryPoint is not in the range of image buffer, it should come from emulation environment. - // So patch ImageAddress here to align the EntryPoint. - // - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) ImageAddress, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - ImageAddress = ImageAddress + (UINTN) DriverEntry->ImageEntryPoint - (UINTN) EntryPointInImage; - } - if (FileName != NULL) { - DriverInfoData = GetMemoryProfileDriverInfoByFileNameAndAddress (ContextData, FileName, ImageAddress); - } - if (DriverInfoData == NULL) { - DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, ImageAddress); - } - if (DriverInfoData == NULL) { - return EFI_NOT_FOUND; - } - - ContextData->Context.TotalImageSize -= DriverInfoData->DriverInfo.ImageSize; - - // Keep the ImageBase for RVA calculation in Application. - //DriverInfoData->DriverInfo.ImageBase = 0; - DriverInfoData->DriverInfo.ImageSize = 0; - - if (DriverInfoData->DriverInfo.PeakUsage == 0) { - ContextData->Context.ImageCount --; - RemoveEntryList (&DriverInfoData->Link); - // - // Use SmmInternalFreePool() that will not update profile for this FreePool action. - // - SmmInternalFreePool (DriverInfoData); - } - - return EFI_SUCCESS; -} - -/** - Return if this memory type needs to be recorded into memory profile. - Only need to record EfiRuntimeServicesCode and EfiRuntimeServicesData for SMRAM profile. - - @param MemoryType Memory type. - - @retval TRUE This memory type need to be recorded. - @retval FALSE This memory type need not to be recorded. - -**/ -BOOLEAN -SmmCoreNeedRecordProfile ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - UINT64 TestBit; - - if (MemoryType != EfiRuntimeServicesCode && - MemoryType != EfiRuntimeServicesData) { - return FALSE; - } - - TestBit = LShiftU64 (1, MemoryType); - - if ((PcdGet64 (PcdMemoryProfileMemoryType) & TestBit) != 0) { - return TRUE; - } else { - return FALSE; - } -} - -/** - Convert EFI memory type to profile memory index. The rule is: - If BIOS memory type (0 ~ EfiMaxMemoryType - 1), ProfileMemoryIndex = MemoryType. - As SMRAM profile is only to record EfiRuntimeServicesCode and EfiRuntimeServicesData, - so return input memory type directly. - - @param MemoryType Memory type. - - @return EFI memory type as profile memory index. - -**/ -EFI_MEMORY_TYPE -GetProfileMemoryIndex ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - return MemoryType; -} - -/** - Update SMRAM profile FreeMemoryPages information - - @param ContextData Memory profile context. - -**/ -VOID -SmramProfileUpdateFreePages ( - IN MEMORY_PROFILE_CONTEXT_DATA *ContextData - ) -{ - LIST_ENTRY *Node; - FREE_PAGE_LIST *Pages; - LIST_ENTRY *FreePageList; - UINTN NumberOfPages; - - NumberOfPages = 0; - FreePageList = &mSmmMemoryMap; - for (Node = FreePageList->BackLink; - Node != FreePageList; - Node = Node->BackLink) { - Pages = BASE_CR (Node, FREE_PAGE_LIST, Link); - NumberOfPages += Pages->NumberOfPages; - } - - mSmramFreeMemory.TotalFreeMemoryPages = NumberOfPages; - - if (NumberOfPages <= SMRAM_INFO_DUMP_PAGE_THRESHOLD) { - DumpSmramInfo (); - } -} - -/** - Update SMRAM profile Allocate information. - - @param CallerAddress Address of caller who call Allocate. - @param Action This Allocate action. - @param MemoryType Memory type. - @param Size Buffer size. - @param Buffer Buffer address. - @param ActionString String for memory profile action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - -**/ -EFI_STATUS -SmmCoreUpdateProfileAllocate ( - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN UINTN Size, - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ) -{ - EFI_STATUS Status; - MEMORY_PROFILE_CONTEXT *Context; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - EFI_MEMORY_TYPE ProfileMemoryIndex; - MEMORY_PROFILE_ACTION BasicAction; - UINTN ActionStringSize; - UINTN ActionStringOccupiedSize; - - BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress); - if (DriverInfoData == NULL) { - return EFI_UNSUPPORTED; - } - - ActionStringSize = 0; - ActionStringOccupiedSize = 0; - if (ActionString != NULL) { - ActionStringSize = AsciiStrSize (ActionString); - ActionStringOccupiedSize = GET_OCCUPIED_SIZE (ActionStringSize, sizeof (UINT64)); - } - - // - // Use SmmInternalAllocatePool() that will not update profile for this AllocatePool action. - // - AllocInfoData = NULL; - Status = SmmInternalAllocatePool ( - EfiRuntimeServicesData, - sizeof (*AllocInfoData) + ActionStringSize, - (VOID **) &AllocInfoData - ); - if (EFI_ERROR (Status)) { - return EFI_OUT_OF_RESOURCES; - } - ASSERT (AllocInfoData != NULL); - - // - // Only update SequenceCount if and only if it is basic action. - // - if (Action == BasicAction) { - ContextData->Context.SequenceCount ++; - } - - AllocInfo = &AllocInfoData->AllocInfo; - AllocInfoData->Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE; - AllocInfo->Header.Signature = MEMORY_PROFILE_ALLOC_INFO_SIGNATURE; - AllocInfo->Header.Length = (UINT16) (sizeof (MEMORY_PROFILE_ALLOC_INFO) + ActionStringOccupiedSize); - AllocInfo->Header.Revision = MEMORY_PROFILE_ALLOC_INFO_REVISION; - AllocInfo->CallerAddress = CallerAddress; - AllocInfo->SequenceId = ContextData->Context.SequenceCount; - AllocInfo->Action = Action; - AllocInfo->MemoryType = MemoryType; - AllocInfo->Buffer = (PHYSICAL_ADDRESS) (UINTN) Buffer; - AllocInfo->Size = Size; - if (ActionString != NULL) { - AllocInfo->ActionStringOffset = (UINT16) sizeof (MEMORY_PROFILE_ALLOC_INFO); - AllocInfoData->ActionString = (CHAR8 *) (AllocInfoData + 1); - CopyMem (AllocInfoData->ActionString, ActionString, ActionStringSize); - } else { - AllocInfo->ActionStringOffset = 0; - AllocInfoData->ActionString = NULL; - } - - InsertTailList (DriverInfoData->AllocInfoList, &AllocInfoData->Link); - - Context = &ContextData->Context; - DriverInfo = &DriverInfoData->DriverInfo; - DriverInfo->AllocRecordCount ++; - - // - // Update summary if and only if it is basic action. - // - if (Action == BasicAction) { - ProfileMemoryIndex = GetProfileMemoryIndex (MemoryType); - - DriverInfo->CurrentUsage += Size; - if (DriverInfo->PeakUsage < DriverInfo->CurrentUsage) { - DriverInfo->PeakUsage = DriverInfo->CurrentUsage; - } - DriverInfo->CurrentUsageByType[ProfileMemoryIndex] += Size; - if (DriverInfo->PeakUsageByType[ProfileMemoryIndex] < DriverInfo->CurrentUsageByType[ProfileMemoryIndex]) { - DriverInfo->PeakUsageByType[ProfileMemoryIndex] = DriverInfo->CurrentUsageByType[ProfileMemoryIndex]; - } - - Context->CurrentTotalUsage += Size; - if (Context->PeakTotalUsage < Context->CurrentTotalUsage) { - Context->PeakTotalUsage = Context->CurrentTotalUsage; - } - Context->CurrentTotalUsageByType[ProfileMemoryIndex] += Size; - if (Context->PeakTotalUsageByType[ProfileMemoryIndex] < Context->CurrentTotalUsageByType[ProfileMemoryIndex]) { - Context->PeakTotalUsageByType[ProfileMemoryIndex] = Context->CurrentTotalUsageByType[ProfileMemoryIndex]; - } - - SmramProfileUpdateFreePages (ContextData); - } - - return EFI_SUCCESS; -} - -/** - Get memory profile alloc info from memory profile - - @param DriverInfoData Driver info - @param BasicAction This Free basic action - @param Size Buffer size - @param Buffer Buffer address - - @return Pointer to memory profile alloc info. -**/ -MEMORY_PROFILE_ALLOC_INFO_DATA * -GetMemoryProfileAllocInfoFromAddress ( - IN MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData, - IN MEMORY_PROFILE_ACTION BasicAction, - IN UINTN Size, - IN VOID *Buffer - ) -{ - LIST_ENTRY *AllocInfoList; - LIST_ENTRY *AllocLink; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - - AllocInfoList = DriverInfoData->AllocInfoList; - - for (AllocLink = AllocInfoList->ForwardLink; - AllocLink != AllocInfoList; - AllocLink = AllocLink->ForwardLink) { - AllocInfoData = CR ( - AllocLink, - MEMORY_PROFILE_ALLOC_INFO_DATA, - Link, - MEMORY_PROFILE_ALLOC_INFO_SIGNATURE - ); - AllocInfo = &AllocInfoData->AllocInfo; - if ((AllocInfo->Action & MEMORY_PROFILE_ACTION_BASIC_MASK) != BasicAction) { - continue; - } - switch (BasicAction) { - case MemoryProfileActionAllocatePages: - if ((AllocInfo->Buffer <= (PHYSICAL_ADDRESS) (UINTN) Buffer) && - ((AllocInfo->Buffer + AllocInfo->Size) >= ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size))) { - return AllocInfoData; - } - break; - case MemoryProfileActionAllocatePool: - if (AllocInfo->Buffer == (PHYSICAL_ADDRESS) (UINTN) Buffer) { - return AllocInfoData; - } - break; - default: - ASSERT (FALSE); - break; - } - } - - return NULL; -} - -/** - Update SMRAM profile Free information. - - @param CallerAddress Address of caller who call Free. - @param Action This Free action. - @param Size Buffer size. - @param Buffer Buffer address. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -SmmCoreUpdateProfileFree ( - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN UINTN Size, - IN VOID *Buffer - ) -{ - MEMORY_PROFILE_CONTEXT *Context; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - LIST_ENTRY *DriverLink; - LIST_ENTRY *DriverInfoList; - MEMORY_PROFILE_DRIVER_INFO_DATA *ThisDriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - EFI_MEMORY_TYPE ProfileMemoryIndex; - MEMORY_PROFILE_ACTION BasicAction; - BOOLEAN Found; - - BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - DriverInfoData = GetMemoryProfileDriverInfoFromAddress (ContextData, CallerAddress); - - // - // Do not return if DriverInfoData == NULL here, - // because driver A might free memory allocated by driver B. - // - - // - // Need use do-while loop to find all possible record, - // because one address might be recorded multiple times. - // - Found = FALSE; - AllocInfoData = NULL; - do { - if (DriverInfoData != NULL) { - switch (BasicAction) { - case MemoryProfileActionFreePages: - AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer); - break; - case MemoryProfileActionFreePool: - AllocInfoData = GetMemoryProfileAllocInfoFromAddress (DriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer); - break; - default: - ASSERT (FALSE); - AllocInfoData = NULL; - break; - } - } - if (AllocInfoData == NULL) { - // - // Legal case, because driver A might free memory allocated by driver B, by some protocol. - // - DriverInfoList = ContextData->DriverInfoList; - - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - ThisDriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - switch (BasicAction) { - case MemoryProfileActionFreePages: - AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePages, Size, Buffer); - break; - case MemoryProfileActionFreePool: - AllocInfoData = GetMemoryProfileAllocInfoFromAddress (ThisDriverInfoData, MemoryProfileActionAllocatePool, 0, Buffer); - break; - default: - ASSERT (FALSE); - AllocInfoData = NULL; - break; - } - if (AllocInfoData != NULL) { - DriverInfoData = ThisDriverInfoData; - break; - } - } - - if (AllocInfoData == NULL) { - // - // If (!Found), no matched allocate info is found for this free action. - // It is because the specified memory type allocate actions have been filtered by - // CoreNeedRecordProfile(), but free actions have no memory type information, - // they can not be filtered by CoreNeedRecordProfile(). Then, they will be - // filtered here. - // - // If (Found), it is normal exit path. - return (Found ? EFI_SUCCESS : EFI_NOT_FOUND); - } - } - - ASSERT (DriverInfoData != NULL); - ASSERT (AllocInfoData != NULL); - - Found = TRUE; - - Context = &ContextData->Context; - DriverInfo = &DriverInfoData->DriverInfo; - AllocInfo = &AllocInfoData->AllocInfo; - - DriverInfo->AllocRecordCount --; - // - // Update summary if and only if it is basic action. - // - if (AllocInfo->Action == (AllocInfo->Action & MEMORY_PROFILE_ACTION_BASIC_MASK)) { - ProfileMemoryIndex = GetProfileMemoryIndex (AllocInfo->MemoryType); - - Context->CurrentTotalUsage -= AllocInfo->Size; - Context->CurrentTotalUsageByType[ProfileMemoryIndex] -= AllocInfo->Size; - - DriverInfo->CurrentUsage -= AllocInfo->Size; - DriverInfo->CurrentUsageByType[ProfileMemoryIndex] -= AllocInfo->Size; - } - - RemoveEntryList (&AllocInfoData->Link); - - if (BasicAction == MemoryProfileActionFreePages) { - if (AllocInfo->Buffer != (PHYSICAL_ADDRESS) (UINTN) Buffer) { - SmmCoreUpdateProfileAllocate ( - AllocInfo->CallerAddress, - AllocInfo->Action, - AllocInfo->MemoryType, - (UINTN) ((PHYSICAL_ADDRESS) (UINTN) Buffer - AllocInfo->Buffer), - (VOID *) (UINTN) AllocInfo->Buffer, - AllocInfoData->ActionString - ); - } - if (AllocInfo->Buffer + AllocInfo->Size != ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)) { - SmmCoreUpdateProfileAllocate ( - AllocInfo->CallerAddress, - AllocInfo->Action, - AllocInfo->MemoryType, - (UINTN) ((AllocInfo->Buffer + AllocInfo->Size) - ((PHYSICAL_ADDRESS) (UINTN) Buffer + Size)), - (VOID *) ((UINTN) Buffer + Size), - AllocInfoData->ActionString - ); - } - } - - // - // Use SmmInternalFreePool() that will not update profile for this FreePool action. - // - SmmInternalFreePool (AllocInfoData); - } while (TRUE); -} - -/** - Update SMRAM profile information. - - @param CallerAddress Address of caller who call Allocate or Free. - @param Action This Allocate or Free action. - @param MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param Size Buffer size. - @param Buffer Buffer address. - @param ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -SmmCoreUpdateProfile ( - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, // Valid for AllocatePages/AllocatePool - IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool - IN VOID *Buffer, - IN CHAR8 *ActionString OPTIONAL - ) -{ - EFI_STATUS Status; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_ACTION BasicAction; - - if (!IS_SMRAM_PROFILE_ENABLED) { - return EFI_UNSUPPORTED; - } - - if (mSmramProfileGettingStatus) { - return EFI_ACCESS_DENIED; - } - - if (!mSmramProfileRecordingEnable) { - return EFI_ABORTED; - } - - // - // Get the basic action to know how to process the record - // - BasicAction = Action & MEMORY_PROFILE_ACTION_BASIC_MASK; - - // - // Free operations have no memory type information, so skip the check. - // - if ((BasicAction == MemoryProfileActionAllocatePages) || (BasicAction == MemoryProfileActionAllocatePool)) { - // - // Only record limited MemoryType. - // - if (!SmmCoreNeedRecordProfile (MemoryType)) { - return EFI_UNSUPPORTED; - } - } - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - switch (BasicAction) { - case MemoryProfileActionAllocatePages: - Status = SmmCoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer, ActionString); - break; - case MemoryProfileActionFreePages: - Status = SmmCoreUpdateProfileFree (CallerAddress, Action, Size, Buffer); - break; - case MemoryProfileActionAllocatePool: - Status = SmmCoreUpdateProfileAllocate (CallerAddress, Action, MemoryType, Size, Buffer, ActionString); - break; - case MemoryProfileActionFreePool: - Status = SmmCoreUpdateProfileFree (CallerAddress, Action, 0, Buffer); - break; - default: - ASSERT (FALSE); - Status = EFI_UNSUPPORTED; - break; - } - - return Status; -} - -/** - SMRAM profile ready to lock callback function. - -**/ -VOID -SmramProfileReadyToLock ( - VOID - ) -{ - if (!IS_SMRAM_PROFILE_ENABLED) { - return; - } - - DEBUG ((EFI_D_INFO, "SmramProfileReadyToLock\n")); - mSmramReadyToLock = TRUE; -} - -//////////////////// - -/** - Get SMRAM profile data size. - - @return SMRAM profile data size. - -**/ -UINTN -SmramProfileGetDataSize ( - VOID - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - LIST_ENTRY *DriverInfoList; - LIST_ENTRY *DriverLink; - LIST_ENTRY *AllocInfoList; - LIST_ENTRY *AllocLink; - UINTN TotalSize; - LIST_ENTRY *Node; - LIST_ENTRY *FreePageList; - LIST_ENTRY *FreePoolList; - FREE_POOL_HEADER *Pool; - UINTN PoolListIndex; - UINTN Index; - UINTN SmmPoolTypeIndex; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return 0; - } - - TotalSize = sizeof (MEMORY_PROFILE_CONTEXT); - - DriverInfoList = ContextData->DriverInfoList; - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - TotalSize += DriverInfoData->DriverInfo.Header.Length; - - AllocInfoList = DriverInfoData->AllocInfoList; - for (AllocLink = AllocInfoList->ForwardLink; - AllocLink != AllocInfoList; - AllocLink = AllocLink->ForwardLink) { - AllocInfoData = CR ( - AllocLink, - MEMORY_PROFILE_ALLOC_INFO_DATA, - Link, - MEMORY_PROFILE_ALLOC_INFO_SIGNATURE - ); - TotalSize += AllocInfoData->AllocInfo.Header.Length; - } - } - - - Index = 0; - FreePageList = &mSmmMemoryMap; - for (Node = FreePageList->BackLink; - Node != FreePageList; - Node = Node->BackLink) { - Index++; - } - for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { - for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { - FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][PoolListIndex]; - for (Node = FreePoolList->BackLink; - Node != FreePoolList; - Node = Node->BackLink) { - Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); - if (Pool->Header.Available) { - Index++; - } - } - } - } - - TotalSize += (sizeof (MEMORY_PROFILE_FREE_MEMORY) + Index * sizeof (MEMORY_PROFILE_DESCRIPTOR)); - TotalSize += (sizeof (MEMORY_PROFILE_MEMORY_RANGE) + mFullSmramRangeCount * sizeof (MEMORY_PROFILE_DESCRIPTOR)); - - return TotalSize; -} - -/** - Copy SMRAM profile data. - - @param ProfileBuffer The buffer to hold SMRAM profile data. - @param ProfileSize On input, profile buffer size. - On output, actual profile data size copied. - @param ProfileOffset On input, profile buffer offset to copy. - On output, next time profile buffer offset to copy. - -**/ -VOID -SmramProfileCopyData ( - OUT VOID *ProfileBuffer, - IN OUT UINT64 *ProfileSize, - IN OUT UINT64 *ProfileOffset - ) -{ - MEMORY_PROFILE_CONTEXT *Context; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - LIST_ENTRY *DriverInfoList; - LIST_ENTRY *DriverLink; - LIST_ENTRY *AllocInfoList; - LIST_ENTRY *AllocLink; - LIST_ENTRY *Node; - FREE_PAGE_LIST *Pages; - LIST_ENTRY *FreePageList; - LIST_ENTRY *FreePoolList; - FREE_POOL_HEADER *Pool; - UINTN PoolListIndex; - UINT32 Index; - MEMORY_PROFILE_FREE_MEMORY *FreeMemory; - MEMORY_PROFILE_MEMORY_RANGE *MemoryRange; - MEMORY_PROFILE_DESCRIPTOR *MemoryProfileDescriptor; - UINT64 Offset; - UINT64 RemainingSize; - UINTN PdbSize; - UINTN ActionStringSize; - UINTN SmmPoolTypeIndex; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return ; - } - - RemainingSize = *ProfileSize; - Offset = 0; - - if (*ProfileOffset < sizeof (MEMORY_PROFILE_CONTEXT)) { - if (RemainingSize >= sizeof (MEMORY_PROFILE_CONTEXT)) { - Context = ProfileBuffer; - CopyMem (Context, &ContextData->Context, sizeof (MEMORY_PROFILE_CONTEXT)); - RemainingSize -= sizeof (MEMORY_PROFILE_CONTEXT); - ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_CONTEXT); - } else { - goto Done; - } - } - Offset += sizeof (MEMORY_PROFILE_CONTEXT); - - DriverInfoList = ContextData->DriverInfoList; - for (DriverLink = DriverInfoList->ForwardLink; - DriverLink != DriverInfoList; - DriverLink = DriverLink->ForwardLink) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - if (*ProfileOffset < (Offset + DriverInfoData->DriverInfo.Header.Length)) { - if (RemainingSize >= DriverInfoData->DriverInfo.Header.Length) { - DriverInfo = ProfileBuffer; - CopyMem (DriverInfo, &DriverInfoData->DriverInfo, sizeof (MEMORY_PROFILE_DRIVER_INFO)); - if (DriverInfo->PdbStringOffset != 0) { - PdbSize = AsciiStrSize (DriverInfoData->PdbString); - CopyMem ((VOID *) ((UINTN) DriverInfo + DriverInfo->PdbStringOffset), DriverInfoData->PdbString, PdbSize); - } - RemainingSize -= DriverInfo->Header.Length; - ProfileBuffer = (UINT8 *) ProfileBuffer + DriverInfo->Header.Length; - } else { - goto Done; - } - } - Offset += DriverInfoData->DriverInfo.Header.Length; - - AllocInfoList = DriverInfoData->AllocInfoList; - for (AllocLink = AllocInfoList->ForwardLink; - AllocLink != AllocInfoList; - AllocLink = AllocLink->ForwardLink) { - AllocInfoData = CR ( - AllocLink, - MEMORY_PROFILE_ALLOC_INFO_DATA, - Link, - MEMORY_PROFILE_ALLOC_INFO_SIGNATURE - ); - if (*ProfileOffset < (Offset + AllocInfoData->AllocInfo.Header.Length)) { - if (RemainingSize >= AllocInfoData->AllocInfo.Header.Length) { - AllocInfo = ProfileBuffer; - CopyMem (AllocInfo, &AllocInfoData->AllocInfo, sizeof (MEMORY_PROFILE_ALLOC_INFO)); - if (AllocInfo->ActionStringOffset) { - ActionStringSize = AsciiStrSize (AllocInfoData->ActionString); - CopyMem ((VOID *) ((UINTN) AllocInfo + AllocInfo->ActionStringOffset), AllocInfoData->ActionString, ActionStringSize); - } - RemainingSize -= AllocInfo->Header.Length; - ProfileBuffer = (UINT8 *) ProfileBuffer + AllocInfo->Header.Length; - } else { - goto Done; - } - } - Offset += AllocInfoData->AllocInfo.Header.Length; - } - } - - - if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_FREE_MEMORY))) { - if (RemainingSize >= sizeof (MEMORY_PROFILE_FREE_MEMORY)) { - FreeMemory = ProfileBuffer; - CopyMem (FreeMemory, &mSmramFreeMemory, sizeof (MEMORY_PROFILE_FREE_MEMORY)); - Index = 0; - FreePageList = &mSmmMemoryMap; - for (Node = FreePageList->BackLink; - Node != FreePageList; - Node = Node->BackLink) { - Index++; - } - for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { - for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { - FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][MAX_POOL_INDEX - PoolListIndex - 1]; - for (Node = FreePoolList->BackLink; - Node != FreePoolList; - Node = Node->BackLink) { - Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); - if (Pool->Header.Available) { - Index++; - } - } - } - } - FreeMemory->FreeMemoryEntryCount = Index; - - RemainingSize -= sizeof (MEMORY_PROFILE_FREE_MEMORY); - ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_FREE_MEMORY); - } else { - goto Done; - } - } - Offset += sizeof (MEMORY_PROFILE_FREE_MEMORY); - FreePageList = &mSmmMemoryMap; - for (Node = FreePageList->BackLink; - Node != FreePageList; - Node = Node->BackLink) { - if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) { - if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) { - Pages = BASE_CR (Node, FREE_PAGE_LIST, Link); - MemoryProfileDescriptor = ProfileBuffer; - MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE; - MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR); - MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION; - MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pages; - MemoryProfileDescriptor->Size = EFI_PAGES_TO_SIZE (Pages->NumberOfPages); - - RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR); - ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR); - } else { - goto Done; - } - } - Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR); - } - for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { - for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { - FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][MAX_POOL_INDEX - PoolListIndex - 1]; - for (Node = FreePoolList->BackLink; - Node != FreePoolList; - Node = Node->BackLink) { - Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); - if (Pool->Header.Available) { - if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) { - if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) { - MemoryProfileDescriptor = ProfileBuffer; - MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE; - MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR); - MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION; - MemoryProfileDescriptor->Address = (PHYSICAL_ADDRESS) (UINTN) Pool; - MemoryProfileDescriptor->Size = Pool->Header.Size; - - RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR); - ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR); - } else { - goto Done; - } - } - Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR); - } - } - } - } - - if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_MEMORY_RANGE))) { - if (RemainingSize >= sizeof (MEMORY_PROFILE_MEMORY_RANGE)) { - MemoryRange = ProfileBuffer; - MemoryRange->Header.Signature = MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE; - MemoryRange->Header.Length = sizeof (MEMORY_PROFILE_MEMORY_RANGE); - MemoryRange->Header.Revision = MEMORY_PROFILE_MEMORY_RANGE_REVISION; - MemoryRange->MemoryRangeCount = (UINT32) mFullSmramRangeCount; - - RemainingSize -= sizeof (MEMORY_PROFILE_MEMORY_RANGE); - ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_MEMORY_RANGE); - } else { - goto Done; - } - } - Offset += sizeof (MEMORY_PROFILE_MEMORY_RANGE); - for (Index = 0; Index < mFullSmramRangeCount; Index++) { - if (*ProfileOffset < (Offset + sizeof (MEMORY_PROFILE_DESCRIPTOR))) { - if (RemainingSize >= sizeof (MEMORY_PROFILE_DESCRIPTOR)) { - MemoryProfileDescriptor = ProfileBuffer; - MemoryProfileDescriptor->Header.Signature = MEMORY_PROFILE_DESCRIPTOR_SIGNATURE; - MemoryProfileDescriptor->Header.Length = sizeof (MEMORY_PROFILE_DESCRIPTOR); - MemoryProfileDescriptor->Header.Revision = MEMORY_PROFILE_DESCRIPTOR_REVISION; - MemoryProfileDescriptor->Address = mFullSmramRanges[Index].PhysicalStart; - MemoryProfileDescriptor->Size = mFullSmramRanges[Index].PhysicalSize; - - RemainingSize -= sizeof (MEMORY_PROFILE_DESCRIPTOR); - ProfileBuffer = (UINT8 *) ProfileBuffer + sizeof (MEMORY_PROFILE_DESCRIPTOR); - } else { - goto Done; - } - } - Offset += sizeof (MEMORY_PROFILE_DESCRIPTOR); - } - -Done: - // - // On output, actual profile data size copied. - // - *ProfileSize -= RemainingSize; - // - // On output, next time profile buffer offset to copy. - // - *ProfileOffset = Offset; -} - -/** - Get memory profile data. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in, out] ProfileSize On entry, points to the size in bytes of the ProfileBuffer. - On return, points to the size of the data returned in ProfileBuffer. - @param[out] ProfileBuffer Profile buffer. - - @return EFI_SUCCESS Get the memory profile data successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_BUFFER_TO_SMALL The ProfileSize is too small for the resulting data. - ProfileSize is updated with the size required. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolGetData ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN OUT UINT64 *ProfileSize, - OUT VOID *ProfileBuffer - ) -{ - UINT64 Size; - UINT64 Offset; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - BOOLEAN SmramProfileGettingStatus; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - SmramProfileGettingStatus = mSmramProfileGettingStatus; - mSmramProfileGettingStatus = TRUE; - - Size = SmramProfileGetDataSize (); - - if (*ProfileSize < Size) { - *ProfileSize = Size; - mSmramProfileGettingStatus = SmramProfileGettingStatus; - return EFI_BUFFER_TOO_SMALL; - } - - Offset = 0; - SmramProfileCopyData (ProfileBuffer, &Size, &Offset); - *ProfileSize = Size; - - mSmramProfileGettingStatus = SmramProfileGettingStatus; - return EFI_SUCCESS; -} - -/** - Register image to memory profile. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in] FilePath File path of the image. - @param[in] ImageBase Image base address. - @param[in] ImageSize Image size. - @param[in] FileType File type of the image. - - @return EFI_SUCCESS Register successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_OUT_OF_RESOURCES No enough resource for this register. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolRegisterImage ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize, - IN EFI_FV_FILETYPE FileType - ) -{ - EFI_STATUS Status; - EFI_SMM_DRIVER_ENTRY DriverEntry; - VOID *EntryPointInImage; - EFI_GUID *Name; - - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - Name = GetFileNameFromFilePath (FilePath); - if (Name != NULL) { - CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID)); - } - DriverEntry.ImageBuffer = ImageBase; - DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN) ImageSize); - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage; - - return RegisterSmramProfileImage (&DriverEntry, FALSE); -} - -/** - Unregister image from memory profile. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in] FilePath File path of the image. - @param[in] ImageBase Image base address. - @param[in] ImageSize Image size. - - @return EFI_SUCCESS Unregister successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required. - @return EFI_NOT_FOUND The image is not found. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolUnregisterImage ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN PHYSICAL_ADDRESS ImageBase, - IN UINT64 ImageSize - ) -{ - EFI_STATUS Status; - EFI_SMM_DRIVER_ENTRY DriverEntry; - VOID *EntryPointInImage; - EFI_GUID *Name; - - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - Name = GetFileNameFromFilePath (FilePath); - if (Name != NULL) { - CopyMem (&DriverEntry.FileName, Name, sizeof (EFI_GUID)); - } - DriverEntry.ImageBuffer = ImageBase; - DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN) ImageSize); - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage; - - return UnregisterSmramProfileImage (&DriverEntry, FALSE); -} - -/** - Get memory profile recording state. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[out] RecordingState Recording state. - - @return EFI_SUCCESS Memory profile recording state is returned. - @return EFI_UNSUPPORTED Memory profile is unsupported. - @return EFI_INVALID_PARAMETER RecordingState is NULL. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolGetRecordingState ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - OUT BOOLEAN *RecordingState - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - if (RecordingState == NULL) { - return EFI_INVALID_PARAMETER; - } - *RecordingState = mSmramProfileRecordingEnable; - return EFI_SUCCESS; -} - -/** - Set memory profile recording state. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in] RecordingState Recording state. - - @return EFI_SUCCESS Set memory profile recording state successfully. - @return EFI_UNSUPPORTED Memory profile is unsupported. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolSetRecordingState ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN BOOLEAN RecordingState - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return EFI_UNSUPPORTED; - } - - mSmramProfileRecordingEnable = RecordingState; - return EFI_SUCCESS; -} - -/** - Record memory profile of multilevel caller. - - @param[in] This The EDKII_SMM_MEMORY_PROFILE_PROTOCOL instance. - @param[in] CallerAddress Address of caller. - @param[in] Action Memory profile action. - @param[in] MemoryType Memory type. - EfiMaxMemoryType means the MemoryType is unknown. - @param[in] Buffer Buffer address. - @param[in] Size Buffer size. - @param[in] ActionString String for memory profile action. - Only needed for user defined allocate action. - - @return EFI_SUCCESS Memory profile is updated. - @return EFI_UNSUPPORTED Memory profile is unsupported, - or memory profile for the image is not required, - or memory profile for the memory type is not required. - @return EFI_ACCESS_DENIED It is during memory profile data getting. - @return EFI_ABORTED Memory profile recording is not enabled. - @return EFI_OUT_OF_RESOURCES No enough resource to update memory profile for allocate action. - @return EFI_NOT_FOUND No matched allocate info found for free action. - -**/ -EFI_STATUS -EFIAPI -SmramProfileProtocolRecord ( - IN EDKII_SMM_MEMORY_PROFILE_PROTOCOL *This, - IN PHYSICAL_ADDRESS CallerAddress, - IN MEMORY_PROFILE_ACTION Action, - IN EFI_MEMORY_TYPE MemoryType, - IN VOID *Buffer, - IN UINTN Size, - IN CHAR8 *ActionString OPTIONAL - ) -{ - return SmmCoreUpdateProfile (CallerAddress, Action, MemoryType, Size, Buffer, ActionString); -} - -/** - SMRAM profile handler to get profile info. - - @param SmramProfileParameterGetInfo The parameter of SMM profile get size. - -**/ -VOID -SmramProfileHandlerGetInfo ( - IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *SmramProfileParameterGetInfo - ) -{ - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - BOOLEAN SmramProfileGettingStatus; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return ; - } - - SmramProfileGettingStatus = mSmramProfileGettingStatus; - mSmramProfileGettingStatus = TRUE; - - SmramProfileParameterGetInfo->ProfileSize = SmramProfileGetDataSize(); - SmramProfileParameterGetInfo->Header.ReturnStatus = 0; - - mSmramProfileGettingStatus = SmramProfileGettingStatus; -} - -/** - SMRAM profile handler to get profile data. - - @param SmramProfileParameterGetData The parameter of SMM profile get data. - -**/ -VOID -SmramProfileHandlerGetData ( - IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *SmramProfileParameterGetData - ) -{ - UINT64 ProfileSize; - UINT64 ProfileOffset; - SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA SmramProfileGetData; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - BOOLEAN SmramProfileGettingStatus; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return ; - } - - SmramProfileGettingStatus = mSmramProfileGettingStatus; - mSmramProfileGettingStatus = TRUE; - - - CopyMem (&SmramProfileGetData, SmramProfileParameterGetData, sizeof (SmramProfileGetData)); - - ProfileSize = SmramProfileGetDataSize(); - - // - // Sanity check - // - if (!SmmIsBufferOutsideSmmValid ((UINTN) SmramProfileGetData.ProfileBuffer, (UINTN) ProfileSize)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetData: SMM ProfileBuffer in SMRAM or overflow!\n")); - SmramProfileParameterGetData->ProfileSize = ProfileSize; - SmramProfileParameterGetData->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_ACCESS_DENIED; - goto Done; - } - - if (SmramProfileGetData.ProfileSize < ProfileSize) { - SmramProfileParameterGetData->ProfileSize = ProfileSize; - SmramProfileParameterGetData->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_BUFFER_TOO_SMALL; - goto Done; - } - - ProfileOffset = 0; - SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetData.ProfileBuffer, &ProfileSize, &ProfileOffset); - SmramProfileParameterGetData->ProfileSize = ProfileSize; - SmramProfileParameterGetData->Header.ReturnStatus = 0; - -Done: - mSmramProfileGettingStatus = SmramProfileGettingStatus; -} - -/** - SMRAM profile handler to get profile data by offset. - - @param SmramProfileParameterGetDataByOffset The parameter of SMM profile get data by offset. - -**/ -VOID -SmramProfileHandlerGetDataByOffset ( - IN SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *SmramProfileParameterGetDataByOffset - ) -{ - SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET SmramProfileGetDataByOffset; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - BOOLEAN SmramProfileGettingStatus; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return ; - } - - SmramProfileGettingStatus = mSmramProfileGettingStatus; - mSmramProfileGettingStatus = TRUE; - - - CopyMem (&SmramProfileGetDataByOffset, SmramProfileParameterGetDataByOffset, sizeof (SmramProfileGetDataByOffset)); - - // - // Sanity check - // - if (!SmmIsBufferOutsideSmmValid ((UINTN) SmramProfileGetDataByOffset.ProfileBuffer, (UINTN) SmramProfileGetDataByOffset.ProfileSize)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetDataByOffset: SMM ProfileBuffer in SMRAM or overflow!\n")); - SmramProfileParameterGetDataByOffset->Header.ReturnStatus = (UINT64) (INT64) (INTN) EFI_ACCESS_DENIED; - goto Done; - } - - SmramProfileCopyData ((VOID *) (UINTN) SmramProfileGetDataByOffset.ProfileBuffer, &SmramProfileGetDataByOffset.ProfileSize, &SmramProfileGetDataByOffset.ProfileOffset); - CopyMem (SmramProfileParameterGetDataByOffset, &SmramProfileGetDataByOffset, sizeof (SmramProfileGetDataByOffset)); - SmramProfileParameterGetDataByOffset->Header.ReturnStatus = 0; - -Done: - mSmramProfileGettingStatus = SmramProfileGettingStatus; -} - -/** - SMRAM profile handler to register SMM image. - - @param SmramProfileParameterRegisterImage The parameter of SMM profile register image. - -**/ -VOID -SmramProfileHandlerRegisterImage ( - IN SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *SmramProfileParameterRegisterImage - ) -{ - EFI_STATUS Status; - EFI_SMM_DRIVER_ENTRY DriverEntry; - VOID *EntryPointInImage; - - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - CopyMem (&DriverEntry.FileName, &SmramProfileParameterRegisterImage->FileName, sizeof(EFI_GUID)); - DriverEntry.ImageBuffer = SmramProfileParameterRegisterImage->ImageBuffer; - DriverEntry.NumberOfPage = (UINTN) SmramProfileParameterRegisterImage->NumberOfPage; - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage; - - Status = RegisterSmramProfileImage (&DriverEntry, FALSE); - if (!EFI_ERROR (Status)) { - SmramProfileParameterRegisterImage->Header.ReturnStatus = 0; - } -} - -/** - SMRAM profile handler to unregister SMM image. - - @param SmramProfileParameterUnregisterImage The parameter of SMM profile unregister image. - -**/ -VOID -SmramProfileHandlerUnregisterImage ( - IN SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *SmramProfileParameterUnregisterImage - ) -{ - EFI_STATUS Status; - EFI_SMM_DRIVER_ENTRY DriverEntry; - VOID *EntryPointInImage; - - ZeroMem (&DriverEntry, sizeof (DriverEntry)); - CopyMem (&DriverEntry.FileName, &SmramProfileParameterUnregisterImage->FileName, sizeof (EFI_GUID)); - DriverEntry.ImageBuffer = SmramProfileParameterUnregisterImage->ImageBuffer; - DriverEntry.NumberOfPage = (UINTN) SmramProfileParameterUnregisterImage->NumberOfPage; - Status = InternalPeCoffGetEntryPoint ((VOID *) (UINTN) DriverEntry.ImageBuffer, &EntryPointInImage); - ASSERT_EFI_ERROR (Status); - DriverEntry.ImageEntryPoint = (PHYSICAL_ADDRESS) (UINTN) EntryPointInImage; - - Status = UnregisterSmramProfileImage (&DriverEntry, FALSE); - if (!EFI_ERROR (Status)) { - SmramProfileParameterUnregisterImage->Header.ReturnStatus = 0; - } -} - -/** - Dispatch function for a Software SMI handler. - - Caution: This function may receive untrusted input. - Communicate buffer and buffer size are external input, so this function will do basic validation. - - @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister(). - @param Context Points to an optional handler context which was specified when the - handler was registered. - @param CommBuffer A pointer to a collection of data in memory that will - be conveyed from a non-SMM environment into an SMM environment. - @param CommBufferSize The size of the CommBuffer. - - @retval EFI_SUCCESS Command is handled successfully. - -**/ -EFI_STATUS -EFIAPI -SmramProfileHandler ( - IN EFI_HANDLE DispatchHandle, - IN CONST VOID *Context OPTIONAL, - IN OUT VOID *CommBuffer OPTIONAL, - IN OUT UINTN *CommBufferSize OPTIONAL - ) -{ - SMRAM_PROFILE_PARAMETER_HEADER *SmramProfileParameterHeader; - UINTN TempCommBufferSize; - SMRAM_PROFILE_PARAMETER_RECORDING_STATE *ParameterRecordingState; - - DEBUG ((EFI_D_ERROR, "SmramProfileHandler Enter\n")); - - // - // If input is invalid, stop processing this SMI - // - if (CommBuffer == NULL || CommBufferSize == NULL) { - return EFI_SUCCESS; - } - - TempCommBufferSize = *CommBufferSize; - - if (TempCommBufferSize < sizeof (SMRAM_PROFILE_PARAMETER_HEADER)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - - if (mSmramReadyToLock && !SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer in SMRAM or overflow!\n")); - return EFI_SUCCESS; - } - - SmramProfileParameterHeader = (SMRAM_PROFILE_PARAMETER_HEADER *) ((UINTN) CommBuffer); - - SmramProfileParameterHeader->ReturnStatus = (UINT64)-1; - - if (GetSmramProfileContext () == NULL) { - SmramProfileParameterHeader->ReturnStatus = (UINT64) (INT64) (INTN) EFI_UNSUPPORTED; - return EFI_SUCCESS; - } - - switch (SmramProfileParameterHeader->Command) { - case SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO: - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetInfo\n")); - if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - SmramProfileHandlerGetInfo ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *) (UINTN) CommBuffer); - break; - case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA: - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetData\n")); - if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - SmramProfileHandlerGetData ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) (UINTN) CommBuffer); - break; - case SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET: - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetDataByOffset\n")); - if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - SmramProfileHandlerGetDataByOffset ((SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) (UINTN) CommBuffer); - break; - case SMRAM_PROFILE_COMMAND_REGISTER_IMAGE: - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerRegisterImage\n")); - if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - if (mSmramReadyToLock) { - return EFI_SUCCESS; - } - SmramProfileHandlerRegisterImage ((SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *) (UINTN) CommBuffer); - break; - case SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE: - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerUnregisterImage\n")); - if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - if (mSmramReadyToLock) { - return EFI_SUCCESS; - } - SmramProfileHandlerUnregisterImage ((SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *) (UINTN) CommBuffer); - break; - case SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE: - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerGetRecordingState\n")); - if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - ParameterRecordingState = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *) (UINTN) CommBuffer; - ParameterRecordingState->RecordingState = mSmramProfileRecordingEnable; - ParameterRecordingState->Header.ReturnStatus = 0; - break; - case SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE: - DEBUG ((EFI_D_ERROR, "SmramProfileHandlerSetRecordingState\n")); - if (TempCommBufferSize != sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE)) { - DEBUG ((EFI_D_ERROR, "SmramProfileHandler: SMM communication buffer size invalid!\n")); - return EFI_SUCCESS; - } - ParameterRecordingState = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *) (UINTN) CommBuffer; - mSmramProfileRecordingEnable = ParameterRecordingState->RecordingState; - ParameterRecordingState->Header.ReturnStatus = 0; - break; - - default: - break; - } - - DEBUG ((EFI_D_ERROR, "SmramProfileHandler Exit\n")); - - return EFI_SUCCESS; -} - -/** - Register SMRAM profile handler. - -**/ -VOID -RegisterSmramProfileHandler ( - VOID - ) -{ - EFI_STATUS Status; - EFI_HANDLE DispatchHandle; - - if (!IS_SMRAM_PROFILE_ENABLED) { - return; - } - - Status = SmiHandlerRegister ( - SmramProfileHandler, - &gEdkiiMemoryProfileGuid, - &DispatchHandle - ); - ASSERT_EFI_ERROR (Status); -} - -//////////////////// - -/** - Dump SMRAM range. - -**/ -VOID -DumpSmramRange ( - VOID - ) -{ - UINTN Index; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - BOOLEAN SmramProfileGettingStatus; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return ; - } - - SmramProfileGettingStatus = mSmramProfileGettingStatus; - mSmramProfileGettingStatus = TRUE; - - DEBUG ((EFI_D_INFO, "FullSmramRange address - 0x%08x\n", mFullSmramRanges)); - - DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n")); - - DEBUG ((EFI_D_INFO, "FullSmramRange:\n")); - for (Index = 0; Index < mFullSmramRangeCount; Index++) { - DEBUG ((EFI_D_INFO, " FullSmramRange (0x%x)\n", Index)); - DEBUG ((EFI_D_INFO, " PhysicalStart - 0x%016lx\n", mFullSmramRanges[Index].PhysicalStart)); - DEBUG ((EFI_D_INFO, " CpuStart - 0x%016lx\n", mFullSmramRanges[Index].CpuStart)); - DEBUG ((EFI_D_INFO, " PhysicalSize - 0x%016lx\n", mFullSmramRanges[Index].PhysicalSize)); - DEBUG ((EFI_D_INFO, " RegionState - 0x%016lx\n", mFullSmramRanges[Index].RegionState)); - } - - DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n")); - - mSmramProfileGettingStatus = SmramProfileGettingStatus; -} - -/** - Dump SMRAM free page list. - -**/ -VOID -DumpFreePagesList ( - VOID - ) -{ - LIST_ENTRY *FreePageList; - LIST_ENTRY *Node; - FREE_PAGE_LIST *Pages; - UINTN Index; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - BOOLEAN SmramProfileGettingStatus; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return ; - } - - SmramProfileGettingStatus = mSmramProfileGettingStatus; - mSmramProfileGettingStatus = TRUE; - - DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n")); - - DEBUG ((EFI_D_INFO, "FreePagesList:\n")); - FreePageList = &mSmmMemoryMap; - for (Node = FreePageList->BackLink, Index = 0; - Node != FreePageList; - Node = Node->BackLink, Index++) { - Pages = BASE_CR (Node, FREE_PAGE_LIST, Link); - DEBUG ((EFI_D_INFO, " Index - 0x%x\n", Index)); - DEBUG ((EFI_D_INFO, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS) (UINTN) Pages)); - DEBUG ((EFI_D_INFO, " NumberOfPages - 0x%08x\n", Pages->NumberOfPages)); - } - - DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n")); - - mSmramProfileGettingStatus = SmramProfileGettingStatus; -} - -/** - Dump SMRAM free pool list. - -**/ -VOID -DumpFreePoolList ( - VOID - ) -{ - LIST_ENTRY *FreePoolList; - LIST_ENTRY *Node; - FREE_POOL_HEADER *Pool; - UINTN Index; - UINTN PoolListIndex; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - BOOLEAN SmramProfileGettingStatus; - UINTN SmmPoolTypeIndex; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return ; - } - - SmramProfileGettingStatus = mSmramProfileGettingStatus; - mSmramProfileGettingStatus = TRUE; - - DEBUG ((DEBUG_INFO, "======= SmramProfile begin =======\n")); - - for (SmmPoolTypeIndex = 0; SmmPoolTypeIndex < SmmPoolTypeMax; SmmPoolTypeIndex++) { - for (PoolListIndex = 0; PoolListIndex < MAX_POOL_INDEX; PoolListIndex++) { - DEBUG ((DEBUG_INFO, "FreePoolList(%d)(%d):\n", SmmPoolTypeIndex, PoolListIndex)); - FreePoolList = &mSmmPoolLists[SmmPoolTypeIndex][PoolListIndex]; - for (Node = FreePoolList->BackLink, Index = 0; - Node != FreePoolList; - Node = Node->BackLink, Index++) { - Pool = BASE_CR (Node, FREE_POOL_HEADER, Link); - DEBUG ((DEBUG_INFO, " Index - 0x%x\n", Index)); - DEBUG ((DEBUG_INFO, " PhysicalStart - 0x%016lx\n", (PHYSICAL_ADDRESS) (UINTN) Pool)); - DEBUG ((DEBUG_INFO, " Size - 0x%08x\n", Pool->Header.Size)); - DEBUG ((DEBUG_INFO, " Available - 0x%02x\n", Pool->Header.Available)); - } - } - } - - DEBUG ((DEBUG_INFO, "======= SmramProfile end =======\n")); - - mSmramProfileGettingStatus = SmramProfileGettingStatus; -} - -GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *mSmmActionString[] = { - "SmmUnknown", - "gSmst->SmmAllocatePages", - "gSmst->SmmFreePages", - "gSmst->SmmAllocatePool", - "gSmst->SmmFreePool", -}; - -typedef struct { - MEMORY_PROFILE_ACTION Action; - CHAR8 *String; -} ACTION_STRING; - -GLOBAL_REMOVE_IF_UNREFERENCED ACTION_STRING mExtActionString[] = { - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES, "Lib:AllocatePages"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES, "Lib:AllocateRuntimePages"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES, "Lib:AllocateReservedPages"}, - {MEMORY_PROFILE_ACTION_LIB_FREE_PAGES, "Lib:FreePages"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES, "Lib:AllocateAlignedPages"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES, "Lib:AllocateAlignedRuntimePages"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, "Lib:AllocateAlignedReservedPages"}, - {MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES, "Lib:FreeAlignedPages"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL, "Lib:AllocatePool"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL, "Lib:AllocateRuntimePool"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL, "Lib:AllocateReservedPool"}, - {MEMORY_PROFILE_ACTION_LIB_FREE_POOL, "Lib:FreePool"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL, "Lib:AllocateZeroPool"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL, "Lib:AllocateRuntimeZeroPool"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL, "Lib:AllocateReservedZeroPool"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL, "Lib:AllocateCopyPool"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL, "Lib:AllocateRuntimeCopyPool"}, - {MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL, "Lib:AllocateReservedCopyPool"}, - {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL, "Lib:ReallocatePool"}, - {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL, "Lib:ReallocateRuntimePool"}, - {MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL, "Lib:ReallocateReservedPool"}, -}; - -typedef struct { - EFI_MEMORY_TYPE MemoryType; - CHAR8 *MemoryTypeStr; -} PROFILE_MEMORY_TYPE_STRING; - -GLOBAL_REMOVE_IF_UNREFERENCED PROFILE_MEMORY_TYPE_STRING mMemoryTypeString[] = { - {EfiRuntimeServicesCode, "EfiRuntimeServicesCode"}, - {EfiRuntimeServicesData, "EfiRuntimeServicesData"} -}; - -/** - Memory type to string. - - @param[in] MemoryType Memory type. - - @return Pointer to string. - -**/ -CHAR8 * -ProfileMemoryTypeToStr ( - IN EFI_MEMORY_TYPE MemoryType - ) -{ - UINTN Index; - for (Index = 0; Index < ARRAY_SIZE (mMemoryTypeString); Index++) { - if (mMemoryTypeString[Index].MemoryType == MemoryType) { - return mMemoryTypeString[Index].MemoryTypeStr; - } - } - - return "UnexpectedMemoryType"; -} - -/** - Action to string. - - @param[in] Action Profile action. - - @return Pointer to string. - -**/ -CHAR8 * -ProfileActionToStr ( - IN MEMORY_PROFILE_ACTION Action - ) -{ - UINTN Index; - UINTN ActionStringCount; - CHAR8 **ActionString; - - ActionString = mSmmActionString; - ActionStringCount = ARRAY_SIZE (mSmmActionString); - - if ((UINTN) (UINT32) Action < ActionStringCount) { - return ActionString[Action]; - } - for (Index = 0; Index < ARRAY_SIZE (mExtActionString); Index++) { - if (mExtActionString[Index].Action == Action) { - return mExtActionString[Index].String; - } - } - - return ActionString[0]; -} - -/** - Dump SMRAM profile. - -**/ -VOID -DumpSmramProfile ( - VOID - ) -{ - MEMORY_PROFILE_CONTEXT *Context; - MEMORY_PROFILE_DRIVER_INFO *DriverInfo; - MEMORY_PROFILE_ALLOC_INFO *AllocInfo; - MEMORY_PROFILE_CONTEXT_DATA *ContextData; - MEMORY_PROFILE_DRIVER_INFO_DATA *DriverInfoData; - MEMORY_PROFILE_ALLOC_INFO_DATA *AllocInfoData; - LIST_ENTRY *SmramDriverInfoList; - UINTN DriverIndex; - LIST_ENTRY *DriverLink; - LIST_ENTRY *AllocInfoList; - UINTN AllocIndex; - LIST_ENTRY *AllocLink; - BOOLEAN SmramProfileGettingStatus; - UINTN TypeIndex; - - ContextData = GetSmramProfileContext (); - if (ContextData == NULL) { - return ; - } - - SmramProfileGettingStatus = mSmramProfileGettingStatus; - mSmramProfileGettingStatus = TRUE; - - Context = &ContextData->Context; - DEBUG ((EFI_D_INFO, "======= SmramProfile begin =======\n")); - DEBUG ((EFI_D_INFO, "MEMORY_PROFILE_CONTEXT\n")); - - DEBUG ((EFI_D_INFO, " CurrentTotalUsage - 0x%016lx\n", Context->CurrentTotalUsage)); - DEBUG ((EFI_D_INFO, " PeakTotalUsage - 0x%016lx\n", Context->PeakTotalUsage)); - for (TypeIndex = 0; TypeIndex < sizeof (Context->CurrentTotalUsageByType) / sizeof (Context->CurrentTotalUsageByType[0]); TypeIndex++) { - if ((Context->CurrentTotalUsageByType[TypeIndex] != 0) || - (Context->PeakTotalUsageByType[TypeIndex] != 0)) { - DEBUG ((EFI_D_INFO, " CurrentTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, Context->CurrentTotalUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex))); - DEBUG ((EFI_D_INFO, " PeakTotalUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, Context->PeakTotalUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex))); - } - } - DEBUG ((EFI_D_INFO, " TotalImageSize - 0x%016lx\n", Context->TotalImageSize)); - DEBUG ((EFI_D_INFO, " ImageCount - 0x%08x\n", Context->ImageCount)); - DEBUG ((EFI_D_INFO, " SequenceCount - 0x%08x\n", Context->SequenceCount)); - - SmramDriverInfoList = ContextData->DriverInfoList; - for (DriverLink = SmramDriverInfoList->ForwardLink, DriverIndex = 0; - DriverLink != SmramDriverInfoList; - DriverLink = DriverLink->ForwardLink, DriverIndex++) { - DriverInfoData = CR ( - DriverLink, - MEMORY_PROFILE_DRIVER_INFO_DATA, - Link, - MEMORY_PROFILE_DRIVER_INFO_SIGNATURE - ); - DriverInfo = &DriverInfoData->DriverInfo; - DEBUG ((EFI_D_INFO, " MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex)); - DEBUG ((EFI_D_INFO, " FileName - %g\n", &DriverInfo->FileName)); - DEBUG ((EFI_D_INFO, " ImageBase - 0x%016lx\n", DriverInfo->ImageBase)); - DEBUG ((EFI_D_INFO, " ImageSize - 0x%016lx\n", DriverInfo->ImageSize)); - DEBUG ((EFI_D_INFO, " EntryPoint - 0x%016lx\n", DriverInfo->EntryPoint)); - DEBUG ((EFI_D_INFO, " ImageSubsystem - 0x%04x\n", DriverInfo->ImageSubsystem)); - DEBUG ((EFI_D_INFO, " FileType - 0x%02x\n", DriverInfo->FileType)); - DEBUG ((EFI_D_INFO, " CurrentUsage - 0x%016lx\n", DriverInfo->CurrentUsage)); - DEBUG ((EFI_D_INFO, " PeakUsage - 0x%016lx\n", DriverInfo->PeakUsage)); - for (TypeIndex = 0; TypeIndex < sizeof (DriverInfo->CurrentUsageByType) / sizeof (DriverInfo->CurrentUsageByType[0]); TypeIndex++) { - if ((DriverInfo->CurrentUsageByType[TypeIndex] != 0) || - (DriverInfo->PeakUsageByType[TypeIndex] != 0)) { - DEBUG ((EFI_D_INFO, " CurrentUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, DriverInfo->CurrentUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex))); - DEBUG ((EFI_D_INFO, " PeakUsage[0x%02x] - 0x%016lx (%a)\n", TypeIndex, DriverInfo->PeakUsageByType[TypeIndex], ProfileMemoryTypeToStr (TypeIndex))); - } - } - DEBUG ((EFI_D_INFO, " AllocRecordCount - 0x%08x\n", DriverInfo->AllocRecordCount)); - - AllocInfoList = DriverInfoData->AllocInfoList; - for (AllocLink = AllocInfoList->ForwardLink, AllocIndex = 0; - AllocLink != AllocInfoList; - AllocLink = AllocLink->ForwardLink, AllocIndex++) { - AllocInfoData = CR ( - AllocLink, - MEMORY_PROFILE_ALLOC_INFO_DATA, - Link, - MEMORY_PROFILE_ALLOC_INFO_SIGNATURE - ); - AllocInfo = &AllocInfoData->AllocInfo; - DEBUG ((EFI_D_INFO, " MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex)); - DEBUG ((EFI_D_INFO, " CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo->CallerAddress, AllocInfo->CallerAddress - DriverInfo->ImageBase)); - DEBUG ((EFI_D_INFO, " SequenceId - 0x%08x\n", AllocInfo->SequenceId)); - if ((AllocInfo->Action & MEMORY_PROFILE_ACTION_USER_DEFINED_MASK) != 0) { - if (AllocInfoData->ActionString != NULL) { - DEBUG ((EFI_D_INFO, " Action - 0x%08x (%a)\n", AllocInfo->Action, AllocInfoData->ActionString)); - } else { - DEBUG ((EFI_D_INFO, " Action - 0x%08x (UserDefined-0x%08x)\n", AllocInfo->Action, AllocInfo->Action)); - } - } else { - DEBUG ((EFI_D_INFO, " Action - 0x%08x (%a)\n", AllocInfo->Action, ProfileActionToStr (AllocInfo->Action))); - } - DEBUG ((EFI_D_INFO, " MemoryType - 0x%08x (%a)\n", AllocInfo->MemoryType, ProfileMemoryTypeToStr (AllocInfo->MemoryType))); - DEBUG ((EFI_D_INFO, " Buffer - 0x%016lx\n", AllocInfo->Buffer)); - DEBUG ((EFI_D_INFO, " Size - 0x%016lx\n", AllocInfo->Size)); - } - } - - DEBUG ((EFI_D_INFO, "======= SmramProfile end =======\n")); - - mSmramProfileGettingStatus = SmramProfileGettingStatus; -} - -/** - Dump SMRAM infromation. - -**/ -VOID -DumpSmramInfo ( - VOID - ) -{ - DEBUG_CODE ( - if (IS_SMRAM_PROFILE_ENABLED) { - DumpSmramProfile (); - DumpFreePagesList (); - DumpFreePoolList (); - DumpSmramRange (); - } - ); -} - diff --git a/MdeModulePkg/Core/RuntimeDxe/Crc32.c b/MdeModulePkg/Core/RuntimeDxe/Crc32.c deleted file mode 100644 index a6fe77fa34..0000000000 --- a/MdeModulePkg/Core/RuntimeDxe/Crc32.c +++ /dev/null @@ -1,115 +0,0 @@ -/** @file - This file implements CalculateCrc32 Boot Services as defined in - Platform Initialization specification 1.0 VOLUME 2 DXE Core Interface. - - This Boot Services is in the Runtime Driver because this service is - also required by SetVirtualAddressMap() when the EFI System Table and - EFI Runtime Services Table are converted from physical address to - virtual addresses. This requires that the 32-bit CRC be recomputed. - -Copyright (c) 2006 - 2008, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - - -#include - -UINT32 mCrcTable[256]; - -/** - Calculate CRC32 for target data. - - @param Data The target data. - @param DataSize The target data size. - @param CrcOut The CRC32 for target data. - - @retval EFI_SUCCESS The CRC32 for target data is calculated successfully. - @retval EFI_INVALID_PARAMETER Some parameter is not valid, so the CRC32 is not - calculated. - -**/ -EFI_STATUS -EFIAPI -RuntimeDriverCalculateCrc32 ( - IN VOID *Data, - IN UINTN DataSize, - OUT UINT32 *CrcOut - ) -{ - UINT32 Crc; - UINTN Index; - UINT8 *Ptr; - - if (Data == NULL || DataSize == 0 || CrcOut == NULL) { - return EFI_INVALID_PARAMETER; - } - - Crc = 0xffffffff; - for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) { - Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr]; - } - - *CrcOut = Crc ^ 0xffffffff; - return EFI_SUCCESS; -} - - -/** - This internal function reverses bits for 32bit data. - - @param Value The data to be reversed. - - @return Data reversed. - -**/ -UINT32 -ReverseBits ( - UINT32 Value - ) -{ - UINTN Index; - UINT32 NewValue; - - NewValue = 0; - for (Index = 0; Index < 32; Index++) { - if ((Value & (1 << Index)) != 0) { - NewValue = NewValue | (1 << (31 - Index)); - } - } - - return NewValue; -} - -/** - Initialize CRC32 table. - -**/ -VOID -RuntimeDriverInitializeCrc32Table ( - VOID - ) -{ - UINTN TableEntry; - UINTN Index; - UINT32 Value; - - for (TableEntry = 0; TableEntry < 256; TableEntry++) { - Value = ReverseBits ((UINT32) TableEntry); - for (Index = 0; Index < 8; Index++) { - if ((Value & 0x80000000) != 0) { - Value = (Value << 1) ^ 0x04c11db7; - } else { - Value = Value << 1; - } - } - - mCrcTable[TableEntry] = ReverseBits (Value); - } -} diff --git a/MdeModulePkg/Core/RuntimeDxe/Runtime.c b/MdeModulePkg/Core/RuntimeDxe/Runtime.c deleted file mode 100644 index c61301cf80..0000000000 --- a/MdeModulePkg/Core/RuntimeDxe/Runtime.c +++ /dev/null @@ -1,427 +0,0 @@ -/** @file - This file implements Runtime Architectural Protocol as defined in the - Platform Initialization specification 1.0 VOLUME 2 DXE Core Interface. - - This code is used to produce the EFI runtime virtual switch over - - THIS IS VERY DANGEROUS CODE BE VERY CAREFUL IF YOU CHANGE IT - - The transition for calling EFI Runtime functions in physical mode to calling - them in virtual mode is very very complex. Every pointer in needs to be - converted from physical mode to virtual mode. Be very careful walking linked - lists! Then to make it really hard the code it's self needs be relocated into - the new virtual address space. - - So here is the concept. The code in this module will never ever be called in - virtual mode. This is the code that collects the information needed to convert - to virtual mode (DXE core registers runtime stuff with this code). Since this - code is used to fix up all runtime images, it CAN NOT fix it's self up. So some - code has to stay behind and that is us. - - Also you need to be careful about when you allocate memory, as once we are in - runtime (including our EVT_SIGNAL_EXIT_BOOT_SERVICES event) you can no longer - allocate memory. - - Any runtime driver that gets loaded before us will not be callable in virtual - mode. This is due to the fact that the DXE core can not register the info - needed with us. This is good, since it keeps the code in this file from - getting registered. - - -Revision History: - - - Move the CalculateCrc32 function from Runtime Arch Protocol to Boot Service. - Runtime Arch Protocol definition no longer contains CalculateCrc32. Boot Service - Table now contains an item named CalculateCrc32. - - -Copyright (c) 2006 - 2015, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Runtime.h" - -// -// Global Variables -// -EFI_MEMORY_DESCRIPTOR *mVirtualMap = NULL; -UINTN mVirtualMapDescriptorSize; -UINTN mVirtualMapMaxIndex; -VOID *mMyImageBase; - -// -// The handle onto which the Runtime Architectural Protocol instance is installed -// -EFI_HANDLE mRuntimeHandle = NULL; - -// -// The Runtime Architectural Protocol instance produced by this driver -// -EFI_RUNTIME_ARCH_PROTOCOL mRuntime = { - INITIALIZE_LIST_HEAD_VARIABLE (mRuntime.ImageHead), - INITIALIZE_LIST_HEAD_VARIABLE (mRuntime.EventHead), - - // - // Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will - // prevent people from having pointer math bugs in their code. - // now you have to use *DescriptorSize to make things work. - // - sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)), - EFI_MEMORY_DESCRIPTOR_VERSION, - 0, - NULL, - NULL, - FALSE, - FALSE -}; - -// -// Worker Functions -// -/** - - Calculate the 32-bit CRC in a EFI table using the Runtime Drivers - internal function. The EFI Boot Services Table can not be used because - the EFI Boot Services Table was destroyed at ExitBootServices(). - This is a internal function. - - - @param Hdr Pointer to an EFI standard header - -**/ -VOID -RuntimeDriverCalculateEfiHdrCrc ( - IN OUT EFI_TABLE_HEADER *Hdr - ) -{ - UINT32 Crc; - - Hdr->CRC32 = 0; - - Crc = 0; - RuntimeDriverCalculateCrc32 ((UINT8 *) Hdr, Hdr->HeaderSize, &Crc); - Hdr->CRC32 = Crc; -} - -/** - - Determines the new virtual address that is to be used on subsequent memory accesses. - - - @param DebugDisposition Supplies type information for the pointer being converted. - @param ConvertAddress A pointer to a pointer that is to be fixed to be the value needed - for the new virtual address mappings being applied. - - @retval EFI_SUCCESS The pointer pointed to by Address was modified. - @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part - of the current memory map. This is normally fatal. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -RuntimeDriverConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **ConvertAddress - ) -{ - UINTN Address; - UINT64 VirtEndOfRange; - EFI_MEMORY_DESCRIPTOR *VirtEntry; - UINTN Index; - - // - // Make sure ConvertAddress is a valid pointer - // - if (ConvertAddress == NULL) { - return EFI_INVALID_PARAMETER; - } - // - // Get the address to convert - // - Address = (UINTN) *ConvertAddress; - - // - // If this is a null pointer, return if it's allowed - // - if (Address == 0) { - if ((DebugDisposition & EFI_OPTIONAL_PTR) != 0) { - return EFI_SUCCESS; - } - - return EFI_INVALID_PARAMETER; - } - - VirtEntry = mVirtualMap; - for (Index = 0; Index < mVirtualMapMaxIndex; Index++) { - // - // To prevent the inclusion of 64-bit math functions a UINTN was placed in - // front of VirtEntry->NumberOfPages to cast it to a 32-bit thing on IA-32 - // platforms. If you get this ASSERT remove the UINTN and do a 64-bit - // multiply. - // - ASSERT (((UINTN) VirtEntry->NumberOfPages < 0xffffffff) || (sizeof (UINTN) > 4)); - - if ((VirtEntry->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) { - if (Address >= VirtEntry->PhysicalStart) { - VirtEndOfRange = VirtEntry->PhysicalStart + (((UINTN) VirtEntry->NumberOfPages) * EFI_PAGE_SIZE); - if (Address < VirtEndOfRange) { - // - // Compute new address - // - *ConvertAddress = (VOID *) (Address - (UINTN) VirtEntry->PhysicalStart + (UINTN) VirtEntry->VirtualStart); - return EFI_SUCCESS; - } - } - } - - VirtEntry = NEXT_MEMORY_DESCRIPTOR (VirtEntry, mVirtualMapDescriptorSize); - } - - return EFI_NOT_FOUND; -} - -/** - - Determines the new virtual address that is to be used on subsequent memory accesses - for internal pointers. - This is a internal function. - - - @param ConvertAddress A pointer to a pointer that is to be fixed to be the value needed - for the new virtual address mappings being applied. - - @retval EFI_SUCCESS The pointer pointed to by Address was modified. - @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part - of the current memory map. This is normally fatal. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -RuntimeDriverConvertInternalPointer ( - IN OUT VOID **ConvertAddress - ) -{ - return RuntimeDriverConvertPointer (0x0, ConvertAddress); -} - -/** - - Changes the runtime addressing mode of EFI firmware from physical to virtual. - - - @param MemoryMapSize The size in bytes of VirtualMap. - @param DescriptorSize The size in bytes of an entry in the VirtualMap. - @param DescriptorVersion The version of the structure entries in VirtualMap. - @param VirtualMap An array of memory descriptors which contain new virtual - address mapping information for all runtime ranges. - - @retval EFI_SUCCESS The virtual address map has been applied. - @retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in - virtual address mapped mode. - @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid. - @retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory - map that requires a mapping. - @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found - in the memory map. - -**/ -EFI_STATUS -EFIAPI -RuntimeDriverSetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *VirtualMap - ) -{ - EFI_STATUS Status; - EFI_RUNTIME_EVENT_ENTRY *RuntimeEvent; - EFI_RUNTIME_IMAGE_ENTRY *RuntimeImage; - LIST_ENTRY *Link; - EFI_PHYSICAL_ADDRESS VirtImageBase; - - // - // Can only switch to virtual addresses once the memory map is locked down, - // and can only set it once - // - if (!mRuntime.AtRuntime || mRuntime.VirtualMode) { - return EFI_UNSUPPORTED; - } - // - // Only understand the original descriptor format - // - if (DescriptorVersion != EFI_MEMORY_DESCRIPTOR_VERSION || DescriptorSize < sizeof (EFI_MEMORY_DESCRIPTOR)) { - return EFI_INVALID_PARAMETER; - } - // - // We are now committed to go to virtual mode, so lets get to it! - // - mRuntime.VirtualMode = TRUE; - - // - // ConvertPointer() needs this mVirtualMap to do the conversion. So set up - // globals we need to parse the virtual address map. - // - mVirtualMapDescriptorSize = DescriptorSize; - mVirtualMapMaxIndex = MemoryMapSize / DescriptorSize; - mVirtualMap = VirtualMap; - - // - // ReporstStatusCodeLib will check and make sure this service can be called in runtime mode. - // - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP)); - - // - // Report Status Code here since EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event will be signalled. - // - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT)); - - // - // Signal all the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE events. - // All runtime events are stored in a list in Runtime AP. - // - for (Link = mRuntime.EventHead.ForwardLink; Link != &mRuntime.EventHead; Link = Link->ForwardLink) { - RuntimeEvent = BASE_CR (Link, EFI_RUNTIME_EVENT_ENTRY, Link); - if ((RuntimeEvent->Type & EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) == EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) { - RuntimeEvent->NotifyFunction ( - RuntimeEvent->Event, - RuntimeEvent->NotifyContext - ); - } - } - - // - // Relocate runtime images. All runtime images are stored in a list in Runtime AP. - // - for (Link = mRuntime.ImageHead.ForwardLink; Link != &mRuntime.ImageHead; Link = Link->ForwardLink) { - RuntimeImage = BASE_CR (Link, EFI_RUNTIME_IMAGE_ENTRY, Link); - // - // We don't want to relocate our selves, as we only run in physical mode. - // - if (mMyImageBase != RuntimeImage->ImageBase) { - - VirtImageBase = (EFI_PHYSICAL_ADDRESS) (UINTN) RuntimeImage->ImageBase; - Status = RuntimeDriverConvertPointer (0, (VOID **) &VirtImageBase); - ASSERT_EFI_ERROR (Status); - - PeCoffLoaderRelocateImageForRuntime ( - (EFI_PHYSICAL_ADDRESS) (UINTN) RuntimeImage->ImageBase, - VirtImageBase, - (UINTN) RuntimeImage->ImageSize, - RuntimeImage->RelocationData - ); - - InvalidateInstructionCacheRange (RuntimeImage->ImageBase, (UINTN) RuntimeImage->ImageSize); - } - } - - // - // Convert all the Runtime Services except ConvertPointer() and SetVirtualAddressMap() - // and recompute the CRC-32 - // - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetTime); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetTime); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetWakeupTime); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetWakeupTime); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->ResetSystem); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextHighMonotonicCount); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetVariable); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->SetVariable); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->GetNextVariableName); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->QueryVariableInfo); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->UpdateCapsule); - RuntimeDriverConvertInternalPointer ((VOID **) &gRT->QueryCapsuleCapabilities); - RuntimeDriverCalculateEfiHdrCrc (&gRT->Hdr); - - // - // UEFI don't require System Configuration Tables Conversion. - // - - // - // Convert the runtime fields of the EFI System Table and recompute the CRC-32 - // - RuntimeDriverConvertInternalPointer ((VOID **) &gST->FirmwareVendor); - RuntimeDriverConvertInternalPointer ((VOID **) &gST->ConfigurationTable); - RuntimeDriverConvertInternalPointer ((VOID **) &gST->RuntimeServices); - RuntimeDriverCalculateEfiHdrCrc (&gST->Hdr); - - // - // At this point, gRT and gST are physical pointers, but the contents of these tables - // have been converted to runtime. - // - // - // mVirtualMap is only valid during SetVirtualAddressMap() call - // - mVirtualMap = NULL; - - return EFI_SUCCESS; -} - -/** - Entry Point for Runtime driver. - - This function installs Runtime Architectural Protocol and registers CalculateCrc32 boot services table, - SetVirtualAddressMap & ConvertPointer runtime services table. - - @param ImageHandle Image handle of this driver. - @param SystemTable a Pointer to the EFI System Table. - - @retval EFI_SUCEESS Runtime Driver Architectural Protocol is successfully installed - @return Others Some error occurs when installing Runtime Driver Architectural Protocol. - -**/ -EFI_STATUS -EFIAPI -RuntimeDriverInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *MyLoadedImage; - - // - // This image needs to be excluded from relocation for virtual mode, so cache - // a copy of the Loaded Image protocol to test later. - // - Status = gBS->HandleProtocol ( - ImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID**)&MyLoadedImage - ); - ASSERT_EFI_ERROR (Status); - mMyImageBase = MyLoadedImage->ImageBase; - - // - // Initialize the table used to compute 32-bit CRCs - // - RuntimeDriverInitializeCrc32Table (); - - // - // Fill in the entries of the EFI Boot Services and EFI Runtime Services Tables - // - gBS->CalculateCrc32 = RuntimeDriverCalculateCrc32; - gRT->SetVirtualAddressMap = RuntimeDriverSetVirtualAddressMap; - gRT->ConvertPointer = RuntimeDriverConvertPointer; - - // - // Install the Runtime Architectural Protocol onto a new handle - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &mRuntimeHandle, - &gEfiRuntimeArchProtocolGuid, - &mRuntime, - NULL - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} diff --git a/MdeModulePkg/Core/RuntimeDxe/Runtime.h b/MdeModulePkg/Core/RuntimeDxe/Runtime.h deleted file mode 100644 index f2cee9c7c6..0000000000 --- a/MdeModulePkg/Core/RuntimeDxe/Runtime.h +++ /dev/null @@ -1,134 +0,0 @@ -/** @file - Runtime Architectural Protocol as defined in the DXE CIS. - - This code is used to produce the EFI runtime architectural protocol. - -Copyright (c) 2006 - 2010, 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 -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _RUNTIME_H_ -#define _RUNTIME_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// -// Function Prototypes -// -/** - Calculate CRC32 for target data. - - @param Data The target data. - @param DataSize The target data size. - @param CrcOut The CRC32 for target data. - - @retval EFI_SUCCESS The CRC32 for target data is calculated successfully. - @retval EFI_INVALID_PARAMETER Some parameter is not valid, so the CRC32 is not - calculated. - -**/ -EFI_STATUS -EFIAPI -RuntimeDriverCalculateCrc32 ( - IN VOID *Data, - IN UINTN DataSize, - OUT UINT32 *CrcOut - ); - -/** - Determines the new virtual address that is to be used on subsequent memory accesses. - - - @param DebugDisposition Supplies type information for the pointer being converted. - @param ConvertAddress A pointer to a pointer that is to be fixed to be the value needed - for the new virtual address mappings being applied. - - @retval EFI_SUCCESS The pointer pointed to by Address was modified. - @retval EFI_NOT_FOUND The pointer pointed to by Address was not found to be part - of the current memory map. This is normally fatal. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - -**/ -EFI_STATUS -EFIAPI -RuntimeDriverConvertPointer ( - IN UINTN DebugDisposition, - IN OUT VOID **ConvertAddress - ); - -/** - Changes the runtime addressing mode of EFI firmware from physical to virtual. - - @param MemoryMapSize The size in bytes of VirtualMap. - @param DescriptorSize The size in bytes of an entry in the VirtualMap. - @param DescriptorVersion The version of the structure entries in VirtualMap. - @param VirtualMap An array of memory descriptors which contain new virtual - address mapping information for all runtime ranges. - - @retval EFI_SUCCESS The virtual address map has been applied. - @retval EFI_UNSUPPORTED EFI firmware is not at runtime, or the EFI firmware is already in - virtual address mapped mode. - @retval EFI_INVALID_PARAMETER DescriptorSize or DescriptorVersion is invalid. - @retval EFI_NO_MAPPING A virtual address was not supplied for a range in the memory - map that requires a mapping. - @retval EFI_NOT_FOUND A virtual address was supplied for an address that is not found - in the memory map. - -**/ -EFI_STATUS -EFIAPI -RuntimeDriverSetVirtualAddressMap ( - IN UINTN MemoryMapSize, - IN UINTN DescriptorSize, - IN UINT32 DescriptorVersion, - IN EFI_MEMORY_DESCRIPTOR *VirtualMap - ); - -/** - Initialize CRC32 table. - -**/ -VOID -RuntimeDriverInitializeCrc32Table ( - VOID - ); - -/** - Install Runtime AP. This code includes the EfiRuntimeLib, but it only - functions at RT in physical mode. - - @param ImageHandle Image handle of this driver. - @param SystemTable Pointer to the EFI System Table. - - @retval EFI_SUCEESS Runtime Driver Architectural Protocol Installed - @return Other value if gBS->InstallMultipleProtocolInterfaces fails. Check - gBS->InstallMultipleProtocolInterfaces for details. - -**/ -EFI_STATUS -EFIAPI -RuntimeDriverInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -#endif diff --git a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf b/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf deleted file mode 100644 index 035aa9a596..0000000000 --- a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +++ /dev/null @@ -1,65 +0,0 @@ -## @file -# Module that produces EFI runtime virtual switch over services. -# -# This runtime module installs Runtime Architectural Protocol and registers -# CalculateCrc32 boot services table, SetVirtualAddressMap & ConvertPointer -# runtime services table. -# -# Copyright (c) 2006 - 2014, 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 -# http://opensource.org/licenses/bsd-license.php -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = RuntimeDxe - MODULE_UNI_FILE = RuntimeDxe.uni - FILE_GUID = B601F8C4-43B7-4784-95B1-F4226CB40CEE - MODULE_TYPE = DXE_RUNTIME_DRIVER - VERSION_STRING = 1.0 - - ENTRY_POINT = RuntimeDriverInitialize - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - Crc32.c - Runtime.h - Runtime.c - - -[Packages] - MdePkg/MdePkg.dec - -[LibraryClasses] - PeCoffLib - CacheMaintenanceLib - UefiBootServicesTableLib - UefiLib - UefiRuntimeServicesTableLib - ReportStatusCodeLib - DebugLib - UefiDriverEntryPoint - BaseLib - -[Protocols] - gEfiRuntimeArchProtocolGuid ## PRODUCES - gEfiLoadedImageProtocolGuid ## CONSUMES - -[depex] - TRUE - -[UserExtensions.TianoCore."ExtraFiles"] - RuntimeDxeExtra.uni \ No newline at end of file diff --git a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.uni b/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.uni deleted file mode 100644 index fa5c4785e8..0000000000 --- a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.uni +++ /dev/null @@ -1,23 +0,0 @@ -// /** @file -// Module that produces EFI runtime virtual switch over services. -// -// This runtime module installs Runtime Architectural Protocol and registers -// CalculateCrc32 boot services table, SetVirtualAddressMap & ConvertPointer -// runtime services table. -// -// Copyright (c) 2006 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Module that produces EFI runtime virtual switchover services" - -#string STR_MODULE_DESCRIPTION #language en-US "This runtime module installs Runtime Architectural Protocol and registers the CalculateCrc32 boot services table, and SetVirtualAddressMap and ConvertPointer runtime services table." - diff --git a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxeExtra.uni b/MdeModulePkg/Core/RuntimeDxe/RuntimeDxeExtra.uni deleted file mode 100644 index 06bd6395e8..0000000000 --- a/MdeModulePkg/Core/RuntimeDxe/RuntimeDxeExtra.uni +++ /dev/null @@ -1,19 +0,0 @@ -// /** @file -// RuntimeDxe Localized Strings and Content -// -// Copyright (c) 2013 - 2014, 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 -// http://opensource.org/licenses/bsd-license.php -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Core Runtime Services Driver" - - -- cgit v1.2.3