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 /* Switch to real mode */
147 BlpArchSwitchContext(BlRealMode
);
149 /* Call EFI directly */
150 if (EfiConOut
!= NULL
)
152 EfiConOut
->OutputString(EfiConOut
, BlScratchBuffer
);
155 /* Switch back to protected mode */
156 BlpArchSwitchContext(BlProtectedMode
);
165 _In_ EFI_HANDLE Handle
,
166 _In_ EFI_GUID
*Protocol
,
167 _Out_ PVOID
* Interface
170 EFI_STATUS EfiStatus
;
172 BL_ARCH_MODE OldMode
;
174 /* Are we using virtual memory/ */
175 if (MmTranslationType
!= BlNone
)
177 /* We need complex tracking to make this work */
178 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
179 Status
= STATUS_NOT_SUPPORTED
;
183 /* Are we in protected mode? */
184 OldMode
= CurrentExecutionContext
->Mode
;
185 if (OldMode
!= BlRealMode
)
187 /* FIXME: Not yet implemented */
188 return STATUS_NOT_IMPLEMENTED
;
191 /* Are we on legacy 1.02? */
192 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
194 /* Make the legacy call */
195 EfiStatus
= EfiBS
->HandleProtocol(Handle
, Protocol
, Interface
);
199 /* Use the UEFI version */
200 EfiStatus
= EfiBS
->OpenProtocol(Handle
,
205 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
207 /* Switch back to protected mode if we came from there */
208 if (OldMode
!= BlRealMode
)
210 BlpArchSwitchContext(OldMode
);
214 /* Convert the error to an NTSTATUS */
215 Status
= EfiGetNtStatusCode(EfiStatus
);
218 /* Clear the interface on failure, and return the status */
219 if (!NT_SUCCESS(Status
))
229 _In_ EFI_HANDLE Handle
,
230 _In_ EFI_GUID
*Protocol
233 EFI_STATUS EfiStatus
;
235 BL_ARCH_MODE OldMode
;
237 /* Are we using virtual memory/ */
238 if (MmTranslationType
!= BlNone
)
240 /* We need complex tracking to make this work */
241 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
242 Status
= STATUS_NOT_SUPPORTED
;
246 /* Are we on legacy 1.02? */
247 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
249 /* Nothing to close */
250 EfiStatus
= STATUS_SUCCESS
;
254 /* Are we in protected mode? */
255 OldMode
= CurrentExecutionContext
->Mode
;
256 if (OldMode
!= BlRealMode
)
258 /* FIXME: Not yet implemented */
259 return STATUS_NOT_IMPLEMENTED
;
262 /* Use the UEFI version */
263 EfiStatus
= EfiBS
->CloseProtocol(Handle
, Protocol
, EfiImageHandle
, NULL
);
265 /* Switch back to protected mode if we came from there */
266 if (OldMode
!= BlRealMode
)
268 BlpArchSwitchContext(OldMode
);
271 /* Normalize not found as success */
272 if (EfiStatus
== EFI_NOT_FOUND
)
274 EfiStatus
= EFI_SUCCESS
;
278 /* Convert the error to an NTSTATUS */
279 Status
= EfiGetNtStatusCode(EfiStatus
);
288 _In_ PWCHAR VariableName
,
289 _In_ EFI_GUID
* VendorGuid
,
290 _Out_opt_ PULONG Attributes
,
291 _Inout_ PULONG DataSize
,
295 EFI_STATUS EfiStatus
;
297 BL_ARCH_MODE OldMode
;
298 ULONG LocalAttributes
;
300 /* Are we in protected mode? */
301 OldMode
= CurrentExecutionContext
->Mode
;
302 if (OldMode
!= BlRealMode
)
304 /* FIXME: Not yet implemented */
305 return STATUS_NOT_IMPLEMENTED
;
308 /* Call the runtime API */
309 EfiStatus
= EfiRT
->GetVariable(VariableName
,
311 (UINT32
*)&LocalAttributes
,
315 /* Switch back to protected mode if we came from there */
316 if (OldMode
!= BlRealMode
)
318 BlpArchSwitchContext(OldMode
);
321 /* Return attributes back to the caller if asked to */
324 *Attributes
= LocalAttributes
;
327 /* Convert the error to an NTSTATUS and return it */
328 Status
= EfiGetNtStatusCode(EfiStatus
);
333 BlpSecureBootEFIIsEnabled (
338 BOOLEAN SetupMode
, SecureBoot
;
341 /* Assume setup mode enabled, and no secure boot */
345 /* Get the SetupMode variable */
346 DataSize
= sizeof(SetupMode
);
347 Status
= EfiGetVariable(L
"SetupMode",
352 if (NT_SUCCESS(Status
))
354 /* If it worked, get the SecureBoot variable */
355 DataSize
= sizeof(SecureBoot
);
356 Status
= EfiGetVariable(L
"SecureBoot",
361 if (NT_SUCCESS(Status
))
363 /* In setup mode or without secureboot turned on, return failure */
364 if ((SecureBoot
!= TRUE
) || (SetupMode
))
366 Status
= STATUS_INVALID_SIGNATURE
;
369 // BlpSbdiStateFlags |= 8u;
373 /* Return secureboot status */
378 BlSecureBootIsEnabled (
379 _Out_ PBOOLEAN SecureBootEnabled
384 /* Have we checked before ? */
385 if (!BlpFirmwareChecked
)
387 /* First time checking */
388 Status
= BlpSecureBootEFIIsEnabled();
389 if NT_SUCCESS(Status
)
392 BlpFirmwareEnabled
= TRUE
;
395 /* Don't check again */
396 BlpFirmwareChecked
= TRUE
;
399 /* Return the firmware result */
400 *SecureBootEnabled
= BlpFirmwareEnabled
;
401 return STATUS_SUCCESS
;
405 BlSecureBootCheckForFactoryReset (
409 BOOLEAN SecureBootEnabled
;
413 /* Initialize locals */
415 SecureBootEnabled
= FALSE
;
417 /* Check if secureboot is enabled */
418 Status
= BlSecureBootIsEnabled(&SecureBootEnabled
);
419 if (!(NT_SUCCESS(Status
)) || !(SecureBootEnabled
))
421 /* It's not. Check if there's a revocation list */
422 Status
= EfiGetVariable(L
"RevocationList",
423 &BlpEfiSecureBootPrivateNamespace
,
427 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_TOO_SMALL
))
429 /* We don't support this yet */
430 EfiPrintf(L
"Not yet supported\r\n");
431 Status
= STATUS_NOT_IMPLEMENTED
;
435 /* Return back to the caller */
444 BL_ARCH_MODE OldMode
;
445 EFI_STATUS EfiStatus
;
447 /* Are we in protected mode? */
448 OldMode
= CurrentExecutionContext
->Mode
;
449 if (OldMode
!= BlRealMode
)
451 /* FIXME: Not yet implemented */
452 return STATUS_NOT_IMPLEMENTED
;
455 /* Make the EFI call */
456 EfiStatus
= EfiConIn
->Reset(EfiConIn
, FALSE
);
458 /* Switch back to protected mode if we came from there */
459 if (OldMode
!= BlRealMode
)
461 BlpArchSwitchContext(OldMode
);
464 /* Convert the error to an NTSTATUS */
465 return EfiGetNtStatusCode(EfiStatus
);
473 BL_ARCH_MODE OldMode
;
474 EFI_STATUS EfiStatus
;
476 /* Are we in protected mode? */
477 OldMode
= CurrentExecutionContext
->Mode
;
478 if (OldMode
!= BlRealMode
)
480 /* FIXME: Not yet implemented */
481 return STATUS_NOT_IMPLEMENTED
;
484 /* Make the EFI call */
485 EfiStatus
= EfiConInEx
->Reset(EfiConInEx
, FALSE
);
487 /* Switch back to protected mode if we came from there */
488 if (OldMode
!= BlRealMode
)
490 BlpArchSwitchContext(OldMode
);
493 /* Convert the error to an NTSTATUS */
494 return EfiGetNtStatusCode(EfiStatus
);
499 _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*ConInEx
,
500 _In_ EFI_KEY_TOGGLE_STATE
* KeyToggleState
503 BL_ARCH_MODE OldMode
;
504 EFI_STATUS EfiStatus
;
506 /* Are we in protected mode? */
507 OldMode
= CurrentExecutionContext
->Mode
;
508 if (OldMode
!= BlRealMode
)
510 /* FIXME: Not yet implemented */
511 return STATUS_NOT_IMPLEMENTED
;
514 /* Make the EFI call */
515 EfiStatus
= ConInEx
->SetState(ConInEx
, KeyToggleState
);
517 /* Switch back to protected mode if we came from there */
518 if (OldMode
!= BlRealMode
)
520 BlpArchSwitchContext(OldMode
);
523 /* Convert the error to an NTSTATUS */
524 return EfiGetNtStatusCode(EfiStatus
);
528 EfiSetWatchdogTimer (
532 BL_ARCH_MODE OldMode
;
533 EFI_STATUS EfiStatus
;
535 /* Are we in protected mode? */
536 OldMode
= CurrentExecutionContext
->Mode
;
537 if (OldMode
!= BlRealMode
)
539 /* FIXME: Not yet implemented */
540 return STATUS_NOT_IMPLEMENTED
;
543 /* Make the EFI call */
544 EfiStatus
= EfiBS
->SetWatchdogTimer(0, 0, 0, NULL
);
546 /* Switch back to protected mode if we came from there */
547 if (OldMode
!= BlRealMode
)
549 BlpArchSwitchContext(OldMode
);
552 /* Convert the error to an NTSTATUS */
553 return EfiGetNtStatusCode(EfiStatus
);
558 _Out_ UINTN
* MemoryMapSize
,
559 _Inout_ EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
561 _Out_ UINTN
* DescriptorSize
,
562 _Out_ UINTN
* DescriptorVersion
565 BL_ARCH_MODE OldMode
;
566 EFI_STATUS EfiStatus
;
567 PHYSICAL_ADDRESS MemoryMapSizePhysical
, MemoryMapPhysical
, MapKeyPhysical
;
568 PHYSICAL_ADDRESS DescriptorSizePhysical
, DescriptorVersionPhysical
;
570 /* Are we in protected mode? */
571 OldMode
= CurrentExecutionContext
->Mode
;
572 if (OldMode
!= BlRealMode
)
574 /* Convert all of the addresses to physical */
575 BlMmTranslateVirtualAddress(MemoryMapSize
, &MemoryMapSizePhysical
);
576 MemoryMapSize
= (UINTN
*)MemoryMapSizePhysical
.LowPart
;
577 BlMmTranslateVirtualAddress(MemoryMap
, &MemoryMapPhysical
);
578 MemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)MemoryMapPhysical
.LowPart
;
579 BlMmTranslateVirtualAddress(MapKey
, &MapKeyPhysical
);
580 MapKey
= (UINTN
*)MapKeyPhysical
.LowPart
;
581 BlMmTranslateVirtualAddress(DescriptorSize
, &DescriptorSizePhysical
);
582 DescriptorSize
= (UINTN
*)DescriptorSizePhysical
.LowPart
;
583 BlMmTranslateVirtualAddress(DescriptorVersion
, &DescriptorVersionPhysical
);
584 DescriptorVersion
= (UINTN
*)DescriptorVersionPhysical
.LowPart
;
586 /* Switch to real mode */
587 BlpArchSwitchContext(BlProtectedMode
);
590 /* Make the EFI call */
591 EfiStatus
= EfiBS
->GetMemoryMap(MemoryMapSize
,
597 /* Switch back to protected mode if we came from there */
598 if (OldMode
!= BlRealMode
)
600 BlpArchSwitchContext(OldMode
);
603 /* Convert the error to an NTSTATUS */
604 return EfiGetNtStatusCode(EfiStatus
);
610 _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress
613 BL_ARCH_MODE OldMode
;
614 EFI_STATUS EfiStatus
;
616 /* Are we in protected mode? */
617 OldMode
= CurrentExecutionContext
->Mode
;
618 if (OldMode
!= BlRealMode
)
620 /* FIXME: Not yet implemented */
621 return STATUS_NOT_IMPLEMENTED
;
624 /* Make the EFI call */
625 EfiStatus
= EfiBS
->FreePages(PhysicalAddress
, Pages
);
627 /* Switch back to protected mode if we came from there */
628 if (OldMode
!= BlRealMode
)
630 BlpArchSwitchContext(OldMode
);
633 /* Convert the error to an NTSTATUS */
634 return EfiGetNtStatusCode(EfiStatus
);
642 BL_ARCH_MODE OldMode
;
643 EFI_STATUS EfiStatus
;
645 /* Are we in protected mode? */
646 OldMode
= CurrentExecutionContext
->Mode
;
647 if (OldMode
!= BlRealMode
)
649 /* FIXME: Not yet implemented */
650 return STATUS_NOT_IMPLEMENTED
;
653 /* Make the EFI call */
654 EfiStatus
= EfiBS
->Stall(StallTime
);
656 /* Switch back to protected mode if we came from there */
657 if (OldMode
!= BlRealMode
)
659 BlpArchSwitchContext(OldMode
);
662 /* Convert the error to an NTSTATUS */
663 return EfiGetNtStatusCode(EfiStatus
);
668 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
674 BL_ARCH_MODE OldMode
;
675 EFI_STATUS EfiStatus
;
677 /* Are we in protected mode? */
678 OldMode
= CurrentExecutionContext
->Mode
;
679 if (OldMode
!= BlRealMode
)
681 /* FIXME: Not yet implemented */
682 return STATUS_NOT_IMPLEMENTED
;
685 /* Make the EFI call */
686 EfiStatus
= TextInterface
->QueryMode(TextInterface
, Mode
, Columns
, Rows
);
688 /* Switch back to protected mode if we came from there */
689 if (OldMode
!= BlRealMode
)
691 BlpArchSwitchContext(OldMode
);
694 /* Convert the error to an NTSTATUS */
695 return EfiGetNtStatusCode(EfiStatus
);
700 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
704 BL_ARCH_MODE OldMode
;
705 EFI_STATUS EfiStatus
;
707 /* Are we in protected mode? */
708 OldMode
= CurrentExecutionContext
->Mode
;
709 if (OldMode
!= BlRealMode
)
711 /* FIXME: Not yet implemented */
712 return STATUS_NOT_IMPLEMENTED
;
715 /* Make the EFI call */
716 EfiStatus
= TextInterface
->SetMode(TextInterface
, Mode
);
718 /* Switch back to protected mode if we came from there */
719 if (OldMode
!= BlRealMode
)
721 BlpArchSwitchContext(OldMode
);
724 /* Convert the error to an NTSTATUS */
725 return EfiGetNtStatusCode(EfiStatus
);
729 EfiConOutSetAttribute (
730 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
734 BL_ARCH_MODE OldMode
;
735 EFI_STATUS EfiStatus
;
737 /* Are we in protected mode? */
738 OldMode
= CurrentExecutionContext
->Mode
;
739 if (OldMode
!= BlRealMode
)
741 /* FIXME: Not yet implemented */
742 return STATUS_NOT_IMPLEMENTED
;
745 /* Make the EFI call */
746 EfiStatus
= TextInterface
->SetAttribute(TextInterface
, Attribute
);
748 /* Switch back to protected mode if we came from there */
749 if (OldMode
!= BlRealMode
)
751 BlpArchSwitchContext(OldMode
);
754 /* Convert the error to an NTSTATUS */
755 return EfiGetNtStatusCode(EfiStatus
);
759 EfiConOutSetCursorPosition (
760 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
765 BL_ARCH_MODE OldMode
;
766 EFI_STATUS EfiStatus
;
768 /* Are we in protected mode? */
769 OldMode
= CurrentExecutionContext
->Mode
;
770 if (OldMode
!= BlRealMode
)
772 /* FIXME: Not yet implemented */
773 return STATUS_NOT_IMPLEMENTED
;
776 /* Make the EFI call */
777 EfiStatus
= TextInterface
->SetCursorPosition(TextInterface
, Column
, Row
);
779 /* Switch back to protected mode if we came from there */
780 if (OldMode
!= BlRealMode
)
782 BlpArchSwitchContext(OldMode
);
785 /* Convert the error to an NTSTATUS */
786 return EfiGetNtStatusCode(EfiStatus
);
790 EfiConOutEnableCursor (
791 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
795 BL_ARCH_MODE OldMode
;
796 EFI_STATUS EfiStatus
;
798 /* Are we in protected mode? */
799 OldMode
= CurrentExecutionContext
->Mode
;
800 if (OldMode
!= BlRealMode
)
802 /* FIXME: Not yet implemented */
803 return STATUS_NOT_IMPLEMENTED
;
806 /* Make the EFI call */
807 EfiStatus
= TextInterface
->EnableCursor(TextInterface
, Visible
);
809 /* Switch back to protected mode if we came from there */
810 if (OldMode
!= BlRealMode
)
812 BlpArchSwitchContext(OldMode
);
815 /* Convert the error to an NTSTATUS */
816 return EfiGetNtStatusCode(EfiStatus
);
820 EfiConOutOutputString (
821 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
825 BL_ARCH_MODE OldMode
;
826 EFI_STATUS EfiStatus
;
828 /* Are we in protected mode? */
829 OldMode
= CurrentExecutionContext
->Mode
;
830 if (OldMode
!= BlRealMode
)
832 /* FIXME: Not yet implemented */
833 return STATUS_NOT_IMPLEMENTED
;
836 /* Make the EFI call */
837 EfiStatus
= TextInterface
->OutputString(TextInterface
, String
);
839 /* Switch back to protected mode if we came from there */
840 if (OldMode
!= BlRealMode
)
842 BlpArchSwitchContext(OldMode
);
845 /* Convert the error to an NTSTATUS */
846 return EfiGetNtStatusCode(EfiStatus
);
851 EfiConOutReadCurrentMode (
852 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
853 _Out_ EFI_SIMPLE_TEXT_OUTPUT_MODE
* Mode
856 BL_ARCH_MODE OldMode
;
858 /* Are we in protected mode? */
859 OldMode
= CurrentExecutionContext
->Mode
;
860 if (OldMode
!= BlRealMode
)
862 /* FIXME: Not yet implemented */
866 /* Make the EFI call */
867 RtlCopyMemory(Mode
, TextInterface
->Mode
, sizeof(*Mode
));
869 /* Switch back to protected mode if we came from there */
870 if (OldMode
!= BlRealMode
)
872 BlpArchSwitchContext(OldMode
);
877 EfiGopGetFrameBuffer (
878 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
879 _Out_ PHYSICAL_ADDRESS
* FrameBuffer
,
880 _Out_ UINTN
*FrameBufferSize
883 BL_ARCH_MODE OldMode
;
885 /* Are we in protected mode? */
886 OldMode
= CurrentExecutionContext
->Mode
;
887 if (OldMode
!= BlRealMode
)
889 /* FIXME: Not yet implemented */
893 /* Make the EFI call */
894 FrameBuffer
->QuadPart
= GopInterface
->Mode
->FrameBufferBase
;
895 *FrameBufferSize
= GopInterface
->Mode
->FrameBufferSize
;
897 /* Switch back to protected mode if we came from there */
898 if (OldMode
!= BlRealMode
)
900 BlpArchSwitchContext(OldMode
);
905 EfiGopGetCurrentMode (
906 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
908 _Out_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Information
911 BL_ARCH_MODE OldMode
;
913 /* Are we in protected mode? */
914 OldMode
= CurrentExecutionContext
->Mode
;
915 if (OldMode
!= BlRealMode
)
917 /* FIXME: Not yet implemented */
918 return STATUS_NOT_IMPLEMENTED
;
921 /* Make the EFI call */
922 *Mode
= GopInterface
->Mode
->Mode
;
923 RtlCopyMemory(Information
, GopInterface
->Mode
->Info
, sizeof(*Information
));
925 /* Switch back to protected mode if we came from there */
926 if (OldMode
!= BlRealMode
)
928 BlpArchSwitchContext(OldMode
);
932 return STATUS_SUCCESS
;
937 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
941 BL_ARCH_MODE OldMode
;
942 EFI_STATUS EfiStatus
;
946 /* Are we in protected mode? */
947 OldMode
= CurrentExecutionContext
->Mode
;
948 if (OldMode
!= BlRealMode
)
950 /* FIXME: Not yet implemented */
951 return STATUS_NOT_IMPLEMENTED
;
954 /* Make the EFI call */
955 if (Mode
== GopInterface
->Mode
->Mode
)
957 EfiStatus
= EFI_SUCCESS
;
961 EfiStatus
= GopInterface
->SetMode(GopInterface
, Mode
);
965 /* Switch back to protected mode if we came from there */
966 if (OldMode
!= BlRealMode
)
968 BlpArchSwitchContext(OldMode
);
971 /* Print out to the debugger if the mode was changed */
972 Status
= EfiGetNtStatusCode(EfiStatus
);
973 if ((ModeChanged
) && (NT_SUCCESS(Status
)))
975 /* FIXME @TODO: Should be BlStatusPrint */
976 EfiPrintf(L
"Console video mode set to 0x%x\r\n", Mode
);
979 /* Convert the error to an NTSTATUS */
984 EfiLocateHandleBuffer (
985 _In_ EFI_LOCATE_SEARCH_TYPE SearchType
,
986 _In_ EFI_GUID
*Protocol
,
987 _Inout_ PULONG HandleCount
,
988 _Inout_ EFI_HANDLE
** Buffer
991 BL_ARCH_MODE OldMode
;
992 EFI_STATUS EfiStatus
;
995 /* Bail out if we're missing parameters */
996 if (!(Buffer
) || !(HandleCount
))
998 return STATUS_INVALID_PARAMETER
;
1001 /* Check if a buffer was passed in*/
1004 /* Then we should already have a buffer size*/
1005 BufferSize
= sizeof(EFI_HANDLE
) * *HandleCount
;
1009 /* Then no buffer size exists */
1013 /* Are we in protected mode? */
1014 OldMode
= CurrentExecutionContext
->Mode
;
1015 if (OldMode
!= BlRealMode
)
1017 /* FIXME: Not yet implemented */
1018 return STATUS_NOT_IMPLEMENTED
;
1021 /* Try the first time */
1022 EfiStatus
= EfiBS
->LocateHandle(SearchType
, Protocol
, NULL
, &BufferSize
, *Buffer
);
1023 if (EfiStatus
== EFI_BUFFER_TOO_SMALL
)
1025 /* Did we have an existing buffer? */
1029 BlMmFreeHeap(*Buffer
);
1032 /* Allocate a new one */
1033 *Buffer
= BlMmAllocateHeap(BufferSize
);
1036 /* No space, fail */
1037 return STATUS_NO_MEMORY
;
1041 EfiStatus
= EfiBS
->LocateHandle(SearchType
, Protocol
, NULL
, &BufferSize
, *Buffer
);
1043 /* Switch back to protected mode if we came from there */
1044 if (OldMode
!= BlRealMode
)
1046 BlpArchSwitchContext(OldMode
);
1050 /* Return the number of handles */
1051 *HandleCount
= BufferSize
/ sizeof(EFI_HANDLE
);
1053 /* Convert the error to an NTSTATUS */
1054 return EfiGetNtStatusCode(EfiStatus
);
1059 _In_ EFI_RESET_TYPE ResetType
1062 BL_ARCH_MODE OldMode
;
1064 /* Are we in protected mode? */
1065 OldMode
= CurrentExecutionContext
->Mode
;
1066 if (OldMode
!= BlRealMode
)
1068 /* FIXME: Not yet implemented */
1072 /* Call the EFI runtime */
1073 EfiRT
->ResetSystem(ResetType
, EFI_SUCCESS
, 0, NULL
);
1077 EfiConnectController (
1078 _In_ EFI_HANDLE ControllerHandle
1081 BL_ARCH_MODE OldMode
;
1082 EFI_STATUS EfiStatus
;
1084 /* Is this EFI 1.02? */
1085 if (EfiST
->Hdr
.Revision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
1087 /* This function didn't exist back then */
1088 return STATUS_NOT_SUPPORTED
;
1091 /* Are we in protected mode? */
1092 OldMode
= CurrentExecutionContext
->Mode
;
1093 if (OldMode
!= BlRealMode
)
1095 /* FIXME: Not yet implemented */
1096 return STATUS_NOT_IMPLEMENTED
;
1099 /* Make the EFI call */
1100 EfiStatus
= EfiBS
->ConnectController(ControllerHandle
, NULL
, NULL
, TRUE
);
1102 /* Switch back to protected mode if we came from there */
1103 if (OldMode
!= BlRealMode
)
1105 BlpArchSwitchContext(OldMode
);
1108 /* Convert the error to an NTSTATUS */
1109 return EfiGetNtStatusCode(EfiStatus
);
1116 _Inout_ EFI_PHYSICAL_ADDRESS
* Memory
1119 BL_ARCH_MODE OldMode
;
1120 EFI_STATUS EfiStatus
;
1122 /* Are we in protected mode? */
1123 OldMode
= CurrentExecutionContext
->Mode
;
1124 if (OldMode
!= BlRealMode
)
1126 /* FIXME: Not yet implemented */
1127 return STATUS_NOT_IMPLEMENTED
;
1130 /* Make the EFI call */
1131 EfiStatus
= EfiBS
->AllocatePages(Type
, EfiLoaderData
, Pages
, Memory
);
1133 /* Switch back to protected mode if we came from there */
1134 if (OldMode
!= BlRealMode
)
1136 BlpArchSwitchContext(OldMode
);
1139 /* Convert the error to an NTSTATUS */
1140 return EfiGetNtStatusCode(EfiStatus
);
1144 EfipGetSystemTable (
1145 _In_ EFI_GUID
*TableGuid
,
1146 _Out_ PPHYSICAL_ADDRESS TableAddress
1152 /* Assume failure */
1153 Status
= STATUS_NOT_FOUND
;
1155 /* Loop through the configuration tables */
1156 for (i
= 0; i
< EfiST
->NumberOfTableEntries
; i
++)
1158 /* Check if this one matches the one we want */
1159 if (RtlEqualMemory(&EfiST
->ConfigurationTable
[i
].VendorGuid
,
1161 sizeof(*TableGuid
)))
1163 /* Return its address */
1164 TableAddress
->QuadPart
= (ULONG_PTR
)EfiST
->ConfigurationTable
[i
].VendorTable
;
1165 Status
= STATUS_SUCCESS
;
1170 /* Return the search result */
1176 _Out_ PPHYSICAL_ADDRESS FoundRsdt
1181 PHYSICAL_ADDRESS RsdpAddress
, Rsdt
;
1184 /* Assume failure */
1188 /* Check if we already know it */
1189 if (EfiRsdt
.QuadPart
)
1192 *FoundRsdt
= EfiRsdt
;
1193 return STATUS_SUCCESS
;
1196 /* Otherwise, look for the ACPI 2.0 RSDP (XSDT really) */
1197 Status
= EfipGetSystemTable(&EfiRootAcpiTableGuid
, &RsdpAddress
);
1198 if (!NT_SUCCESS(Status
))
1200 /* Didn't fint it, look for the ACPI 1.0 RSDP (RSDT really) */
1201 Status
= EfipGetSystemTable(&EfiRootAcpiTable10Guid
, &RsdpAddress
);
1202 if (!NT_SUCCESS(Status
))
1209 Length
= sizeof(*Rsdp
);
1210 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1214 if (NT_SUCCESS(Status
))
1216 /* Check the revision (anything >= 2.0 is XSDT) */
1219 /* Check if the table is bigger than just its header */
1220 if (Rsdp
->Length
> Length
)
1222 /* Capture the real length */
1223 Length
= Rsdp
->Length
;
1225 /* Unmap our header mapping */
1226 BlMmUnmapVirtualAddressEx(Rsdp
, sizeof(*Rsdp
));
1228 /* And map the whole thing now */
1229 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1233 if (!NT_SUCCESS(Status
))
1239 /* Read the XSDT address from the table*/
1240 Rsdt
= Rsdp
->XsdtAddress
;
1244 /* ACPI 1.0 so just read the RSDT */
1245 Rsdt
.QuadPart
= Rsdp
->RsdtAddress
;
1248 /* Save it for later */
1251 /* And return it back */
1255 /* Check if we had mapped the RSDP */
1259 BlMmUnmapVirtualAddressEx(Rsdp
, Length
);
1262 /* Return search result back to caller */
1267 MmFwpGetOsAttributeType (
1268 _In_ ULONGLONG Attribute
1271 BL_MEMORY_ATTR OsAttribute
= 0;
1273 if (Attribute
& EFI_MEMORY_UC
)
1275 OsAttribute
= BlMemoryUncached
;
1278 if (Attribute
& EFI_MEMORY_WC
)
1280 OsAttribute
|= BlMemoryWriteCombined
;
1283 if (Attribute
& EFI_MEMORY_WT
)
1285 OsAttribute
|= BlMemoryWriteThrough
;
1288 if (Attribute
& EFI_MEMORY_WB
)
1290 OsAttribute
|= BlMemoryWriteBack
;
1293 if (Attribute
& EFI_MEMORY_UCE
)
1295 OsAttribute
|= BlMemoryUncachedExported
;
1298 if (Attribute
& EFI_MEMORY_WP
)
1300 OsAttribute
|= BlMemoryWriteProtected
;
1303 if (Attribute
& EFI_MEMORY_RP
)
1305 OsAttribute
|= BlMemoryReadProtected
;
1308 if (Attribute
& EFI_MEMORY_XP
)
1310 OsAttribute
|= BlMemoryExecuteProtected
;
1313 if (Attribute
& EFI_MEMORY_RUNTIME
)
1315 OsAttribute
|= BlMemoryRuntime
;
1322 MmFwpGetOsMemoryType (
1323 _In_ EFI_MEMORY_TYPE MemoryType
1326 BL_MEMORY_TYPE OsType
;
1332 OsType
= BlLoaderMemory
;
1335 case EfiBootServicesCode
:
1336 case EfiBootServicesData
:
1337 OsType
= BlEfiBootMemory
;
1340 case EfiRuntimeServicesCode
:
1341 case EfiRuntimeServicesData
:
1342 OsType
= BlEfiRuntimeMemory
;
1345 case EfiConventionalMemory
:
1346 OsType
= BlConventionalMemory
;
1349 case EfiUnusableMemory
:
1350 OsType
= BlUnusableMemory
;
1353 case EfiACPIReclaimMemory
:
1354 OsType
= BlAcpiReclaimMemory
;
1357 case EfiACPIMemoryNVS
:
1358 OsType
= BlAcpiNvsMemory
;
1361 case EfiMemoryMappedIO
:
1362 OsType
= BlDeviceIoMemory
;
1365 case EfiMemoryMappedIOPortSpace
:
1366 OsType
= BlDevicePortMemory
;
1370 OsType
= BlPalMemory
;
1374 OsType
= BlReservedMemory
;
1383 _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap
,
1387 BL_LIBRARY_PARAMETERS LibraryParameters
= BlpLibraryParameters
;
1388 BOOLEAN UseEfiBuffer
, HaveRamDisk
;
1390 ULONGLONG Pages
, StartPage
, EndPage
;
1391 UINTN EfiMemoryMapSize
, MapKey
, DescriptorSize
, DescriptorVersion
;
1392 EFI_PHYSICAL_ADDRESS EfiBuffer
= 0;
1393 EFI_MEMORY_DESCRIPTOR
* EfiMemoryMap
;
1394 EFI_STATUS EfiStatus
;
1395 BL_ARCH_MODE OldMode
;
1396 EFI_MEMORY_DESCRIPTOR EfiDescriptor
;
1397 BL_MEMORY_TYPE MemoryType
;
1398 PBL_MEMORY_DESCRIPTOR Descriptor
;
1399 BL_MEMORY_ATTR Attribute
;
1401 /* Initialize EFI memory map attributes */
1402 EfiMemoryMapSize
= MapKey
= DescriptorSize
= DescriptorVersion
= 0;
1404 /* Increment the nesting depth */
1405 MmDescriptorCallTreeCount
++;
1407 /* Determine if we should use EFI or our own allocator at this point */
1408 UseEfiBuffer
= Flags
& BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS
;
1409 if (!(LibraryParameters
.LibraryFlags
& BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
))
1411 UseEfiBuffer
= TRUE
;
1414 /* Bail out if we don't have a list to use */
1415 if (MemoryMap
== NULL
)
1417 Status
= STATUS_INVALID_PARAMETER
;
1421 /* Free the current descriptor list */
1422 MmMdFreeList(MemoryMap
);
1424 /* Call into EFI to get the size of the memory map */
1425 Status
= EfiGetMemoryMap(&EfiMemoryMapSize
,
1429 &DescriptorVersion
);
1430 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
1432 /* This should've failed because our buffer was too small, nothing else */
1433 EfiPrintf(L
"Got strange EFI status for memory map: %lx\r\n", Status
);
1434 if (NT_SUCCESS(Status
))
1436 Status
= STATUS_UNSUCCESSFUL
;
1441 /* Add 4 more descriptors just in case things changed */
1442 EfiMemoryMapSize
+= (4 * DescriptorSize
);
1443 Pages
= BYTES_TO_PAGES(EfiMemoryMapSize
);
1444 EfiPrintf(L
"Memory map size: %lx bytes, %d pages\r\n", EfiMemoryMapSize
, Pages
);
1446 /* Should we use EFI to grab memory? */
1449 /* Yes -- request one more page to align up correctly */
1452 /* Grab the required pages */
1453 Status
= EfiAllocatePages(AllocateAnyPages
,
1456 if (!NT_SUCCESS(Status
))
1458 EfiPrintf(L
"EFI allocation failed: %lx\r\n", Status
);
1462 /* Free the pages for now */
1463 Status
= EfiFreePages(Pages
, EfiBuffer
);
1464 if (!NT_SUCCESS(Status
))
1470 /* Now round to the actual buffer size, removing the extra page */
1471 EfiBuffer
= ROUND_TO_PAGES(EfiBuffer
);
1473 Status
= EfiAllocatePages(AllocateAddress
,
1476 if (!NT_SUCCESS(Status
))
1482 /* Get the final aligned size and proper buffer */
1483 EfiMemoryMapSize
= EFI_PAGES_TO_SIZE(Pages
);
1484 EfiMemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)(ULONG_PTR
)EfiBuffer
;
1486 /* Switch to real mode if not already in it */
1487 OldMode
= CurrentExecutionContext
->Mode
;
1488 if (OldMode
!= BlRealMode
)
1490 BlpArchSwitchContext(BlRealMode
);
1493 /* Call EFI to get the memory map */
1494 EfiStatus
= EfiBS
->GetMemoryMap(&EfiMemoryMapSize
,
1498 &DescriptorVersion
);
1500 /* Switch back into the previous mode */
1501 if (OldMode
!= BlRealMode
)
1503 BlpArchSwitchContext(OldMode
);
1506 /* Convert the result code */
1507 Status
= EfiGetNtStatusCode(EfiStatus
);
1511 /* We don't support this path yet */
1512 Status
= STATUS_NOT_IMPLEMENTED
;
1515 /* So far so good? */
1516 if (!NT_SUCCESS(Status
))
1518 EfiPrintf(L
"Failed to get EFI memory map: %lx\r\n", Status
);
1522 /* Did we get correct data from firmware? */
1523 if (((EfiMemoryMapSize
% DescriptorSize
)) ||
1524 (DescriptorSize
< sizeof(EFI_MEMORY_DESCRIPTOR
)))
1526 EfiPrintf(L
"Incorrect descriptor size\r\n");
1527 Status
= STATUS_UNSUCCESSFUL
;
1531 /* Did we boot from a RAM disk? */
1532 if ((BlpBootDevice
->DeviceType
== LocalDevice
) &&
1533 (BlpBootDevice
->Local
.Type
== RamDiskDevice
))
1535 /* We don't handle this yet */
1536 EfiPrintf(L
"RAM boot not supported\r\n");
1537 Status
= STATUS_NOT_IMPLEMENTED
;
1542 /* We didn't, so there won't be any need to find the memory descriptor */
1543 HaveRamDisk
= FALSE
;
1546 /* Loop the EFI memory map */
1548 EfiPrintf(L
"UEFI MEMORY MAP\r\n\r\n");
1549 EfiPrintf(L
"TYPE START END ATTRIBUTES\r\n");
1550 EfiPrintf(L
"===============================================================\r\n");
1552 while (EfiMemoryMapSize
!= 0)
1554 /* Check if this is an EFI buffer, but we're not in real mode */
1555 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1557 BlpArchSwitchContext(BlRealMode
);
1560 /* Capture it so we can go back to protected mode (if possible) */
1561 EfiDescriptor
= *EfiMemoryMap
;
1563 /* Go back to protected mode, if we had switched */
1564 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1566 BlpArchSwitchContext(OldMode
);
1569 /* Convert to OS memory type */
1570 MemoryType
= MmFwpGetOsMemoryType(EfiDescriptor
.Type
);
1572 /* Round up or round down depending on where the memory is coming from */
1573 if (MemoryType
== BlConventionalMemory
)
1575 StartPage
= BYTES_TO_PAGES(EfiDescriptor
.PhysicalStart
);
1579 StartPage
= EfiDescriptor
.PhysicalStart
>> PAGE_SHIFT
;
1582 /* Calculate the ending page */
1583 EndPage
= StartPage
+ EfiDescriptor
.NumberOfPages
;
1585 /* If after rounding, we ended up with 0 pages, skip this */
1586 if (StartPage
== EndPage
)
1591 EfiPrintf(L
"%08X 0x%016I64X-0x%016I64X 0x%I64X\r\n",
1593 StartPage
<< PAGE_SHIFT
,
1594 EndPage
<< PAGE_SHIFT
,
1595 EfiDescriptor
.Attribute
);
1597 /* Check for any range of memory below 1MB */
1598 if (StartPage
< 0x100)
1600 /* Does this range actually contain NULL? */
1603 /* Manually create a reserved descriptof for this page */
1604 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1605 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1612 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1616 /* Add this descriptor into the list */
1617 Status
= MmMdAddDescriptorToList(MemoryMap
,
1619 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1620 if (!NT_SUCCESS(Status
))
1622 EfiPrintf(L
"Failed to add zero page descriptor: %lx\r\n", Status
);
1626 /* Now handle the rest of the range, unless this was it */
1634 /* Does the range go beyond 1MB? */
1635 if (EndPage
> 0x100)
1637 /* Then create the descriptor for everything up until the megabyte */
1638 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1639 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1646 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1650 /* Check if this region is currently free RAM */
1651 if (Descriptor
->Type
== BlConventionalMemory
)
1653 /* Set the reserved flag on the descriptor */
1654 EfiPrintf(L
"Adding magic flag\r\n");
1655 Descriptor
->Flags
|= BlMemoryReserved
;
1658 /* Add this descriptor into the list */
1659 Status
= MmMdAddDescriptorToList(MemoryMap
,
1661 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1662 if (!NT_SUCCESS(Status
))
1664 EfiPrintf(L
"Failed to add 1MB descriptor: %lx\r\n", Status
);
1668 /* Now handle the rest of the range above 1MB */
1673 /* Check if we loaded from a RAM disk */
1676 /* We don't handle this yet */
1677 EfiPrintf(L
"RAM boot not supported\r\n");
1678 Status
= STATUS_NOT_IMPLEMENTED
;
1682 /* Create a descriptor for the current range */
1683 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1684 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1688 EndPage
- StartPage
);
1691 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1695 /* Check if this region is currently free RAM below 1MB */
1696 if ((Descriptor
->Type
== BlConventionalMemory
) && (EndPage
<= 0x100))
1698 /* Set the reserved flag on the descriptor */
1699 EfiPrintf(L
"Adding magic flag\r\n");
1700 Descriptor
->Flags
|= BlMemoryReserved
;
1703 /* Add the descriptor to the list, requesting coalescing as asked */
1704 Status
= MmMdAddDescriptorToList(MemoryMap
,
1706 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
|
1707 ((Flags
& BL_MM_FLAG_REQUEST_COALESCING
) ?
1708 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
: 0));
1709 if (!NT_SUCCESS(Status
))
1711 EfiPrintf(L
"Failed to add full descriptor: %lx\r\n", Status
);
1716 /* Consume this descriptor, and move to the next one */
1717 EfiMemoryMapSize
-= DescriptorSize
;
1718 EfiMemoryMap
= (PVOID
)((ULONG_PTR
)EfiMemoryMap
+ DescriptorSize
);
1721 /* FIXME: @TODO: Mark the EfiBuffer as free, since we're about to free it */
1722 /* For now, just "leak" the 1-2 pages... */
1725 /* Free the EFI buffer, if we had one */
1728 EfiFreePages(Pages
, EfiBuffer
);
1731 /* On failure, free the memory map if one was passed in */
1732 if (!NT_SUCCESS(Status
) && (MemoryMap
!= NULL
))
1734 MmMdFreeList(MemoryMap
);
1737 /* Decrement the nesting depth and return */
1738 MmDescriptorCallTreeCount
--;
1745 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
1748 NTSTATUS Status
= STATUS_SUCCESS
;
1749 EFI_KEY_TOGGLE_STATE KeyToggleState
;
1751 /* Check if we have valid firmware data */
1752 if (!(FirmwareData
) || !(FirmwareData
->Version
))
1754 return STATUS_INVALID_PARAMETER
;
1757 /* Check which boot phase we're in */
1760 /* Memory manager is ready, open the extended input protocol */
1761 Status
= EfiOpenProtocol(EfiST
->ConsoleInHandle
,
1762 &EfiSimpleTextInputExProtocol
,
1763 (PVOID
*)&EfiConInEx
);
1764 if (NT_SUCCESS(Status
))
1766 /* Set the initial key toggle state */
1767 KeyToggleState
= EFI_TOGGLE_STATE_VALID
| 40;
1768 EfiConInExSetState(EfiConInEx
, &KeyToggleState
);
1771 /* Setup the watchdog timer */
1772 EfiSetWatchdogTimer();
1776 /* Make a copy of the parameters */
1777 EfiFirmwareParameters
= &EfiFirmwareData
;
1779 /* Check which version we received */
1780 if (FirmwareData
->Version
== 1)
1782 /* FIXME: Not supported */
1783 Status
= STATUS_NOT_SUPPORTED
;
1785 else if (FirmwareData
->Version
>= BL_FIRMWARE_DESCRIPTOR_VERSION
)
1787 /* Version 2 -- save the data */
1788 EfiFirmwareData
= *FirmwareData
;
1789 EfiSystemTable
= FirmwareData
->SystemTable
;
1790 EfiImageHandle
= FirmwareData
->ImageHandle
;
1792 /* Set the EDK-II style variables as well */
1793 EfiST
= EfiSystemTable
;
1794 EfiBS
= EfiSystemTable
->BootServices
;
1795 EfiRT
= EfiSystemTable
->RuntimeServices
;
1796 EfiConOut
= EfiSystemTable
->ConOut
;
1797 EfiConIn
= EfiSystemTable
->ConIn
;
1802 /* Unknown version */
1803 Status
= STATUS_NOT_SUPPORTED
;
1807 /* Return the initialization state */
1813 _In_ PBL_FIRMWARE_DESCRIPTOR Parameters
1816 /* Make sure we got an argument */
1819 return STATUS_INVALID_PARAMETER
;
1822 /* Copy the static data */
1823 *Parameters
= *EfiFirmwareParameters
;
1824 return STATUS_SUCCESS
;
1828 BlFwEnumerateDevice (
1829 _In_ PBL_DEVICE_DESCRIPTOR Device
1833 ULONG PathProtocols
, BlockProtocols
;
1834 EFI_HANDLE
* PathArray
;
1835 EFI_HANDLE
* BlockArray
;
1837 /* Initialize locals */
1843 /* Enumeration only makes sense on disks or partitions */
1844 if ((Device
->DeviceType
!= DiskDevice
) &&
1845 (Device
->DeviceType
!= LegacyPartitionDevice
) &&
1846 (Device
->DeviceType
!= PartitionDevice
))
1848 return STATUS_NOT_SUPPORTED
;
1851 /* Enumerate the list of device paths */
1852 Status
= EfiLocateHandleBuffer(ByProtocol
,
1853 &EfiDevicePathProtocol
,
1856 if (NT_SUCCESS(Status
))
1858 /* Loop through each one */
1859 Status
= STATUS_NOT_FOUND
;
1860 while (PathProtocols
)
1862 /* Attempt to connect the driver for this device epath */
1863 Status
= EfiConnectController(PathArray
[--PathProtocols
]);
1864 if (NT_SUCCESS(Status
))
1866 /* Now enumerate any block I/O devices the driver added */
1867 Status
= EfiLocateHandleBuffer(ByProtocol
,
1868 &EfiBlockIoProtocol
,
1871 if (!NT_SUCCESS(Status
))
1876 /* Loop through each one */
1877 while (BlockProtocols
)
1879 /* Check if one of the new devices is the one we want */
1880 Status
= BlockIoEfiCompareDevice(Device
,
1881 BlockArray
[--BlockProtocols
]);
1882 if (NT_SUCCESS(Status
))
1889 /* Move on to the next device path */
1890 BlMmFreeHeap(BlockArray
);
1897 /* We're done -- free the array of device path protocols, if any */
1900 BlMmFreeHeap(PathArray
);
1903 /* We're done -- free the array of block I/O protocols, if any */
1906 BlMmFreeHeap(BlockArray
);
1909 /* Return if we found the device or not */
1914 * @name EfiGetEfiStatusCode
1916 * The EfiGetEfiStatusCode routine converts an NT Status to an EFI status.
1919 * NT Status code to be converted.
1921 * @remark Only certain, specific NT status codes are converted to EFI codes.
1923 * @return The corresponding EFI Status code, EFI_NO_MAPPING otherwise.
1927 EfiGetEfiStatusCode(
1928 _In_ NTSTATUS Status
1933 case STATUS_NOT_SUPPORTED
:
1934 return EFI_UNSUPPORTED
;
1935 case STATUS_DISK_FULL
:
1936 return EFI_VOLUME_FULL
;
1937 case STATUS_INSUFFICIENT_RESOURCES
:
1938 return EFI_OUT_OF_RESOURCES
;
1939 case STATUS_MEDIA_WRITE_PROTECTED
:
1940 return EFI_WRITE_PROTECTED
;
1941 case STATUS_DEVICE_NOT_READY
:
1942 return EFI_NOT_STARTED
;
1943 case STATUS_DEVICE_ALREADY_ATTACHED
:
1944 return EFI_ALREADY_STARTED
;
1945 case STATUS_MEDIA_CHANGED
:
1946 return EFI_MEDIA_CHANGED
;
1947 case STATUS_INVALID_PARAMETER
:
1948 return EFI_INVALID_PARAMETER
;
1949 case STATUS_ACCESS_DENIED
:
1950 return EFI_ACCESS_DENIED
;
1951 case STATUS_BUFFER_TOO_SMALL
:
1952 return EFI_BUFFER_TOO_SMALL
;
1953 case STATUS_DISK_CORRUPT_ERROR
:
1954 return EFI_VOLUME_CORRUPTED
;
1955 case STATUS_REQUEST_ABORTED
:
1957 case STATUS_NO_MEDIA
:
1958 return EFI_NO_MEDIA
;
1959 case STATUS_IO_DEVICE_ERROR
:
1960 return EFI_DEVICE_ERROR
;
1961 case STATUS_INVALID_BUFFER_SIZE
:
1962 return EFI_BAD_BUFFER_SIZE
;
1963 case STATUS_NOT_FOUND
:
1964 return EFI_NOT_FOUND
;
1965 case STATUS_DRIVER_UNABLE_TO_LOAD
:
1966 return EFI_LOAD_ERROR
;
1967 case STATUS_NO_MATCH
:
1968 return EFI_NO_MAPPING
;
1969 case STATUS_SUCCESS
:
1971 case STATUS_TIMEOUT
:
1974 return EFI_NO_MAPPING
;
1979 * @name EfiGetNtStatusCode
1981 * The EfiGetNtStatusCode routine converts an EFI Status to an NT status.
1984 * EFI Status code to be converted.
1986 * @remark Only certain, specific EFI status codes are converted to NT codes.
1988 * @return The corresponding NT Status code, STATUS_UNSUCCESSFUL otherwise.
1992 EfiGetNtStatusCode (
1993 _In_ EFI_STATUS EfiStatus
2000 return STATUS_NOT_FOUND
;
2002 return STATUS_NO_MEDIA
;
2003 case EFI_MEDIA_CHANGED
:
2004 return STATUS_MEDIA_CHANGED
;
2005 case EFI_ACCESS_DENIED
:
2006 case EFI_SECURITY_VIOLATION
:
2007 return STATUS_ACCESS_DENIED
;
2009 case EFI_NO_RESPONSE
:
2010 return STATUS_TIMEOUT
;
2011 case EFI_NO_MAPPING
:
2012 return STATUS_NO_MATCH
;
2013 case EFI_NOT_STARTED
:
2014 return STATUS_DEVICE_NOT_READY
;
2015 case EFI_ALREADY_STARTED
:
2016 return STATUS_DEVICE_ALREADY_ATTACHED
;
2018 return STATUS_REQUEST_ABORTED
;
2019 case EFI_VOLUME_FULL
:
2020 return STATUS_DISK_FULL
;
2021 case EFI_DEVICE_ERROR
:
2022 return STATUS_IO_DEVICE_ERROR
;
2023 case EFI_WRITE_PROTECTED
:
2024 return STATUS_MEDIA_WRITE_PROTECTED
;
2025 /* @FIXME: ReactOS Headers don't yet have this */
2026 //case EFI_OUT_OF_RESOURCES:
2027 //return STATUS_INSUFFICIENT_NVRAM_RESOURCES;
2028 case EFI_VOLUME_CORRUPTED
:
2029 return STATUS_DISK_CORRUPT_ERROR
;
2030 case EFI_BUFFER_TOO_SMALL
:
2031 return STATUS_BUFFER_TOO_SMALL
;
2033 return STATUS_SUCCESS
;
2034 case EFI_LOAD_ERROR
:
2035 return STATUS_DRIVER_UNABLE_TO_LOAD
;
2036 case EFI_INVALID_PARAMETER
:
2037 return STATUS_INVALID_PARAMETER
;
2038 case EFI_UNSUPPORTED
:
2039 return STATUS_NOT_SUPPORTED
;
2040 case EFI_BAD_BUFFER_SIZE
:
2041 return STATUS_INVALID_BUFFER_SIZE
;
2043 return STATUS_UNSUCCESSFUL
;