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 /* Switch to real mode */
621 BlpArchSwitchContext(BlProtectedMode
);
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 /* Switch to real mode */
650 BlpArchSwitchContext(BlProtectedMode
);
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
;
1121 PHYSICAL_ADDRESS MemoryPhysical
;
1123 /* Are we in protected mode? */
1124 OldMode
= CurrentExecutionContext
->Mode
;
1125 if (OldMode
!= BlRealMode
)
1127 /* Translate output address */
1128 BlMmTranslateVirtualAddress(Memory
, &MemoryPhysical
);
1129 Memory
= (EFI_PHYSICAL_ADDRESS
*)MemoryPhysical
.LowPart
;
1131 /* Switch to real mode */
1132 BlpArchSwitchContext(BlProtectedMode
);
1135 /* Make the EFI call */
1136 EfiStatus
= EfiBS
->AllocatePages(Type
, EfiLoaderData
, Pages
, Memory
);
1138 /* Switch back to protected mode if we came from there */
1139 if (OldMode
!= BlRealMode
)
1141 BlpArchSwitchContext(OldMode
);
1144 /* Convert the error to an NTSTATUS */
1145 return EfiGetNtStatusCode(EfiStatus
);
1149 EfipGetSystemTable (
1150 _In_ EFI_GUID
*TableGuid
,
1151 _Out_ PPHYSICAL_ADDRESS TableAddress
1157 /* Assume failure */
1158 Status
= STATUS_NOT_FOUND
;
1160 /* Loop through the configuration tables */
1161 for (i
= 0; i
< EfiST
->NumberOfTableEntries
; i
++)
1163 /* Check if this one matches the one we want */
1164 if (RtlEqualMemory(&EfiST
->ConfigurationTable
[i
].VendorGuid
,
1166 sizeof(*TableGuid
)))
1168 /* Return its address */
1169 TableAddress
->QuadPart
= (ULONG_PTR
)EfiST
->ConfigurationTable
[i
].VendorTable
;
1170 Status
= STATUS_SUCCESS
;
1175 /* Return the search result */
1181 _Out_ PPHYSICAL_ADDRESS FoundRsdt
1186 PHYSICAL_ADDRESS RsdpAddress
, Rsdt
;
1189 /* Assume failure */
1193 /* Check if we already know it */
1194 if (EfiRsdt
.QuadPart
)
1197 *FoundRsdt
= EfiRsdt
;
1198 return STATUS_SUCCESS
;
1201 /* Otherwise, look for the ACPI 2.0 RSDP (XSDT really) */
1202 Status
= EfipGetSystemTable(&EfiRootAcpiTableGuid
, &RsdpAddress
);
1203 if (!NT_SUCCESS(Status
))
1205 /* Didn't fint it, look for the ACPI 1.0 RSDP (RSDT really) */
1206 Status
= EfipGetSystemTable(&EfiRootAcpiTable10Guid
, &RsdpAddress
);
1207 if (!NT_SUCCESS(Status
))
1214 Length
= sizeof(*Rsdp
);
1215 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1219 if (NT_SUCCESS(Status
))
1221 /* Check the revision (anything >= 2.0 is XSDT) */
1224 /* Check if the table is bigger than just its header */
1225 if (Rsdp
->Length
> Length
)
1227 /* Capture the real length */
1228 Length
= Rsdp
->Length
;
1230 /* Unmap our header mapping */
1231 BlMmUnmapVirtualAddressEx(Rsdp
, sizeof(*Rsdp
));
1233 /* And map the whole thing now */
1234 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1238 if (!NT_SUCCESS(Status
))
1244 /* Read the XSDT address from the table*/
1245 Rsdt
= Rsdp
->XsdtAddress
;
1249 /* ACPI 1.0 so just read the RSDT */
1250 Rsdt
.QuadPart
= Rsdp
->RsdtAddress
;
1253 /* Save it for later */
1256 /* And return it back */
1260 /* Check if we had mapped the RSDP */
1264 BlMmUnmapVirtualAddressEx(Rsdp
, Length
);
1267 /* Return search result back to caller */
1272 MmFwpGetOsAttributeType (
1273 _In_ ULONGLONG Attribute
1276 BL_MEMORY_ATTR OsAttribute
= 0;
1278 if (Attribute
& EFI_MEMORY_UC
)
1280 OsAttribute
= BlMemoryUncached
;
1283 if (Attribute
& EFI_MEMORY_WC
)
1285 OsAttribute
|= BlMemoryWriteCombined
;
1288 if (Attribute
& EFI_MEMORY_WT
)
1290 OsAttribute
|= BlMemoryWriteThrough
;
1293 if (Attribute
& EFI_MEMORY_WB
)
1295 OsAttribute
|= BlMemoryWriteBack
;
1298 if (Attribute
& EFI_MEMORY_UCE
)
1300 OsAttribute
|= BlMemoryUncachedExported
;
1303 if (Attribute
& EFI_MEMORY_WP
)
1305 OsAttribute
|= BlMemoryWriteProtected
;
1308 if (Attribute
& EFI_MEMORY_RP
)
1310 OsAttribute
|= BlMemoryReadProtected
;
1313 if (Attribute
& EFI_MEMORY_XP
)
1315 OsAttribute
|= BlMemoryExecuteProtected
;
1318 if (Attribute
& EFI_MEMORY_RUNTIME
)
1320 OsAttribute
|= BlMemoryRuntime
;
1327 MmFwpGetOsMemoryType (
1328 _In_ EFI_MEMORY_TYPE MemoryType
1331 BL_MEMORY_TYPE OsType
;
1337 OsType
= BlLoaderMemory
;
1340 case EfiBootServicesCode
:
1341 case EfiBootServicesData
:
1342 OsType
= BlEfiBootMemory
;
1345 case EfiRuntimeServicesCode
:
1346 case EfiRuntimeServicesData
:
1347 OsType
= BlEfiRuntimeMemory
;
1350 case EfiConventionalMemory
:
1351 OsType
= BlConventionalMemory
;
1354 case EfiUnusableMemory
:
1355 OsType
= BlUnusableMemory
;
1358 case EfiACPIReclaimMemory
:
1359 OsType
= BlAcpiReclaimMemory
;
1362 case EfiACPIMemoryNVS
:
1363 OsType
= BlAcpiNvsMemory
;
1366 case EfiMemoryMappedIO
:
1367 OsType
= BlDeviceIoMemory
;
1370 case EfiMemoryMappedIOPortSpace
:
1371 OsType
= BlDevicePortMemory
;
1375 OsType
= BlPalMemory
;
1379 OsType
= BlReservedMemory
;
1388 _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap
,
1392 BL_LIBRARY_PARAMETERS LibraryParameters
= BlpLibraryParameters
;
1393 BOOLEAN UseEfiBuffer
, HaveRamDisk
;
1395 ULONGLONG Pages
, StartPage
, EndPage
, EfiBufferPage
;
1396 UINTN EfiMemoryMapSize
, MapKey
, DescriptorSize
, DescriptorVersion
;
1397 EFI_PHYSICAL_ADDRESS EfiBuffer
= 0;
1398 EFI_MEMORY_DESCRIPTOR
* EfiMemoryMap
;
1399 EFI_STATUS EfiStatus
;
1400 BL_ARCH_MODE OldMode
;
1401 EFI_MEMORY_DESCRIPTOR EfiDescriptor
;
1402 BL_MEMORY_TYPE MemoryType
;
1403 PBL_MEMORY_DESCRIPTOR Descriptor
;
1404 BL_MEMORY_ATTR Attribute
;
1405 PVOID LibraryBuffer
;
1407 /* Initialize EFI memory map attributes */
1408 EfiMemoryMapSize
= MapKey
= DescriptorSize
= DescriptorVersion
= 0;
1409 LibraryBuffer
= NULL
;
1411 /* Increment the nesting depth */
1412 MmDescriptorCallTreeCount
++;
1414 /* Determine if we should use EFI or our own allocator at this point */
1415 UseEfiBuffer
= Flags
& BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS
;
1416 if (!(LibraryParameters
.LibraryFlags
& BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
))
1418 UseEfiBuffer
= TRUE
;
1421 /* Bail out if we don't have a list to use */
1422 if (MemoryMap
== NULL
)
1424 Status
= STATUS_INVALID_PARAMETER
;
1428 /* Free the current descriptor list */
1429 MmMdFreeList(MemoryMap
);
1431 /* Call into EFI to get the size of the memory map */
1432 Status
= EfiGetMemoryMap(&EfiMemoryMapSize
,
1436 &DescriptorVersion
);
1437 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
1439 /* This should've failed because our buffer was too small, nothing else */
1440 if (NT_SUCCESS(Status
))
1442 Status
= STATUS_UNSUCCESSFUL
;
1447 /* Add 4 more descriptors just in case things changed */
1448 EfiMemoryMapSize
+= (4 * DescriptorSize
);
1449 Pages
= BYTES_TO_PAGES(EfiMemoryMapSize
);
1451 /* Should we use EFI to grab memory? */
1454 /* Yes -- request one more page to align up correctly */
1457 /* Grab the required pages */
1458 Status
= EfiAllocatePages(AllocateAnyPages
,
1461 if (!NT_SUCCESS(Status
))
1463 EfiPrintf(L
"EFI allocation failed: %lx\r\n", Status
);
1467 /* Free the pages for now */
1468 Status
= EfiFreePages(Pages
, EfiBuffer
);
1469 if (!NT_SUCCESS(Status
))
1475 /* Now round to the actual buffer size, removing the extra page */
1476 EfiBuffer
= ROUND_TO_PAGES(EfiBuffer
);
1478 Status
= EfiAllocatePages(AllocateAddress
,
1481 if (!NT_SUCCESS(Status
))
1487 /* Get the final aligned size and proper buffer */
1488 EfiMemoryMapSize
= EFI_PAGES_TO_SIZE(Pages
);
1489 EfiMemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)(ULONG_PTR
)EfiBuffer
;
1491 /* Switch to real mode if not already in it */
1492 OldMode
= CurrentExecutionContext
->Mode
;
1493 if (OldMode
!= BlRealMode
)
1495 BlpArchSwitchContext(BlRealMode
);
1498 /* Call EFI to get the memory map */
1499 EfiStatus
= EfiBS
->GetMemoryMap(&EfiMemoryMapSize
,
1503 &DescriptorVersion
);
1505 /* Switch back into the previous mode */
1506 if (OldMode
!= BlRealMode
)
1508 BlpArchSwitchContext(OldMode
);
1511 /* Convert the result code */
1512 Status
= EfiGetNtStatusCode(EfiStatus
);
1516 /* Round the map to pages */
1517 Pages
= BYTES_TO_PAGES(EfiMemoryMapSize
);
1519 /* Allocate a large enough buffer */
1520 Status
= MmPapAllocatePagesInRange(&LibraryBuffer
,
1527 if (!NT_SUCCESS(Status
))
1529 EfiPrintf(L
"Failed to allocate mapped VM for EFI map: %lx\r\n", Status
);
1533 /* Call EFI to get the memory map */
1534 EfiMemoryMap
= LibraryBuffer
;
1535 Status
= EfiGetMemoryMap(&EfiMemoryMapSize
,
1539 &DescriptorVersion
);
1542 /* So far so good? */
1543 if (!NT_SUCCESS(Status
))
1545 EfiPrintf(L
"Failed to get EFI memory map: %lx\r\n", Status
);
1549 /* Did we get correct data from firmware? */
1550 if (((EfiMemoryMapSize
% DescriptorSize
)) ||
1551 (DescriptorSize
< sizeof(EFI_MEMORY_DESCRIPTOR
)))
1553 EfiPrintf(L
"Incorrect descriptor size\r\n");
1554 Status
= STATUS_UNSUCCESSFUL
;
1558 /* Did we boot from a RAM disk? */
1559 if ((BlpBootDevice
->DeviceType
== LocalDevice
) &&
1560 (BlpBootDevice
->Local
.Type
== RamDiskDevice
))
1562 /* We don't handle this yet */
1563 EfiPrintf(L
"RAM boot not supported\r\n");
1564 Status
= STATUS_NOT_IMPLEMENTED
;
1569 /* We didn't, so there won't be any need to find the memory descriptor */
1570 HaveRamDisk
= FALSE
;
1573 /* Loop the EFI memory map */
1575 EfiPrintf(L
"UEFI MEMORY MAP\r\n\r\n");
1576 EfiPrintf(L
"TYPE START END ATTRIBUTES\r\n");
1577 EfiPrintf(L
"===============================================================\r\n");
1579 while (EfiMemoryMapSize
!= 0)
1581 /* Check if this is an EFI buffer, but we're not in real mode */
1582 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1584 BlpArchSwitchContext(BlRealMode
);
1587 /* Capture it so we can go back to protected mode (if possible) */
1588 EfiDescriptor
= *EfiMemoryMap
;
1590 /* Go back to protected mode, if we had switched */
1591 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1593 BlpArchSwitchContext(OldMode
);
1596 /* Convert to OS memory type */
1597 MemoryType
= MmFwpGetOsMemoryType(EfiDescriptor
.Type
);
1599 /* Round up or round down depending on where the memory is coming from */
1600 if (MemoryType
== BlConventionalMemory
)
1602 StartPage
= BYTES_TO_PAGES(EfiDescriptor
.PhysicalStart
);
1606 StartPage
= EfiDescriptor
.PhysicalStart
>> PAGE_SHIFT
;
1609 /* Calculate the ending page */
1610 EndPage
= StartPage
+ EfiDescriptor
.NumberOfPages
;
1612 /* If after rounding, we ended up with 0 pages, skip this */
1613 if (StartPage
== EndPage
)
1618 EfiPrintf(L
"%08X 0x%016I64X-0x%016I64X 0x%I64X\r\n",
1620 StartPage
<< PAGE_SHIFT
,
1621 EndPage
<< PAGE_SHIFT
,
1622 EfiDescriptor
.Attribute
);
1624 /* Check for any range of memory below 1MB */
1625 if (StartPage
< 0x100)
1627 /* Does this range actually contain NULL? */
1630 /* Manually create a reserved descriptof for this page */
1631 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1632 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1639 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1643 /* Add this descriptor into the list */
1644 Status
= MmMdAddDescriptorToList(MemoryMap
,
1646 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1647 if (!NT_SUCCESS(Status
))
1649 EfiPrintf(L
"Failed to add zero page descriptor: %lx\r\n", Status
);
1653 /* Now handle the rest of the range, unless this was it */
1661 /* Does the range go beyond 1MB? */
1662 if (EndPage
> 0x100)
1664 /* Then create the descriptor for everything up until the megabyte */
1665 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1666 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1673 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1677 /* Check if this region is currently free RAM */
1678 if (Descriptor
->Type
== BlConventionalMemory
)
1680 /* Set the appropriate flag on the descriptor */
1681 Descriptor
->Flags
|= BlMemoryBelow1MB
;
1684 /* Add this descriptor into the list */
1685 Status
= MmMdAddDescriptorToList(MemoryMap
,
1687 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1688 if (!NT_SUCCESS(Status
))
1690 EfiPrintf(L
"Failed to add 1MB descriptor: %lx\r\n", Status
);
1694 /* Now handle the rest of the range above 1MB */
1699 /* Check if we loaded from a RAM disk */
1702 /* We don't handle this yet */
1703 EfiPrintf(L
"RAM boot not supported\r\n");
1704 Status
= STATUS_NOT_IMPLEMENTED
;
1708 /* Create a descriptor for the current range */
1709 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1710 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1714 EndPage
- StartPage
);
1717 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1721 /* Check if this region is currently free RAM below 1MB */
1722 if ((Descriptor
->Type
== BlConventionalMemory
) && (EndPage
<= 0x100))
1724 /* Set the appropriate flag on the descriptor */
1725 Descriptor
->Flags
|= BlMemoryBelow1MB
;
1728 /* Add the descriptor to the list, requesting coalescing as asked */
1729 Status
= MmMdAddDescriptorToList(MemoryMap
,
1731 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
|
1732 ((Flags
& BL_MM_FLAG_REQUEST_COALESCING
) ?
1733 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
: 0));
1734 if (!NT_SUCCESS(Status
))
1736 EfiPrintf(L
"Failed to add full descriptor: %lx\r\n", Status
);
1741 /* Consume this descriptor, and move to the next one */
1742 EfiMemoryMapSize
-= DescriptorSize
;
1743 EfiMemoryMap
= (PVOID
)((ULONG_PTR
)EfiMemoryMap
+ DescriptorSize
);
1746 /* Check if we are using the local UEFI buffer */
1752 /* Free the EFI buffer */
1753 Status
= EfiFreePages(Pages
, EfiBuffer
);
1754 if (!NT_SUCCESS(Status
))
1756 /* Keep the pages marked 'in use' and fake success */
1757 Status
= STATUS_SUCCESS
;
1761 /* Get the base page of the EFI buffer */
1762 EfiBufferPage
= EfiBuffer
>> PAGE_SHIFT
;
1763 Pages
= (EfiBufferPage
+ Pages
) - EfiBufferPage
;
1765 /* Don't try freeing below */
1768 /* Find the current descriptor for the allocation */
1769 Descriptor
= MmMdFindDescriptorFromMdl(MemoryMap
,
1770 BL_MM_REMOVE_PHYSICAL_REGION_FLAG
,
1774 Status
= STATUS_UNSUCCESSFUL
;
1778 /* Convert it to a free descriptor */
1779 Descriptor
= MmMdInitByteGranularDescriptor(Descriptor
->Flags
,
1780 BlConventionalMemory
,
1786 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1790 /* Remove the region from the memory map */
1791 Status
= MmMdRemoveRegionFromMdlEx(MemoryMap
,
1792 BL_MM_REMOVE_PHYSICAL_REGION_FLAG
,
1796 if (!NT_SUCCESS(Status
))
1798 MmMdFreeDescriptor(Descriptor
);
1802 /* Add it back as free memory */
1803 Status
= MmMdAddDescriptorToList(MemoryMap
,
1805 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
);
1808 /* Free the EFI buffer, if we had one */
1811 EfiFreePages(Pages
, EfiBuffer
);
1814 /* Free the library-allocated buffer, if we had one */
1815 if (LibraryBuffer
!= 0)
1817 MmPapFreePages(LibraryBuffer
, BL_MM_INCLUDE_MAPPED_ALLOCATED
);
1820 /* On failure, free the memory map if one was passed in */
1821 if (!NT_SUCCESS(Status
) && (MemoryMap
!= NULL
))
1823 MmMdFreeList(MemoryMap
);
1826 /* Decrement the nesting depth and return */
1827 MmDescriptorCallTreeCount
--;
1834 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
1837 NTSTATUS Status
= STATUS_SUCCESS
;
1838 EFI_KEY_TOGGLE_STATE KeyToggleState
;
1840 /* Check if we have valid firmware data */
1841 if (!(FirmwareData
) || !(FirmwareData
->Version
))
1843 return STATUS_INVALID_PARAMETER
;
1846 /* Check which boot phase we're in */
1849 /* Memory manager is ready, open the extended input protocol */
1850 Status
= EfiOpenProtocol(EfiST
->ConsoleInHandle
,
1851 &EfiSimpleTextInputExProtocol
,
1852 (PVOID
*)&EfiConInEx
);
1853 if (NT_SUCCESS(Status
))
1855 /* Set the initial key toggle state */
1856 KeyToggleState
= EFI_TOGGLE_STATE_VALID
| 40;
1857 EfiConInExSetState(EfiConInEx
, &KeyToggleState
);
1860 /* Setup the watchdog timer */
1861 EfiSetWatchdogTimer();
1865 /* Make a copy of the parameters */
1866 EfiFirmwareParameters
= &EfiFirmwareData
;
1868 /* Check which version we received */
1869 if (FirmwareData
->Version
== 1)
1871 /* FIXME: Not supported */
1872 Status
= STATUS_NOT_SUPPORTED
;
1874 else if (FirmwareData
->Version
>= BL_FIRMWARE_DESCRIPTOR_VERSION
)
1876 /* Version 2 -- save the data */
1877 EfiFirmwareData
= *FirmwareData
;
1878 EfiSystemTable
= FirmwareData
->SystemTable
;
1879 EfiImageHandle
= FirmwareData
->ImageHandle
;
1881 /* Set the EDK-II style variables as well */
1882 EfiST
= EfiSystemTable
;
1883 EfiBS
= EfiSystemTable
->BootServices
;
1884 EfiRT
= EfiSystemTable
->RuntimeServices
;
1885 EfiConOut
= EfiSystemTable
->ConOut
;
1886 EfiConIn
= EfiSystemTable
->ConIn
;
1891 /* Unknown version */
1892 Status
= STATUS_NOT_SUPPORTED
;
1896 /* Return the initialization state */
1902 _In_ PBL_FIRMWARE_DESCRIPTOR Parameters
1905 /* Make sure we got an argument */
1908 return STATUS_INVALID_PARAMETER
;
1911 /* Copy the static data */
1912 *Parameters
= *EfiFirmwareParameters
;
1913 return STATUS_SUCCESS
;
1917 BlFwEnumerateDevice (
1918 _In_ PBL_DEVICE_DESCRIPTOR Device
1922 ULONG PathProtocols
, BlockProtocols
;
1923 EFI_HANDLE
* PathArray
;
1924 EFI_HANDLE
* BlockArray
;
1926 /* Initialize locals */
1932 /* Enumeration only makes sense on disks or partitions */
1933 if ((Device
->DeviceType
!= DiskDevice
) &&
1934 (Device
->DeviceType
!= LegacyPartitionDevice
) &&
1935 (Device
->DeviceType
!= PartitionDevice
))
1937 return STATUS_NOT_SUPPORTED
;
1940 /* Enumerate the list of device paths */
1941 Status
= EfiLocateHandleBuffer(ByProtocol
,
1942 &EfiDevicePathProtocol
,
1945 if (NT_SUCCESS(Status
))
1947 /* Loop through each one */
1948 Status
= STATUS_NOT_FOUND
;
1949 while (PathProtocols
)
1951 /* Attempt to connect the driver for this device epath */
1952 Status
= EfiConnectController(PathArray
[--PathProtocols
]);
1953 if (NT_SUCCESS(Status
))
1955 /* Now enumerate any block I/O devices the driver added */
1956 Status
= EfiLocateHandleBuffer(ByProtocol
,
1957 &EfiBlockIoProtocol
,
1960 if (!NT_SUCCESS(Status
))
1965 /* Loop through each one */
1966 while (BlockProtocols
)
1968 /* Check if one of the new devices is the one we want */
1969 Status
= BlockIoEfiCompareDevice(Device
,
1970 BlockArray
[--BlockProtocols
]);
1971 if (NT_SUCCESS(Status
))
1978 /* Move on to the next device path */
1979 BlMmFreeHeap(BlockArray
);
1986 /* We're done -- free the array of device path protocols, if any */
1989 BlMmFreeHeap(PathArray
);
1992 /* We're done -- free the array of block I/O protocols, if any */
1995 BlMmFreeHeap(BlockArray
);
1998 /* Return if we found the device or not */
2003 * @name EfiGetEfiStatusCode
2005 * The EfiGetEfiStatusCode routine converts an NT Status to an EFI status.
2008 * NT Status code to be converted.
2010 * @remark Only certain, specific NT status codes are converted to EFI codes.
2012 * @return The corresponding EFI Status code, EFI_NO_MAPPING otherwise.
2016 EfiGetEfiStatusCode(
2017 _In_ NTSTATUS Status
2022 case STATUS_NOT_SUPPORTED
:
2023 return EFI_UNSUPPORTED
;
2024 case STATUS_DISK_FULL
:
2025 return EFI_VOLUME_FULL
;
2026 case STATUS_INSUFFICIENT_RESOURCES
:
2027 return EFI_OUT_OF_RESOURCES
;
2028 case STATUS_MEDIA_WRITE_PROTECTED
:
2029 return EFI_WRITE_PROTECTED
;
2030 case STATUS_DEVICE_NOT_READY
:
2031 return EFI_NOT_STARTED
;
2032 case STATUS_DEVICE_ALREADY_ATTACHED
:
2033 return EFI_ALREADY_STARTED
;
2034 case STATUS_MEDIA_CHANGED
:
2035 return EFI_MEDIA_CHANGED
;
2036 case STATUS_INVALID_PARAMETER
:
2037 return EFI_INVALID_PARAMETER
;
2038 case STATUS_ACCESS_DENIED
:
2039 return EFI_ACCESS_DENIED
;
2040 case STATUS_BUFFER_TOO_SMALL
:
2041 return EFI_BUFFER_TOO_SMALL
;
2042 case STATUS_DISK_CORRUPT_ERROR
:
2043 return EFI_VOLUME_CORRUPTED
;
2044 case STATUS_REQUEST_ABORTED
:
2046 case STATUS_NO_MEDIA
:
2047 return EFI_NO_MEDIA
;
2048 case STATUS_IO_DEVICE_ERROR
:
2049 return EFI_DEVICE_ERROR
;
2050 case STATUS_INVALID_BUFFER_SIZE
:
2051 return EFI_BAD_BUFFER_SIZE
;
2052 case STATUS_NOT_FOUND
:
2053 return EFI_NOT_FOUND
;
2054 case STATUS_DRIVER_UNABLE_TO_LOAD
:
2055 return EFI_LOAD_ERROR
;
2056 case STATUS_NO_MATCH
:
2057 return EFI_NO_MAPPING
;
2058 case STATUS_SUCCESS
:
2060 case STATUS_TIMEOUT
:
2063 return EFI_NO_MAPPING
;
2068 * @name EfiGetNtStatusCode
2070 * The EfiGetNtStatusCode routine converts an EFI Status to an NT status.
2073 * EFI Status code to be converted.
2075 * @remark Only certain, specific EFI status codes are converted to NT codes.
2077 * @return The corresponding NT Status code, STATUS_UNSUCCESSFUL otherwise.
2081 EfiGetNtStatusCode (
2082 _In_ EFI_STATUS EfiStatus
2089 return STATUS_NOT_FOUND
;
2091 return STATUS_NO_MEDIA
;
2092 case EFI_MEDIA_CHANGED
:
2093 return STATUS_MEDIA_CHANGED
;
2094 case EFI_ACCESS_DENIED
:
2095 case EFI_SECURITY_VIOLATION
:
2096 return STATUS_ACCESS_DENIED
;
2098 case EFI_NO_RESPONSE
:
2099 return STATUS_TIMEOUT
;
2100 case EFI_NO_MAPPING
:
2101 return STATUS_NO_MATCH
;
2102 case EFI_NOT_STARTED
:
2103 return STATUS_DEVICE_NOT_READY
;
2104 case EFI_ALREADY_STARTED
:
2105 return STATUS_DEVICE_ALREADY_ATTACHED
;
2107 return STATUS_REQUEST_ABORTED
;
2108 case EFI_VOLUME_FULL
:
2109 return STATUS_DISK_FULL
;
2110 case EFI_DEVICE_ERROR
:
2111 return STATUS_IO_DEVICE_ERROR
;
2112 case EFI_WRITE_PROTECTED
:
2113 return STATUS_MEDIA_WRITE_PROTECTED
;
2114 /* @FIXME: ReactOS Headers don't yet have this */
2115 //case EFI_OUT_OF_RESOURCES:
2116 //return STATUS_INSUFFICIENT_NVRAM_RESOURCES;
2117 case EFI_VOLUME_CORRUPTED
:
2118 return STATUS_DISK_CORRUPT_ERROR
;
2119 case EFI_BUFFER_TOO_SMALL
:
2120 return STATUS_BUFFER_TOO_SMALL
;
2122 return STATUS_SUCCESS
;
2123 case EFI_LOAD_ERROR
:
2124 return STATUS_DRIVER_UNABLE_TO_LOAD
;
2125 case EFI_INVALID_PARAMETER
:
2126 return STATUS_INVALID_PARAMETER
;
2127 case EFI_UNSUPPORTED
:
2128 return STATUS_NOT_SUPPORTED
;
2129 case EFI_BAD_BUFFER_SIZE
:
2130 return STATUS_INVALID_BUFFER_SIZE
;
2132 return STATUS_UNSUCCESSFUL
;