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 */
147 // FIXME: Hack while we are in early rosload mode
148 if (EfiConOut
!= NULL
)
150 EfiConOut
->OutputString(EfiConOut
, BlScratchBuffer
);
160 _In_ EFI_HANDLE Handle
,
161 _In_ EFI_GUID
*Protocol
,
162 _Out_ PVOID
* Interface
165 EFI_STATUS EfiStatus
;
167 BL_ARCH_MODE OldMode
;
169 /* Are we using virtual memory/ */
170 if (MmTranslationType
!= BlNone
)
172 /* We need complex tracking to make this work */
173 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
174 Status
= STATUS_NOT_SUPPORTED
;
178 /* Are we in protected mode? */
179 OldMode
= CurrentExecutionContext
->Mode
;
180 if (OldMode
!= BlRealMode
)
182 /* FIXME: Not yet implemented */
183 return STATUS_NOT_IMPLEMENTED
;
186 /* Are we on legacy 1.02? */
187 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
189 /* Make the legacy call */
190 EfiStatus
= EfiBS
->HandleProtocol(Handle
, Protocol
, Interface
);
194 /* Use the UEFI version */
195 EfiStatus
= EfiBS
->OpenProtocol(Handle
,
200 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
202 /* Switch back to protected mode if we came from there */
203 if (OldMode
!= BlRealMode
)
205 BlpArchSwitchContext(OldMode
);
209 /* Convert the error to an NTSTATUS */
210 Status
= EfiGetNtStatusCode(EfiStatus
);
213 /* Clear the interface on failure, and return the status */
214 if (!NT_SUCCESS(Status
))
224 _In_ EFI_HANDLE Handle
,
225 _In_ EFI_GUID
*Protocol
228 EFI_STATUS EfiStatus
;
230 BL_ARCH_MODE OldMode
;
232 /* Are we using virtual memory/ */
233 if (MmTranslationType
!= BlNone
)
235 /* We need complex tracking to make this work */
236 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
237 Status
= STATUS_NOT_SUPPORTED
;
241 /* Are we on legacy 1.02? */
242 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
244 /* Nothing to close */
245 EfiStatus
= STATUS_SUCCESS
;
249 /* Are we in protected mode? */
250 OldMode
= CurrentExecutionContext
->Mode
;
251 if (OldMode
!= BlRealMode
)
253 /* FIXME: Not yet implemented */
254 return STATUS_NOT_IMPLEMENTED
;
257 /* Use the UEFI version */
258 EfiStatus
= EfiBS
->CloseProtocol(Handle
, Protocol
, EfiImageHandle
, NULL
);
260 /* Switch back to protected mode if we came from there */
261 if (OldMode
!= BlRealMode
)
263 BlpArchSwitchContext(OldMode
);
266 /* Normalize not found as success */
267 if (EfiStatus
== EFI_NOT_FOUND
)
269 EfiStatus
= EFI_SUCCESS
;
273 /* Convert the error to an NTSTATUS */
274 Status
= EfiGetNtStatusCode(EfiStatus
);
283 _In_ PWCHAR VariableName
,
284 _In_ EFI_GUID
* VendorGuid
,
285 _Out_opt_ PULONG Attributes
,
286 _Inout_ PULONG DataSize
,
290 EFI_STATUS EfiStatus
;
292 BL_ARCH_MODE OldMode
;
293 ULONG LocalAttributes
;
295 /* Are we in protected mode? */
296 OldMode
= CurrentExecutionContext
->Mode
;
297 if (OldMode
!= BlRealMode
)
299 /* FIXME: Not yet implemented */
300 return STATUS_NOT_IMPLEMENTED
;
303 /* Call the runtime API */
304 EfiStatus
= EfiRT
->GetVariable(VariableName
,
306 (UINT32
*)&LocalAttributes
,
310 /* Switch back to protected mode if we came from there */
311 if (OldMode
!= BlRealMode
)
313 BlpArchSwitchContext(OldMode
);
316 /* Return attributes back to the caller if asked to */
319 *Attributes
= LocalAttributes
;
322 /* Convert the error to an NTSTATUS and return it */
323 Status
= EfiGetNtStatusCode(EfiStatus
);
328 BlpSecureBootEFIIsEnabled (
333 BOOLEAN SetupMode
, SecureBoot
;
336 /* Assume setup mode enabled, and no secure boot */
340 /* Get the SetupMode variable */
341 DataSize
= sizeof(SetupMode
);
342 Status
= EfiGetVariable(L
"SetupMode",
347 if (NT_SUCCESS(Status
))
349 /* If it worked, get the SecureBoot variable */
350 DataSize
= sizeof(SecureBoot
);
351 Status
= EfiGetVariable(L
"SecureBoot",
356 if (NT_SUCCESS(Status
))
358 /* In setup mode or without secureboot turned on, return failure */
359 if ((SecureBoot
!= TRUE
) || (SetupMode
))
361 Status
= STATUS_INVALID_SIGNATURE
;
364 // BlpSbdiStateFlags |= 8u;
368 /* Return secureboot status */
373 BlSecureBootIsEnabled (
374 _Out_ PBOOLEAN SecureBootEnabled
379 /* Have we checked before ? */
380 if (!BlpFirmwareChecked
)
382 /* First time checking */
383 Status
= BlpSecureBootEFIIsEnabled();
384 if NT_SUCCESS(Status
)
387 BlpFirmwareEnabled
= TRUE
;
390 /* Don't check again */
391 BlpFirmwareChecked
= TRUE
;
394 /* Return the firmware result */
395 *SecureBootEnabled
= BlpFirmwareEnabled
;
396 return STATUS_SUCCESS
;
400 BlSecureBootCheckForFactoryReset (
404 BOOLEAN SecureBootEnabled
;
408 /* Initialize locals */
410 SecureBootEnabled
= FALSE
;
412 /* Check if secureboot is enabled */
413 Status
= BlSecureBootIsEnabled(&SecureBootEnabled
);
414 if (!(NT_SUCCESS(Status
)) || !(SecureBootEnabled
))
416 /* It's not. Check if there's a revocation list */
417 Status
= EfiGetVariable(L
"RevocationList",
418 &BlpEfiSecureBootPrivateNamespace
,
422 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_TOO_SMALL
))
424 /* We don't support this yet */
425 EfiPrintf(L
"Not yet supported\r\n");
426 Status
= STATUS_NOT_IMPLEMENTED
;
430 /* Return back to the caller */
439 BL_ARCH_MODE OldMode
;
440 EFI_STATUS EfiStatus
;
442 /* Are we in protected mode? */
443 OldMode
= CurrentExecutionContext
->Mode
;
444 if (OldMode
!= BlRealMode
)
446 /* FIXME: Not yet implemented */
447 return STATUS_NOT_IMPLEMENTED
;
450 /* Make the EFI call */
451 EfiStatus
= EfiConIn
->Reset(EfiConIn
, FALSE
);
453 /* Switch back to protected mode if we came from there */
454 if (OldMode
!= BlRealMode
)
456 BlpArchSwitchContext(OldMode
);
459 /* Convert the error to an NTSTATUS */
460 return EfiGetNtStatusCode(EfiStatus
);
468 BL_ARCH_MODE OldMode
;
469 EFI_STATUS EfiStatus
;
471 /* Are we in protected mode? */
472 OldMode
= CurrentExecutionContext
->Mode
;
473 if (OldMode
!= BlRealMode
)
475 /* FIXME: Not yet implemented */
476 return STATUS_NOT_IMPLEMENTED
;
479 /* Make the EFI call */
480 EfiStatus
= EfiConInEx
->Reset(EfiConInEx
, FALSE
);
482 /* Switch back to protected mode if we came from there */
483 if (OldMode
!= BlRealMode
)
485 BlpArchSwitchContext(OldMode
);
488 /* Convert the error to an NTSTATUS */
489 return EfiGetNtStatusCode(EfiStatus
);
494 _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*ConInEx
,
495 _In_ EFI_KEY_TOGGLE_STATE
* KeyToggleState
498 BL_ARCH_MODE OldMode
;
499 EFI_STATUS EfiStatus
;
501 /* Are we in protected mode? */
502 OldMode
= CurrentExecutionContext
->Mode
;
503 if (OldMode
!= BlRealMode
)
505 /* FIXME: Not yet implemented */
506 return STATUS_NOT_IMPLEMENTED
;
509 /* Make the EFI call */
510 EfiStatus
= ConInEx
->SetState(ConInEx
, KeyToggleState
);
512 /* Switch back to protected mode if we came from there */
513 if (OldMode
!= BlRealMode
)
515 BlpArchSwitchContext(OldMode
);
518 /* Convert the error to an NTSTATUS */
519 return EfiGetNtStatusCode(EfiStatus
);
523 EfiSetWatchdogTimer (
527 BL_ARCH_MODE OldMode
;
528 EFI_STATUS EfiStatus
;
530 /* Are we in protected mode? */
531 OldMode
= CurrentExecutionContext
->Mode
;
532 if (OldMode
!= BlRealMode
)
534 /* FIXME: Not yet implemented */
535 return STATUS_NOT_IMPLEMENTED
;
538 /* Make the EFI call */
539 EfiStatus
= EfiBS
->SetWatchdogTimer(0, 0, 0, NULL
);
541 /* Switch back to protected mode if we came from there */
542 if (OldMode
!= BlRealMode
)
544 BlpArchSwitchContext(OldMode
);
547 /* Convert the error to an NTSTATUS */
548 return EfiGetNtStatusCode(EfiStatus
);
553 _Out_ UINTN
* MemoryMapSize
,
554 _Inout_ EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
556 _Out_ UINTN
* DescriptorSize
,
557 _Out_ UINTN
* DescriptorVersion
560 BL_ARCH_MODE OldMode
;
561 EFI_STATUS EfiStatus
;
563 /* Are we in protected mode? */
564 OldMode
= CurrentExecutionContext
->Mode
;
565 if (OldMode
!= BlRealMode
)
567 /* FIXME: Not yet implemented */
568 return STATUS_NOT_IMPLEMENTED
;
571 /* Make the EFI call */
572 EfiStatus
= EfiBS
->GetMemoryMap(MemoryMapSize
,
578 /* Switch back to protected mode if we came from there */
579 if (OldMode
!= BlRealMode
)
581 BlpArchSwitchContext(OldMode
);
584 /* Convert the error to an NTSTATUS */
585 return EfiGetNtStatusCode(EfiStatus
);
591 _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress
594 BL_ARCH_MODE OldMode
;
595 EFI_STATUS EfiStatus
;
597 /* Are we in protected mode? */
598 OldMode
= CurrentExecutionContext
->Mode
;
599 if (OldMode
!= BlRealMode
)
601 /* FIXME: Not yet implemented */
602 return STATUS_NOT_IMPLEMENTED
;
605 /* Make the EFI call */
606 EfiStatus
= EfiBS
->FreePages(PhysicalAddress
, Pages
);
608 /* Switch back to protected mode if we came from there */
609 if (OldMode
!= BlRealMode
)
611 BlpArchSwitchContext(OldMode
);
614 /* Convert the error to an NTSTATUS */
615 return EfiGetNtStatusCode(EfiStatus
);
623 BL_ARCH_MODE OldMode
;
624 EFI_STATUS EfiStatus
;
626 /* Are we in protected mode? */
627 OldMode
= CurrentExecutionContext
->Mode
;
628 if (OldMode
!= BlRealMode
)
630 /* FIXME: Not yet implemented */
631 return STATUS_NOT_IMPLEMENTED
;
634 /* Make the EFI call */
635 EfiStatus
= EfiBS
->Stall(StallTime
);
637 /* Switch back to protected mode if we came from there */
638 if (OldMode
!= BlRealMode
)
640 BlpArchSwitchContext(OldMode
);
643 /* Convert the error to an NTSTATUS */
644 return EfiGetNtStatusCode(EfiStatus
);
649 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
655 BL_ARCH_MODE OldMode
;
656 EFI_STATUS EfiStatus
;
658 /* Are we in protected mode? */
659 OldMode
= CurrentExecutionContext
->Mode
;
660 if (OldMode
!= BlRealMode
)
662 /* FIXME: Not yet implemented */
663 return STATUS_NOT_IMPLEMENTED
;
666 /* Make the EFI call */
667 EfiStatus
= TextInterface
->QueryMode(TextInterface
, Mode
, Columns
, Rows
);
669 /* Switch back to protected mode if we came from there */
670 if (OldMode
!= BlRealMode
)
672 BlpArchSwitchContext(OldMode
);
675 /* Convert the error to an NTSTATUS */
676 return EfiGetNtStatusCode(EfiStatus
);
681 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
685 BL_ARCH_MODE OldMode
;
686 EFI_STATUS EfiStatus
;
688 /* Are we in protected mode? */
689 OldMode
= CurrentExecutionContext
->Mode
;
690 if (OldMode
!= BlRealMode
)
692 /* FIXME: Not yet implemented */
693 return STATUS_NOT_IMPLEMENTED
;
696 /* Make the EFI call */
697 EfiStatus
= TextInterface
->SetMode(TextInterface
, Mode
);
699 /* Switch back to protected mode if we came from there */
700 if (OldMode
!= BlRealMode
)
702 BlpArchSwitchContext(OldMode
);
705 /* Convert the error to an NTSTATUS */
706 return EfiGetNtStatusCode(EfiStatus
);
710 EfiConOutSetAttribute (
711 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
715 BL_ARCH_MODE OldMode
;
716 EFI_STATUS EfiStatus
;
718 /* Are we in protected mode? */
719 OldMode
= CurrentExecutionContext
->Mode
;
720 if (OldMode
!= BlRealMode
)
722 /* FIXME: Not yet implemented */
723 return STATUS_NOT_IMPLEMENTED
;
726 /* Make the EFI call */
727 EfiStatus
= TextInterface
->SetAttribute(TextInterface
, Attribute
);
729 /* Switch back to protected mode if we came from there */
730 if (OldMode
!= BlRealMode
)
732 BlpArchSwitchContext(OldMode
);
735 /* Convert the error to an NTSTATUS */
736 return EfiGetNtStatusCode(EfiStatus
);
740 EfiConOutSetCursorPosition (
741 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
746 BL_ARCH_MODE OldMode
;
747 EFI_STATUS EfiStatus
;
749 /* Are we in protected mode? */
750 OldMode
= CurrentExecutionContext
->Mode
;
751 if (OldMode
!= BlRealMode
)
753 /* FIXME: Not yet implemented */
754 return STATUS_NOT_IMPLEMENTED
;
757 /* Make the EFI call */
758 EfiStatus
= TextInterface
->SetCursorPosition(TextInterface
, Column
, Row
);
760 /* Switch back to protected mode if we came from there */
761 if (OldMode
!= BlRealMode
)
763 BlpArchSwitchContext(OldMode
);
766 /* Convert the error to an NTSTATUS */
767 return EfiGetNtStatusCode(EfiStatus
);
771 EfiConOutEnableCursor (
772 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
776 BL_ARCH_MODE OldMode
;
777 EFI_STATUS EfiStatus
;
779 /* Are we in protected mode? */
780 OldMode
= CurrentExecutionContext
->Mode
;
781 if (OldMode
!= BlRealMode
)
783 /* FIXME: Not yet implemented */
784 return STATUS_NOT_IMPLEMENTED
;
787 /* Make the EFI call */
788 EfiStatus
= TextInterface
->EnableCursor(TextInterface
, Visible
);
790 /* Switch back to protected mode if we came from there */
791 if (OldMode
!= BlRealMode
)
793 BlpArchSwitchContext(OldMode
);
796 /* Convert the error to an NTSTATUS */
797 return EfiGetNtStatusCode(EfiStatus
);
801 EfiConOutOutputString (
802 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
806 BL_ARCH_MODE OldMode
;
807 EFI_STATUS EfiStatus
;
809 /* Are we in protected mode? */
810 OldMode
= CurrentExecutionContext
->Mode
;
811 if (OldMode
!= BlRealMode
)
813 /* FIXME: Not yet implemented */
814 return STATUS_NOT_IMPLEMENTED
;
817 /* Make the EFI call */
818 EfiStatus
= TextInterface
->OutputString(TextInterface
, String
);
820 /* Switch back to protected mode if we came from there */
821 if (OldMode
!= BlRealMode
)
823 BlpArchSwitchContext(OldMode
);
826 /* Convert the error to an NTSTATUS */
827 return EfiGetNtStatusCode(EfiStatus
);
832 EfiConOutReadCurrentMode (
833 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
834 _Out_ EFI_SIMPLE_TEXT_OUTPUT_MODE
* Mode
837 BL_ARCH_MODE OldMode
;
839 /* Are we in protected mode? */
840 OldMode
= CurrentExecutionContext
->Mode
;
841 if (OldMode
!= BlRealMode
)
843 /* FIXME: Not yet implemented */
847 /* Make the EFI call */
848 RtlCopyMemory(Mode
, TextInterface
->Mode
, sizeof(*Mode
));
850 /* Switch back to protected mode if we came from there */
851 if (OldMode
!= BlRealMode
)
853 BlpArchSwitchContext(OldMode
);
858 EfiGopGetFrameBuffer (
859 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
860 _Out_ PHYSICAL_ADDRESS
* FrameBuffer
,
861 _Out_ UINTN
*FrameBufferSize
864 BL_ARCH_MODE OldMode
;
866 /* Are we in protected mode? */
867 OldMode
= CurrentExecutionContext
->Mode
;
868 if (OldMode
!= BlRealMode
)
870 /* FIXME: Not yet implemented */
874 /* Make the EFI call */
875 FrameBuffer
->QuadPart
= GopInterface
->Mode
->FrameBufferBase
;
876 *FrameBufferSize
= GopInterface
->Mode
->FrameBufferSize
;
878 /* Switch back to protected mode if we came from there */
879 if (OldMode
!= BlRealMode
)
881 BlpArchSwitchContext(OldMode
);
886 EfiGopGetCurrentMode (
887 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
889 _Out_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Information
892 BL_ARCH_MODE OldMode
;
894 /* Are we in protected mode? */
895 OldMode
= CurrentExecutionContext
->Mode
;
896 if (OldMode
!= BlRealMode
)
898 /* FIXME: Not yet implemented */
899 return STATUS_NOT_IMPLEMENTED
;
902 /* Make the EFI call */
903 *Mode
= GopInterface
->Mode
->Mode
;
904 RtlCopyMemory(Information
, GopInterface
->Mode
->Info
, sizeof(*Information
));
906 /* Switch back to protected mode if we came from there */
907 if (OldMode
!= BlRealMode
)
909 BlpArchSwitchContext(OldMode
);
913 return STATUS_SUCCESS
;
918 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
922 BL_ARCH_MODE OldMode
;
923 EFI_STATUS EfiStatus
;
927 /* Are we in protected mode? */
928 OldMode
= CurrentExecutionContext
->Mode
;
929 if (OldMode
!= BlRealMode
)
931 /* FIXME: Not yet implemented */
932 return STATUS_NOT_IMPLEMENTED
;
935 /* Make the EFI call */
936 if (Mode
== GopInterface
->Mode
->Mode
)
938 EfiStatus
= EFI_SUCCESS
;
942 EfiStatus
= GopInterface
->SetMode(GopInterface
, Mode
);
946 /* Switch back to protected mode if we came from there */
947 if (OldMode
!= BlRealMode
)
949 BlpArchSwitchContext(OldMode
);
952 /* Print out to the debugger if the mode was changed */
953 Status
= EfiGetNtStatusCode(EfiStatus
);
954 if ((ModeChanged
) && (NT_SUCCESS(Status
)))
956 /* FIXME @TODO: Should be BlStatusPrint */
957 EfiPrintf(L
"Console video mode set to 0x%x\r\n", Mode
);
960 /* Convert the error to an NTSTATUS */
965 EfiLocateHandleBuffer (
966 _In_ EFI_LOCATE_SEARCH_TYPE SearchType
,
967 _In_ EFI_GUID
*Protocol
,
968 _Inout_ PULONG HandleCount
,
969 _Inout_ EFI_HANDLE
** Buffer
972 BL_ARCH_MODE OldMode
;
973 EFI_STATUS EfiStatus
;
976 /* Bail out if we're missing parameters */
977 if (!(Buffer
) || !(HandleCount
))
979 return STATUS_INVALID_PARAMETER
;
982 /* Check if a buffer was passed in*/
985 /* Then we should already have a buffer size*/
986 BufferSize
= sizeof(EFI_HANDLE
) * *HandleCount
;
990 /* Then no buffer size exists */
994 /* Are we in protected mode? */
995 OldMode
= CurrentExecutionContext
->Mode
;
996 if (OldMode
!= BlRealMode
)
998 /* FIXME: Not yet implemented */
999 return STATUS_NOT_IMPLEMENTED
;
1002 /* Try the first time */
1003 EfiStatus
= EfiBS
->LocateHandle(SearchType
, Protocol
, NULL
, &BufferSize
, *Buffer
);
1004 if (EfiStatus
== EFI_BUFFER_TOO_SMALL
)
1006 /* Did we have an existing buffer? */
1010 BlMmFreeHeap(*Buffer
);
1013 /* Allocate a new one */
1014 *Buffer
= BlMmAllocateHeap(BufferSize
);
1017 /* No space, fail */
1018 return STATUS_NO_MEMORY
;
1022 EfiStatus
= EfiBS
->LocateHandle(SearchType
, Protocol
, NULL
, &BufferSize
, *Buffer
);
1024 /* Switch back to protected mode if we came from there */
1025 if (OldMode
!= BlRealMode
)
1027 BlpArchSwitchContext(OldMode
);
1031 /* Return the number of handles */
1032 *HandleCount
= BufferSize
/ sizeof(EFI_HANDLE
);
1034 /* Convert the error to an NTSTATUS */
1035 return EfiGetNtStatusCode(EfiStatus
);
1040 _In_ EFI_RESET_TYPE ResetType
1043 BL_ARCH_MODE OldMode
;
1045 /* Are we in protected mode? */
1046 OldMode
= CurrentExecutionContext
->Mode
;
1047 if (OldMode
!= BlRealMode
)
1049 /* FIXME: Not yet implemented */
1053 /* Call the EFI runtime */
1054 EfiRT
->ResetSystem(ResetType
, EFI_SUCCESS
, 0, NULL
);
1058 EfiConnectController (
1059 _In_ EFI_HANDLE ControllerHandle
1062 BL_ARCH_MODE OldMode
;
1063 EFI_STATUS EfiStatus
;
1065 /* Is this EFI 1.02? */
1066 if (EfiST
->Hdr
.Revision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
1068 /* This function didn't exist back then */
1069 return STATUS_NOT_SUPPORTED
;
1072 /* Are we in protected mode? */
1073 OldMode
= CurrentExecutionContext
->Mode
;
1074 if (OldMode
!= BlRealMode
)
1076 /* FIXME: Not yet implemented */
1077 return STATUS_NOT_IMPLEMENTED
;
1080 /* Make the EFI call */
1081 EfiStatus
= EfiBS
->ConnectController(ControllerHandle
, NULL
, NULL
, TRUE
);
1083 /* Switch back to protected mode if we came from there */
1084 if (OldMode
!= BlRealMode
)
1086 BlpArchSwitchContext(OldMode
);
1089 /* Convert the error to an NTSTATUS */
1090 return EfiGetNtStatusCode(EfiStatus
);
1097 _Inout_ EFI_PHYSICAL_ADDRESS
* Memory
1100 BL_ARCH_MODE OldMode
;
1101 EFI_STATUS EfiStatus
;
1103 /* Are we in protected mode? */
1104 OldMode
= CurrentExecutionContext
->Mode
;
1105 if (OldMode
!= BlRealMode
)
1107 /* FIXME: Not yet implemented */
1108 return STATUS_NOT_IMPLEMENTED
;
1111 /* Make the EFI call */
1112 EfiStatus
= EfiBS
->AllocatePages(Type
, EfiLoaderData
, Pages
, Memory
);
1114 /* Switch back to protected mode if we came from there */
1115 if (OldMode
!= BlRealMode
)
1117 BlpArchSwitchContext(OldMode
);
1120 /* Convert the error to an NTSTATUS */
1121 return EfiGetNtStatusCode(EfiStatus
);
1125 EfipGetSystemTable (
1126 _In_ EFI_GUID
*TableGuid
,
1127 _Out_ PPHYSICAL_ADDRESS TableAddress
1133 /* Assume failure */
1134 Status
= STATUS_NOT_FOUND
;
1136 /* Loop through the configuration tables */
1137 for (i
= 0; i
< EfiST
->NumberOfTableEntries
; i
++)
1139 /* Check if this one matches the one we want */
1140 if (RtlEqualMemory(&EfiST
->ConfigurationTable
[i
].VendorGuid
,
1142 sizeof(*TableGuid
)))
1144 /* Return its address */
1145 TableAddress
->QuadPart
= (ULONG_PTR
)EfiST
->ConfigurationTable
[i
].VendorTable
;
1146 Status
= STATUS_SUCCESS
;
1151 /* Return the search result */
1157 _Out_ PPHYSICAL_ADDRESS FoundRsdt
1162 PHYSICAL_ADDRESS RsdpAddress
, Rsdt
;
1165 /* Assume failure */
1169 /* Check if we already know it */
1170 if (EfiRsdt
.QuadPart
)
1173 *FoundRsdt
= EfiRsdt
;
1174 return STATUS_SUCCESS
;
1177 /* Otherwise, look for the ACPI 2.0 RSDP (XSDT really) */
1178 Status
= EfipGetSystemTable(&EfiRootAcpiTableGuid
, &RsdpAddress
);
1179 if (!NT_SUCCESS(Status
))
1181 /* Didn't fint it, look for the ACPI 1.0 RSDP (RSDT really) */
1182 Status
= EfipGetSystemTable(&EfiRootAcpiTable10Guid
, &RsdpAddress
);
1183 if (!NT_SUCCESS(Status
))
1190 Length
= sizeof(*Rsdp
);
1191 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1195 if (NT_SUCCESS(Status
))
1197 /* Check the revision (anything >= 2.0 is XSDT) */
1200 /* Check if the table is bigger than just its header */
1201 if (Rsdp
->Length
> Length
)
1203 /* Capture the real length */
1204 Length
= Rsdp
->Length
;
1206 /* Unmap our header mapping */
1207 BlMmUnmapVirtualAddressEx(Rsdp
, sizeof(*Rsdp
));
1209 /* And map the whole thing now */
1210 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1214 if (!NT_SUCCESS(Status
))
1220 /* Read the XSDT address from the table*/
1221 Rsdt
= Rsdp
->XsdtAddress
;
1225 /* ACPI 1.0 so just read the RSDT */
1226 Rsdt
.QuadPart
= Rsdp
->RsdtAddress
;
1229 /* Save it for later */
1232 /* And return it back */
1236 /* Check if we had mapped the RSDP */
1240 BlMmUnmapVirtualAddressEx(Rsdp
, Length
);
1243 /* Return search result back to caller */
1248 MmFwpGetOsAttributeType (
1249 _In_ ULONGLONG Attribute
1252 BL_MEMORY_ATTR OsAttribute
= 0;
1254 if (Attribute
& EFI_MEMORY_UC
)
1256 OsAttribute
= BlMemoryUncached
;
1259 if (Attribute
& EFI_MEMORY_WC
)
1261 OsAttribute
|= BlMemoryWriteCombined
;
1264 if (Attribute
& EFI_MEMORY_WT
)
1266 OsAttribute
|= BlMemoryWriteThrough
;
1269 if (Attribute
& EFI_MEMORY_WB
)
1271 OsAttribute
|= BlMemoryWriteBack
;
1274 if (Attribute
& EFI_MEMORY_UCE
)
1276 OsAttribute
|= BlMemoryUncachedExported
;
1279 if (Attribute
& EFI_MEMORY_WP
)
1281 OsAttribute
|= BlMemoryWriteProtected
;
1284 if (Attribute
& EFI_MEMORY_RP
)
1286 OsAttribute
|= BlMemoryReadProtected
;
1289 if (Attribute
& EFI_MEMORY_XP
)
1291 OsAttribute
|= BlMemoryExecuteProtected
;
1294 if (Attribute
& EFI_MEMORY_RUNTIME
)
1296 OsAttribute
|= BlMemoryRuntime
;
1303 MmFwpGetOsMemoryType (
1304 _In_ EFI_MEMORY_TYPE MemoryType
1307 BL_MEMORY_TYPE OsType
;
1313 OsType
= BlLoaderMemory
;
1316 case EfiBootServicesCode
:
1317 case EfiBootServicesData
:
1318 OsType
= BlEfiBootMemory
;
1321 case EfiRuntimeServicesCode
:
1322 case EfiRuntimeServicesData
:
1323 OsType
= BlEfiRuntimeMemory
;
1326 case EfiConventionalMemory
:
1327 OsType
= BlConventionalMemory
;
1330 case EfiUnusableMemory
:
1331 OsType
= BlUnusableMemory
;
1334 case EfiACPIReclaimMemory
:
1335 OsType
= BlAcpiReclaimMemory
;
1338 case EfiACPIMemoryNVS
:
1339 OsType
= BlAcpiNvsMemory
;
1342 case EfiMemoryMappedIO
:
1343 OsType
= BlDeviceIoMemory
;
1346 case EfiMemoryMappedIOPortSpace
:
1347 OsType
= BlDevicePortMemory
;
1351 OsType
= BlPalMemory
;
1355 OsType
= BlReservedMemory
;
1364 _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap
,
1368 BL_LIBRARY_PARAMETERS LibraryParameters
= BlpLibraryParameters
;
1369 BOOLEAN UseEfiBuffer
, HaveRamDisk
;
1371 ULONGLONG Pages
, StartPage
, EndPage
;
1372 UINTN EfiMemoryMapSize
, MapKey
, DescriptorSize
, DescriptorVersion
;
1373 EFI_PHYSICAL_ADDRESS EfiBuffer
= 0;
1374 EFI_MEMORY_DESCRIPTOR
* EfiMemoryMap
;
1375 EFI_STATUS EfiStatus
;
1376 BL_ARCH_MODE OldMode
;
1377 EFI_MEMORY_DESCRIPTOR EfiDescriptor
;
1378 BL_MEMORY_TYPE MemoryType
;
1379 PBL_MEMORY_DESCRIPTOR Descriptor
;
1380 BL_MEMORY_ATTR Attribute
;
1382 /* Initialize EFI memory map attributes */
1383 EfiMemoryMapSize
= MapKey
= DescriptorSize
= DescriptorVersion
= 0;
1385 /* Increment the nesting depth */
1386 MmDescriptorCallTreeCount
++;
1388 /* Determine if we should use EFI or our own allocator at this point */
1389 UseEfiBuffer
= Flags
& BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS
;
1390 if (!(LibraryParameters
.LibraryFlags
& BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
))
1392 UseEfiBuffer
= TRUE
;
1395 /* Bail out if we don't have a list to use */
1396 if (MemoryMap
== NULL
)
1398 Status
= STATUS_INVALID_PARAMETER
;
1402 /* Free the current descriptor list */
1403 MmMdFreeList(MemoryMap
);
1405 /* Call into EFI to get the size of the memory map */
1406 Status
= EfiGetMemoryMap(&EfiMemoryMapSize
,
1410 &DescriptorVersion
);
1411 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
1413 /* This should've failed because our buffer was too small, nothing else */
1414 EfiPrintf(L
"Got strange EFI status for memory map: %lx\r\n", Status
);
1415 if (NT_SUCCESS(Status
))
1417 Status
= STATUS_UNSUCCESSFUL
;
1422 /* Add 4 more descriptors just in case things changed */
1423 EfiMemoryMapSize
+= (4 * DescriptorSize
);
1424 Pages
= BYTES_TO_PAGES(EfiMemoryMapSize
);
1425 EfiPrintf(L
"Memory map size: %lx bytes, %d pages\r\n", EfiMemoryMapSize
, Pages
);
1427 /* Should we use EFI to grab memory? */
1430 /* Yes -- request one more page to align up correctly */
1433 /* Grab the required pages */
1434 Status
= EfiAllocatePages(AllocateAnyPages
,
1437 if (!NT_SUCCESS(Status
))
1439 EfiPrintf(L
"EFI allocation failed: %lx\r\n", Status
);
1443 /* Free the pages for now */
1444 Status
= EfiFreePages(Pages
, EfiBuffer
);
1445 if (!NT_SUCCESS(Status
))
1451 /* Now round to the actual buffer size, removing the extra page */
1452 EfiBuffer
= ROUND_TO_PAGES(EfiBuffer
);
1454 Status
= EfiAllocatePages(AllocateAddress
,
1457 if (!NT_SUCCESS(Status
))
1463 /* Get the final aligned size and proper buffer */
1464 EfiMemoryMapSize
= EFI_PAGES_TO_SIZE(Pages
);
1465 EfiMemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)(ULONG_PTR
)EfiBuffer
;
1467 /* Switch to real mode if not already in it */
1468 OldMode
= CurrentExecutionContext
->Mode
;
1469 if (OldMode
!= BlRealMode
)
1471 BlpArchSwitchContext(BlRealMode
);
1474 /* Call EFI to get the memory map */
1475 EfiStatus
= EfiBS
->GetMemoryMap(&EfiMemoryMapSize
,
1479 &DescriptorVersion
);
1481 /* Switch back into the previous mode */
1482 if (OldMode
!= BlRealMode
)
1484 BlpArchSwitchContext(OldMode
);
1487 /* Convert the result code */
1488 Status
= EfiGetNtStatusCode(EfiStatus
);
1492 /* We don't support this path yet */
1493 Status
= STATUS_NOT_IMPLEMENTED
;
1496 /* So far so good? */
1497 if (!NT_SUCCESS(Status
))
1499 EfiPrintf(L
"Failed to get EFI memory map: %lx\r\n", Status
);
1503 /* Did we get correct data from firmware? */
1504 if (((EfiMemoryMapSize
% DescriptorSize
)) ||
1505 (DescriptorSize
< sizeof(EFI_MEMORY_DESCRIPTOR
)))
1507 EfiPrintf(L
"Incorrect descriptor size\r\n");
1508 Status
= STATUS_UNSUCCESSFUL
;
1512 /* Did we boot from a RAM disk? */
1513 if ((BlpBootDevice
->DeviceType
== LocalDevice
) &&
1514 (BlpBootDevice
->Local
.Type
== RamDiskDevice
))
1516 /* We don't handle this yet */
1517 EfiPrintf(L
"RAM boot not supported\r\n");
1518 Status
= STATUS_NOT_IMPLEMENTED
;
1523 /* We didn't, so there won't be any need to find the memory descriptor */
1524 HaveRamDisk
= FALSE
;
1527 /* Loop the EFI memory map */
1529 EfiPrintf(L
"UEFI MEMORY MAP\r\n\r\n");
1530 EfiPrintf(L
"TYPE START END ATTRIBUTES\r\n");
1531 EfiPrintf(L
"===============================================================\r\n");
1533 while (EfiMemoryMapSize
!= 0)
1535 /* Check if this is an EFI buffer, but we're not in real mode */
1536 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1538 BlpArchSwitchContext(BlRealMode
);
1541 /* Capture it so we can go back to protected mode (if possible) */
1542 EfiDescriptor
= *EfiMemoryMap
;
1544 /* Go back to protected mode, if we had switched */
1545 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1547 BlpArchSwitchContext(OldMode
);
1550 /* Convert to OS memory type */
1551 MemoryType
= MmFwpGetOsMemoryType(EfiDescriptor
.Type
);
1553 /* Round up or round down depending on where the memory is coming from */
1554 if (MemoryType
== BlConventionalMemory
)
1556 StartPage
= BYTES_TO_PAGES(EfiDescriptor
.PhysicalStart
);
1560 StartPage
= EfiDescriptor
.PhysicalStart
>> PAGE_SHIFT
;
1563 /* Calculate the ending page */
1564 EndPage
= StartPage
+ EfiDescriptor
.NumberOfPages
;
1566 /* If after rounding, we ended up with 0 pages, skip this */
1567 if (StartPage
== EndPage
)
1572 EfiPrintf(L
"%08X 0x%016I64X-0x%016I64X 0x%I64X\r\n",
1574 StartPage
<< PAGE_SHIFT
,
1575 EndPage
<< PAGE_SHIFT
,
1576 EfiDescriptor
.Attribute
);
1578 /* Check for any range of memory below 1MB */
1579 if (StartPage
< 0x100)
1581 /* Does this range actually contain NULL? */
1584 /* Manually create a reserved descriptof for this page */
1585 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1586 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1593 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1597 /* Add this descriptor into the list */
1598 Status
= MmMdAddDescriptorToList(MemoryMap
,
1600 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1601 if (!NT_SUCCESS(Status
))
1603 EfiPrintf(L
"Failed to add zero page descriptor: %lx\r\n", Status
);
1607 /* Now handle the rest of the range, unless this was it */
1615 /* Does the range go beyond 1MB? */
1616 if (EndPage
> 0x100)
1618 /* Then create the descriptor for everything up until the megabyte */
1619 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1620 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1627 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1631 /* Check if this region is currently free RAM */
1632 if (Descriptor
->Type
== BlConventionalMemory
)
1634 /* Set the reserved flag on the descriptor */
1635 EfiPrintf(L
"Adding magic flag\r\n");
1636 Descriptor
->Flags
|= BlMemoryReserved
;
1639 /* Add this descriptor into the list */
1640 Status
= MmMdAddDescriptorToList(MemoryMap
,
1642 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1643 if (!NT_SUCCESS(Status
))
1645 EfiPrintf(L
"Failed to add 1MB descriptor: %lx\r\n", Status
);
1649 /* Now handle the rest of the range above 1MB */
1654 /* Check if we loaded from a RAM disk */
1657 /* We don't handle this yet */
1658 EfiPrintf(L
"RAM boot not supported\r\n");
1659 Status
= STATUS_NOT_IMPLEMENTED
;
1663 /* Create a descriptor for the current range */
1664 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1665 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1669 EndPage
- StartPage
);
1672 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1676 /* Check if this region is currently free RAM below 1MB */
1677 if ((Descriptor
->Type
== BlConventionalMemory
) && (EndPage
<= 0x100))
1679 /* Set the reserved flag on the descriptor */
1680 EfiPrintf(L
"Adding magic flag\r\n");
1681 Descriptor
->Flags
|= BlMemoryReserved
;
1684 /* Add the descriptor to the list, requesting coalescing as asked */
1685 Status
= MmMdAddDescriptorToList(MemoryMap
,
1687 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
|
1688 ((Flags
& BL_MM_FLAG_REQUEST_COALESCING
) ?
1689 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
: 0));
1690 if (!NT_SUCCESS(Status
))
1692 EfiPrintf(L
"Failed to add full descriptor: %lx\r\n", Status
);
1697 /* Consume this descriptor, and move to the next one */
1698 EfiMemoryMapSize
-= DescriptorSize
;
1699 EfiMemoryMap
= (PVOID
)((ULONG_PTR
)EfiMemoryMap
+ DescriptorSize
);
1702 /* FIXME: @TODO: Mark the EfiBuffer as free, since we're about to free it */
1703 /* For now, just "leak" the 1-2 pages... */
1706 /* Free the EFI buffer, if we had one */
1709 EfiFreePages(Pages
, EfiBuffer
);
1712 /* On failure, free the memory map if one was passed in */
1713 if (!NT_SUCCESS(Status
) && (MemoryMap
!= NULL
))
1715 MmMdFreeList(MemoryMap
);
1718 /* Decrement the nesting depth and return */
1719 MmDescriptorCallTreeCount
--;
1726 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
1729 NTSTATUS Status
= STATUS_SUCCESS
;
1730 EFI_KEY_TOGGLE_STATE KeyToggleState
;
1732 /* Check if we have valid firmware data */
1733 if (!(FirmwareData
) || !(FirmwareData
->Version
))
1735 return STATUS_INVALID_PARAMETER
;
1738 /* Check which boot phase we're in */
1741 /* Memory manager is ready, open the extended input protocol */
1742 Status
= EfiOpenProtocol(EfiST
->ConsoleInHandle
,
1743 &EfiSimpleTextInputExProtocol
,
1744 (PVOID
*)&EfiConInEx
);
1745 if (NT_SUCCESS(Status
))
1747 /* Set the initial key toggle state */
1748 KeyToggleState
= EFI_TOGGLE_STATE_VALID
| 40;
1749 EfiConInExSetState(EfiConInEx
, &KeyToggleState
);
1752 /* Setup the watchdog timer */
1753 EfiSetWatchdogTimer();
1757 /* Make a copy of the parameters */
1758 EfiFirmwareParameters
= &EfiFirmwareData
;
1760 /* Check which version we received */
1761 if (FirmwareData
->Version
== 1)
1763 /* FIXME: Not supported */
1764 Status
= STATUS_NOT_SUPPORTED
;
1766 else if (FirmwareData
->Version
>= BL_FIRMWARE_DESCRIPTOR_VERSION
)
1768 /* Version 2 -- save the data */
1769 EfiFirmwareData
= *FirmwareData
;
1770 EfiSystemTable
= FirmwareData
->SystemTable
;
1771 EfiImageHandle
= FirmwareData
->ImageHandle
;
1773 /* Set the EDK-II style variables as well */
1774 EfiST
= EfiSystemTable
;
1775 EfiBS
= EfiSystemTable
->BootServices
;
1776 EfiRT
= EfiSystemTable
->RuntimeServices
;
1777 EfiConOut
= EfiSystemTable
->ConOut
;
1778 EfiConIn
= EfiSystemTable
->ConIn
;
1783 /* Unknown version */
1784 Status
= STATUS_NOT_SUPPORTED
;
1788 /* Return the initialization state */
1794 _In_ PBL_FIRMWARE_DESCRIPTOR Parameters
1797 /* Make sure we got an argument */
1800 return STATUS_INVALID_PARAMETER
;
1803 /* Copy the static data */
1804 *Parameters
= *EfiFirmwareParameters
;
1805 return STATUS_SUCCESS
;
1809 BlFwEnumerateDevice (
1810 _In_ PBL_DEVICE_DESCRIPTOR Device
1814 ULONG PathProtocols
, BlockProtocols
;
1815 EFI_HANDLE
* PathArray
;
1816 EFI_HANDLE
* BlockArray
;
1818 /* Initialize locals */
1824 /* Enumeration only makes sense on disks or partitions */
1825 if ((Device
->DeviceType
!= DiskDevice
) &&
1826 (Device
->DeviceType
!= LegacyPartitionDevice
) &&
1827 (Device
->DeviceType
!= PartitionDevice
))
1829 return STATUS_NOT_SUPPORTED
;
1832 /* Enumerate the list of device paths */
1833 Status
= EfiLocateHandleBuffer(ByProtocol
,
1834 &EfiDevicePathProtocol
,
1837 if (NT_SUCCESS(Status
))
1839 /* Loop through each one */
1840 Status
= STATUS_NOT_FOUND
;
1841 while (PathProtocols
)
1843 /* Attempt to connect the driver for this device epath */
1844 Status
= EfiConnectController(PathArray
[--PathProtocols
]);
1845 if (NT_SUCCESS(Status
))
1847 /* Now enumerate any block I/O devices the driver added */
1848 Status
= EfiLocateHandleBuffer(ByProtocol
,
1849 &EfiBlockIoProtocol
,
1852 if (!NT_SUCCESS(Status
))
1857 /* Loop through each one */
1858 while (BlockProtocols
)
1860 /* Check if one of the new devices is the one we want */
1861 Status
= BlockIoEfiCompareDevice(Device
,
1862 BlockArray
[--BlockProtocols
]);
1863 if (NT_SUCCESS(Status
))
1870 /* Move on to the next device path */
1871 BlMmFreeHeap(BlockArray
);
1878 /* We're done -- free the array of device path protocols, if any */
1881 BlMmFreeHeap(PathArray
);
1884 /* We're done -- free the array of block I/O protocols, if any */
1887 BlMmFreeHeap(BlockArray
);
1890 /* Return if we found the device or not */
1895 * @name EfiGetEfiStatusCode
1897 * The EfiGetEfiStatusCode routine converts an NT Status to an EFI status.
1900 * NT Status code to be converted.
1902 * @remark Only certain, specific NT status codes are converted to EFI codes.
1904 * @return The corresponding EFI Status code, EFI_NO_MAPPING otherwise.
1908 EfiGetEfiStatusCode(
1909 _In_ NTSTATUS Status
1914 case STATUS_NOT_SUPPORTED
:
1915 return EFI_UNSUPPORTED
;
1916 case STATUS_DISK_FULL
:
1917 return EFI_VOLUME_FULL
;
1918 case STATUS_INSUFFICIENT_RESOURCES
:
1919 return EFI_OUT_OF_RESOURCES
;
1920 case STATUS_MEDIA_WRITE_PROTECTED
:
1921 return EFI_WRITE_PROTECTED
;
1922 case STATUS_DEVICE_NOT_READY
:
1923 return EFI_NOT_STARTED
;
1924 case STATUS_DEVICE_ALREADY_ATTACHED
:
1925 return EFI_ALREADY_STARTED
;
1926 case STATUS_MEDIA_CHANGED
:
1927 return EFI_MEDIA_CHANGED
;
1928 case STATUS_INVALID_PARAMETER
:
1929 return EFI_INVALID_PARAMETER
;
1930 case STATUS_ACCESS_DENIED
:
1931 return EFI_ACCESS_DENIED
;
1932 case STATUS_BUFFER_TOO_SMALL
:
1933 return EFI_BUFFER_TOO_SMALL
;
1934 case STATUS_DISK_CORRUPT_ERROR
:
1935 return EFI_VOLUME_CORRUPTED
;
1936 case STATUS_REQUEST_ABORTED
:
1938 case STATUS_NO_MEDIA
:
1939 return EFI_NO_MEDIA
;
1940 case STATUS_IO_DEVICE_ERROR
:
1941 return EFI_DEVICE_ERROR
;
1942 case STATUS_INVALID_BUFFER_SIZE
:
1943 return EFI_BAD_BUFFER_SIZE
;
1944 case STATUS_NOT_FOUND
:
1945 return EFI_NOT_FOUND
;
1946 case STATUS_DRIVER_UNABLE_TO_LOAD
:
1947 return EFI_LOAD_ERROR
;
1948 case STATUS_NO_MATCH
:
1949 return EFI_NO_MAPPING
;
1950 case STATUS_SUCCESS
:
1952 case STATUS_TIMEOUT
:
1955 return EFI_NO_MAPPING
;
1960 * @name EfiGetNtStatusCode
1962 * The EfiGetNtStatusCode routine converts an EFI Status to an NT status.
1965 * EFI Status code to be converted.
1967 * @remark Only certain, specific EFI status codes are converted to NT codes.
1969 * @return The corresponding NT Status code, STATUS_UNSUCCESSFUL otherwise.
1973 EfiGetNtStatusCode (
1974 _In_ EFI_STATUS EfiStatus
1981 return STATUS_NOT_FOUND
;
1983 return STATUS_NO_MEDIA
;
1984 case EFI_MEDIA_CHANGED
:
1985 return STATUS_MEDIA_CHANGED
;
1986 case EFI_ACCESS_DENIED
:
1987 case EFI_SECURITY_VIOLATION
:
1988 return STATUS_ACCESS_DENIED
;
1990 case EFI_NO_RESPONSE
:
1991 return STATUS_TIMEOUT
;
1992 case EFI_NO_MAPPING
:
1993 return STATUS_NO_MATCH
;
1994 case EFI_NOT_STARTED
:
1995 return STATUS_DEVICE_NOT_READY
;
1996 case EFI_ALREADY_STARTED
:
1997 return STATUS_DEVICE_ALREADY_ATTACHED
;
1999 return STATUS_REQUEST_ABORTED
;
2000 case EFI_VOLUME_FULL
:
2001 return STATUS_DISK_FULL
;
2002 case EFI_DEVICE_ERROR
:
2003 return STATUS_IO_DEVICE_ERROR
;
2004 case EFI_WRITE_PROTECTED
:
2005 return STATUS_MEDIA_WRITE_PROTECTED
;
2006 /* @FIXME: ReactOS Headers don't yet have this */
2007 //case EFI_OUT_OF_RESOURCES:
2008 //return STATUS_INSUFFICIENT_NVRAM_RESOURCES;
2009 case EFI_VOLUME_CORRUPTED
:
2010 return STATUS_DISK_CORRUPT_ERROR
;
2011 case EFI_BUFFER_TOO_SMALL
:
2012 return STATUS_BUFFER_TOO_SMALL
;
2014 return STATUS_SUCCESS
;
2015 case EFI_LOAD_ERROR
:
2016 return STATUS_DRIVER_UNABLE_TO_LOAD
;
2017 case EFI_INVALID_PARAMETER
:
2018 return STATUS_INVALID_PARAMETER
;
2019 case EFI_UNSUPPORTED
:
2020 return STATUS_NOT_SUPPORTED
;
2021 case EFI_BAD_BUFFER_SIZE
:
2022 return STATUS_INVALID_BUFFER_SIZE
;
2024 return STATUS_UNSUCCESSFUL
;