2 Entry point to a EFI/DXE driver.
4 Copyright (c) 2006, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <FrameworkSmm.h>
18 #include <Protocol/LoadedImage.h>
19 #include <Protocol/SmmBase.h>
20 #include <Protocol/DevicePath.h>
22 #include <Library/DxeSmmDriverEntryPoint.h>
23 #include <Library/UefiBootServicesTableLib.h>
24 #include <Library/DebugLib.h>
27 EFI_BOOT_SERVICES
*mBS
;
30 This function returns the size, in bytes,
31 of the device path data structure specified by DevicePath.
32 If DevicePath is NULL, then 0 is returned.
34 @param DevicePath A pointer to a device path data structure.
36 @return The size of a device path in bytes.
42 SmmGetDevicePathSize (
43 IN CONST EFI_DEVICE_PATH_PROTOCOL
*DevicePath
46 CONST EFI_DEVICE_PATH_PROTOCOL
*Start
;
48 if (DevicePath
== NULL
) {
53 // Search for the end of the device path structure
56 while (!EfiIsDevicePathEnd (DevicePath
)) {
57 DevicePath
= EfiNextDevicePathNode (DevicePath
);
61 // Compute the size and add back in the size of the end device path structure
63 return ((UINTN
) DevicePath
- (UINTN
) Start
) + sizeof (EFI_DEVICE_PATH_PROTOCOL
);
67 This function appends the device path SecondDevicePath
68 to every device path instance in FirstDevicePath.
70 @param FirstDevicePath A pointer to a device path data structure.
72 @param SecondDevicePath A pointer to a device path data structure.
74 @return A pointer to the new device path is returned.
75 NULL is returned if space for the new device path could not be allocated from pool.
76 It is up to the caller to free the memory used by FirstDevicePath and SecondDevicePath
77 if they are no longer needed.
80 EFI_DEVICE_PATH_PROTOCOL
*
83 IN CONST EFI_DEVICE_PATH_PROTOCOL
*FirstDevicePath
,
84 IN CONST EFI_DEVICE_PATH_PROTOCOL
*SecondDevicePath
91 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
92 EFI_DEVICE_PATH_PROTOCOL
*DevicePath2
;
94 ASSERT (FirstDevicePath
!= NULL
&& SecondDevicePath
!= NULL
);
97 // Allocate space for the combined device path. It only has one end node of
98 // length EFI_DEVICE_PATH_PROTOCOL
100 Size1
= SmmGetDevicePathSize (FirstDevicePath
);
101 Size2
= SmmGetDevicePathSize (SecondDevicePath
);
102 Size
= Size1
+ Size2
- sizeof (EFI_DEVICE_PATH_PROTOCOL
);
104 Status
= mBS
->AllocatePool (EfiBootServicesData
, Size
, (VOID
**) &NewDevicePath
);
106 if (EFI_SUCCESS
== Status
) {
107 mBS
->CopyMem ((VOID
*) NewDevicePath
, (VOID
*) FirstDevicePath
, Size1
);
109 // Over write Src1 EndNode and do the copy
111 DevicePath2
= (EFI_DEVICE_PATH_PROTOCOL
*) ((CHAR8
*) NewDevicePath
+ (Size1
- sizeof (EFI_DEVICE_PATH_PROTOCOL
)));
112 mBS
->CopyMem ((VOID
*) DevicePath2
, (VOID
*) SecondDevicePath
, Size2
);
115 return NewDevicePath
;
119 Unload function that is registered in the LoadImage protocol. It un-installs
120 protocols produced and deallocates pool used by the driver. Called by the core
121 when unloading the driver.
123 @param ImageHandle ImageHandle of the unloaded driver
125 @return Status of the ProcessModuleUnloadList.
130 _DriverUnloadHandler (
131 EFI_HANDLE ImageHandle
137 // Call the unload handlers for all the modules
139 Status
= ProcessModuleUnloadList (ImageHandle
);
142 // If the driver specific unload handler does not return an error, then call all of the
143 // library destructors. If the unload handler returned an error, then the driver can not be
144 // unloaded, and the library destructors should not be called
146 if (!EFI_ERROR (Status
)) {
147 ProcessLibraryDestructorList (ImageHandle
, gST
);
151 // Return the status from the driver specific unload handler
157 Enrty point to DXE SMM Driver.
159 @param ImageHandle ImageHandle of the loaded driver.
160 @param SystemTable Pointer to the EFI System Table.
162 @retval EFI_SUCCESS One or more of the drivers returned a success code.
163 @retval !EFI_SUCESS The return status from the last driver entry point in the list.
169 IN EFI_HANDLE ImageHandle
,
170 IN EFI_SYSTEM_TABLE
*SystemTable
174 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
175 EFI_SMM_BASE_PROTOCOL
*SmmBase
;
177 EFI_DEVICE_PATH_PROTOCOL
*CompleteFilePath
;
178 EFI_DEVICE_PATH_PROTOCOL
*ImageDevicePath
;
182 // Cache a pointer to the Boot Services Table
184 mBS
= SystemTable
->BootServices
;
187 // Retrieve the Loaded Image Protocol
189 Status
= mBS
->HandleProtocol (
191 &gEfiLoadedImageProtocolGuid
,
194 ASSERT_EFI_ERROR (Status
);
197 // Retrieve SMM Base Protocol
199 Status
= mBS
->LocateProtocol (
200 &gEfiSmmBaseProtocolGuid
,
204 ASSERT_EFI_ERROR (Status
);
207 // Check to see if we are already in SMM
209 SmmBase
->InSmm (SmmBase
, &InSmm
);
216 // Retrieve the Device Path Protocol from the DeviceHandle tha this driver was loaded from
218 Status
= mBS
->HandleProtocol (
219 LoadedImage
->DeviceHandle
,
220 &gEfiDevicePathProtocolGuid
,
221 (VOID
*)&ImageDevicePath
223 ASSERT_EFI_ERROR (Status
);
226 // Build the full device path to the currently execuing image
228 CompleteFilePath
= SmmAppendDevicePath (ImageDevicePath
, LoadedImage
->FilePath
);
231 // Load the image in memory to SMRAM; it will automatically generate the
234 Status
= SmmBase
->Register (SmmBase
, CompleteFilePath
, NULL
, 0, &Handle
, FALSE
);
235 ASSERT_EFI_ERROR (Status
);
240 // Call constructor for all libraries
242 ProcessLibraryConstructorList (ImageHandle
, SystemTable
);
245 // Optionally install the unload handler
247 if (_gDriverUnloadImageCount
> 0) {
248 Status
= mBS
->HandleProtocol (
250 &gEfiLoadedImageProtocolGuid
,
251 (VOID
**)&LoadedImage
253 ASSERT_EFI_ERROR (Status
);
254 LoadedImage
->Unload
= _DriverUnloadHandler
;
258 // Call the list of driver entry points
260 Status
= ProcessModuleEntryPointList (ImageHandle
, SystemTable
);
261 if (EFI_ERROR (Status
)) {
262 ProcessLibraryDestructorList (ImageHandle
, SystemTable
);
269 Enrty point wrapper of DXE SMM Driver.
271 @param ImageHandle ImageHandle of the loaded driver.
272 @param SystemTable Pointer to the EFI System Table.
274 @retval EFI_SUCCESS One or more of the drivers returned a success code.
275 @retval !EFI_SUCESS The return status from the last driver entry point in the list.
281 IN EFI_HANDLE ImageHandle
,
282 IN EFI_SYSTEM_TABLE
*SystemTable
285 return _ModuleEntryPoint (ImageHandle
, SystemTable
);