OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
ConsoleGop.c
Go to the documentation of this file.
1
16#include "ConsoleGopInternal.h"
17
20#include <Protocol/GraphicsOutput.h>
21#include <Protocol/SimpleTextOut.h>
22
23#include <Library/BaseMemoryLib.h>
24#include <Library/BaseOverflowLib.h>
25#include <Library/BaseLib.h>
26#include <Library/DebugLib.h>
27#include <Library/OcBlitLib.h>
28#include <Library/MemoryAllocationLib.h>
29#include <Library/MtrrLib.h>
31#include <Library/OcMiscLib.h>
32#include <Library/UefiBootServicesTableLib.h>
33#include <Library/UefiRuntimeServicesTableLib.h>
34
36
37STATIC
38EFI_STATUS
39EFIAPI
41 IN EFI_HANDLE Handle,
42 IN EFI_GUID *Protocol,
43 OUT VOID **Interface
44 )
45{
46 EFI_STATUS Status;
47
48 Status = mGop.OriginalHandleProtocol (Handle, Protocol, Interface);
49
50 if ((Status != EFI_UNSUPPORTED) && EFI_ERROR (Status)) {
51 return Status;
52 }
53
54 if ((mGop.ConsoleGop != NULL) && CompareGuid (&gEfiGraphicsOutputProtocolGuid, Protocol)) {
55 *Interface = mGop.ConsoleGop;
56 return EFI_SUCCESS;
57 }
58
59 if (!EFI_ERROR (Status)) {
60 return Status;
61 }
62
63 if (CompareGuid (&gEfiUgaDrawProtocolGuid, Protocol)) {
64 //
65 // EfiBoot from 10.4 can only use UgaDraw protocol.
66 //
67 Status = gBS->LocateProtocol (
69 NULL,
70 Interface
71 );
72 if (!EFI_ERROR (Status)) {
73 return EFI_SUCCESS;
74 }
75 }
76
77 return EFI_UNSUPPORTED;
78}
79
80EFI_STATUS
82 IN BOOLEAN Route
83 )
84{
85 EFI_STATUS Status;
86 EFI_GRAPHICS_OUTPUT_PROTOCOL *OriginalGop;
87 EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
88 UINTN HandleCount;
89 EFI_HANDLE *HandleBuffer;
90 UINTN Index;
91
92 //
93 // Shell may replace gST->ConsoleOutHandle, so we have to ensure
94 // that HandleProtocol always reports valid chosen GOP.
95 //
96 if (Route) {
97 mGop.OriginalHandleProtocol = gBS->HandleProtocol;
98 gBS->HandleProtocol = ConsoleHandleProtocol;
99 gBS->Hdr.CRC32 = 0;
100 gBS->CalculateCrc32 (gBS, gBS->Hdr.HeaderSize, &gBS->Hdr.CRC32);
101 }
102
103 OriginalGop = NULL;
104 Status = gBS->HandleProtocol (
105 gST->ConsoleOutHandle,
107 (VOID **)&OriginalGop
108 );
109
110 if (!EFI_ERROR (Status)) {
111 DEBUG ((
112 DEBUG_INFO,
113 "OCC: GOP exists on ConsoleOutHandle and has %u modes\n",
114 (UINT32)OriginalGop->Mode->MaxMode
115 ));
116
117 if (OriginalGop->Mode->Info->PixelFormat == PixelBltOnly) {
118 //
119 // ASUS Z690F has GOP aggregator on console handle with blit only
120 // formats. This GOP obviously does not work on macOS, so we need
121 // to uninstall it, but only when we have an alternative.
122 //
123 DEBUG ((
124 DEBUG_INFO,
125 "OCC: Looking for GOP replacement due to blit-only GOP\n"
126 ));
127 } else if (OriginalGop->Mode->MaxMode == 0) {
128 //
129 // No modes on MacPro5,1 with Mac EFI incompatible GPU.
130 // Here we need to uninstall ConOut GOP in favour of GPU GOP.
131 //
132 DEBUG ((
133 DEBUG_INFO,
134 "OCC: Looking for GOP replacement due to invalid mode count\n"
135 ));
136 } else {
137 mGop.ConsoleGop = OriginalGop;
138 return EFI_ALREADY_STARTED;
139 }
140
141 Status = gBS->LocateHandleBuffer (
142 ByProtocol,
144 NULL,
145 &HandleCount,
146 &HandleBuffer
147 );
148
149 if (EFI_ERROR (Status)) {
150 DEBUG ((DEBUG_INFO, "OCC: No handles with GOP protocol - %r\n", Status));
151 return EFI_UNSUPPORTED;
152 }
153
154 Status = EFI_NOT_FOUND;
155 for (Index = 0; Index < HandleCount; ++Index) {
156 if (HandleBuffer[Index] != gST->ConsoleOutHandle) {
157 Status = gBS->HandleProtocol (
158 HandleBuffer[Index],
160 (VOID **)&Gop
161 );
162 break;
163 }
164 }
165
166 DEBUG ((DEBUG_INFO, "OCC: Alternative GOP status is - %r\n", Status));
167 FreePool (HandleBuffer);
168
169 if ( !EFI_ERROR (Status)
170 && (OriginalGop->Mode->Info->PixelFormat == PixelBltOnly))
171 {
172 if ((UINT32)Gop->Mode->Info->PixelFormat >= PixelBltOnly) {
173 Status = EFI_NOT_FOUND;
174 }
175
176 DEBUG ((
177 DEBUG_INFO,
178 "OCC: Checking alternative GOP mode %u - %r\n",
179 Gop->Mode->Info->PixelFormat,
180 Status
181 ));
182
183 //
184 // We cannot uninstall this GOP as ASUS will reinstall it.
185 // Hook HandleProtocol instead.
186 //
187 if (!EFI_ERROR (Status)) {
188 mGop.ConsoleGop = Gop;
189 return EFI_SUCCESS;
190 }
191 }
192
193 if (!EFI_ERROR (Status)) {
194 gBS->UninstallProtocolInterface (
195 gST->ConsoleOutHandle,
197 OriginalGop
198 );
199 }
200 } else {
201 DEBUG ((DEBUG_INFO, "OCC: Installing GOP (%r) on ConsoleOutHandle...\n", Status));
202 Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, (VOID **)&Gop);
203 }
204
205 if (!EFI_ERROR (Status)) {
206 Status = gBS->InstallMultipleProtocolInterfaces (
207 &gST->ConsoleOutHandle,
209 Gop,
210 NULL
211 );
212 if (EFI_ERROR (Status)) {
213 DEBUG ((DEBUG_WARN, "OCC: Failed to install GOP on ConsoleOutHandle - %r\n", Status));
214 }
215
216 mGop.ConsoleGop = Gop;
217 } else {
218 DEBUG ((DEBUG_WARN, "OCC: Missing compatible GOP - %r\n", Status));
219 }
220
221 return Status;
222}
223
232STATIC
233VOID
235 IN OUT EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
236 IN BOOLEAN UseCustom
237 )
238{
239 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Source;
240
241 ASSERT (This != NULL);
242 ASSERT (This->Mode != NULL);
243 ASSERT (This->Mode->Info != NULL);
244
245 if (UseCustom) {
246 Source = &mGop.CustomModeInfo;
247 This->Mode->FrameBufferBase = 0;
248 This->Mode->FrameBufferSize = 0;
249 } else {
250 Source = &mGop.OriginalModeInfo;
251 This->Mode->FrameBufferBase = mGop.OriginalFrameBufferBase;
252 This->Mode->FrameBufferSize = mGop.OriginalFrameBufferSize;
253 }
254
255 This->Mode->Info->VerticalResolution = Source->VerticalResolution;
256 This->Mode->Info->HorizontalResolution = Source->HorizontalResolution;
257 This->Mode->Info->PixelsPerScanLine = Source->PixelsPerScanLine;
258}
259
267STATIC
268VOID
270 IN OUT EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
271 IN UINT32 Rotation
272 )
273{
274 ASSERT (This != NULL);
275 ASSERT (This->Mode != NULL);
276 ASSERT (This->Mode->Info != NULL);
277
278 CopyMem (&mGop.OriginalModeInfo, This->Mode->Info, sizeof (mGop.OriginalModeInfo));
279
280 if ((Rotation == 90) || (Rotation == 270)) {
281 This->Mode->Info->HorizontalResolution = mGop.OriginalModeInfo.VerticalResolution;
282 This->Mode->Info->VerticalResolution = mGop.OriginalModeInfo.HorizontalResolution;
283 This->Mode->Info->PixelsPerScanLine = This->Mode->Info->HorizontalResolution;
284 }
285
286 mGop.OriginalFrameBufferBase = This->Mode->FrameBufferBase;
287 mGop.OriginalFrameBufferSize = This->Mode->FrameBufferSize;
288
289 if (Rotation != 0) {
290 //
291 // macOS requires FrameBufferBase to be 0 for rotation to work, which
292 // forces it inspect the AppleFramebufferInfo protocol.
293 // It also requires PixelFormat to be <= PixelBitMask, otherwise Apple
294 // logo will not show.
295 // REF: https://github.com/acidanthera/bugtracker/issues/1498#issuecomment-782822654
296 //
297 // Windows and Linux bootloaders only draw directly to the framebuffer.
298 //
299 This->Mode->FrameBufferBase = 0;
300 This->Mode->FrameBufferSize = 0;
301 }
302
303 CopyMem (&mGop.CustomModeInfo, This->Mode->Info, sizeof (mGop.CustomModeInfo));
304}
305
306STATIC
308EFIAPI
310 IN EFI_PHYSICAL_ADDRESS FramebufferBase,
311 IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info,
312 OUT UINTN *PageCount
313 )
314{
315 EFI_STATUS Status;
316 UINTN ConfigureSize;
317 OC_BLIT_CONFIGURE *Context;
318
319 ConfigureSize = 0;
320 Status = OcBlitConfigure (
321 (VOID *)(UINTN)FramebufferBase,
322 Info,
324 NULL,
325 &ConfigureSize
326 );
327 if (Status != EFI_BUFFER_TOO_SMALL) {
328 return NULL;
329 }
330
331 *PageCount = EFI_SIZE_TO_PAGES (ConfigureSize);
332 Context = AllocatePages (*PageCount);
333 if (Context == NULL) {
334 return NULL;
335 }
336
337 Status = OcBlitConfigure (
338 (VOID *)(UINTN)FramebufferBase,
339 Info,
341 Context,
342 &ConfigureSize
343 );
344 if (EFI_ERROR (Status)) {
345 FreePages (Context, *PageCount);
346 return NULL;
347 }
348
349 return Context;
350}
351
352STATIC
353EFI_STATUS
354EFIAPI
356 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
357 IN UINT32 ModeNumber
358 )
359{
360 EFI_STATUS Status;
361 EFI_TPL OldTpl;
362 OC_BLIT_CONFIGURE *Original;
363
364 if (ModeNumber == This->Mode->Mode) {
365 return EFI_SUCCESS;
366 }
367
368 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
369
370 //
371 // Protect from invalid Blt calls during SetMode.
372 //
373 Original = mGop.FramebufferContext;
375
376 //
377 // Protect from mishandling of rotated info.
378 //
379 SwitchMode (This, FALSE);
380
381 Status = mGop.OriginalGopSetMode (This, ModeNumber);
382 if (EFI_ERROR (Status)) {
383 SwitchMode (This, TRUE);
384 mGop.FramebufferContext = Original;
385 gBS->RestoreTPL (OldTpl);
386 return Status;
387 }
388
389 if (Original != NULL) {
390 FreePages (Original, mGop.FramebufferContextPageCount);
391 }
392
393 RotateMode (This, mGop.Rotation);
394
399 );
400 if (mGop.FramebufferContext == NULL) {
401 gBS->RestoreTPL (OldTpl);
402 return EFI_DEVICE_ERROR;
403 }
404
405 if (mGop.CachePolicy >= 0) {
406 MtrrSetMemoryAttribute (
410 );
411 }
412
413 gBS->RestoreTPL (OldTpl);
414 return EFI_SUCCESS;
415}
416
417STATIC
418EFI_STATUS
419EFIAPI
421 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
422 IN UINT32 ModeNumber,
423 OUT UINTN *SizeOfInfo,
424 OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
425 )
426{
427 EFI_STATUS Status;
428 UINT32 HorizontalResolution;
429
430 SwitchMode (This, FALSE);
431 Status = mGop.OriginalGopQueryMode (This, ModeNumber, SizeOfInfo, Info);
432 if (EFI_ERROR (Status)) {
433 SwitchMode (This, TRUE);
434 return Status;
435 }
436
437 if ((mGop.Rotation == 90) || (mGop.Rotation == 270)) {
438 HorizontalResolution = (*Info)->HorizontalResolution;
439 (*Info)->HorizontalResolution = (*Info)->VerticalResolution;
440 (*Info)->VerticalResolution = HorizontalResolution;
441 (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;
442 }
443
444 return Status;
445}
446
447STATIC
448EFI_STATUS
449EFIAPI
451 IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
452 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL,
453 IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
454 IN UINTN SourceX,
455 IN UINTN SourceY,
456 IN UINTN DestinationX,
457 IN UINTN DestinationY,
458 IN UINTN Width,
459 IN UINTN Height,
460 IN UINTN Delta OPTIONAL
461 )
462{
463 if (mGop.FramebufferContext != NULL) {
464 return OcBlitRender (
466 BltBuffer,
467 BltOperation,
468 SourceX,
469 SourceY,
470 DestinationX,
471 DestinationY,
472 Width,
473 Height,
474 Delta
475 );
476 }
477
478 return EFI_DEVICE_ERROR;
479}
480
481VOID
483 VOID
484 )
485{
486 EFI_STATUS Status;
487 UINTN HandleCount;
488 EFI_HANDLE *HandleBuffer;
489 UINTN Index;
490
491 //
492 // When we change the GOP mode on some types of firmware, we need to reconnect the
493 // drivers that produce simple text out as otherwise, they will not produce text
494 // at the new resolution.
495 //
496 // Needy reports that boot.efi seems to work fine without this block of code.
497 // However, I believe that UEFI specification does not provide any standard way
498 // to inform TextOut protocol about resolution change, which means the firmware
499 // may not be aware of the change, especially when custom GOP is used.
500 // We can move this to quirks if it causes problems, but I believe the code below
501 // is legit.
502 //
503 // Note: this block of code may result in black screens on APTIO IV boards when
504 // launching OpenCore from the Shell. Hence it is optional.
505 //
506
507 Status = gBS->LocateHandleBuffer (
508 ByProtocol,
510 NULL,
511 &HandleCount,
512 &HandleBuffer
513 );
514 if (!EFI_ERROR (Status)) {
515 for (Index = 0; Index < HandleCount; ++Index) {
516 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
517 }
518
519 for (Index = 0; Index < HandleCount; ++Index) {
520 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
521 }
522
523 FreePool (HandleBuffer);
524
525 //
526 // It is implementation defined, which console mode is used by ConOut.
527 // Assume the implementation chooses most sensible value based on GOP resolution.
528 // If it does not, there is a separate ConsoleMode param, which expands to SetConsoleMode.
529 //
530 } else {
531 DEBUG ((DEBUG_WARN, "OCC: Failed to find any text output handles\n"));
532 }
533}
534
535EFI_STATUS
537 IN INT32 CacheType
538 )
539{
540 EFI_STATUS Status;
541 EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
543 UINT32 Rotation;
544
545 DEBUG ((DEBUG_INFO, "OCC: Switching to direct GOP renderer...\n"));
546
547 Status = gBS->HandleProtocol (
548 gST->ConsoleOutHandle,
550 (VOID **)&Gop
551 );
552
553 if (EFI_ERROR (Status)) {
554 DEBUG ((DEBUG_INFO, "OCC: Cannot find console GOP for direct GOP - %r\n", Status));
555 return Status;
556 }
557
558 if (Gop->Mode->Info->PixelFormat == PixelBltOnly) {
559 DEBUG ((DEBUG_INFO, "OCC: This GOP does not support direct rendering\n"));
560 return EFI_UNSUPPORTED;
561 }
562
563 Status = gBS->LocateProtocol (
565 NULL,
566 (VOID **)&Eg2
567 );
568 if (!EFI_ERROR (Status)) {
569 DEBUG ((DEBUG_INFO, "OCC: Found EG2 support %X\n", Eg2->Revision));
571 Rotation = 0;
572 Status = Eg2->GetRotation (Eg2, &Rotation);
573 if (!EFI_ERROR (Status) && (Rotation < AppleDisplayRotateMax)) {
574 if (Rotation == AppleDisplayRotate90) {
575 mGop.Rotation = 90;
576 } else if (Rotation == AppleDisplayRotate180) {
577 mGop.Rotation = 180;
578 } else if (Rotation == AppleDisplayRotate270) {
579 mGop.Rotation = 270;
580 }
581
582 DEBUG ((DEBUG_INFO, "OCC: Got rotation %u degrees from EG2\n", mGop.Rotation));
583 } else {
584 DEBUG ((DEBUG_INFO, "OCC: Invalid rotation %u from EG2 - %r\n", Rotation, Status));
585 }
586 }
587 } else {
588 DEBUG ((DEBUG_INFO, "OCC: No Apple EG2 support - %r\n", Status));
589 }
590
591 RotateMode (Gop, mGop.Rotation);
592
597 );
598 if (mGop.FramebufferContext == NULL) {
599 DEBUG ((DEBUG_INFO, "OCC: Delaying direct GOP configuration...\n"));
600 //
601 // This is possible at the start.
602 //
603 }
604
605 mGop.OriginalGopSetMode = Gop->SetMode;
606 mGop.OriginalGopQueryMode = Gop->QueryMode;
607 Gop->SetMode = DirectGopSetMode;
608 Gop->QueryMode = DirectQueryMode;
609 Gop->Blt = DirectGopBlt;
610 mGop.CachePolicy = -1;
611
612 if (CacheType >= 0) {
613 Status = MtrrSetMemoryAttribute (
616 CacheType
617 );
618 DEBUG ((
619 DEBUG_INFO,
620 "OCC: FB (%Lx, %Lx) MTRR (%x) - %r\n",
623 CacheType,
624 Status
625 ));
626 if (!EFI_ERROR (Status)) {
627 mGop.CachePolicy = CacheType;
628 }
629 }
630
631 return EFI_SUCCESS;
632}
633
636 VOID
637 )
638{
639 if ((mGop.Rotation != 0) && (mGop.OriginalGopSetMode != NULL)) {
640 return &mGop;
641 }
642
643 return NULL;
644}
#define APPLE_EG2_INFO_PROTOCOL_REVISION
EFI_GUID gAppleEg2InfoProtocolGuid
@ AppleDisplayRotate90
@ AppleDisplayRotate270
@ AppleDisplayRotate180
@ AppleDisplayRotateMax
EFI_STATUS OcUseDirectGop(IN INT32 CacheType)
Definition ConsoleGop.c:536
STATIC VOID RotateMode(IN OUT EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 Rotation)
Definition ConsoleGop.c:269
STATIC EFI_STATUS EFIAPI DirectGopSetMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber)
Definition ConsoleGop.c:355
STATIC EFI_STATUS EFIAPI DirectQueryMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber, OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info)
Definition ConsoleGop.c:420
STATIC OC_BLIT_CONFIGURE *EFIAPI DirectGopFromTarget(IN EFI_PHYSICAL_ADDRESS FramebufferBase, IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info, OUT UINTN *PageCount)
Definition ConsoleGop.c:309
EFI_STATUS OcProvideConsoleGop(IN BOOLEAN Route)
Definition ConsoleGop.c:81
STATIC CONSOLE_GOP_CONTEXT mGop
Definition ConsoleGop.c:35
STATIC EFI_STATUS EFIAPI ConsoleHandleProtocol(IN EFI_HANDLE Handle, IN EFI_GUID *Protocol, OUT VOID **Interface)
Definition ConsoleGop.c:40
STATIC EFI_STATUS EFIAPI DirectGopBlt(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta OPTIONAL)
Definition ConsoleGop.c:450
VOID OcReconnectConsole(VOID)
Definition ConsoleGop.c:482
CONST CONSOLE_GOP_CONTEXT * InternalGetDirectGopContext(VOID)
Definition ConsoleGop.c:635
STATIC VOID SwitchMode(IN OUT EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN BOOLEAN UseCustom)
Definition ConsoleGop.c:234
RETURN_STATUS EFIAPI OcBlitRender(IN OC_BLIT_CONFIGURE *Configure, IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer OPTIONAL, IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta)
Definition OcBlitLib.c:688
RETURN_STATUS EFIAPI OcBlitConfigure(IN VOID *FrameBuffer, IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, IN UINT32 Rotation, IN OUT OC_BLIT_CONFIGURE *Configure, IN OUT UINTN *ConfigureSize)
Definition OcBlitLib.c:602
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
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 gEfiUgaDrawProtocolGuid
EFI_GUID gEfiSimpleTextOutProtocolGuid
EFI_GUID gEfiGraphicsOutputProtocolGuid
#define ASSERT(x)
Definition coder.h:55
APPLE_EG2_INFO_GET_ROTATION GetRotation
EFI_PHYSICAL_ADDRESS OriginalFrameBufferBase
EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE OriginalGopQueryMode
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION OriginalModeInfo
OC_BLIT_CONFIGURE * FramebufferContext
EFI_GRAPHICS_OUTPUT_PROTOCOL * ConsoleGop
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION CustomModeInfo
EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE OriginalGopSetMode
EFI_HANDLE_PROTOCOL OriginalHandleProtocol