]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkPkg/Library/DxeSmmDriverEntryPoint/DriverEntryPoint.c
remove some comments introduced by tools.
[mirror_edk2.git] / IntelFrameworkPkg / Library / DxeSmmDriverEntryPoint / DriverEntryPoint.c
1 /** @file
2 Entry point to a EFI/DXE driver.
3
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
9
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.
12
13 **/
14
15
16 #include <FrameworkSmm.h>
17
18 #include <Protocol/LoadedImage.h>
19 #include <Protocol/SmmBase.h>
20 #include <Protocol/DevicePath.h>
21
22 #include <Library/DxeSmmDriverEntryPoint.h>
23 #include <Library/UefiBootServicesTableLib.h>
24 #include <Library/DebugLib.h>
25
26
27 EFI_BOOT_SERVICES *mBS;
28
29 /**
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.
33
34 @param DevicePath A pointer to a device path data structure.
35
36 @return The size of a device path in bytes.
37
38 **/
39 STATIC
40 UINTN
41 EFIAPI
42 SmmGetDevicePathSize (
43 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
44 )
45 {
46 CONST EFI_DEVICE_PATH_PROTOCOL *Start;
47
48 if (DevicePath == NULL) {
49 return 0;
50 }
51
52 //
53 // Search for the end of the device path structure
54 //
55 Start = DevicePath;
56 while (!EfiIsDevicePathEnd (DevicePath)) {
57 DevicePath = EfiNextDevicePathNode (DevicePath);
58 }
59
60 //
61 // Compute the size and add back in the size of the end device path structure
62 //
63 return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
64 }
65
66 /**
67 This function appends the device path SecondDevicePath
68 to every device path instance in FirstDevicePath.
69
70 @param FirstDevicePath A pointer to a device path data structure.
71
72 @param SecondDevicePath A pointer to a device path data structure.
73
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.
78
79 **/
80 EFI_DEVICE_PATH_PROTOCOL *
81 EFIAPI
82 SmmAppendDevicePath (
83 IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,
84 IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath
85 )
86 {
87 EFI_STATUS Status;
88 UINTN Size;
89 UINTN Size1;
90 UINTN Size2;
91 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
92 EFI_DEVICE_PATH_PROTOCOL *DevicePath2;
93
94 ASSERT (FirstDevicePath != NULL && SecondDevicePath != NULL);
95
96 //
97 // Allocate space for the combined device path. It only has one end node of
98 // length EFI_DEVICE_PATH_PROTOCOL
99 //
100 Size1 = SmmGetDevicePathSize (FirstDevicePath);
101 Size2 = SmmGetDevicePathSize (SecondDevicePath);
102 Size = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);
103
104 Status = mBS->AllocatePool (EfiBootServicesData, Size, (VOID **) &NewDevicePath);
105
106 if (EFI_SUCCESS == Status) {
107 mBS->CopyMem ((VOID *) NewDevicePath, (VOID *) FirstDevicePath, Size1);
108 //
109 // Over write Src1 EndNode and do the copy
110 //
111 DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
112 mBS->CopyMem ((VOID *) DevicePath2, (VOID *) SecondDevicePath, Size2);
113 }
114
115 return NewDevicePath;
116 }
117
118 /**
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.
122
123 @param ImageHandle ImageHandle of the unloaded driver
124
125 @return Status of the ProcessModuleUnloadList.
126
127 **/
128 EFI_STATUS
129 EFIAPI
130 _DriverUnloadHandler (
131 EFI_HANDLE ImageHandle
132 )
133 {
134 EFI_STATUS Status;
135
136 //
137 // Call the unload handlers for all the modules
138 //
139 Status = ProcessModuleUnloadList (ImageHandle);
140
141 //
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
145 //
146 if (!EFI_ERROR (Status)) {
147 ProcessLibraryDestructorList (ImageHandle, gST);
148 }
149
150 //
151 // Return the status from the driver specific unload handler
152 //
153 return Status;
154 }
155
156 /**
157 Enrty point to DXE SMM Driver.
158
159 @param ImageHandle ImageHandle of the loaded driver.
160 @param SystemTable Pointer to the EFI System Table.
161
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.
164
165 **/
166 EFI_STATUS
167 EFIAPI
168 _ModuleEntryPoint (
169 IN EFI_HANDLE ImageHandle,
170 IN EFI_SYSTEM_TABLE *SystemTable
171 )
172 {
173 EFI_STATUS Status;
174 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
175 EFI_SMM_BASE_PROTOCOL *SmmBase;
176 BOOLEAN InSmm;
177 EFI_DEVICE_PATH_PROTOCOL *CompleteFilePath;
178 EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
179 EFI_HANDLE Handle;
180
181 //
182 // Cache a pointer to the Boot Services Table
183 //
184 mBS = SystemTable->BootServices;
185
186 //
187 // Retrieve the Loaded Image Protocol
188 //
189 Status = mBS->HandleProtocol (
190 ImageHandle,
191 &gEfiLoadedImageProtocolGuid,
192 (VOID*)&LoadedImage
193 );
194 ASSERT_EFI_ERROR (Status);
195
196 //
197 // Retrieve SMM Base Protocol
198 //
199 Status = mBS->LocateProtocol (
200 &gEfiSmmBaseProtocolGuid,
201 NULL,
202 (VOID **) &SmmBase
203 );
204 ASSERT_EFI_ERROR (Status);
205
206 //
207 // Check to see if we are already in SMM
208 //
209 SmmBase->InSmm (SmmBase, &InSmm);
210
211 //
212 //
213 //
214 if (!InSmm) {
215 //
216 // Retrieve the Device Path Protocol from the DeviceHandle tha this driver was loaded from
217 //
218 Status = mBS->HandleProtocol (
219 LoadedImage->DeviceHandle,
220 &gEfiDevicePathProtocolGuid,
221 (VOID*)&ImageDevicePath
222 );
223 ASSERT_EFI_ERROR (Status);
224
225 //
226 // Build the full device path to the currently execuing image
227 //
228 CompleteFilePath = SmmAppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
229
230 //
231 // Load the image in memory to SMRAM; it will automatically generate the
232 // SMI.
233 //
234 Status = SmmBase->Register (SmmBase, CompleteFilePath, NULL, 0, &Handle, FALSE);
235 ASSERT_EFI_ERROR (Status);
236 return Status;
237 }
238
239 //
240 // Call constructor for all libraries
241 //
242 ProcessLibraryConstructorList (ImageHandle, SystemTable);
243
244 //
245 // Optionally install the unload handler
246 //
247 if (_gDriverUnloadImageCount > 0) {
248 Status = mBS->HandleProtocol (
249 ImageHandle,
250 &gEfiLoadedImageProtocolGuid,
251 (VOID **)&LoadedImage
252 );
253 ASSERT_EFI_ERROR (Status);
254 LoadedImage->Unload = _DriverUnloadHandler;
255 }
256
257 //
258 // Call the list of driver entry points
259 //
260 Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);
261 if (EFI_ERROR (Status)) {
262 ProcessLibraryDestructorList (ImageHandle, SystemTable);
263 }
264
265 return Status;
266 }
267
268 /**
269 Enrty point wrapper of DXE SMM Driver.
270
271 @param ImageHandle ImageHandle of the loaded driver.
272 @param SystemTable Pointer to the EFI System Table.
273
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.
276
277 **/
278 EFI_STATUS
279 EFIAPI
280 EfiMain (
281 IN EFI_HANDLE ImageHandle,
282 IN EFI_SYSTEM_TABLE *SystemTable
283 )
284 {
285 return _ModuleEntryPoint (ImageHandle, SystemTable);
286 }