From f1cd55fe2445361c02a74ac2e353f42aaf52765c Mon Sep 17 00:00:00 2001 From: mdkinney Date: Wed, 6 Dec 2006 05:17:50 +0000 Subject: [PATCH] Add DxeDebugLibSerialPort that provides a debug library that layers directly on top of a serial port Add an EdkDxeRuntimeSalLib that provide a SalLib that is safe for runtime use. The EdkDxeSalLib is now a boot service only lib. Move the registration and processing of ExitBootServicesEvents() from the RuntimeLib to the UEFI DriverEntryPointLib in the MdePkg. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2057 6f19259b-4bc3-4df7-8a09-765794883524 --- EdkModulePkg/EdkModulePkg.spd | 2 + .../Library/DxeDebugLibSerialPort/DebugLib.c | 243 +++++++++++++++ .../DxeDebugLibSerialPort.msa | 76 +++++ .../EdkDxeRuntimeSalLib.msa | 64 ++++ .../Ipf/AsmEsalServiceLib.s | 149 +++++++++ .../EdkDxeRuntimeSalLib/Ipf/EsalServiceLib.c | 285 ++++++++++++++++++ .../Library/EdkDxeSalLib/EdkDxeSalLib.msa | 5 +- .../EdkUefiRuntimeLib/Common/RuntimeLib.c | 36 +-- .../EdkUefiRuntimeLib/EdkUefiRuntimeLib.msa | 3 + .../EdkUefiRuntimeLib/Ipf/RuntimeLib.c | 68 ++--- .../Universal/Runtime/RuntimeDxe/Runtime.msa | 3 + 11 files changed, 849 insertions(+), 85 deletions(-) create mode 100644 EdkModulePkg/Library/DxeDebugLibSerialPort/DebugLib.c create mode 100644 EdkModulePkg/Library/DxeDebugLibSerialPort/DxeDebugLibSerialPort.msa create mode 100644 EdkModulePkg/Library/EdkDxeRuntimeSalLib/EdkDxeRuntimeSalLib.msa create mode 100644 EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/AsmEsalServiceLib.s create mode 100644 EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/EsalServiceLib.c diff --git a/EdkModulePkg/EdkModulePkg.spd b/EdkModulePkg/EdkModulePkg.spd index 3c1bd0c394..f720d1a94d 100644 --- a/EdkModulePkg/EdkModulePkg.spd +++ b/EdkModulePkg/EdkModulePkg.spd @@ -386,12 +386,14 @@ Library/DxeCorePerformanceLib/DxeCorePerformanceLib.msa Library/DxeCoreTianoDecompressLibFromHob/DxeCoreTianoDecompressLibFromHob.msa Library/DxeCoreUefiDecompressLibFromHob/DxeCoreUefiDecompressLibFromHob.msa + Library/DxeDebugLibSerialPort/DxeDebugLibSerialPort.msa Library/EdkDxeDebugLibReportStatusCode/EdkDxeDebugLibReportStatusCode.msa Library/EdkDxePeCoffLoaderFromHobLib/EdkDxePeCoffLoaderFromHobLib.msa Library/DxePerformanceLib/DxePerformanceLib.msa Library/EdkDxePrintLib/EdkDxePrintLib.msa Library/EdkUefiRuntimeLib/EdkUefiRuntimeLib.msa Library/EdkDxeSalLib/EdkDxeSalLib.msa + Library/EdkDxeRuntimeSalLib/EdkDxeRuntimeSalLib.msa Library/EdkFvbServiceLib/EdkFvbServiceLib.msa Library/EdkGraphicsLib/EdkGraphicsLib.msa Library/EdkIfrSupportLib/EdkIfrSupportLib.msa diff --git a/EdkModulePkg/Library/DxeDebugLibSerialPort/DebugLib.c b/EdkModulePkg/Library/DxeDebugLibSerialPort/DebugLib.c new file mode 100644 index 0000000000..45fbcf4777 --- /dev/null +++ b/EdkModulePkg/Library/DxeDebugLibSerialPort/DebugLib.c @@ -0,0 +1,243 @@ +/** @file + UEFI Debug Library that uses PrintLib to send messages to CONOUT. + + 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. + +**/ + +// +// Define the maximum debug and assert message length that this library supports +// +#define MAX_DEBUG_MESSAGE_LENGTH 0x100 + + +/** + + Prints a debug message to the debug output device if the specified error level is enabled. + + If any bit in ErrorLevel is also set in PcdDebugPrintErrorLevel, then print + the message specified by Format and the associated variable argument list to + the debug output device. + + If Format is NULL, then ASSERT(). + + @param ErrorLevel The error level of the debug message. + @param Format Format string for the debug message to print. + +**/ +VOID +EFIAPI +DebugPrint ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + ... + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + VA_LIST Marker; + + // + // If Format is NULL, then ASSERT(). + // + ASSERT (Format != NULL); + + // + // Check driver debug mask value and global mask + // + if ((ErrorLevel & PcdGet32(PcdDebugPrintErrorLevel)) == 0) { + return; + } + + // + // Convert the DEBUG() message to an ASCII String + // + VA_START (Marker, Format); + AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker); + VA_END (Marker); + + // + // Send the print string to a Serial Port + // + SerialPortWrite (Buffer, AsciiStrLen(Buffer)); +} + + +/** + + Prints an assert message containing a filename, line number, and description. + This may be followed by a breakpoint or a dead loop. + + Print a message of the form "ASSERT (): \n" + to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of + PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then + CpuDeadLoop() is called. If neither of these bits are set, then this function + returns immediately after the message is printed to the debug output device. + DebugAssert() must actively prevent recusrsion. If DebugAssert() is called while + processing another DebugAssert(), then DebugAssert() must return immediately. + + If FileName is NULL, then a string of "(NULL) Filename" is printed. + + If Description is NULL, then a string of "(NULL) Description" is printed. + + @param FileName Pointer to the name of the source file that generated the assert condition. + @param LineNumber The line number in the source file that generated the assert condition + @param Description Pointer to the description of the assert condition. + +**/ +VOID +EFIAPI +DebugAssert ( + IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + + // + // Generate the ASSERT() message in Unicode format + // + AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT %a(%d): %a\n", FileName, LineNumber, Description); + + // + // Send the print string to the Console Output device + // + SerialPortWrite (Buffer, AsciiStrLen(Buffer)); + + // + // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings + // + if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { + CpuBreakpoint (); + } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { + CpuDeadLoop (); + } +} + + +/** + + Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer. + + This function fills Length bytes of Buffer with the value specified by + PcdDebugClearMemoryValue, and returns Buffer. + + If Buffer is NULL, then ASSERT(). + + If Length is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). + + @param Buffer Pointer to the target buffer to fill with PcdDebugClearMemoryValue. + @param Length Number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. + + @return Buffer + +**/ +VOID * +EFIAPI +DebugClearMemory ( + OUT VOID *Buffer, + IN UINTN Length + ) +{ + // + // If Buffer is NULL, then ASSERT(). + // + ASSERT (Buffer != NULL); + + // + // SetMem() checks for the the ASSERT() condition on Length and returns Buffer + // + return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue)); +} + + +/** + + Returns TRUE if ASSERT() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugAssertEnabled ( + VOID + ) +{ + return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0); +} + + +/** + + Returns TRUE if DEBUG()macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugPrintEnabled ( + VOID + ) +{ + return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0); +} + + +/** + + Returns TRUE if DEBUG_CODE()macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugCodeEnabled ( + VOID + ) +{ + return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0); +} + + +/** + + Returns TRUE if DEBUG_CLEAR_MEMORY()macro is enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugClearMemoryEnabled ( + VOID + ) +{ + return ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0); +} diff --git a/EdkModulePkg/Library/DxeDebugLibSerialPort/DxeDebugLibSerialPort.msa b/EdkModulePkg/Library/DxeDebugLibSerialPort/DxeDebugLibSerialPort.msa new file mode 100644 index 0000000000..2274f0e44c --- /dev/null +++ b/EdkModulePkg/Library/DxeDebugLibSerialPort/DxeDebugLibSerialPort.msa @@ -0,0 +1,76 @@ + + + + DxeDebugLibSerialPort + DXE_DRIVER + BB83F95F-EDBC-4884-A520-CD42AF388FAE + 1.0 + Debug Library for UEFI drivers + Library to abstract Framework extensions that conflict with UEFI 2.0 Specification + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + UefiDebugLibConOut + + + + BaseLib + + + DebugLib + + + PrintLib + + + PcdLib + + + BaseMemoryLib + + + SerialPortLib + + + + DebugLib.c + + + + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + + + PcdDebugPropertyMask + gEfiMdePkgTokenSpaceGuid + The bitmask of flags that specify the enable/disable of Debug + Assert, Debug Print, Debug Code, Clear Memory, Assert + Breakpoint and Assert Deadloop. + + + PcdDebugClearMemoryValue + gEfiMdePkgTokenSpaceGuid + The value used by DebugClearMemory () to fill a certain range + of memory. + + + PcdDebugPrintErrorLevel + gEfiMdePkgTokenSpaceGuid + The bitmask of flags that specify the kind of debug message + output when Debug Print is enabled. + + + \ No newline at end of file diff --git a/EdkModulePkg/Library/EdkDxeRuntimeSalLib/EdkDxeRuntimeSalLib.msa b/EdkModulePkg/Library/EdkDxeRuntimeSalLib/EdkDxeRuntimeSalLib.msa new file mode 100644 index 0000000000..6df0cb970b --- /dev/null +++ b/EdkModulePkg/Library/EdkDxeRuntimeSalLib/EdkDxeRuntimeSalLib.msa @@ -0,0 +1,64 @@ + + + + EdkDxeRuntimeSalLib + DXE_DRIVER + 61999c3c-72a5-4506-a4ff-4271d18a1d14 + 1.0 + SAL library for BS/RT drivers + Contains APIs to register/invoke SAL functions. + 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + EdkDxeSalLib + + + + EdkDxeSalLib + + + BaseLib + + + DebugLib + + + UefiBootServicesTableLib + + + UefiRuntimeLib + + + + Ipf/EsalServiceLib.c + Ipf/AsmEsalServiceLib.s + + + + + + + + gEfiExtendedSalBootServiceProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + DxeSalLibConstructor + + + DxeSalVirtualNotifyEvent + + + \ No newline at end of file diff --git a/EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/AsmEsalServiceLib.s b/EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/AsmEsalServiceLib.s new file mode 100644 index 0000000000..c5cb881fe2 --- /dev/null +++ b/EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/AsmEsalServiceLib.s @@ -0,0 +1,149 @@ +//++ +// 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. +// +// Module Name: +// +// EsalLib.s +// +// Abstract: +// +// +// Revision History: +// +//-- + +.file "EsalLib.s" + +#include "IpfMacro.i" + +// +// Exports +// +.globl GetEsalEntryPoint + + +//----------------------------------------------------------------------------- +//++ +// GetEsalEntryPoint +// +// Return Esal global and PSR register. +// +// On Entry : +// +// +// Return Value: +// r8 = EFI_SAL_SUCCESS +// r9 = Physical Plabel +// r10 = Virtual Plabel +// r11 = psr +// +// As per static calling conventions. +// +//-- +//--------------------------------------------------------------------------- +PROCEDURE_ENTRY (GetEsalEntryPoint) + + NESTED_SETUP (0,8,0,0) + +EsalCalcStart: + mov r8 = ip;; + add r8 = (EsalEntryPoint - EsalCalcStart), r8;; + mov r9 = r8;; + add r10 = 0x10, r8;; + mov r11 = psr;; + mov r8 = r0;; + + NESTED_RETURN + +PROCEDURE_EXIT (GetEsalEntryPoint) + + + + + +//----------------------------------------------------------------------------- +//++ +// SetEsalPhysicalEntryPoint +// +// Set the dispatcher entry point +// +// On Entry: +// in0 = Physical address of Esal Dispatcher +// in1 = Physical GP +// +// Return Value: +// r8 = EFI_SAL_SUCCESS +// +// As per static calling conventions. +// +//-- +//--------------------------------------------------------------------------- +PROCEDURE_ENTRY (SetEsalPhysicalEntryPoint) + + NESTED_SETUP (2,8,0,0) + +EsalCalcStart1: + mov r8 = ip;; + add r8 = (EsalEntryPoint - EsalCalcStart1), r8;; + st8 [r8] = in0;; + add r8 = 0x08, r8;; + st8 [r8] = in1;; + mov r8 = r0;; + + NESTED_RETURN + +PROCEDURE_EXIT (SetEsalPhysicalEntryPoint) + + +//----------------------------------------------------------------------------- +//++ +// SetEsalVirtualEntryPoint +// +// Register physical address of Esal globals. +// +// On Entry : +// in0 = Virtual address of Esal Dispatcher +// in1 = Virtual GP +// +// Return Value: +// r8 = EFI_SAL_ERROR +// +// As per static calling conventions. +// +//-- +//--------------------------------------------------------------------------- +PROCEDURE_ENTRY (SetEsalVirtualEntryPoint) + + NESTED_SETUP (2,8,0,0) + +EsalCalcStart2: + mov r8 = ip;; + add r8 = (EsalEntryPoint - EsalCalcStart2), r8;; + add r8 = 0x10, r8;; + st8 [r8] = in0;; + add r8 = 0x08, r8;; + st8 [r8] = in1;; + mov r8 = r0;; + + NESTED_RETURN + +PROCEDURE_EXIT (SetEsalVirtualEntryPoint) + + + + +.align 32 +EsalEntryPoint: + data8 0 // Physical Entry + data8 0 // GP + data8 0 // Virtual Entry + data8 0 // GP + + diff --git a/EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/EsalServiceLib.c b/EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/EsalServiceLib.c new file mode 100644 index 0000000000..9eb909dcd3 --- /dev/null +++ b/EdkModulePkg/Library/EdkDxeRuntimeSalLib/Ipf/EsalServiceLib.c @@ -0,0 +1,285 @@ +/*++ + +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. + +Module Name: + + EsalServiceLib.c + +Abstract: + +--*/ + +#include + +EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService = NULL; +EFI_PLABEL mPlabel; + +EFI_STATUS +EFIAPI +DxeSalLibInitialize ( + VOID + ) +{ + EFI_PLABEL *Plabel; + EFI_STATUS Status; + + if (mEsalBootService != NULL) { + return EFI_SUCCESS; + } + + // + // The protocol contains a function pointer, which is an indirect procedure call. + // An indirect procedure call goes through a plabel, and pointer to a function is + // a pointer to a plabel. To implement indirect procedure calls that can work in + // both physical and virtual mode, two plabels are required (one physical and one + // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it + // away. We cache it in a module global, so we can register the vitrual version. + // + Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService); + if (EFI_ERROR (Status)) { + mEsalBootService = NULL; + return EFI_SUCCESS; + } + + Plabel = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc; + + mPlabel.EntryPoint = Plabel->EntryPoint; + mPlabel.GP = Plabel->GP; + SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +DxeSalLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return DxeSalLibInitialize (); +} + +VOID +EFIAPI +DxeSalVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + + Fixup virtual address pointer of label. + +Arguments: + + Event - The Event that is being processed + + Context - Event Context + +Returns: + + None + +--*/ +{ + EfiConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint); + EfiConvertPointer (EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP); + + SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP); +} + +EFI_STATUS +EFIAPI +RegisterEsalFunction ( + IN UINT64 FunctionId, + IN EFI_GUID *ClassGuid, + IN SAL_INTERNAL_EXTENDED_SAL_PROC Function, + IN VOID *ModuleGlobal + ) +/*++ + +Routine Description: + + Register ESAL Class Function and it's asociated global. + This function is boot service only! + +Arguments: + FunctionId - ID of function to register + ClassGuid - GUID of function class + Function - Function to register under ClassGuid/FunctionId pair + ModuleGlobal - Module global for Function. + +Returns: + EFI_SUCCESS - If ClassGuid/FunctionId Function was registered. + +--*/ +{ + DxeSalLibInitialize (); + return mEsalBootService->AddExtendedSalProc ( + mEsalBootService, + ClassGuid, + FunctionId, + Function, + ModuleGlobal + ); +} + +EFI_STATUS +EFIAPI +RegisterEsalClass ( + IN EFI_GUID *ClassGuid, + IN VOID *ModuleGlobal, + ... + ) +/*++ + +Routine Description: + + Register ESAL Class and it's asociated global. + This function is boot service only! + +Arguments: + ClassGuid - GUID of function class + ModuleGlobal - Module global for Function. + ... - SAL_INTERNAL_EXTENDED_SAL_PROC and FunctionId pairs. NULL + indicates the end of the list. + +Returns: + EFI_SUCCESS - All members of ClassGuid registered + +--*/ +{ + VA_LIST Args; + EFI_STATUS Status; + SAL_INTERNAL_EXTENDED_SAL_PROC Function; + UINT64 FunctionId; + EFI_HANDLE NewHandle; + + VA_START (Args, ModuleGlobal); + + Status = EFI_SUCCESS; + while (!EFI_ERROR (Status)) { + Function = (SAL_INTERNAL_EXTENDED_SAL_PROC) VA_ARG (Args, SAL_INTERNAL_EXTENDED_SAL_PROC); + if (Function == NULL) { + break; + } + + FunctionId = VA_ARG (Args, UINT64); + + Status = RegisterEsalFunction (FunctionId, ClassGuid, Function, ModuleGlobal); + } + + if (EFI_ERROR (Status)) { + return Status; + } + + NewHandle = NULL; + return gBS->InstallProtocolInterface ( + &NewHandle, + ClassGuid, + EFI_NATIVE_INTERFACE, + NULL + ); +} + +SAL_RETURN_REGS +EFIAPI +EfiCallEsalService ( + IN EFI_GUID *ClassGuid, + IN UINT64 FunctionId, + IN UINT64 Arg2, + IN UINT64 Arg3, + IN UINT64 Arg4, + IN UINT64 Arg5, + IN UINT64 Arg6, + IN UINT64 Arg7, + IN UINT64 Arg8 + ) +/*++ + +Routine Description: + + Call module that is not linked direclty to this module. This code is IP + relative and hides the binding issues of virtual or physical calling. The + function that gets dispatched has extra arguments that include the registered + module global and a boolean flag to indicate if the system is in virutal mode. + +Arguments: + ClassGuid - GUID of function + FunctionId - Function in ClassGuid to call + Arg2 - Argument 2 ClassGuid/FunctionId defined + Arg3 - Argument 3 ClassGuid/FunctionId defined + Arg4 - Argument 4 ClassGuid/FunctionId defined + Arg5 - Argument 5 ClassGuid/FunctionId defined + Arg6 - Argument 6 ClassGuid/FunctionId defined + Arg7 - Argument 7 ClassGuid/FunctionId defined + Arg8 - Argument 8 ClassGuid/FunctionId defined + +Returns: + Status of ClassGuid/FuncitonId + +--*/ +{ + SAL_RETURN_REGS ReturnReg; + SAL_EXTENDED_SAL_PROC EsalProc; + + ReturnReg = GetEsalEntryPoint (); + if (ReturnReg.Status != EFI_SAL_SUCCESS) { + return ReturnReg; + } + + // + // Look at the physical mode ESAL entry point to determine of the ESAL entry point has been initialized + // + if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) { + // + // Both the function ponter and the GP value are zero, so attempt to initialize the ESAL Entry Point + // + DxeSalLibInitialize (); + ReturnReg = GetEsalEntryPoint (); + if (ReturnReg.Status != EFI_SAL_SUCCESS) { + return ReturnReg; + } + if (*(UINT64 *)ReturnReg.r9 == 0 && *(UINT64 *)(ReturnReg.r9 + 8) == 0) { + // + // The ESAL Entry Point could not be initialized + // + ReturnReg.Status = EFI_SAL_ERROR; + return ReturnReg; + } + } + + if (ReturnReg.r11 & PSR_IT_MASK) { + // + // Virtual mode plabel to entry point + // + EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r10; + } else { + // + // Physical mode plabel to entry point + // + EsalProc = (SAL_EXTENDED_SAL_PROC) ReturnReg.r9; + } + + return EsalProc ( + ClassGuid, + FunctionId, + Arg2, + Arg3, + Arg4, + Arg5, + Arg6, + Arg7, + Arg8 + ); +} diff --git a/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.msa b/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.msa index 10c3f8cb4f..9d90f42102 100644 --- a/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.msa +++ b/EdkModulePkg/Library/EdkDxeSalLib/EdkDxeSalLib.msa @@ -3,7 +3,7 @@ EdkDxeSalLib DXE_DRIVER - 61999c3c-72a5-4506-a4ff-4271d18a1d14 + F0AC8548-34DE-45bd-9B0A-A5A2DE819E65 1.0 SAL library for BS/RT drivers Contains APIs to register/invoke SAL functions. @@ -57,8 +57,5 @@ DxeSalLibConstructor - - DxeSalVirtualNotifyEvent - \ No newline at end of file diff --git a/EdkModulePkg/Library/EdkUefiRuntimeLib/Common/RuntimeLib.c b/EdkModulePkg/Library/EdkUefiRuntimeLib/Common/RuntimeLib.c index 12f06e1324..0cef1f7ffc 100644 --- a/EdkModulePkg/Library/EdkUefiRuntimeLib/Common/RuntimeLib.c +++ b/EdkModulePkg/Library/EdkUefiRuntimeLib/Common/RuntimeLib.c @@ -21,14 +21,11 @@ Module Name: // Driver Lib Module Globals // -STATIC EFI_EVENT mRuntimeNotifyEvent; STATIC EFI_EVENT mEfiVirtualNotifyEvent; STATIC BOOLEAN mEfiGoneVirtual = FALSE; STATIC BOOLEAN mEfiAtRuntime = FALSE; - EFI_RUNTIME_SERVICES *mRT; -STATIC VOID EFIAPI RuntimeDriverExitBootServices ( @@ -53,16 +50,6 @@ Returns: --*/ { - EFI_EVENT_NOTIFY ChildNotifyEventHandler; - UINTN Index; - - for (Index = 0; - _gDriverExitBootServicesEvent[Index] != NULL; - Index++) { - ChildNotifyEventHandler = _gDriverExitBootServicesEvent[Index]; - ChildNotifyEventHandler (Event, NULL); - } - // // Clear out BootService globals // @@ -146,22 +133,10 @@ Returns: mRT = SystemTable->RuntimeServices; - // - // Register our ExitBootServices () notify function - // - Status = gBS->CreateEvent ( - EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES, - EFI_TPL_NOTIFY, - RuntimeDriverExitBootServices, - NULL, - &mRuntimeNotifyEvent - ); - - ASSERT_EFI_ERROR (Status); - // // Register SetVirtualAddressMap () notify function // + if (_gDriverSetVirtualAddressMapEvent[0] != NULL) { Status = gBS->CreateEvent ( EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, EFI_TPL_NOTIFY, @@ -171,6 +146,7 @@ Returns: ); ASSERT_EFI_ERROR (Status); + } return EFI_SUCCESS; } @@ -201,17 +177,13 @@ Returns: { EFI_STATUS Status; - // - // Close our ExitBootServices () notify function - // - Status = gBS->CloseEvent (mRuntimeNotifyEvent); - ASSERT_EFI_ERROR (Status); - // // Close SetVirtualAddressMap () notify function // + if (_gDriverSetVirtualAddressMapEvent[0] != NULL) { Status = gBS->CloseEvent (mEfiVirtualNotifyEvent); ASSERT_EFI_ERROR (Status); + } return EFI_SUCCESS; } diff --git a/EdkModulePkg/Library/EdkUefiRuntimeLib/EdkUefiRuntimeLib.msa b/EdkModulePkg/Library/EdkUefiRuntimeLib/EdkUefiRuntimeLib.msa index 3cba52c514..32aa525bc8 100644 --- a/EdkModulePkg/Library/EdkUefiRuntimeLib/EdkUefiRuntimeLib.msa +++ b/EdkModulePkg/Library/EdkUefiRuntimeLib/EdkUefiRuntimeLib.msa @@ -71,5 +71,8 @@ RuntimeDriverLibConstruct RuntimeDriverLibDeconstruct + + RuntimeDriverExitBootServices + \ No newline at end of file diff --git a/EdkModulePkg/Library/EdkUefiRuntimeLib/Ipf/RuntimeLib.c b/EdkModulePkg/Library/EdkUefiRuntimeLib/Ipf/RuntimeLib.c index 00f557aa41..35598f2958 100644 --- a/EdkModulePkg/Library/EdkUefiRuntimeLib/Ipf/RuntimeLib.c +++ b/EdkModulePkg/Library/EdkUefiRuntimeLib/Ipf/RuntimeLib.c @@ -21,13 +21,9 @@ Module Name: // // Driver Lib Module Globals // +static EFI_EVENT mEfiVirtualNotifyEvent; +EFI_RUNTIME_SERVICES *mRT; -STATIC EFI_EVENT mRuntimeNotifyEvent; -STATIC EFI_EVENT mEfiVirtualNotifyEvent; - -EFI_RUNTIME_SERVICES *mRT; - -STATIC VOID EFIAPI RuntimeDriverExitBootServices ( @@ -52,21 +48,11 @@ Returns: --*/ { - EFI_EVENT_NOTIFY ChildNotifyEventHandler; - UINTN Index; - - for (Index = 0; _gDriverExitBootServicesEvent[Index] != NULL; Index++) { - ChildNotifyEventHandler = _gDriverExitBootServicesEvent[Index]; - ChildNotifyEventHandler (Event, NULL); + if (EfiAtRuntime()) { + return; } - - // - // Clear out BootService globals - // - gBS = NULL; } -STATIC VOID EFIAPI RuntimeLibVirtualNotifyEvent ( @@ -93,7 +79,7 @@ Returns: --*/ { - UINTN Index; + UINTN Index; EFI_EVENT_NOTIFY ChildNotifyEventHandler; for (Index = 0; _gDriverSetVirtualAddressMapEvent[Index] != NULL; Index++) { @@ -137,31 +123,19 @@ Returns: mRT = SystemTable->RuntimeServices; - // - // Register our ExitBootServices () notify function - // - - Status = gBS->CreateEvent ( - EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES, - EFI_TPL_NOTIFY, - RuntimeDriverExitBootServices, - NULL, - &mRuntimeNotifyEvent - ); - ASSERT_EFI_ERROR (Status); - // // Register SetVirtualAddressMap () notify function // - - Status = gBS->CreateEvent ( - EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, - EFI_TPL_NOTIFY, - RuntimeLibVirtualNotifyEvent, - NULL, - &mEfiVirtualNotifyEvent - ); - ASSERT_EFI_ERROR (Status); + if (_gDriverSetVirtualAddressMapEvent[0] != NULL) { + Status = gBS->CreateEvent ( + EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, + EFI_TPL_NOTIFY, + RuntimeLibVirtualNotifyEvent, + NULL, + &mEfiVirtualNotifyEvent + ); + ASSERT_EFI_ERROR (Status); + } return EFI_SUCCESS; } @@ -192,17 +166,13 @@ Returns: { EFI_STATUS Status; - // - // Close our ExitBootServices () notify function - // - Status = gBS->CloseEvent (mRuntimeNotifyEvent); - ASSERT_EFI_ERROR (Status); - // // Close SetVirtualAddressMap () notify function // - Status = gBS->CloseEvent (mEfiVirtualNotifyEvent); - ASSERT_EFI_ERROR (Status); + if (_gDriverSetVirtualAddressMapEvent[0] != NULL) { + Status = gBS->CloseEvent (mEfiVirtualNotifyEvent); + ASSERT_EFI_ERROR (Status); + } return EFI_SUCCESS; } diff --git a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa index 516dfa4855..936d81afc6 100644 --- a/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa +++ b/EdkModulePkg/Universal/Runtime/RuntimeDxe/Runtime.msa @@ -52,6 +52,9 @@ CacheMaintenanceLib + + PeCoffLib + Runtime.dxs