2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/firmware/efi/firmware.c
5 * PURPOSE: Boot Library Firmware Initialization for EFI
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
13 /* DATA VARIABLES ************************************************************/
15 PBL_FIRMWARE_DESCRIPTOR EfiFirmwareParameters
;
16 BL_FIRMWARE_DESCRIPTOR EfiFirmwareData
;
17 EFI_HANDLE EfiImageHandle
;
18 EFI_SYSTEM_TABLE
* EfiSystemTable
;
20 EFI_SYSTEM_TABLE
*EfiST
;
21 EFI_BOOT_SERVICES
*EfiBS
;
22 EFI_RUNTIME_SERVICES
*EfiRT
;
23 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*EfiConOut
;
24 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*EfiConIn
;
25 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*EfiConInEx
;
26 PHYSICAL_ADDRESS EfiRsdt
;
28 EFI_GUID EfiGraphicsOutputProtocol
= EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
;
29 EFI_GUID EfiUgaDrawProtocol
= EFI_UGA_DRAW_PROTOCOL_GUID
;
30 EFI_GUID EfiLoadedImageProtocol
= EFI_LOADED_IMAGE_PROTOCOL_GUID
;
31 EFI_GUID EfiDevicePathProtocol
= EFI_DEVICE_PATH_PROTOCOL_GUID
;
32 EFI_GUID EfiSimpleTextInputExProtocol
= EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID
;
33 EFI_GUID EfiBlockIoProtocol
= EFI_BLOCK_IO_PROTOCOL_GUID
;
34 EFI_GUID EfiRootAcpiTableGuid
= EFI_ACPI_20_TABLE_GUID
;
35 EFI_GUID EfiRootAcpiTable10Guid
= EFI_ACPI_TABLE_GUID
;
36 EFI_GUID EfiGlobalVariable
= EFI_GLOBAL_VARIABLE
;
37 EFI_GUID BlpEfiSecureBootPrivateNamespace
= { 0x77FA9ABD , 0x0359, 0x4D32, { 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B } };
39 WCHAR BlScratchBuffer
[8192];
41 BOOLEAN BlpFirmwareChecked
;
42 BOOLEAN BlpFirmwareEnabled
;
44 /* FUNCTIONS *****************************************************************/
47 EfiIsDevicePathParent (
48 _In_ EFI_DEVICE_PATH
*DevicePath1
,
49 _In_ EFI_DEVICE_PATH
*DevicePath2
52 EFI_DEVICE_PATH
* CurrentPath1
;
53 EFI_DEVICE_PATH
* CurrentPath2
;
54 USHORT Length1
, Length2
;
56 /* Start with the current nodes */
57 CurrentPath1
= DevicePath1
;
58 CurrentPath2
= DevicePath2
;
60 /* Loop each element of the device path */
61 while (!(IsDevicePathEndType(CurrentPath1
)) &&
62 !(IsDevicePathEndType(CurrentPath2
)))
64 /* Check if the element has a different length */
65 Length1
= DevicePathNodeLength(CurrentPath1
);
66 Length2
= DevicePathNodeLength(CurrentPath2
);
67 if (Length1
!= Length2
)
69 /* Then they're not related */
73 /* Check if the rest of the element data matches */
74 if (RtlCompareMemory(CurrentPath1
, CurrentPath2
, Length1
) != Length1
)
76 /* Nope, not related */
80 /* Move to the next element */
81 CurrentPath1
= NextDevicePathNode(CurrentPath1
);
82 CurrentPath2
= NextDevicePathNode(CurrentPath2
);
85 /* If the last element in path 1 is empty, then path 2 is the child (deeper) */
86 if (!IsDevicePathEndType(CurrentPath1
))
91 /* If the last element in path 2 is empty, then path 1 is the child (deeper) */
92 if (!IsDevicePathEndType(CurrentPath2
))
97 /* They're both the end, so they're identical, so there's no parent */
103 _In_ EFI_DEVICE_PATH
*DevicePath
106 EFI_DEVICE_PATH
*NextDevicePath
;
108 /* Make sure we're not already at the end */
109 if (!IsDevicePathEndType(DevicePath
))
111 /* Grab the next node element, and keep going until the end */
112 for (NextDevicePath
= NextDevicePathNode(DevicePath
);
113 !IsDevicePathEndType(NextDevicePath
);
114 NextDevicePath
= NextDevicePathNode(NextDevicePath
))
116 /* Save the current node we're at */
117 DevicePath
= NextDevicePath
;
121 /* This now contains the deepest (leaf) node */
132 va_start(args
, Format
);
134 /* Capture the buffer in our scratch pad, and NULL-terminate */
135 vsnwprintf(BlScratchBuffer
, RTL_NUMBER_OF(BlScratchBuffer
) - 1, Format
, args
);
136 BlScratchBuffer
[RTL_NUMBER_OF(BlScratchBuffer
) - 1] = UNICODE_NULL
;
138 /* Check which mode we're in */
139 if (CurrentExecutionContext
->Mode
== BlRealMode
)
141 /* Call EFI directly */
142 EfiConOut
->OutputString(EfiConOut
, BlScratchBuffer
);
146 /* FIXME: @TODO: Not yet supported */
155 _In_ EFI_HANDLE Handle
,
156 _In_ EFI_GUID
*Protocol
,
157 _Out_ PVOID
* Interface
160 EFI_STATUS EfiStatus
;
162 BL_ARCH_MODE OldMode
;
164 /* Are we using virtual memory/ */
165 if (MmTranslationType
!= BlNone
)
167 /* We need complex tracking to make this work */
168 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
169 Status
= STATUS_NOT_SUPPORTED
;
173 /* Are we in protected mode? */
174 OldMode
= CurrentExecutionContext
->Mode
;
175 if (OldMode
!= BlRealMode
)
177 /* FIXME: Not yet implemented */
178 return STATUS_NOT_IMPLEMENTED
;
181 /* Are we on legacy 1.02? */
182 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
184 /* Make the legacy call */
185 EfiStatus
= EfiBS
->HandleProtocol(Handle
, Protocol
, Interface
);
189 /* Use the UEFI version */
190 EfiStatus
= EfiBS
->OpenProtocol(Handle
,
195 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
197 /* Switch back to protected mode if we came from there */
198 if (OldMode
!= BlRealMode
)
200 BlpArchSwitchContext(OldMode
);
204 /* Convert the error to an NTSTATUS */
205 Status
= EfiGetNtStatusCode(EfiStatus
);
208 /* Clear the interface on failure, and return the status */
209 if (!NT_SUCCESS(Status
))
219 _In_ EFI_HANDLE Handle
,
220 _In_ EFI_GUID
*Protocol
223 EFI_STATUS EfiStatus
;
225 BL_ARCH_MODE OldMode
;
227 /* Are we using virtual memory/ */
228 if (MmTranslationType
!= BlNone
)
230 /* We need complex tracking to make this work */
231 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
232 Status
= STATUS_NOT_SUPPORTED
;
236 /* Are we on legacy 1.02? */
237 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
239 /* Nothing to close */
240 EfiStatus
= STATUS_SUCCESS
;
244 /* Are we in protected mode? */
245 OldMode
= CurrentExecutionContext
->Mode
;
246 if (OldMode
!= BlRealMode
)
248 /* FIXME: Not yet implemented */
249 return STATUS_NOT_IMPLEMENTED
;
252 /* Use the UEFI version */
253 EfiStatus
= EfiBS
->CloseProtocol(Handle
, Protocol
, EfiImageHandle
, NULL
);
255 /* Switch back to protected mode if we came from there */
256 if (OldMode
!= BlRealMode
)
258 BlpArchSwitchContext(OldMode
);
261 /* Normalize not found as success */
262 if (EfiStatus
== EFI_NOT_FOUND
)
264 EfiStatus
= EFI_SUCCESS
;
268 /* Convert the error to an NTSTATUS */
269 Status
= EfiGetNtStatusCode(EfiStatus
);
278 _In_ PWCHAR VariableName
,
279 _In_ EFI_GUID
* VendorGuid
,
280 _Out_opt_ PULONG Attributes
,
281 _Inout_ PULONG DataSize
,
285 EFI_STATUS EfiStatus
;
287 BL_ARCH_MODE OldMode
;
288 ULONG LocalAttributes
;
290 /* Are we in protected mode? */
291 OldMode
= CurrentExecutionContext
->Mode
;
292 if (OldMode
!= BlRealMode
)
294 /* FIXME: Not yet implemented */
295 return STATUS_NOT_IMPLEMENTED
;
298 /* Call the runtime API */
299 EfiStatus
= EfiRT
->GetVariable(VariableName
,
301 (UINT32
*)&LocalAttributes
,
305 /* Switch back to protected mode if we came from there */
306 if (OldMode
!= BlRealMode
)
308 BlpArchSwitchContext(OldMode
);
311 /* Return attributes back to the caller if asked to */
314 *Attributes
= LocalAttributes
;
317 /* Convert the error to an NTSTATUS and return it */
318 Status
= EfiGetNtStatusCode(EfiStatus
);
323 BlpSecureBootEFIIsEnabled (
328 BOOLEAN SetupMode
, SecureBoot
;
331 /* Assume setup mode enabled, and no secure boot */
335 /* Get the SetupMode variable */
336 DataSize
= sizeof(SetupMode
);
337 Status
= EfiGetVariable(L
"SetupMode",
342 if (NT_SUCCESS(Status
))
344 /* If it worked, get the SecureBoot variable */
345 DataSize
= sizeof(SecureBoot
);
346 Status
= EfiGetVariable(L
"SecureBoot",
351 if (NT_SUCCESS(Status
))
353 /* In setup mode or without secureboot turned on, return failure */
354 if ((SecureBoot
!= TRUE
) || (SetupMode
))
356 Status
= STATUS_INVALID_SIGNATURE
;
359 // BlpSbdiStateFlags |= 8u;
363 /* Return secureboot status */
368 BlSecureBootIsEnabled (
369 _Out_ PBOOLEAN SecureBootEnabled
374 /* Have we checked before ? */
375 if (!BlpFirmwareChecked
)
377 /* First time checking */
378 Status
= BlpSecureBootEFIIsEnabled();
379 if NT_SUCCESS(Status
)
382 BlpFirmwareEnabled
= TRUE
;
385 /* Don't check again */
386 BlpFirmwareChecked
= TRUE
;
389 /* Return the firmware result */
390 *SecureBootEnabled
= BlpFirmwareEnabled
;
391 return STATUS_SUCCESS
;
395 BlSecureBootCheckForFactoryReset (
399 BOOLEAN SecureBootEnabled
;
403 /* Initialize locals */
405 SecureBootEnabled
= FALSE
;
407 /* Check if secureboot is enabled */
408 Status
= BlSecureBootIsEnabled(&SecureBootEnabled
);
409 if (!(NT_SUCCESS(Status
)) || !(SecureBootEnabled
))
411 /* It's not. Check if there's a revocation list */
412 Status
= EfiGetVariable(L
"RevocationList",
413 &BlpEfiSecureBootPrivateNamespace
,
417 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_TOO_SMALL
))
419 /* We don't support this yet */
420 EfiPrintf(L
"Not yet supported\r\n");
421 Status
= STATUS_NOT_IMPLEMENTED
;
425 /* Return back to the caller */
434 BL_ARCH_MODE OldMode
;
435 EFI_STATUS EfiStatus
;
437 /* Are we in protected mode? */
438 OldMode
= CurrentExecutionContext
->Mode
;
439 if (OldMode
!= BlRealMode
)
441 /* FIXME: Not yet implemented */
442 return STATUS_NOT_IMPLEMENTED
;
445 /* Make the EFI call */
446 EfiStatus
= EfiConIn
->Reset(EfiConIn
, FALSE
);
448 /* Switch back to protected mode if we came from there */
449 if (OldMode
!= BlRealMode
)
451 BlpArchSwitchContext(OldMode
);
454 /* Convert the error to an NTSTATUS */
455 return EfiGetNtStatusCode(EfiStatus
);
463 BL_ARCH_MODE OldMode
;
464 EFI_STATUS EfiStatus
;
466 /* Are we in protected mode? */
467 OldMode
= CurrentExecutionContext
->Mode
;
468 if (OldMode
!= BlRealMode
)
470 /* FIXME: Not yet implemented */
471 return STATUS_NOT_IMPLEMENTED
;
474 /* Make the EFI call */
475 EfiStatus
= EfiConInEx
->Reset(EfiConInEx
, FALSE
);
477 /* Switch back to protected mode if we came from there */
478 if (OldMode
!= BlRealMode
)
480 BlpArchSwitchContext(OldMode
);
483 /* Convert the error to an NTSTATUS */
484 return EfiGetNtStatusCode(EfiStatus
);
489 _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*ConInEx
,
490 _In_ EFI_KEY_TOGGLE_STATE
* KeyToggleState
493 BL_ARCH_MODE OldMode
;
494 EFI_STATUS EfiStatus
;
496 /* Are we in protected mode? */
497 OldMode
= CurrentExecutionContext
->Mode
;
498 if (OldMode
!= BlRealMode
)
500 /* FIXME: Not yet implemented */
501 return STATUS_NOT_IMPLEMENTED
;
504 /* Make the EFI call */
505 EfiStatus
= ConInEx
->SetState(ConInEx
, KeyToggleState
);
507 /* Switch back to protected mode if we came from there */
508 if (OldMode
!= BlRealMode
)
510 BlpArchSwitchContext(OldMode
);
513 /* Convert the error to an NTSTATUS */
514 return EfiGetNtStatusCode(EfiStatus
);
518 EfiSetWatchdogTimer (
522 BL_ARCH_MODE OldMode
;
523 EFI_STATUS EfiStatus
;
525 /* Are we in protected mode? */
526 OldMode
= CurrentExecutionContext
->Mode
;
527 if (OldMode
!= BlRealMode
)
529 /* FIXME: Not yet implemented */
530 return STATUS_NOT_IMPLEMENTED
;
533 /* Make the EFI call */
534 EfiStatus
= EfiBS
->SetWatchdogTimer(0, 0, 0, NULL
);
536 /* Switch back to protected mode if we came from there */
537 if (OldMode
!= BlRealMode
)
539 BlpArchSwitchContext(OldMode
);
542 /* Convert the error to an NTSTATUS */
543 return EfiGetNtStatusCode(EfiStatus
);
548 _Out_ UINTN
* MemoryMapSize
,
549 _Inout_ EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
551 _Out_ UINTN
* DescriptorSize
,
552 _Out_ UINTN
* DescriptorVersion
555 BL_ARCH_MODE OldMode
;
556 EFI_STATUS EfiStatus
;
558 /* Are we in protected mode? */
559 OldMode
= CurrentExecutionContext
->Mode
;
560 if (OldMode
!= BlRealMode
)
562 /* FIXME: Not yet implemented */
563 return STATUS_NOT_IMPLEMENTED
;
566 /* Make the EFI call */
567 EfiStatus
= EfiBS
->GetMemoryMap(MemoryMapSize
,
573 /* Switch back to protected mode if we came from there */
574 if (OldMode
!= BlRealMode
)
576 BlpArchSwitchContext(OldMode
);
579 /* Convert the error to an NTSTATUS */
580 return EfiGetNtStatusCode(EfiStatus
);
586 _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress
589 BL_ARCH_MODE OldMode
;
590 EFI_STATUS EfiStatus
;
592 /* Are we in protected mode? */
593 OldMode
= CurrentExecutionContext
->Mode
;
594 if (OldMode
!= BlRealMode
)
596 /* FIXME: Not yet implemented */
597 return STATUS_NOT_IMPLEMENTED
;
600 /* Make the EFI call */
601 EfiStatus
= EfiBS
->FreePages(PhysicalAddress
, Pages
);
603 /* Switch back to protected mode if we came from there */
604 if (OldMode
!= BlRealMode
)
606 BlpArchSwitchContext(OldMode
);
609 /* Convert the error to an NTSTATUS */
610 return EfiGetNtStatusCode(EfiStatus
);
618 BL_ARCH_MODE OldMode
;
619 EFI_STATUS EfiStatus
;
621 /* Are we in protected mode? */
622 OldMode
= CurrentExecutionContext
->Mode
;
623 if (OldMode
!= BlRealMode
)
625 /* FIXME: Not yet implemented */
626 return STATUS_NOT_IMPLEMENTED
;
629 /* Make the EFI call */
630 EfiStatus
= EfiBS
->Stall(StallTime
);
632 /* Switch back to protected mode if we came from there */
633 if (OldMode
!= BlRealMode
)
635 BlpArchSwitchContext(OldMode
);
638 /* Convert the error to an NTSTATUS */
639 return EfiGetNtStatusCode(EfiStatus
);
644 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
650 BL_ARCH_MODE OldMode
;
651 EFI_STATUS EfiStatus
;
653 /* Are we in protected mode? */
654 OldMode
= CurrentExecutionContext
->Mode
;
655 if (OldMode
!= BlRealMode
)
657 /* FIXME: Not yet implemented */
658 return STATUS_NOT_IMPLEMENTED
;
661 /* Make the EFI call */
662 EfiStatus
= TextInterface
->QueryMode(TextInterface
, Mode
, Columns
, Rows
);
664 /* Switch back to protected mode if we came from there */
665 if (OldMode
!= BlRealMode
)
667 BlpArchSwitchContext(OldMode
);
670 /* Convert the error to an NTSTATUS */
671 return EfiGetNtStatusCode(EfiStatus
);
676 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
680 BL_ARCH_MODE OldMode
;
681 EFI_STATUS EfiStatus
;
683 /* Are we in protected mode? */
684 OldMode
= CurrentExecutionContext
->Mode
;
685 if (OldMode
!= BlRealMode
)
687 /* FIXME: Not yet implemented */
688 return STATUS_NOT_IMPLEMENTED
;
691 /* Make the EFI call */
692 EfiStatus
= TextInterface
->SetMode(TextInterface
, Mode
);
694 /* Switch back to protected mode if we came from there */
695 if (OldMode
!= BlRealMode
)
697 BlpArchSwitchContext(OldMode
);
700 /* Convert the error to an NTSTATUS */
701 return EfiGetNtStatusCode(EfiStatus
);
705 EfiConOutSetAttribute (
706 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
710 BL_ARCH_MODE OldMode
;
711 EFI_STATUS EfiStatus
;
713 /* Are we in protected mode? */
714 OldMode
= CurrentExecutionContext
->Mode
;
715 if (OldMode
!= BlRealMode
)
717 /* FIXME: Not yet implemented */
718 return STATUS_NOT_IMPLEMENTED
;
721 /* Make the EFI call */
722 EfiStatus
= TextInterface
->SetAttribute(TextInterface
, Attribute
);
724 /* Switch back to protected mode if we came from there */
725 if (OldMode
!= BlRealMode
)
727 BlpArchSwitchContext(OldMode
);
730 /* Convert the error to an NTSTATUS */
731 return EfiGetNtStatusCode(EfiStatus
);
735 EfiConOutSetCursorPosition (
736 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
741 BL_ARCH_MODE OldMode
;
742 EFI_STATUS EfiStatus
;
744 /* Are we in protected mode? */
745 OldMode
= CurrentExecutionContext
->Mode
;
746 if (OldMode
!= BlRealMode
)
748 /* FIXME: Not yet implemented */
749 return STATUS_NOT_IMPLEMENTED
;
752 /* Make the EFI call */
753 EfiStatus
= TextInterface
->SetCursorPosition(TextInterface
, Column
, Row
);
755 /* Switch back to protected mode if we came from there */
756 if (OldMode
!= BlRealMode
)
758 BlpArchSwitchContext(OldMode
);
761 /* Convert the error to an NTSTATUS */
762 return EfiGetNtStatusCode(EfiStatus
);
766 EfiConOutEnableCursor (
767 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
771 BL_ARCH_MODE OldMode
;
772 EFI_STATUS EfiStatus
;
774 /* Are we in protected mode? */
775 OldMode
= CurrentExecutionContext
->Mode
;
776 if (OldMode
!= BlRealMode
)
778 /* FIXME: Not yet implemented */
779 return STATUS_NOT_IMPLEMENTED
;
782 /* Make the EFI call */
783 EfiStatus
= TextInterface
->EnableCursor(TextInterface
, Visible
);
785 /* Switch back to protected mode if we came from there */
786 if (OldMode
!= BlRealMode
)
788 BlpArchSwitchContext(OldMode
);
791 /* Convert the error to an NTSTATUS */
792 return EfiGetNtStatusCode(EfiStatus
);
796 EfiConOutOutputString (
797 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
801 BL_ARCH_MODE OldMode
;
802 EFI_STATUS EfiStatus
;
804 /* Are we in protected mode? */
805 OldMode
= CurrentExecutionContext
->Mode
;
806 if (OldMode
!= BlRealMode
)
808 /* FIXME: Not yet implemented */
809 return STATUS_NOT_IMPLEMENTED
;
812 /* Make the EFI call */
813 EfiStatus
= TextInterface
->OutputString(TextInterface
, String
);
815 /* Switch back to protected mode if we came from there */
816 if (OldMode
!= BlRealMode
)
818 BlpArchSwitchContext(OldMode
);
821 /* Convert the error to an NTSTATUS */
822 return EfiGetNtStatusCode(EfiStatus
);
827 EfiConOutReadCurrentMode (
828 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
829 _Out_ EFI_SIMPLE_TEXT_OUTPUT_MODE
* Mode
832 BL_ARCH_MODE OldMode
;
834 /* Are we in protected mode? */
835 OldMode
= CurrentExecutionContext
->Mode
;
836 if (OldMode
!= BlRealMode
)
838 /* FIXME: Not yet implemented */
842 /* Make the EFI call */
843 RtlCopyMemory(Mode
, TextInterface
->Mode
, sizeof(*Mode
));
845 /* Switch back to protected mode if we came from there */
846 if (OldMode
!= BlRealMode
)
848 BlpArchSwitchContext(OldMode
);
853 EfiGopGetFrameBuffer (
854 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
855 _Out_ PHYSICAL_ADDRESS
* FrameBuffer
,
856 _Out_ UINTN
*FrameBufferSize
859 BL_ARCH_MODE OldMode
;
861 /* Are we in protected mode? */
862 OldMode
= CurrentExecutionContext
->Mode
;
863 if (OldMode
!= BlRealMode
)
865 /* FIXME: Not yet implemented */
869 /* Make the EFI call */
870 FrameBuffer
->QuadPart
= GopInterface
->Mode
->FrameBufferBase
;
871 *FrameBufferSize
= GopInterface
->Mode
->FrameBufferSize
;
873 /* Switch back to protected mode if we came from there */
874 if (OldMode
!= BlRealMode
)
876 BlpArchSwitchContext(OldMode
);
881 EfiGopGetCurrentMode (
882 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
884 _Out_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Information
887 BL_ARCH_MODE OldMode
;
889 /* Are we in protected mode? */
890 OldMode
= CurrentExecutionContext
->Mode
;
891 if (OldMode
!= BlRealMode
)
893 /* FIXME: Not yet implemented */
894 return STATUS_NOT_IMPLEMENTED
;
897 /* Make the EFI call */
898 *Mode
= GopInterface
->Mode
->Mode
;
899 RtlCopyMemory(Information
, GopInterface
->Mode
->Info
, sizeof(*Information
));
901 /* Switch back to protected mode if we came from there */
902 if (OldMode
!= BlRealMode
)
904 BlpArchSwitchContext(OldMode
);
908 return STATUS_SUCCESS
;
913 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
917 BL_ARCH_MODE OldMode
;
918 EFI_STATUS EfiStatus
;
922 /* Are we in protected mode? */
923 OldMode
= CurrentExecutionContext
->Mode
;
924 if (OldMode
!= BlRealMode
)
926 /* FIXME: Not yet implemented */
927 return STATUS_NOT_IMPLEMENTED
;
930 /* Make the EFI call */
931 if (Mode
== GopInterface
->Mode
->Mode
)
933 EfiStatus
= EFI_SUCCESS
;
937 EfiStatus
= GopInterface
->SetMode(GopInterface
, Mode
);
941 /* Switch back to protected mode if we came from there */
942 if (OldMode
!= BlRealMode
)
944 BlpArchSwitchContext(OldMode
);
947 /* Print out to the debugger if the mode was changed */
948 Status
= EfiGetNtStatusCode(EfiStatus
);
949 if ((ModeChanged
) && (NT_SUCCESS(Status
)))
951 /* FIXME @TODO: Should be BlStatusPrint */
952 EfiPrintf(L
"Console video mode set to 0x%x\r\n", Mode
);
955 /* Convert the error to an NTSTATUS */
960 EfiLocateHandleBuffer (
961 _In_ EFI_LOCATE_SEARCH_TYPE SearchType
,
962 _In_ EFI_GUID
*Protocol
,
963 _Inout_ PULONG HandleCount
,
964 _Inout_ EFI_HANDLE
** Buffer
967 BL_ARCH_MODE OldMode
;
968 EFI_STATUS EfiStatus
;
971 /* Bail out if we're missing parameters */
972 if (!(Buffer
) || !(HandleCount
))
974 return STATUS_INVALID_PARAMETER
;
977 /* Check if a buffer was passed in*/
980 /* Then we should already have a buffer size*/
981 BufferSize
= sizeof(EFI_HANDLE
) * *HandleCount
;
985 /* Then no buffer size exists */
989 /* Are we in protected mode? */
990 OldMode
= CurrentExecutionContext
->Mode
;
991 if (OldMode
!= BlRealMode
)
993 /* FIXME: Not yet implemented */
994 return STATUS_NOT_IMPLEMENTED
;
997 /* Try the first time */
998 EfiStatus
= EfiBS
->LocateHandle(SearchType
, Protocol
, NULL
, &BufferSize
, *Buffer
);
999 if (EfiStatus
== EFI_BUFFER_TOO_SMALL
)
1001 /* Did we have an existing buffer? */
1005 BlMmFreeHeap(*Buffer
);
1008 /* Allocate a new one */
1009 *Buffer
= BlMmAllocateHeap(BufferSize
);
1012 /* No space, fail */
1013 return STATUS_NO_MEMORY
;
1017 EfiStatus
= EfiBS
->LocateHandle(SearchType
, Protocol
, NULL
, &BufferSize
, *Buffer
);
1019 /* Switch back to protected mode if we came from there */
1020 if (OldMode
!= BlRealMode
)
1022 BlpArchSwitchContext(OldMode
);
1026 /* Return the number of handles */
1027 *HandleCount
= BufferSize
/ sizeof(EFI_HANDLE
);
1029 /* Convert the error to an NTSTATUS */
1030 return EfiGetNtStatusCode(EfiStatus
);
1035 _In_ EFI_RESET_TYPE ResetType
1038 BL_ARCH_MODE OldMode
;
1040 /* Are we in protected mode? */
1041 OldMode
= CurrentExecutionContext
->Mode
;
1042 if (OldMode
!= BlRealMode
)
1044 /* FIXME: Not yet implemented */
1048 /* Call the EFI runtime */
1049 EfiRT
->ResetSystem(ResetType
, EFI_SUCCESS
, 0, NULL
);
1053 EfiConnectController (
1054 _In_ EFI_HANDLE ControllerHandle
1057 BL_ARCH_MODE OldMode
;
1058 EFI_STATUS EfiStatus
;
1060 /* Is this EFI 1.02? */
1061 if (EfiST
->Hdr
.Revision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
1063 /* This function didn't exist back then */
1064 return STATUS_NOT_SUPPORTED
;
1067 /* Are we in protected mode? */
1068 OldMode
= CurrentExecutionContext
->Mode
;
1069 if (OldMode
!= BlRealMode
)
1071 /* FIXME: Not yet implemented */
1072 return STATUS_NOT_IMPLEMENTED
;
1075 /* Make the EFI call */
1076 EfiStatus
= EfiBS
->ConnectController(ControllerHandle
, NULL
, NULL
, TRUE
);
1078 /* Switch back to protected mode if we came from there */
1079 if (OldMode
!= BlRealMode
)
1081 BlpArchSwitchContext(OldMode
);
1084 /* Convert the error to an NTSTATUS */
1085 return EfiGetNtStatusCode(EfiStatus
);
1092 _Inout_ EFI_PHYSICAL_ADDRESS
* Memory
1095 BL_ARCH_MODE OldMode
;
1096 EFI_STATUS EfiStatus
;
1098 /* Are we in protected mode? */
1099 OldMode
= CurrentExecutionContext
->Mode
;
1100 if (OldMode
!= BlRealMode
)
1102 /* FIXME: Not yet implemented */
1103 return STATUS_NOT_IMPLEMENTED
;
1106 /* Make the EFI call */
1107 EfiStatus
= EfiBS
->AllocatePages(Type
, EfiLoaderData
, Pages
, Memory
);
1109 /* Switch back to protected mode if we came from there */
1110 if (OldMode
!= BlRealMode
)
1112 BlpArchSwitchContext(OldMode
);
1115 /* Convert the error to an NTSTATUS */
1116 return EfiGetNtStatusCode(EfiStatus
);
1120 EfipGetSystemTable (
1121 _In_ EFI_GUID
*TableGuid
,
1122 _Out_ PPHYSICAL_ADDRESS TableAddress
1128 /* Assume failure */
1129 Status
= STATUS_NOT_FOUND
;
1131 /* Loop through the configuration tables */
1132 for (i
= 0; i
< EfiST
->NumberOfTableEntries
; i
++)
1134 /* Check if this one matches the one we want */
1135 if (RtlEqualMemory(&EfiST
->ConfigurationTable
[i
].VendorGuid
,
1137 sizeof(*TableGuid
)))
1139 /* Return its address */
1140 TableAddress
->QuadPart
= (ULONG_PTR
)EfiST
->ConfigurationTable
[i
].VendorTable
;
1141 Status
= STATUS_SUCCESS
;
1146 /* Return the search result */
1152 _Out_ PPHYSICAL_ADDRESS FoundRsdt
1157 PHYSICAL_ADDRESS RsdpAddress
, Rsdt
;
1160 /* Assume failure */
1164 /* Check if we already know it */
1165 if (EfiRsdt
.QuadPart
)
1168 *FoundRsdt
= EfiRsdt
;
1169 return STATUS_SUCCESS
;
1172 /* Otherwise, look for the ACPI 2.0 RSDP (XSDT really) */
1173 Status
= EfipGetSystemTable(&EfiRootAcpiTableGuid
, &RsdpAddress
);
1174 if (!NT_SUCCESS(Status
))
1176 /* Didn't fint it, look for the ACPI 1.0 RSDP (RSDT really) */
1177 Status
= EfipGetSystemTable(&EfiRootAcpiTable10Guid
, &RsdpAddress
);
1178 if (!NT_SUCCESS(Status
))
1185 Length
= sizeof(*Rsdp
);
1186 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1190 if (NT_SUCCESS(Status
))
1192 /* Check the revision (anything >= 2.0 is XSDT) */
1195 /* Check if the table is bigger than just its header */
1196 if (Rsdp
->Length
> Length
)
1198 /* Capture the real length */
1199 Length
= Rsdp
->Length
;
1201 /* Unmap our header mapping */
1202 BlMmUnmapVirtualAddressEx(Rsdp
, sizeof(*Rsdp
));
1204 /* And map the whole thing now */
1205 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1209 if (!NT_SUCCESS(Status
))
1215 /* Read the XSDT address from the table*/
1216 Rsdt
= Rsdp
->XsdtAddress
;
1220 /* ACPI 1.0 so just read the RSDT */
1221 Rsdt
.QuadPart
= Rsdp
->RsdtAddress
;
1224 /* Save it for later */
1227 /* And return it back */
1231 /* Check if we had mapped the RSDP */
1235 BlMmUnmapVirtualAddressEx(Rsdp
, Length
);
1238 /* Return search result back to caller */
1243 MmFwpGetOsAttributeType (
1244 _In_ ULONGLONG Attribute
1247 BL_MEMORY_ATTR OsAttribute
= 0;
1249 if (Attribute
& EFI_MEMORY_UC
)
1251 OsAttribute
= BlMemoryUncached
;
1254 if (Attribute
& EFI_MEMORY_WC
)
1256 OsAttribute
|= BlMemoryWriteCombined
;
1259 if (Attribute
& EFI_MEMORY_WT
)
1261 OsAttribute
|= BlMemoryWriteThrough
;
1264 if (Attribute
& EFI_MEMORY_WB
)
1266 OsAttribute
|= BlMemoryWriteBack
;
1269 if (Attribute
& EFI_MEMORY_UCE
)
1271 OsAttribute
|= BlMemoryUncachedExported
;
1274 if (Attribute
& EFI_MEMORY_WP
)
1276 OsAttribute
|= BlMemoryWriteProtected
;
1279 if (Attribute
& EFI_MEMORY_RP
)
1281 OsAttribute
|= BlMemoryReadProtected
;
1284 if (Attribute
& EFI_MEMORY_XP
)
1286 OsAttribute
|= BlMemoryExecuteProtected
;
1289 if (Attribute
& EFI_MEMORY_RUNTIME
)
1291 OsAttribute
|= BlMemoryRuntime
;
1298 MmFwpGetOsMemoryType (
1299 _In_ EFI_MEMORY_TYPE MemoryType
1302 BL_MEMORY_TYPE OsType
;
1308 OsType
= BlLoaderMemory
;
1311 case EfiBootServicesCode
:
1312 case EfiBootServicesData
:
1313 OsType
= BlEfiBootMemory
;
1316 case EfiRuntimeServicesCode
:
1317 case EfiRuntimeServicesData
:
1318 OsType
= BlEfiRuntimeMemory
;
1321 case EfiConventionalMemory
:
1322 OsType
= BlConventionalMemory
;
1325 case EfiUnusableMemory
:
1326 OsType
= BlUnusableMemory
;
1329 case EfiACPIReclaimMemory
:
1330 OsType
= BlAcpiReclaimMemory
;
1333 case EfiACPIMemoryNVS
:
1334 OsType
= BlAcpiNvsMemory
;
1337 case EfiMemoryMappedIO
:
1338 OsType
= BlDeviceIoMemory
;
1341 case EfiMemoryMappedIOPortSpace
:
1342 OsType
= BlDevicePortMemory
;
1346 OsType
= BlPalMemory
;
1350 OsType
= BlReservedMemory
;
1359 _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap
,
1363 BL_LIBRARY_PARAMETERS LibraryParameters
= BlpLibraryParameters
;
1364 BOOLEAN UseEfiBuffer
, HaveRamDisk
;
1366 ULONGLONG Pages
, StartPage
, EndPage
;
1367 UINTN EfiMemoryMapSize
, MapKey
, DescriptorSize
, DescriptorVersion
;
1368 EFI_PHYSICAL_ADDRESS EfiBuffer
= 0;
1369 EFI_MEMORY_DESCRIPTOR
* EfiMemoryMap
;
1370 EFI_STATUS EfiStatus
;
1371 BL_ARCH_MODE OldMode
;
1372 EFI_MEMORY_DESCRIPTOR EfiDescriptor
;
1373 BL_MEMORY_TYPE MemoryType
;
1374 PBL_MEMORY_DESCRIPTOR Descriptor
;
1375 BL_MEMORY_ATTR Attribute
;
1377 /* Initialize EFI memory map attributes */
1378 EfiMemoryMapSize
= MapKey
= DescriptorSize
= DescriptorVersion
= 0;
1380 /* Increment the nesting depth */
1381 MmDescriptorCallTreeCount
++;
1383 /* Determine if we should use EFI or our own allocator at this point */
1384 UseEfiBuffer
= Flags
& BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS
;
1385 if (!(LibraryParameters
.LibraryFlags
& BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
))
1387 UseEfiBuffer
= TRUE
;
1390 /* Bail out if we don't have a list to use */
1391 if (MemoryMap
== NULL
)
1393 Status
= STATUS_INVALID_PARAMETER
;
1397 /* Free the current descriptor list */
1398 MmMdFreeList(MemoryMap
);
1400 /* Call into EFI to get the size of the memory map */
1401 Status
= EfiGetMemoryMap(&EfiMemoryMapSize
,
1405 &DescriptorVersion
);
1406 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
1408 /* This should've failed because our buffer was too small, nothing else */
1409 EfiPrintf(L
"Got strange EFI status for memory map: %lx\r\n", Status
);
1410 if (NT_SUCCESS(Status
))
1412 Status
= STATUS_UNSUCCESSFUL
;
1417 /* Add 4 more descriptors just in case things changed */
1418 EfiMemoryMapSize
+= (4 * DescriptorSize
);
1419 Pages
= BYTES_TO_PAGES(EfiMemoryMapSize
);
1420 EfiPrintf(L
"Memory map size: %lx bytes, %d pages\r\n", EfiMemoryMapSize
, Pages
);
1422 /* Should we use EFI to grab memory? */
1425 /* Yes -- request one more page to align up correctly */
1428 /* Grab the required pages */
1429 Status
= EfiAllocatePages(AllocateAnyPages
,
1432 if (!NT_SUCCESS(Status
))
1434 EfiPrintf(L
"EFI allocation failed: %lx\r\n", Status
);
1438 /* Free the pages for now */
1439 Status
= EfiFreePages(Pages
, EfiBuffer
);
1440 if (!NT_SUCCESS(Status
))
1446 /* Now round to the actual buffer size, removing the extra page */
1447 EfiBuffer
= ROUND_TO_PAGES(EfiBuffer
);
1449 Status
= EfiAllocatePages(AllocateAddress
,
1452 if (!NT_SUCCESS(Status
))
1458 /* Get the final aligned size and proper buffer */
1459 EfiMemoryMapSize
= EFI_PAGES_TO_SIZE(Pages
);
1460 EfiMemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)(ULONG_PTR
)EfiBuffer
;
1462 /* Switch to real mode if not already in it */
1463 OldMode
= CurrentExecutionContext
->Mode
;
1464 if (OldMode
!= BlRealMode
)
1466 BlpArchSwitchContext(BlRealMode
);
1469 /* Call EFI to get the memory map */
1470 EfiStatus
= EfiBS
->GetMemoryMap(&EfiMemoryMapSize
,
1474 &DescriptorVersion
);
1476 /* Switch back into the previous mode */
1477 if (OldMode
!= BlRealMode
)
1479 BlpArchSwitchContext(OldMode
);
1482 /* Convert the result code */
1483 Status
= EfiGetNtStatusCode(EfiStatus
);
1487 /* We don't support this path yet */
1488 Status
= STATUS_NOT_IMPLEMENTED
;
1491 /* So far so good? */
1492 if (!NT_SUCCESS(Status
))
1494 EfiPrintf(L
"Failed to get EFI memory map: %lx\r\n", Status
);
1498 /* Did we get correct data from firmware? */
1499 if (((EfiMemoryMapSize
% DescriptorSize
)) ||
1500 (DescriptorSize
< sizeof(EFI_MEMORY_DESCRIPTOR
)))
1502 EfiPrintf(L
"Incorrect descriptor size\r\n");
1503 Status
= STATUS_UNSUCCESSFUL
;
1507 /* Did we boot from a RAM disk? */
1508 if ((BlpBootDevice
->DeviceType
== LocalDevice
) &&
1509 (BlpBootDevice
->Local
.Type
== RamDiskDevice
))
1511 /* We don't handle this yet */
1512 EfiPrintf(L
"RAM boot not supported\r\n");
1513 Status
= STATUS_NOT_IMPLEMENTED
;
1518 /* We didn't, so there won't be any need to find the memory descriptor */
1519 HaveRamDisk
= FALSE
;
1522 /* Loop the EFI memory map */
1524 EfiPrintf(L
"UEFI MEMORY MAP\r\n\r\n");
1525 EfiPrintf(L
"TYPE START END ATTRIBUTES\r\n");
1526 EfiPrintf(L
"===============================================================\r\n");
1528 while (EfiMemoryMapSize
!= 0)
1530 /* Check if this is an EFI buffer, but we're not in real mode */
1531 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1533 BlpArchSwitchContext(BlRealMode
);
1536 /* Capture it so we can go back to protected mode (if possible) */
1537 EfiDescriptor
= *EfiMemoryMap
;
1539 /* Go back to protected mode, if we had switched */
1540 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1542 BlpArchSwitchContext(OldMode
);
1545 /* Convert to OS memory type */
1546 MemoryType
= MmFwpGetOsMemoryType(EfiDescriptor
.Type
);
1548 /* Round up or round down depending on where the memory is coming from */
1549 if (MemoryType
== BlConventionalMemory
)
1551 StartPage
= BYTES_TO_PAGES(EfiDescriptor
.PhysicalStart
);
1555 StartPage
= EfiDescriptor
.PhysicalStart
>> PAGE_SHIFT
;
1558 /* Calculate the ending page */
1559 EndPage
= StartPage
+ EfiDescriptor
.NumberOfPages
;
1561 /* If after rounding, we ended up with 0 pages, skip this */
1562 if (StartPage
== EndPage
)
1567 EfiPrintf(L
"%08X 0x%016I64X-0x%016I64X 0x%I64X\r\n",
1569 StartPage
<< PAGE_SHIFT
,
1570 EndPage
<< PAGE_SHIFT
,
1571 EfiDescriptor
.Attribute
);
1573 /* Check for any range of memory below 1MB */
1574 if (StartPage
< 0x100)
1576 /* Does this range actually contain NULL? */
1579 /* Manually create a reserved descriptof for this page */
1580 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1581 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1588 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1592 /* Add this descriptor into the list */
1593 Status
= MmMdAddDescriptorToList(MemoryMap
,
1595 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1596 if (!NT_SUCCESS(Status
))
1598 EfiPrintf(L
"Failed to add zero page descriptor: %lx\r\n", Status
);
1602 /* Now handle the rest of the range, unless this was it */
1610 /* Does the range go beyond 1MB? */
1611 if (EndPage
> 0x100)
1613 /* Then create the descriptor for everything up until the megabyte */
1614 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1615 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1622 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1626 /* Check if this region is currently free RAM */
1627 if (Descriptor
->Type
== BlConventionalMemory
)
1629 /* Set the reserved flag on the descriptor */
1630 EfiPrintf(L
"Adding magic flag\r\n");
1631 Descriptor
->Flags
|= BlMemoryReserved
;
1634 /* Add this descriptor into the list */
1635 Status
= MmMdAddDescriptorToList(MemoryMap
,
1637 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1638 if (!NT_SUCCESS(Status
))
1640 EfiPrintf(L
"Failed to add 1MB descriptor: %lx\r\n", Status
);
1644 /* Now handle the rest of the range above 1MB */
1649 /* Check if we loaded from a RAM disk */
1652 /* We don't handle this yet */
1653 EfiPrintf(L
"RAM boot not supported\r\n");
1654 Status
= STATUS_NOT_IMPLEMENTED
;
1658 /* Create a descriptor for the current range */
1659 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1660 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1664 EndPage
- StartPage
);
1667 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1671 /* Check if this region is currently free RAM below 1MB */
1672 if ((Descriptor
->Type
== BlConventionalMemory
) && (EndPage
<= 0x100))
1674 /* Set the reserved flag on the descriptor */
1675 EfiPrintf(L
"Adding magic flag\r\n");
1676 Descriptor
->Flags
|= BlMemoryReserved
;
1679 /* Add the descriptor to the list, requesting coalescing as asked */
1680 Status
= MmMdAddDescriptorToList(MemoryMap
,
1682 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
|
1683 (Flags
& BL_MM_FLAG_REQUEST_COALESCING
) ?
1684 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
: 0);
1685 if (!NT_SUCCESS(Status
))
1687 EfiPrintf(L
"Failed to add full descriptor: %lx\r\n", Status
);
1692 /* Consume this descriptor, and move to the next one */
1693 EfiMemoryMapSize
-= DescriptorSize
;
1694 EfiMemoryMap
= (PVOID
)((ULONG_PTR
)EfiMemoryMap
+ DescriptorSize
);
1697 /* FIXME: @TODO: Mark the EfiBuffer as free, since we're about to free it */
1698 /* For now, just "leak" the 1-2 pages... */
1701 /* Free the EFI buffer, if we had one */
1704 EfiFreePages(Pages
, EfiBuffer
);
1707 /* On failure, free the memory map if one was passed in */
1708 if (!NT_SUCCESS(Status
) && (MemoryMap
!= NULL
))
1710 MmMdFreeList(MemoryMap
);
1713 /* Decrement the nesting depth and return */
1714 MmDescriptorCallTreeCount
--;
1721 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
1724 NTSTATUS Status
= STATUS_SUCCESS
;
1725 EFI_KEY_TOGGLE_STATE KeyToggleState
;
1727 /* Check if we have valid firmware data */
1728 if (!(FirmwareData
) || !(FirmwareData
->Version
))
1730 return STATUS_INVALID_PARAMETER
;
1733 /* Check which boot phase we're in */
1736 /* Memory manager is ready, open the extended input protocol */
1737 Status
= EfiOpenProtocol(EfiST
->ConsoleInHandle
,
1738 &EfiSimpleTextInputExProtocol
,
1739 (PVOID
*)&EfiConInEx
);
1740 if (NT_SUCCESS(Status
))
1742 /* Set the initial key toggle state */
1743 KeyToggleState
= EFI_TOGGLE_STATE_VALID
| 40;
1744 EfiConInExSetState(EfiConInEx
, &KeyToggleState
);
1747 /* Setup the watchdog timer */
1748 EfiSetWatchdogTimer();
1752 /* Make a copy of the parameters */
1753 EfiFirmwareParameters
= &EfiFirmwareData
;
1755 /* Check which version we received */
1756 if (FirmwareData
->Version
== 1)
1758 /* FIXME: Not supported */
1759 Status
= STATUS_NOT_SUPPORTED
;
1761 else if (FirmwareData
->Version
>= 2)
1763 /* Version 2 -- save the data */
1764 EfiFirmwareData
= *FirmwareData
;
1765 EfiSystemTable
= FirmwareData
->SystemTable
;
1766 EfiImageHandle
= FirmwareData
->ImageHandle
;
1768 /* Set the EDK-II style variables as well */
1769 EfiST
= EfiSystemTable
;
1770 EfiBS
= EfiSystemTable
->BootServices
;
1771 EfiRT
= EfiSystemTable
->RuntimeServices
;
1772 EfiConOut
= EfiSystemTable
->ConOut
;
1773 EfiConIn
= EfiSystemTable
->ConIn
;
1778 /* Unknown version */
1779 Status
= STATUS_NOT_SUPPORTED
;
1783 /* Return the initialization state */
1788 BlFwEnumerateDevice (
1789 _In_ PBL_DEVICE_DESCRIPTOR Device
1793 ULONG PathProtocols
, BlockProtocols
;
1794 EFI_HANDLE
* PathArray
;
1795 EFI_HANDLE
* BlockArray
;
1797 /* Initialize locals */
1803 /* Enumeration only makes sense on disks or partitions */
1804 if ((Device
->DeviceType
!= DiskDevice
) &&
1805 (Device
->DeviceType
!= LegacyPartitionDevice
) &&
1806 (Device
->DeviceType
!= PartitionDevice
))
1808 return STATUS_NOT_SUPPORTED
;
1811 /* Enumerate the list of device paths */
1812 Status
= EfiLocateHandleBuffer(ByProtocol
,
1813 &EfiDevicePathProtocol
,
1816 if (NT_SUCCESS(Status
))
1818 /* Loop through each one */
1819 Status
= STATUS_NOT_FOUND
;
1820 while (PathProtocols
)
1822 /* Attempt to connect the driver for this device epath */
1823 Status
= EfiConnectController(PathArray
[--PathProtocols
]);
1824 if (NT_SUCCESS(Status
))
1826 /* Now enumerate any block I/O devices the driver added */
1827 Status
= EfiLocateHandleBuffer(ByProtocol
,
1828 &EfiBlockIoProtocol
,
1831 if (!NT_SUCCESS(Status
))
1836 /* Loop through each one */
1837 while (BlockProtocols
)
1839 /* Check if one of the new devices is the one we want */
1840 Status
= BlockIoEfiCompareDevice(Device
,
1841 BlockArray
[--BlockProtocols
]);
1842 if (NT_SUCCESS(Status
))
1849 /* Move on to the next device path */
1850 BlMmFreeHeap(BlockArray
);
1857 /* We're done -- free the array of device path protocols, if any */
1860 BlMmFreeHeap(PathArray
);
1863 /* We're done -- free the array of block I/O protocols, if any */
1866 BlMmFreeHeap(BlockArray
);
1869 /* Return if we found the device or not */
1874 * @name EfiGetEfiStatusCode
1876 * The EfiGetEfiStatusCode routine converts an NT Status to an EFI status.
1879 * NT Status code to be converted.
1881 * @remark Only certain, specific NT status codes are converted to EFI codes.
1883 * @return The corresponding EFI Status code, EFI_NO_MAPPING otherwise.
1887 EfiGetEfiStatusCode(
1888 _In_ NTSTATUS Status
1893 case STATUS_NOT_SUPPORTED
:
1894 return EFI_UNSUPPORTED
;
1895 case STATUS_DISK_FULL
:
1896 return EFI_VOLUME_FULL
;
1897 case STATUS_INSUFFICIENT_RESOURCES
:
1898 return EFI_OUT_OF_RESOURCES
;
1899 case STATUS_MEDIA_WRITE_PROTECTED
:
1900 return EFI_WRITE_PROTECTED
;
1901 case STATUS_DEVICE_NOT_READY
:
1902 return EFI_NOT_STARTED
;
1903 case STATUS_DEVICE_ALREADY_ATTACHED
:
1904 return EFI_ALREADY_STARTED
;
1905 case STATUS_MEDIA_CHANGED
:
1906 return EFI_MEDIA_CHANGED
;
1907 case STATUS_INVALID_PARAMETER
:
1908 return EFI_INVALID_PARAMETER
;
1909 case STATUS_ACCESS_DENIED
:
1910 return EFI_ACCESS_DENIED
;
1911 case STATUS_BUFFER_TOO_SMALL
:
1912 return EFI_BUFFER_TOO_SMALL
;
1913 case STATUS_DISK_CORRUPT_ERROR
:
1914 return EFI_VOLUME_CORRUPTED
;
1915 case STATUS_REQUEST_ABORTED
:
1917 case STATUS_NO_MEDIA
:
1918 return EFI_NO_MEDIA
;
1919 case STATUS_IO_DEVICE_ERROR
:
1920 return EFI_DEVICE_ERROR
;
1921 case STATUS_INVALID_BUFFER_SIZE
:
1922 return EFI_BAD_BUFFER_SIZE
;
1923 case STATUS_NOT_FOUND
:
1924 return EFI_NOT_FOUND
;
1925 case STATUS_DRIVER_UNABLE_TO_LOAD
:
1926 return EFI_LOAD_ERROR
;
1927 case STATUS_NO_MATCH
:
1928 return EFI_NO_MAPPING
;
1929 case STATUS_SUCCESS
:
1931 case STATUS_TIMEOUT
:
1934 return EFI_NO_MAPPING
;
1939 * @name EfiGetNtStatusCode
1941 * The EfiGetNtStatusCode routine converts an EFI Status to an NT status.
1944 * EFI Status code to be converted.
1946 * @remark Only certain, specific EFI status codes are converted to NT codes.
1948 * @return The corresponding NT Status code, STATUS_UNSUCCESSFUL otherwise.
1952 EfiGetNtStatusCode (
1953 _In_ EFI_STATUS EfiStatus
1960 return STATUS_NOT_FOUND
;
1962 return STATUS_NO_MEDIA
;
1963 case EFI_MEDIA_CHANGED
:
1964 return STATUS_MEDIA_CHANGED
;
1965 case EFI_ACCESS_DENIED
:
1966 case EFI_SECURITY_VIOLATION
:
1967 return STATUS_ACCESS_DENIED
;
1969 case EFI_NO_RESPONSE
:
1970 return STATUS_TIMEOUT
;
1971 case EFI_NO_MAPPING
:
1972 return STATUS_NO_MATCH
;
1973 case EFI_NOT_STARTED
:
1974 return STATUS_DEVICE_NOT_READY
;
1975 case EFI_ALREADY_STARTED
:
1976 return STATUS_DEVICE_ALREADY_ATTACHED
;
1978 return STATUS_REQUEST_ABORTED
;
1979 case EFI_VOLUME_FULL
:
1980 return STATUS_DISK_FULL
;
1981 case EFI_DEVICE_ERROR
:
1982 return STATUS_IO_DEVICE_ERROR
;
1983 case EFI_WRITE_PROTECTED
:
1984 return STATUS_MEDIA_WRITE_PROTECTED
;
1985 /* @FIXME: ReactOS Headers don't yet have this */
1986 //case EFI_OUT_OF_RESOURCES:
1987 //return STATUS_INSUFFICIENT_NVRAM_RESOURCES;
1988 case EFI_VOLUME_CORRUPTED
:
1989 return STATUS_DISK_CORRUPT_ERROR
;
1990 case EFI_BUFFER_TOO_SMALL
:
1991 return STATUS_BUFFER_TOO_SMALL
;
1993 return STATUS_SUCCESS
;
1994 case EFI_LOAD_ERROR
:
1995 return STATUS_DRIVER_UNABLE_TO_LOAD
;
1996 case EFI_INVALID_PARAMETER
:
1997 return STATUS_INVALID_PARAMETER
;
1998 case EFI_UNSUPPORTED
:
1999 return STATUS_NOT_SUPPORTED
;
2000 case EFI_BAD_BUFFER_SIZE
:
2001 return STATUS_INVALID_BUFFER_SIZE
;
2003 return STATUS_UNSUCCESSFUL
;