]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Library/EdkUefiRuntimeLib/Ipf/RuntimeLib.c
Change DxeRuntimeDriverLib name to UefiRuntimeLib.
[mirror_edk2.git] / EdkModulePkg / Library / EdkUefiRuntimeLib / Ipf / RuntimeLib.c
diff --git a/EdkModulePkg/Library/EdkUefiRuntimeLib/Ipf/RuntimeLib.c b/EdkModulePkg/Library/EdkUefiRuntimeLib/Ipf/RuntimeLib.c
new file mode 100644 (file)
index 0000000..a4eeb33
--- /dev/null
@@ -0,0 +1,284 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+    RuntimeLib.c\r
+\r
+Abstract:\r
+\r
+  Light weight lib to support Tiano drivers.\r
+\r
+--*/\r
+\r
+#include <SalApi.h>\r
+#include <RuntimeLibInternal.h>\r
+\r
+//\r
+// Driver Lib Module Globals\r
+//\r
+\r
+STATIC EFI_EVENT            mRuntimeNotifyEvent;\r
+STATIC EFI_EVENT            mEfiVirtualNotifyEvent;\r
+\r
+STATIC EFI_PLABEL           mPlabel;\r
+STATIC EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;\r
+\r
+EFI_RUNTIME_SERVICES        *mRT                    = NULL;\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+RuntimeDriverExitBootServices (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set AtRuntime flag as TRUE after ExitBootServices\r
+\r
+Arguments:\r
+\r
+  Event   - The Event that is being processed\r
+  \r
+  Context - Event Context\r
+\r
+Returns: \r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  EFI_EVENT_NOTIFY  ChildNotifyEventHandler;\r
+  UINTN             Index;\r
+\r
+  for (Index = 0; _gDriverExitBootServicesEvent[Index] != NULL; Index++) {\r
+    ChildNotifyEventHandler = _gDriverExitBootServicesEvent[Index];\r
+    ChildNotifyEventHandler (Event, NULL);\r
+  }\r
+}\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+RuntimeLibVirtualNotifyEvent (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Fixup internal data so that EFI can be call in virtual mode.\r
+  Call the passed in Child Notify event and convert any pointers in \r
+  lib to virtual mode.\r
+\r
+Arguments:\r
+\r
+  Event   - The Event that is being processed\r
+  \r
+  Context - Event Context\r
+\r
+Returns: \r
+\r
+  None\r
+\r
+--*/\r
+{\r
+  UINTN Index;\r
+  EFI_EVENT_NOTIFY  ChildNotifyEventHandler;\r
+\r
+  for (Index = 0; _gDriverSetVirtualAddressMapEvent[Index] != NULL; Index++) {\r
+    ChildNotifyEventHandler = _gDriverSetVirtualAddressMapEvent[Index];\r
+    ChildNotifyEventHandler (Event, NULL);\r
+  }\r
+\r
+  mRT->ConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);\r
+  mRT->ConvertPointer (EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);\r
+\r
+  SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
+\r
+  //\r
+  // Clear out BootService globals\r
+  //\r
+  gBS             = NULL;\r
+  gST             = NULL;\r
+  mRT             = NULL;\r
+}\r
+\r
+EFI_STATUS\r
+RuntimeDriverLibConstruct (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Intialize runtime Driver Lib if it has not yet been initialized. \r
+\r
+Arguments:\r
+\r
+  ImageHandle     - The firmware allocated handle for the EFI image.\r
+  \r
+  SystemTable     - A pointer to the EFI System Table.\r
+\r
+  GoVirtualChildEvent - Caller can register a virtual notification event.\r
+\r
+Returns: \r
+\r
+  EFI_STATUS always returns EFI_SUCCESS except EFI_ALREADY_STARTED if already started.\r
+\r
+--*/\r
+{\r
+  EFI_PLABEL  *Plabel;\r
+  EFI_STATUS  Status;\r
+\r
+  mRT = SystemTable->RuntimeServices;\r
+\r
+  //\r
+  // The protocol contains a function pointer, which is an indirect procedure call.\r
+  // An indirect procedure call goes through a plabel, and pointer to a function is\r
+  // a pointer to a plabel. To implement indirect procedure calls that can work in\r
+  // both physical and virtual mode, two plabels are required (one physical and one\r
+  // virtual). So lets grap the physical PLABEL for the EsalEntryPoint and store it\r
+  // away. We cache it in a module global, so we can register the vitrual version.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Plabel              = (EFI_PLABEL *) (UINTN) mEsalBootService->ExtendedSalProc;\r
+\r
+  mPlabel.EntryPoint  = Plabel->EntryPoint;\r
+  mPlabel.GP          = Plabel->GP;\r
+\r
+  SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
+\r
+  //\r
+  // Register our ExitBootServices () notify function\r
+  //\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,\r
+                  EFI_TPL_NOTIFY,\r
+                  RuntimeDriverExitBootServices,\r
+                  NULL,\r
+                  &mRuntimeNotifyEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Register SetVirtualAddressMap () notify function\r
+  //\r
+  \r
+  Status = gBS->CreateEvent (\r
+                  EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
+                  EFI_TPL_NOTIFY,\r
+                  RuntimeLibVirtualNotifyEvent,\r
+                  NULL,\r
+                  mEfiVirtualNotifyEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+RuntimeDriverLibDeconstruct (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This routine will free some resources which have been allocated in\r
+  EfiInitializeRuntimeDriverLib(). If a runtime driver exits with an error, \r
+  it must call this routine to free the allocated resource before the exiting.\r
+\r
+Arguments:\r
+\r
+  None\r
+\r
+Returns: \r
+\r
+  EFI_SUCCESS     - Shotdown the Runtime Driver Lib successfully\r
+  EFI_UNSUPPORTED - Runtime Driver lib was not initialized at all\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Close our ExitBootServices () notify function\r
+  //\r
+  Status = gBS->CloseEvent (mRuntimeNotifyEvent);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Close SetVirtualAddressMap () notify function\r
+  //\r
+  Status = gBS->CloseEvent (mEfiVirtualNotifyEvent);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+EfiAtRuntime (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Return TRUE if ExitBootService () has been called\r
+\r
+Arguments:\r
+  NONE\r
+\r
+Returns: \r
+  TRUE - If ExitBootService () has been called\r
+\r
+--*/\r
+{\r
+  EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;\r
+  SAL_RETURN_REGS ReturnReg;\r
+\r
+  ReturnReg = EfiCallEsalService (&Guid, IsEfiRuntime, 0, 0, 0, 0, 0, 0, 0);\r
+\r
+  return (BOOLEAN) (ReturnReg.r9 == 1);\r
+}\r
+\r
+BOOLEAN\r
+EfiGoneVirtual (\r
+  VOID\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Return TRUE if SetVirtualAddressMap () has been called\r
+\r
+Arguments:\r
+  NONE\r
+\r
+Returns: \r
+  TRUE - If SetVirtualAddressMap () has been called\r
+\r
+--*/\r
+{\r
+  EFI_GUID Guid = EFI_EXTENDED_SAL_VIRTUAL_SERVICES_PROTOCOL_GUID;\r
+  SAL_RETURN_REGS ReturnReg;\r
+\r
+  ReturnReg = EfiCallEsalService (&Guid, IsVirtual, 0, 0, 0, 0, 0, 0, 0);\r
+\r
+  return (BOOLEAN) (ReturnReg.r9 == 1);\r
+}\r