]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/UefiDriverEntryPoint/DriverEntryPoint.c
57b6a755b2535ab7f844d65147b4bc846e1e2346
[mirror_edk2.git] / MdePkg / Library / UefiDriverEntryPoint / 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 EFI_EVENT _mDriverExitBootServicesNotifyEvent;
17
18 /**
19 Unload function that is registered in the LoadImage protocol. It un-installs
20 protocols produced and deallocates pool used by the driver. Called by the core
21 when unloading the driver.
22
23 @param ImageHandle
24
25 @retval EFI_SUCCESS
26
27 **/
28 EFI_STATUS
29 EFIAPI
30 _DriverUnloadHandler (
31 EFI_HANDLE ImageHandle
32 )
33 {
34 EFI_STATUS Status;
35
36 //
37 // If an UnloadImage() handler is specified, then call it
38 //
39 Status = ProcessModuleUnloadList (ImageHandle);
40
41 //
42 // If the driver specific unload handler does not return an error, then call all of the
43 // library destructors. If the unload handler returned an error, then the driver can not be
44 // unloaded, and the library destructors should not be called
45 //
46 if (!EFI_ERROR (Status)) {
47 //
48 // Close our ExitBootServices () notify function
49 //
50 if (_gDriverExitBootServicesEvent[0] != NULL) {
51 Status = gBS->CloseEvent (_mDriverExitBootServicesNotifyEvent);
52 ASSERT_EFI_ERROR (Status);
53 }
54
55 ProcessLibraryDestructorList (ImageHandle, gST);
56 }
57
58 //
59 // Return the status from the driver specific unload handler
60 //
61 return Status;
62 }
63
64
65 /**
66 Notification Entry of ExitBootService event. In the entry, all notifications in _gDriverExitBootServicesEvent[]
67 would be invoked.
68
69 @param Event The Event that is being processed.
70 @param Context Event Context.
71
72 **/
73 VOID
74 EFIAPI
75 _DriverExitBootServices (
76 IN EFI_EVENT Event,
77 IN VOID *Context
78 )
79 {
80 EFI_EVENT_NOTIFY ChildNotifyEventHandler;
81 UINTN Index;
82
83 for (Index = 0; _gDriverExitBootServicesEvent[Index] != NULL; Index++) {
84 ChildNotifyEventHandler = _gDriverExitBootServicesEvent[Index];
85 ChildNotifyEventHandler (Event, NULL);
86 }
87 }
88
89 /**
90 Enrty point to DXE Driver.
91
92 @param ImageHandle ImageHandle of the loaded driver.
93 @param SystemTable Pointer to the EFI System Table.
94
95 @retval EFI_SUCCESS One or more of the drivers returned a success code.
96 @retval !EFI_SUCESS The return status from the last driver entry point in the list.
97
98 **/
99 EFI_STATUS
100 EFIAPI
101 _ModuleEntryPoint (
102 IN EFI_HANDLE ImageHandle,
103 IN EFI_SYSTEM_TABLE *SystemTable
104 )
105 {
106 EFI_STATUS Status;
107 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
108
109 if (_gUefiDriverRevision != 0) {
110 //
111 // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the driver
112 //
113 if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {
114 return EFI_INCOMPATIBLE_VERSION;
115 }
116 }
117
118 //
119 // Call constructor for all libraries
120 //
121 ProcessLibraryConstructorList (ImageHandle, SystemTable);
122
123 //
124 // Register our ExitBootServices () notify function
125 //
126 if (_gDriverExitBootServicesEvent[0] != NULL) {
127 Status = gBS->CreateEvent (
128 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
129 EFI_TPL_NOTIFY,
130 _DriverExitBootServices,
131 NULL,
132 &_mDriverExitBootServicesNotifyEvent
133 );
134
135 ASSERT_EFI_ERROR (Status);
136 }
137
138 //
139 // Install unload handler...
140 //
141 if (_gDriverUnloadImageCount != 0) {
142 Status = gBS->HandleProtocol (
143 ImageHandle,
144 &gEfiLoadedImageProtocolGuid,
145 (VOID **)&LoadedImage
146 );
147 ASSERT_EFI_ERROR (Status);
148 LoadedImage->Unload = _DriverUnloadHandler;
149 }
150
151 //
152 // Call the driver entry point
153 //
154 Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);
155
156 //
157 // If all of the drivers returned errors, then invoke all of the library destructors
158 //
159 if (EFI_ERROR (Status)) {
160 //
161 // Close our ExitBootServices () notify function
162 //
163 if (_gDriverExitBootServicesEvent[0] != NULL) {
164 Status = gBS->CloseEvent (_mDriverExitBootServicesNotifyEvent);
165 ASSERT_EFI_ERROR (Status);
166 }
167
168 ProcessLibraryDestructorList (ImageHandle, SystemTable);
169 }
170
171 //
172 // Return the cummalative return status code from all of the driver entry points
173 //
174 return Status;
175 }
176
177
178 /**
179 Enrty point wrapper of DXE Driver.
180
181 @param ImageHandle ImageHandle of the loaded driver.
182 @param SystemTable Pointer to the EFI System Table.
183
184 @retval EFI_SUCCESS One or more of the drivers returned a success code.
185 @retval !EFI_SUCESS The return status from the last driver entry point in the list.
186
187 **/
188 EFI_STATUS
189 EFIAPI
190 EfiMain (
191 IN EFI_HANDLE ImageHandle,
192 IN EFI_SYSTEM_TABLE *SystemTable
193 )
194 {
195 return _ModuleEntryPoint (ImageHandle, SystemTable);
196 }