]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OldMdePkg/Library/DxeSmmDriverEntryPoint/DriverEntryPoint.c
Moved the MdePkg to OldMdePkg so that new code in MdePkg does not break existing...
[mirror_edk2.git] / OldMdePkg / Library / DxeSmmDriverEntryPoint / DriverEntryPoint.c
diff --git a/OldMdePkg/Library/DxeSmmDriverEntryPoint/DriverEntryPoint.c b/OldMdePkg/Library/DxeSmmDriverEntryPoint/DriverEntryPoint.c
new file mode 100644 (file)
index 0000000..3439d6d
--- /dev/null
@@ -0,0 +1,274 @@
+/** @file\r
+  Entry point to a EFI/DXE driver.\r
+\r
+Copyright (c) 2006, Intel Corporation<BR>\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
+**/\r
+\r
+EFI_BOOT_SERVICES  *mBS;\r
+\r
+/**\r
+  This function returns the size, in bytes, \r
+  of the device path data structure specified by DevicePath.\r
+  If DevicePath is NULL, then 0 is returned.\r
+\r
+  @param  DevicePath A pointer to a device path data structure.\r
+\r
+  @return The size of a device path in bytes.\r
+\r
+**/\r
+STATIC\r
+UINTN\r
+EFIAPI\r
+SmmGetDevicePathSize (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath\r
+  )\r
+{\r
+  CONST EFI_DEVICE_PATH_PROTOCOL  *Start;\r
+\r
+  if (DevicePath == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // Search for the end of the device path structure\r
+  //\r
+  Start = DevicePath;\r
+  while (!EfiIsDevicePathEnd (DevicePath)) {\r
+    DevicePath = EfiNextDevicePathNode (DevicePath);\r
+  }\r
+\r
+  //\r
+  // Compute the size and add back in the size of the end device path structure\r
+  //\r
+  return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
+}\r
+\r
+/**\r
+  This function appends the device path SecondDevicePath\r
+  to every device path instance in FirstDevicePath. \r
+\r
+  @param  FirstDevicePath A pointer to a device path data structure.\r
+  \r
+  @param  SecondDevicePath A pointer to a device path data structure.\r
+\r
+  @return A pointer to the new device path is returned.\r
+          NULL is returned if space for the new device path could not be allocated from pool.\r
+          It is up to the caller to free the memory used by FirstDevicePath and SecondDevicePath\r
+          if they are no longer needed.\r
+\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+EFIAPI\r
+SmmAppendDevicePath (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *FirstDevicePath,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UINTN                     Size;\r
+  UINTN                     Size1;\r
+  UINTN                     Size2;\r
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath2;\r
+\r
+  ASSERT (FirstDevicePath != NULL && SecondDevicePath != NULL);\r
+\r
+  //\r
+  // Allocate space for the combined device path. It only has one end node of\r
+  // length EFI_DEVICE_PATH_PROTOCOL\r
+  //\r
+  Size1         = SmmGetDevicePathSize (FirstDevicePath);\r
+  Size2         = SmmGetDevicePathSize (SecondDevicePath);\r
+  Size          = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
+\r
+  Status = mBS->AllocatePool (EfiBootServicesData, Size, (VOID **) &NewDevicePath);\r
+\r
+  if (EFI_SUCCESS == Status) {\r
+    mBS->CopyMem ((VOID *) NewDevicePath, (VOID *) FirstDevicePath, Size1);\r
+    //\r
+    // Over write Src1 EndNode and do the copy\r
+    //\r
+    DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));\r
+    mBS->CopyMem ((VOID *) DevicePath2, (VOID *) SecondDevicePath, Size2);\r
+  }\r
+\r
+  return NewDevicePath;\r
+}\r
+\r
+/**\r
+  Unload function that is registered in the LoadImage protocol.  It un-installs\r
+  protocols produced and deallocates pool used by the driver.  Called by the core\r
+  when unloading the driver.\r
+\r
+  @param  ImageHandle   ImageHandle of the unloaded driver\r
+\r
+  @return Status of the ProcessModuleUnloadList.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+_DriverUnloadHandler (\r
+  EFI_HANDLE ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Call the unload handlers for all the modules\r
+  //\r
+  Status = ProcessModuleUnloadList (ImageHandle);\r
+\r
+  //\r
+  // If the driver specific unload handler does not return an error, then call all of the\r
+  // library destructors.  If the unload handler returned an error, then the driver can not be\r
+  // unloaded, and the library destructors should not be called\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    ProcessLibraryDestructorList (ImageHandle, gST);\r
+  }\r
+\r
+  //\r
+  // Return the status from the driver specific unload handler\r
+  //\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Enrty point to DXE SMM Driver.\r
+\r
+  @param  ImageHandle ImageHandle of the loaded driver.\r
+  @param  SystemTable Pointer to the EFI System Table.\r
+\r
+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.\r
+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+_ModuleEntryPoint (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                 Status;\r
+  EFI_LOADED_IMAGE_PROTOCOL  *LoadedImage;\r
+  EFI_SMM_BASE_PROTOCOL      *SmmBase;\r
+  BOOLEAN                    InSmm;\r
+  EFI_DEVICE_PATH_PROTOCOL   *CompleteFilePath;\r
+  EFI_DEVICE_PATH_PROTOCOL   *ImageDevicePath;\r
+  EFI_HANDLE                 Handle;\r
+\r
+  //\r
+  // Cache a pointer to the Boot Services Table \r
+  //\r
+  mBS = SystemTable->BootServices;\r
+\r
+  //\r
+  // Retrieve the Loaded Image Protocol\r
+  //\r
+  Status = mBS->HandleProtocol (\r
+                  ImageHandle, \r
+                  &gEfiLoadedImageProtocolGuid,\r
+                  (VOID*)&LoadedImage\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Retrieve SMM Base Protocol\r
+  //\r
+  Status = mBS->LocateProtocol (\r
+                  &gEfiSmmBaseProtocolGuid, \r
+                  NULL, \r
+                  (VOID **) &SmmBase\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Check to see if we are already in SMM\r
+  //\r
+  SmmBase->InSmm (SmmBase, &InSmm);\r
+\r
+  //\r
+  //\r
+  //\r
+  if (!InSmm) {\r
+    //\r
+    // Retrieve the Device Path Protocol from the DeviceHandle tha this driver was loaded from\r
+    //\r
+    Status = mBS->HandleProtocol (\r
+                    LoadedImage->DeviceHandle, \r
+                    &gEfiDevicePathProtocolGuid,\r
+                    (VOID*)&ImageDevicePath\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Build the full device path to the currently execuing image\r
+    //\r
+    CompleteFilePath = SmmAppendDevicePath (ImageDevicePath, LoadedImage->FilePath);\r
+\r
+    //\r
+    // Load the image in memory to SMRAM; it will automatically generate the\r
+    // SMI.\r
+    //\r
+    Status = SmmBase->Register (SmmBase, CompleteFilePath, NULL, 0, &Handle, FALSE);\r
+    ASSERT_EFI_ERROR (Status);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Call constructor for all libraries\r
+  //\r
+  ProcessLibraryConstructorList (ImageHandle, SystemTable);\r
+\r
+  //\r
+  // Optionally install the unload handler\r
+  //\r
+  if (_gDriverUnloadImageCount > 0) {\r
+    Status = mBS->HandleProtocol (\r
+                    ImageHandle,\r
+                    &gEfiLoadedImageProtocolGuid,\r
+                    (VOID **)&LoadedImage\r
+                    );\r
+    ASSERT_EFI_ERROR (Status);\r
+    LoadedImage->Unload = _DriverUnloadHandler;\r
+  }\r
+\r
+  //\r
+  // Call the list of driver entry points\r
+  //\r
+  Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);\r
+  if (EFI_ERROR (Status)) {\r
+    ProcessLibraryDestructorList (ImageHandle, SystemTable);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Enrty point wrapper of DXE SMM Driver.\r
+\r
+  @param  ImageHandle ImageHandle of the loaded driver.\r
+  @param  SystemTable Pointer to the EFI System Table.\r
+\r
+  @retval  EFI_SUCCESS One or more of the drivers returned a success code.\r
+  @retval  !EFI_SUCESS The return status from the last driver entry point in the list.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiMain (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  return _ModuleEntryPoint (ImageHandle, SystemTable);\r
+}\r