]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Remove the implementation limitation in the SmmBaseHelper driver that it assumes...
authorrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 17 Mar 2010 02:06:04 +0000 (02:06 +0000)
committerrsun3 <rsun3@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 17 Mar 2010 02:06:04 +0000 (02:06 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10258 6f19259b-4bc3-4df7-8a09-765794883524

EdkCompatibilityPkg/Compatibility/Include/Guid/SmmBaseThunkCommunication.h
EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.c
EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf
EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.c

index ae369165c90e1682a6703271256274020ac988dd..4a2a32eb05a1dfb8d640b2b492ff0c526cfdbab2 100644 (file)
@@ -74,9 +74,10 @@ typedef enum {
 } SMMBASE_FUNCTION;\r
 \r
 typedef struct {\r
-  SMMBASE_FUNCTION               Function;\r
-  EFI_STATUS                     Status;\r
-  SMMBASE_FUNCTION_ARGS          Args;\r
+  SMMBASE_FUNCTION       Function;\r
+  EFI_STATUS             Status;\r
+  SMMBASE_FUNCTION_ARGS  Args;\r
+  EFI_HANDLE             SmmBaseImageHandle;\r
 } SMMBASE_FUNCTION_DATA;\r
 \r
 #pragma pack(1)\r
index 3d344c7bcb6669d9581df2e8ef4f6cb1f7a9b15c..1c52fa83b8b4480294fca5e628bdd5b2aafef397 100644 (file)
@@ -31,6 +31,7 @@
 #include <Protocol/LoadedImage.h>\r
 #include <Protocol/SmmCpuSaveState.h>\r
 #include <Protocol/MpService.h>\r
+#include <Protocol/LoadPe32Image.h>\r
 \r
 ///\r
 /// Structure for tracking paired information of registered Framework SMI handler\r
@@ -59,6 +60,7 @@ typedef struct {
 \r
 EFI_HANDLE                         mDispatchHandle;\r
 EFI_SMM_CPU_PROTOCOL               *mSmmCpu;\r
+EFI_PE32_IMAGE_PROTOCOL            *mLoadPe32Image;\r
 EFI_GUID                           mEfiSmmCpuIoGuid = EFI_SMM_CPU_IO_GUID;\r
 EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady;\r
 EFI_SMM_SYSTEM_TABLE               *mFrameworkSmst;\r
@@ -174,6 +176,7 @@ ConstructFrameworkSmst (
 /**\r
   Load a given Framework SMM driver into SMRAM and invoke its entry point.\r
 \r
+  @param[in]   ParentImageHandle     Parent Image Handle.\r
   @param[in]   FilePath              Location of the image to be installed as the handler.\r
   @param[in]   SourceBuffer          Optional source buffer in case the image file\r
                                      is in memory.\r
@@ -189,149 +192,72 @@ ConstructFrameworkSmst (
 **/\r
 EFI_STATUS\r
 LoadImage (\r
+  IN      EFI_HANDLE                ParentImageHandle,\r
   IN      EFI_DEVICE_PATH_PROTOCOL  *FilePath,\r
   IN      VOID                      *SourceBuffer,\r
   IN      UINTN                     SourceSize,\r
   OUT     EFI_HANDLE                *ImageHandle\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  UINTN                         PageCount;\r
-  EFI_PHYSICAL_ADDRESS          Buffer;\r
-  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;\r
-  EFI_HANDLE                    PesudoImageHandle;\r
-  UINTN                         NumHandles;\r
-  UINTN                         Index;\r
-  EFI_HANDLE                    *HandleBuffer;\r
-  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;\r
-  EFI_DEVICE_PATH               *LoadedImageDevicePath;\r
-  UINTN                         DevicePathSize;\r
+  EFI_STATUS            Status;\r
+  UINTN                 PageCount;\r
+  UINTN                 OrgPageCount;\r
+  EFI_PHYSICAL_ADDRESS  DstBuffer;\r
 \r
   if (FilePath == NULL || ImageHandle == NULL) {    \r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  ///\r
-  /// Assume Framework SMM driver has an image copy in memory before registering itself into SMRAM.\r
-  /// Currently only supports load Framework SMM driver from existing image copy in memory.\r
-  /// Load PE32 Image Protocol can be used to support loading Framework SMM driver directly from FV.\r
-  ///\r
-  if (SourceBuffer == NULL) {\r
-    Status = gBS->LocateHandleBuffer (\r
-                    ByProtocol,\r
-                    &gEfiLoadedImageDevicePathProtocolGuid,\r
-                    NULL,\r
-                    &NumHandles,\r
-                    &HandleBuffer\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
-    DevicePathSize = GetDevicePathSize (FilePath);\r
-\r
-    for (Index = 0; Index < NumHandles; Index++) {\r
-      Status = gBS->HandleProtocol (\r
-                      HandleBuffer[Index],\r
-                      &gEfiLoadedImageDevicePathProtocolGuid,\r
-                      (VOID **)&LoadedImageDevicePath\r
+  PageCount = 1;\r
+  do {\r
+    OrgPageCount = PageCount;\r
+    DstBuffer = (UINTN)-1;\r
+    Status = gSmst->SmmAllocatePages (\r
+                      AllocateMaxAddress,\r
+                      EfiRuntimeServicesCode,\r
+                      PageCount,\r
+                      &DstBuffer\r
                       );\r
-      ASSERT_EFI_ERROR (Status);\r
-\r
-      if (GetDevicePathSize (LoadedImageDevicePath) == DevicePathSize &&\r
-          CompareMem (LoadedImageDevicePath, FilePath, DevicePathSize) == 0) {\r
-          break;\r
-      }     \r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
     }\r
 \r
-    if (Index < NumHandles) {\r
-      Status = gBS->HandleProtocol (\r
-                      HandleBuffer[Index],\r
-                      &gEfiLoadedImageProtocolGuid,\r
-                      (VOID **)&LoadedImage\r
-                      );\r
-      ASSERT_EFI_ERROR (Status);\r
-      \r
-      SourceBuffer = LoadedImage->ImageBase;\r
-      gBS->FreePool (HandleBuffer);\r
-    } else {\r
-      gBS->FreePool (HandleBuffer);\r
-      return EFI_UNSUPPORTED;\r
+    Status = mLoadPe32Image->LoadPeImage (\r
+                               mLoadPe32Image,\r
+                               ParentImageHandle,\r
+                               FilePath,\r
+                               SourceBuffer,\r
+                               SourceSize,\r
+                               DstBuffer,\r
+                               &PageCount,\r
+                               ImageHandle,\r
+                               NULL,\r
+                               EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE\r
+                               );\r
+    if (EFI_ERROR (Status)) {\r
+      FreePages ((VOID *)(UINTN)DstBuffer, OrgPageCount);\r
     }\r
-  }\r
+  } while (Status == EFI_BUFFER_TOO_SMALL);\r
 \r
-  ImageContext.Handle = SourceBuffer;\r
-  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
-\r
-  ///\r
-  /// Get information about the image being loaded\r
-  ///\r
-  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  ///\r
-  /// Allocate buffer for loading image into SMRAM\r
-  ///\r
-  PageCount = (UINTN)EFI_SIZE_TO_PAGES (ImageContext.ImageSize + ImageContext.SectionAlignment);\r
-  Status = gSmst->SmmAllocatePages (AllocateAnyPages, EfiRuntimeServicesCode, PageCount, &Buffer);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  ImageContext.ImageAddress = (PHYSICAL_ADDRESS)Buffer;\r
-\r
-  ///\r
-  /// Align buffer on section boundry\r
-  ///\r
-  ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;\r
-  ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);\r
-\r
-  ///\r
-  /// Load the image into SMRAM\r
-  ///\r
-  Status = PeCoffLoaderLoadImage (&ImageContext);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-\r
-  ///\r
-  /// Relocate the image in our new buffer\r
-  ///\r
-  Status = PeCoffLoaderRelocateImage (&ImageContext);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-\r
-  ///\r
-  /// Flush the instruction cache so the image data are written before we execute it\r
-  ///\r
-  InvalidateInstructionCacheRange ((VOID *)(UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.ImageSize);\r
-\r
-  ///\r
-  /// Update MP state in Framework SMST before transferring control to Framework SMM driver entry point\r
-  /// in case it may invoke AP\r
-  ///\r
-  mFrameworkSmst->CurrentlyExecutingCpu = gSmst->CurrentlyExecutingCpu;\r
-\r
-  ///\r
-  /// For Framework SMM, ImageHandle does not have to be a UEFI image handle.  The only requirement is that the \r
-  /// ImageHandle is a unique value.  Use image base address as the unique value.\r
-  ///\r
-  PesudoImageHandle = (EFI_HANDLE)(UINTN)ImageContext.ImageAddress;\r
-\r
-  Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)ImageContext.EntryPoint) (PesudoImageHandle, gST);\r
   if (!EFI_ERROR (Status)) {\r
-    *ImageHandle = PesudoImageHandle;\r
-    return EFI_SUCCESS;\r
+    ///\r
+    /// Update MP state in Framework SMST before transferring control to Framework SMM driver entry point\r
+    /// in case it may invoke AP\r
+    ///\r
+    mFrameworkSmst->CurrentlyExecutingCpu = gSmst->CurrentlyExecutingCpu;\r
+\r
+    Status = gBS->StartImage (*ImageHandle, NULL, NULL);\r
+    if (EFI_ERROR (Status)) {\r
+      mLoadPe32Image->UnLoadPeImage (mLoadPe32Image, *ImageHandle);\r
+      *ImageHandle = NULL;\r
+      FreePages ((VOID *)(UINTN)DstBuffer, PageCount);\r
+    }\r
   }\r
 \r
-Error:\r
-  FreePages ((VOID *)(UINTN)Buffer, PageCount);\r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
+\r
 /** \r
   Thunk service of EFI_SMM_BASE_PROTOCOL.Register().\r
 \r
@@ -348,6 +274,7 @@ Register (
     Status = EFI_UNSUPPORTED;\r
   } else {\r
     Status = LoadImage (\r
+               FunctionData->SmmBaseImageHandle,\r
                FunctionData->Args.Register.FilePath,\r
                FunctionData->Args.Register.SourceBuffer,\r
                FunctionData->Args.Register.SourceSize,\r
@@ -735,6 +662,12 @@ SmmBaseHelperMain (
   Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **) &mSmmCpu);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  ///\r
+  /// Locate PE32 Image Protocol which is used later to load Framework SMM driver\r
+  ///\r
+  Status = SystemTable->BootServices->LocateProtocol (&gEfiLoadPeImageProtocolGuid, NULL, (VOID **) &mLoadPe32Image);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   //\r
   // Get MP Services Protocol\r
   //\r
index 1dd447b4ef90cd98c0a2e00b68d24735f6082b61..e4c0f42bd6dfec4fedcf6ed0f2b3bf4167d57e0c 100644 (file)
@@ -33,6 +33,7 @@
  \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
   IntelFrameworkPkg/IntelFrameworkPkg.dec\r
   EdkCompatibilityPkg/EdkCompatibilityPkg.dec\r
 \r
   gEfiSmmCpuSaveStateProtocolGuid        # PROTOCOL ALWAYS_CONSUMED\r
   gEfiMpServiceProtocolGuid              # PROTOCOL ALWAYS_CONSUMED\r
   gEfiSmmCpuIo2ProtocolGuid              # PROTOCOL ALWAYS_CONSUMED\r
-  \r
+  gEfiLoadPeImageProtocolGuid            # PROTOCOL ALWAYS_CONSUMED\r
+\r
 [Depex]\r
-  gEfiSmmCpuProtocolGuid AND gEfiMpServiceProtocolGuid AND gEfiSmmCpuIo2ProtocolGuid\r
+  gEfiSmmCpuProtocolGuid AND\r
+  gEfiMpServiceProtocolGuid AND\r
+  gEfiSmmCpuIo2ProtocolGuid AND\r
+  gEfiLoadPeImageProtocolGuid
\ No newline at end of file
index 8bbfd8049b6f7c8364f5cd527357999bf3c4ca35..51240bbdc78f9f9b5fb08a50a0816f1d2de5c9de 100644 (file)
@@ -75,6 +75,7 @@ SmmBaseHelperService (
   UINTN DataSize;\r
 \r
   mCommunicationData.FunctionData.Status = EFI_UNSUPPORTED;\r
+  mCommunicationData.FunctionData.SmmBaseImageHandle = mSmmBaseHandle;\r
 \r
   if ((mCommunicationData.FunctionData.Function != SmmBaseFunctionCommunicate) && IsInSmm()) {\r
     ///\r
@@ -421,6 +422,8 @@ SmmBaseThunkMain (
   EFI_STATUS  Status;\r
   EFI_EVENT   Event;\r
 \r
+  mSmmBaseHandle = ImageHandle;\r
+\r
   //\r
   // Assume only one instance of SMM Base2 Protocol in the system\r
   // Locate SMM Base2 Protocol\r