]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkPkg/Library/DxeSmmDriverEntryPoint/DriverEntryPoint.c
Add comments for library function interface.
[mirror_edk2.git] / IntelFrameworkPkg / Library / DxeSmmDriverEntryPoint / DriverEntryPoint.c
CommitLineData
79964ac8 1/** @file\r
bb557845 2 This file implement EfiMain() for library class DxeSmmDriverEntryPoint.\r
3 EfiMain() is common driver entry point for all SMM driver who uses DxeSmmDriverEntryPoint\r
4 library class.\r
79964ac8 5\r
6Copyright (c) 2006, Intel Corporation<BR>\r
7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
ed7748fe 17\r
564995cd 18#include <FrameworkSmm.h>\r
ed7748fe 19\r
564995cd 20#include <Protocol/LoadedImage.h>\r
21#include <Protocol/SmmBase.h>\r
22#include <Protocol/DevicePath.h>\r
ed7748fe 23\r
564995cd 24#include <Library/DxeSmmDriverEntryPoint.h>\r
79964ac8 25#include <Library/UefiBootServicesTableLib.h>\r
26#include <Library/DebugLib.h>\r
79964ac8 27\r
79964ac8 28\r
29EFI_BOOT_SERVICES *mBS;\r
30\r
31/**\r
32 This function returns the size, in bytes,\r
33 of the device path data structure specified by DevicePath.\r
34 If DevicePath is NULL, then 0 is returned.\r
35\r
36 @param DevicePath A pointer to a device path data structure.\r
37\r
38 @return The size of a device path in bytes.\r
39\r
40**/\r
41STATIC\r
42UINTN\r
43EFIAPI\r
44SmmGetDevicePathSize (\r
45 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
46 )\r
47{\r
48 CONST EFI_DEVICE_PATH_PROTOCOL *Start;\r
49\r
50 if (DevicePath == NULL) {\r
51 return 0;\r
52 }\r
53\r
54 //\r
55 // Search for the end of the device path structure\r
56 //\r
57 Start = DevicePath;\r
58 while (!EfiIsDevicePathEnd (DevicePath)) {\r
59 DevicePath = EfiNextDevicePathNode (DevicePath);\r
60 }\r
61\r
62 //\r
63 // Compute the size and add back in the size of the end device path structure\r
64 //\r
65 return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
66}\r
67\r
68/**\r
69 This function appends the device path SecondDevicePath\r
70 to every device path instance in FirstDevicePath.\r
71\r
72 @param FirstDevicePath A pointer to a device path data structure.\r
73\r
74 @param SecondDevicePath A pointer to a device path data structure.\r
75\r
76 @return A pointer to the new device path is returned.\r
77 NULL is returned if space for the new device path could not be allocated from pool.\r
78 It is up to the caller to free the memory used by FirstDevicePath and SecondDevicePath\r
79 if they are no longer needed.\r
80\r
81**/\r
82EFI_DEVICE_PATH_PROTOCOL *\r
83EFIAPI\r
84SmmAppendDevicePath (\r
85 IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,\r
86 IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath\r
87 )\r
88{\r
89 EFI_STATUS Status;\r
90 UINTN Size;\r
91 UINTN Size1;\r
92 UINTN Size2;\r
93 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
94 EFI_DEVICE_PATH_PROTOCOL *DevicePath2;\r
95\r
96 ASSERT (FirstDevicePath != NULL && SecondDevicePath != NULL);\r
97\r
98 //\r
99 // Allocate space for the combined device path. It only has one end node of\r
100 // length EFI_DEVICE_PATH_PROTOCOL\r
101 //\r
102 Size1 = SmmGetDevicePathSize (FirstDevicePath);\r
103 Size2 = SmmGetDevicePathSize (SecondDevicePath);\r
104 Size = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
105\r
106 Status = mBS->AllocatePool (EfiBootServicesData, Size, (VOID **) &NewDevicePath);\r
107\r
108 if (EFI_SUCCESS == Status) {\r
109 mBS->CopyMem ((VOID *) NewDevicePath, (VOID *) FirstDevicePath, Size1);\r
110 //\r
111 // Over write Src1 EndNode and do the copy\r
112 //\r
113 DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));\r
114 mBS->CopyMem ((VOID *) DevicePath2, (VOID *) SecondDevicePath, Size2);\r
115 }\r
116\r
117 return NewDevicePath;\r
118}\r
119\r
120/**\r
121 Unload function that is registered in the LoadImage protocol. It un-installs\r
122 protocols produced and deallocates pool used by the driver. Called by the core\r
123 when unloading the driver.\r
124\r
125 @param ImageHandle ImageHandle of the unloaded driver\r
126\r
127 @return Status of the ProcessModuleUnloadList.\r
128\r
129**/\r
130EFI_STATUS\r
131EFIAPI\r
132_DriverUnloadHandler (\r
133 EFI_HANDLE ImageHandle\r
134 )\r
135{\r
136 EFI_STATUS Status;\r
137\r
138 //\r
139 // Call the unload handlers for all the modules\r
140 //\r
141 Status = ProcessModuleUnloadList (ImageHandle);\r
142\r
143 //\r
144 // If the driver specific unload handler does not return an error, then call all of the\r
145 // library destructors. If the unload handler returned an error, then the driver can not be\r
146 // unloaded, and the library destructors should not be called\r
147 //\r
148 if (!EFI_ERROR (Status)) {\r
149 ProcessLibraryDestructorList (ImageHandle, gST);\r
150 }\r
151\r
152 //\r
153 // Return the status from the driver specific unload handler\r
154 //\r
155 return Status;\r
156}\r
157\r
158/**\r
159 Enrty point to DXE SMM Driver.\r
160\r
161 @param ImageHandle ImageHandle of the loaded driver.\r
162 @param SystemTable Pointer to the EFI System Table.\r
163\r
164 @retval EFI_SUCCESS One or more of the drivers returned a success code.\r
165 @retval !EFI_SUCESS The return status from the last driver entry point in the list.\r
166\r
167**/\r
168EFI_STATUS\r
169EFIAPI\r
170_ModuleEntryPoint (\r
171 IN EFI_HANDLE ImageHandle,\r
172 IN EFI_SYSTEM_TABLE *SystemTable\r
173 )\r
174{\r
175 EFI_STATUS Status;\r
176 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
177 EFI_SMM_BASE_PROTOCOL *SmmBase;\r
178 BOOLEAN InSmm;\r
179 EFI_DEVICE_PATH_PROTOCOL *CompleteFilePath;\r
180 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;\r
181 EFI_HANDLE Handle;\r
182\r
183 //\r
184 // Cache a pointer to the Boot Services Table\r
185 //\r
186 mBS = SystemTable->BootServices;\r
187\r
188 //\r
189 // Retrieve the Loaded Image Protocol\r
190 //\r
191 Status = mBS->HandleProtocol (\r
192 ImageHandle,\r
193 &gEfiLoadedImageProtocolGuid,\r
194 (VOID*)&LoadedImage\r
195 );\r
196 ASSERT_EFI_ERROR (Status);\r
197\r
198 //\r
199 // Retrieve SMM Base Protocol\r
200 //\r
201 Status = mBS->LocateProtocol (\r
202 &gEfiSmmBaseProtocolGuid,\r
203 NULL,\r
204 (VOID **) &SmmBase\r
205 );\r
206 ASSERT_EFI_ERROR (Status);\r
207\r
208 //\r
209 // Check to see if we are already in SMM\r
210 //\r
211 SmmBase->InSmm (SmmBase, &InSmm);\r
212\r
213 //\r
214 //\r
215 //\r
216 if (!InSmm) {\r
217 //\r
218 // Retrieve the Device Path Protocol from the DeviceHandle tha this driver was loaded from\r
219 //\r
220 Status = mBS->HandleProtocol (\r
221 LoadedImage->DeviceHandle,\r
222 &gEfiDevicePathProtocolGuid,\r
223 (VOID*)&ImageDevicePath\r
224 );\r
225 ASSERT_EFI_ERROR (Status);\r
226\r
227 //\r
228 // Build the full device path to the currently execuing image\r
229 //\r
230 CompleteFilePath = SmmAppendDevicePath (ImageDevicePath, LoadedImage->FilePath);\r
231\r
232 //\r
233 // Load the image in memory to SMRAM; it will automatically generate the\r
234 // SMI.\r
235 //\r
236 Status = SmmBase->Register (SmmBase, CompleteFilePath, NULL, 0, &Handle, FALSE);\r
237 ASSERT_EFI_ERROR (Status);\r
238 return Status;\r
239 }\r
240\r
241 //\r
242 // Call constructor for all libraries\r
243 //\r
244 ProcessLibraryConstructorList (ImageHandle, SystemTable);\r
245\r
246 //\r
247 // Optionally install the unload handler\r
248 //\r
249 if (_gDriverUnloadImageCount > 0) {\r
250 Status = mBS->HandleProtocol (\r
251 ImageHandle,\r
252 &gEfiLoadedImageProtocolGuid,\r
253 (VOID **)&LoadedImage\r
254 );\r
255 ASSERT_EFI_ERROR (Status);\r
256 LoadedImage->Unload = _DriverUnloadHandler;\r
257 }\r
258\r
259 //\r
260 // Call the list of driver entry points\r
261 //\r
262 Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);\r
263 if (EFI_ERROR (Status)) {\r
264 ProcessLibraryDestructorList (ImageHandle, SystemTable);\r
265 }\r
266\r
267 return Status;\r
268}\r
269\r
270/**\r
271 Enrty point wrapper of DXE SMM Driver.\r
272\r
273 @param ImageHandle ImageHandle of the loaded driver.\r
274 @param SystemTable Pointer to the EFI System Table.\r
275\r
276 @retval EFI_SUCCESS One or more of the drivers returned a success code.\r
277 @retval !EFI_SUCESS The return status from the last driver entry point in the list.\r
278\r
279**/\r
280EFI_STATUS\r
281EFIAPI\r
282EfiMain (\r
283 IN EFI_HANDLE ImageHandle,\r
284 IN EFI_SYSTEM_TABLE *SystemTable\r
285 )\r
286{\r
287 return _ModuleEntryPoint (ImageHandle, SystemTable);\r
288}\r