]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Library/EdkDxeSalLib/Ipf/EsalServiceLib.c
1) Make a slightly better work around for the EdkDxeSalLib by removing constructor...
[mirror_edk2.git] / EdkModulePkg / Library / EdkDxeSalLib / Ipf / EsalServiceLib.c
index d258b98cabdc178b7614241fd54ce939b846c56f..706dda2873e92a278ce3f5bb668f927e7068c7f9 100644 (file)
@@ -19,25 +19,78 @@ Abstract:
 \r
 #include <Ipf/IpfDefines.h>\r
 \r
-\r
+BOOLEAN mLibraryInitialized = FALSE;\r
 STATIC EXTENDED_SAL_BOOT_SERVICE_PROTOCOL *mEsalBootService;\r
+STATIC EFI_PLABEL                         mPlabel;\r
 \r
 EFI_STATUS\r
 EFIAPI\r
 DxeSalLibConstruct (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
+//  IN EFI_HANDLE        ImageHandle,\r
+//  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  VOID\r
   )\r
 {\r
-  EFI_STATUS Status;\r
+  EFI_PLABEL  *Plabel;\r
+  EFI_STATUS  Status;\r
 \r
-  Status = gBS->LocateProtocol (&gEfiExtendedSalBootServiceProtocolGuid, NULL, &mEsalBootService);\r
+  if (mLibraryInitialized == TRUE) {\r
+    return EFI_SUCCESS;\r
+  }\r
+  mLibraryInitialized = TRUE;\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
+  SetEsalPhysicalEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
+\r
   return Status;\r
 }\r
 \r
+VOID\r
+EFIAPI\r
+DxeSalVirtualNotifyEvent (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Fixup virtual address pointer of label.\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
+  EfiConvertPointer (0x0, (VOID **) &mPlabel.EntryPoint);\r
+  EfiConvertPointer (EFI_IPF_GP_POINTER, (VOID **) &mPlabel.GP);\r
+\r
+  SetEsalVirtualEntryPoint (mPlabel.EntryPoint, mPlabel.GP);\r
+}\r
+\r
 EFI_STATUS\r
+EFIAPI\r
 RegisterEsalFunction (\r
   IN  UINT64                                    FunctionId,\r
   IN  EFI_GUID                                  *ClassGuid,\r
@@ -62,6 +115,7 @@ Returns:
 \r
 --*/\r
 {\r
+  DxeSalLibConstruct ();\r
   return mEsalBootService->AddExtendedSalProc (\r
                             mEsalBootService,\r
                             ClassGuid,\r
@@ -72,6 +126,7 @@ Returns:
 }\r
 \r
 EFI_STATUS\r
+EFIAPI\r
 RegisterEsalClass (\r
   IN  EFI_GUID                                  *ClassGuid,\r
   IN  VOID                                      *ModuleGlobal,\r
@@ -129,6 +184,7 @@ Returns:
 }\r
 \r
 SAL_RETURN_REGS\r
+EFIAPI\r
 EfiCallEsalService (\r
   IN  EFI_GUID                                      *ClassGuid,\r
   IN  UINT64                                        FunctionId,\r
@@ -168,6 +224,7 @@ Returns:
   SAL_RETURN_REGS       ReturnReg;\r
   SAL_EXTENDED_SAL_PROC EsalProc;\r
 \r
+  DxeSalLibConstruct ();\r
   ReturnReg = GetEsalEntryPoint ();\r
   if (ReturnReg.Status != EFI_SAL_SUCCESS) {\r
     return ReturnReg;\r