OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcBootServicesTableLib.c
Go to the documentation of this file.
1
11#include <Uefi.h>
12
14#include <Library/BaseMemoryLib.h>
15#include <Library/DebugLib.h>
16#include <Library/DevicePathLib.h>
17
18#include <Protocol/DevicePath.h>
19#include <Protocol/LoadedImage.h>
20
26
27EFI_HANDLE gImageHandle = NULL;
28EFI_SYSTEM_TABLE *gST = NULL;
29EFI_BOOT_SERVICES *gBS = NULL;
30
31STATIC EFI_CONNECT_CONTROLLER mConnectController = NULL;
32STATIC EFI_OPEN_PROTOCOL mOpenProtocol = NULL;
33STATIC EFI_LOCATE_HANDLE_BUFFER mLocateHandleBuffer = NULL;
34STATIC EFI_LOCATE_PROTOCOL mLocateProtocol = NULL;
36STATIC UINTN mRegisteredProtocolCount = 0;
37
38STATIC
39EFI_STATUS
40EFIAPI
42 IN EFI_HANDLE ControllerHandle,
43 IN EFI_HANDLE *DriverImageHandle OPTIONAL,
44 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
45 IN BOOLEAN Recursive
46 )
47{
48 EFI_STATUS Status;
49 VOID *DevicePath;
50
51 if (ControllerHandle == NULL) {
52 return EFI_INVALID_PARAMETER;
53 }
54
55 //
56 // Do not connect controllers without device paths.
57 //
58 // REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2460
59 //
60 // Doing this reduces the amount of needless work during device
61 // connection and resolves issues with firmware that freeze
62 // when connecting handles without device paths.
63 //
64 Status = gBS->HandleProtocol (
65 ControllerHandle,
67 &DevicePath
68 );
69 if (EFI_ERROR (Status)) {
70 return EFI_NOT_FOUND;
71 }
72
73 Status = mConnectController (
74 ControllerHandle,
75 DriverImageHandle,
76 RemainingDevicePath,
77 Recursive
78 );
79
80 return Status;
81}
82
83STATIC
84EFI_STATUS
85EFIAPI
87 IN EFI_HANDLE Handle,
88 IN EFI_GUID *Protocol,
89 OUT VOID **Interface OPTIONAL,
90 IN EFI_HANDLE AgentHandle,
91 IN EFI_HANDLE ControllerHandle,
92 IN UINT32 Attributes
93 )
94{
95 EFI_STATUS Status;
96 UINTN Index;
97 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
98
99 Status = mOpenProtocol (
100 Handle,
101 Protocol,
102 Interface,
103 AgentHandle,
104 ControllerHandle,
105 Attributes
106 );
107
108 //
109 // On Apple EFI some paths may not be valid for our DevicePath library.
110 // As a result we can end up in an infinite loop in GetImageNameFromHandle
111 // calling "drivers" in the Shell. Workaround by discarding unsupported paths.
112 //
113 if ( !EFI_ERROR (Status)
115 && (Interface != NULL))
116 {
117 LoadedImage = *Interface;
118
119 if ((LoadedImage->FilePath != NULL) && !IsDevicePathValid (LoadedImage->FilePath, 0)) {
120 LoadedImage->FilePath = NULL;
121 }
122 }
123
124 if ((Status != EFI_UNSUPPORTED) || (Handle != gImageHandle)) {
125 return Status;
126 }
127
128 if ((Interface == NULL) && (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {
129 return EFI_INVALID_PARAMETER;
130 }
131
132 //
133 // Process all protocols as overrides are not specific to handle.
134 //
135 for (Index = 0; Index < mRegisteredProtocolCount; ++Index) {
136 if (CompareGuid (mRegisteredProtocols[Index].ProtocolGuid, Protocol)) {
137 if (Interface != NULL) {
138 *Interface = mRegisteredProtocols[Index].ProtocolInstance;
139 }
140
141 return EFI_SUCCESS;
142 }
143 }
144
145 return Status;
146}
147
148STATIC
149EFI_STATUS
150EFIAPI
152 IN EFI_LOCATE_SEARCH_TYPE SearchType,
153 IN EFI_GUID *Protocol OPTIONAL,
154 IN VOID *SearchKey OPTIONAL,
155 IN OUT UINTN *NoHandles,
156 OUT EFI_HANDLE **Buffer
157 )
158{
159 EFI_STATUS Status;
160 UINTN Index;
161
162 Status = mLocateHandleBuffer (
163 SearchType,
164 Protocol,
165 SearchKey,
166 NoHandles,
167 Buffer
168 );
169
170 if ((Status == EFI_NOT_FOUND) && (SearchType == ByProtocol)) {
171 //
172 // Process all protocols as overrides are not specific to handle.
173 //
174 for (Index = 0; Index < mRegisteredProtocolCount; ++Index) {
175 if (CompareGuid (mRegisteredProtocols[Index].ProtocolGuid, Protocol)) {
176 Status = gBS->AllocatePool (
177 EfiBootServicesData,
178 sizeof (**Buffer),
179 (VOID **)Buffer
180 );
181 if (!EFI_ERROR (Status)) {
182 *NoHandles = 1;
184 return EFI_SUCCESS;
185 }
186
187 return EFI_NOT_FOUND;
188 }
189 }
190 }
191
192 return Status;
193}
194
195STATIC
196EFI_STATUS
197EFIAPI
199 IN EFI_GUID *Protocol,
200 IN VOID *Registration OPTIONAL,
201 OUT VOID **Interface
202 )
203{
204 EFI_STATUS Status;
205 UINTN Index;
206
207 if ((Protocol == NULL) || (Interface == NULL)) {
208 return EFI_INVALID_PARAMETER;
209 }
210
211 //
212 // Process overriding protocols first.
213 //
214 for (Index = 0; Index < mRegisteredProtocolCount; ++Index) {
215 if ( mRegisteredProtocols[Index].Override
216 && CompareGuid (mRegisteredProtocols[Index].ProtocolGuid, Protocol))
217 {
218 *Interface = mRegisteredProtocols[Index].ProtocolInstance;
219 return EFI_SUCCESS;
220 }
221 }
222
223 //
224 // Call the original function second.
225 //
226 Status = mLocateProtocol (
227 Protocol,
228 Registration,
229 Interface
230 );
231
232 //
233 // Process fallback protocols third.
234 //
235 if (EFI_ERROR (Status)) {
236 for (Index = 0; Index < mRegisteredProtocolCount; ++Index) {
237 if ( !mRegisteredProtocols[Index].Override
238 && CompareGuid (mRegisteredProtocols[Index].ProtocolGuid, Protocol))
239 {
240 *Interface = mRegisteredProtocols[Index].ProtocolInstance;
241 return EFI_SUCCESS;
242 }
243 }
244 }
245
246 return Status;
247}
248
249EFI_STATUS
251 IN EFI_GUID *ProtocolGuid,
252 IN VOID *ProtocolInstance,
253 IN BOOLEAN Override
254 )
255{
257 return EFI_OUT_OF_RESOURCES;
258 }
259
263
265
266 return EFI_SUCCESS;
267}
268
269EFI_STATUS
270EFIAPI
272 IN EFI_HANDLE ImageHandle,
273 IN EFI_SYSTEM_TABLE *SystemTable
274 )
275{
276 EFI_STATUS Status;
277
278 //
279 // Assert on invalid startup arguments.
280 //
281 ASSERT (ImageHandle != NULL);
282 ASSERT (SystemTable != NULL);
283 ASSERT (SystemTable->BootServices != NULL);
284
285 //
286 // Cache the Image Handle.
287 //
288 gImageHandle = ImageHandle;
289
290 //
291 // Cache EFI System Table.
292 // Note, we cannot override it as it may be used for ConOut
293 // spoofing to redirect output for tools.
294 //
295 gST = SystemTable;
296
297 //
298 // Allocate a copy of EFI Boot Services Table.
299 //
300 Status = SystemTable->BootServices->AllocatePool (
301 EfiBootServicesData,
302 SystemTable->BootServices->Hdr.HeaderSize,
303 (VOID **)&gBS
304 );
305 if (EFI_ERROR (Status)) {
306 return Status;
307 }
308
309 //
310 // Copy the original EFI Boot Services Table into our custom table.
311 //
312 CopyMem (
313 gBS,
314 SystemTable->BootServices,
315 SystemTable->BootServices->Hdr.HeaderSize
316 );
317
318 //
319 // Override boot services functions and rehash.
320 //
321 mConnectController = gBS->ConnectController;
322 mOpenProtocol = gBS->OpenProtocol;
323 mLocateHandleBuffer = gBS->LocateHandleBuffer;
324 mLocateProtocol = gBS->LocateProtocol;
325 gBS->ConnectController = OcConnectController;
326 gBS->OpenProtocol = OcOpenProtocol;
327 gBS->LocateHandleBuffer = OcLocateHandleBuffer;
328 gBS->LocateProtocol = OcLocateProtocol;
329 gBS->Hdr.CRC32 = 0;
330 SystemTable->BootServices->CalculateCrc32 (
331 gBS,
332 gBS->Hdr.HeaderSize,
333 &gBS->Hdr.CRC32
334 );
335
336 return EFI_SUCCESS;
337}
338
339EFI_STATUS
340EFIAPI
342 IN EFI_HANDLE ImageHandle,
343 IN EFI_SYSTEM_TABLE *SystemTable
344 )
345{
346 //
347 // Free memory for table copies.
348 //
349 SystemTable->BootServices->FreePool (gBS);
350 return EFI_SUCCESS;
351}
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
EFI_SYSTEM_TABLE * gST
STATIC EFI_CONNECT_CONTROLLER mConnectController
EFI_STATUS EFIAPI OcBootServicesTableLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_OPEN_PROTOCOL mOpenProtocol
STATIC EFI_STATUS EFIAPI OcConnectController(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE *DriverImageHandle OPTIONAL, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, IN BOOLEAN Recursive)
EFI_STATUS EFIAPI OcBootServicesTableLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC EFI_LOCATE_HANDLE_BUFFER mLocateHandleBuffer
EFI_HANDLE gImageHandle
STATIC OC_REGISTERED_PROTOCOL mRegisteredProtocols[16]
STATIC EFI_LOCATE_PROTOCOL mLocateProtocol
STATIC EFI_STATUS EFIAPI OcOpenProtocol(IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT VOID **Interface OPTIONAL, IN EFI_HANDLE AgentHandle, IN EFI_HANDLE ControllerHandle, IN UINT32 Attributes)
STATIC EFI_STATUS EFIAPI OcLocateHandleBuffer(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *NoHandles, OUT EFI_HANDLE **Buffer)
EFI_STATUS OcRegisterBootServicesProtocol(IN EFI_GUID *ProtocolGuid, IN VOID *ProtocolInstance, IN BOOLEAN Override)
struct OC_REGISTERED_PROTOCOL_ OC_REGISTERED_PROTOCOL
STATIC UINTN mRegisteredProtocolCount
EFI_BOOT_SERVICES * gBS
STATIC EFI_STATUS EFIAPI OcLocateProtocol(IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface)
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
EFI_GUID gEfiLoadedImageProtocolGuid
EFI_GUID gEfiDevicePathProtocolGuid
#define ASSERT(x)
Definition coder.h:55