diff options
author | mdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524> | 2006-12-06 05:17:50 +0000 |
---|---|---|
committer | mdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524> | 2006-12-06 05:17:50 +0000 |
commit | f1cd55fe2445361c02a74ac2e353f42aaf52765c (patch) | |
tree | 8b491db30f0be10e19b7385b12a5bda0df1b3690 /EdkModulePkg/Library | |
parent | 756e4264d3e06c986cab44abe9a4db55787f7a49 (diff) | |
download | edk2-platforms-f1cd55fe2445361c02a74ac2e353f42aaf52765c.tar.xz |
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
Diffstat (limited to 'EdkModulePkg/Library')
9 files changed, 844 insertions, 85 deletions
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<BR>
+ 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 <FileName>(<LineNumber>): <Description>\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 <FileName> string of "(NULL) Filename" is printed.
+
+ If Description is NULL, then a <Description> 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 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <MsaHeader>
+ <ModuleName>DxeDebugLibSerialPort</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>BB83F95F-EDBC-4884-A520-CD42AF388FAE</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Debug Library for UEFI drivers</Abstract>
+ <Description>Library to abstract Framework extensions that conflict with UEFI 2.0 Specification</Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation.</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>UefiDebugLibConOut</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_PRODUCED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PrintLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PcdLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>SerialPortLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>DebugLib.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ </PackageDependencies>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ </Externs>
+ <PcdCoded>
+ <PcdEntry PcdItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugPropertyMask</C_Name>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>The bitmask of flags that specify the enable/disable of Debug + Assert, Debug Print, Debug Code, Clear Memory, Assert + Breakpoint and Assert Deadloop.</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugClearMemoryValue</C_Name>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>The value used by DebugClearMemory () to fill a certain range + of memory.</HelpText>
+ </PcdEntry>
+ <PcdEntry PcdItemType="DYNAMIC">
+ <C_Name>PcdDebugPrintErrorLevel</C_Name>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <HelpText>The bitmask of flags that specify the kind of debug message + output when Debug Print is enabled.</HelpText>
+ </PcdEntry>
+ </PcdCoded>
+</ModuleSurfaceArea>
\ 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 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+ <MsaHeader>
+ <ModuleName>EdkDxeRuntimeSalLib</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>61999c3c-72a5-4506-a4ff-4271d18a1d14</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>SAL library for BS/RT drivers</Abstract>
+ <Description>Contains APIs to register/invoke SAL functions.</Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation.</Copyright>
+ <License>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.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>EdkDxeSalLib</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_PRODUCED">
+ <Keyword>EdkDxeSalLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiRuntimeLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename SupArchList="IPF">Ipf/EsalServiceLib.c</Filename>
+ <Filename SupArchList="IPF">Ipf/AsmEsalServiceLib.s</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiExtendedSalBootServiceProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <Constructor>DxeSalLibConstructor</Constructor>
+ </Extern>
+ <Extern>
+ <SetVirtualAddressMapCallBack>DxeSalVirtualNotifyEvent</SetVirtualAddressMapCallBack>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
\ 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 <Ipf/IpfDefines.h>
+
+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 @@ <MsaHeader>
<ModuleName>EdkDxeSalLib</ModuleName>
<ModuleType>DXE_DRIVER</ModuleType>
- <GuidValue>61999c3c-72a5-4506-a4ff-4271d18a1d14</GuidValue>
+ <GuidValue>F0AC8548-34DE-45bd-9B0A-A5A2DE819E65</GuidValue>
<Version>1.0</Version>
<Abstract>SAL library for BS/RT drivers</Abstract>
<Description>Contains APIs to register/invoke SAL functions.</Description>
@@ -57,8 +57,5 @@ <Extern>
<Constructor>DxeSalLibConstructor</Constructor>
</Extern>
- <Extern>
- <SetVirtualAddressMapCallBack>DxeSalVirtualNotifyEvent</SetVirtualAddressMapCallBack>
- </Extern>
</Externs>
</ModuleSurfaceArea>
\ 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
//
@@ -147,21 +134,9 @@ 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;
}
@@ -202,16 +178,12 @@ 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 @@ <Constructor>RuntimeDriverLibConstruct</Constructor>
<Destructor>RuntimeDriverLibDeconstruct</Destructor>
</Extern>
+ <Extern>
+ <ExitBootServicesCallBack>RuntimeDriverExitBootServices</ExitBootServicesCallBack>
+ </Extern>
</Externs>
</ModuleSurfaceArea>
\ 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++) {
@@ -138,30 +124,18 @@ 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;
}
@@ -193,16 +167,12 @@ 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;
}
|