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
);
163 BOOLEAN EfiProtHashTableInitialized
;
164 ULONG EfiProtHashTableId
;
166 typedef struct _BL_EFI_PROTOCOL
168 LIST_ENTRY ListEntry
;
172 BOOLEAN AddressMapped
;
173 } BL_EFI_PROTOCOL
, *PBL_EFI_PROTOCOL
;
177 _In_ EFI_HANDLE Handle
,
178 _In_ EFI_GUID
* Protocol
,
179 _Outptr_ PVOID
* Interface
182 BOOLEAN AddressMapped
;
183 PLIST_ENTRY HashList
, NextEntry
;
184 PHYSICAL_ADDRESS InterfaceAddress
, TranslatedAddress
;
186 BL_HASH_ENTRY HashEntry
;
187 PBL_HASH_VALUE HashValue
;
188 PBL_EFI_PROTOCOL EfiProtocol
;
189 BL_ARCH_MODE OldMode
;
190 EFI_STATUS EfiStatus
;
193 /* Initialize failure paths */
194 AddressMapped
= FALSE
;
196 InterfaceAddress
.QuadPart
= 0;
198 /* Have we initialized the protocol table yet? */
199 if (!EfiProtHashTableInitialized
)
201 /* Nope -- create the hash table */
202 Status
= BlHtCreate(0, NULL
, NULL
, &EfiProtHashTableId
);
203 if (!NT_SUCCESS(Status
))
208 /* Remember for next time */
209 EfiProtHashTableInitialized
= TRUE
;
212 /* Check if we already have a list of protocols for this handle */
213 HashEntry
.Flags
= BL_HT_VALUE_IS_INLINE
;
214 HashEntry
.Size
= sizeof(Handle
);
215 HashEntry
.Value
= Handle
;
216 Status
= BlHtLookup(EfiProtHashTableId
, &HashEntry
, &HashValue
);
217 if (NT_SUCCESS(Status
))
219 /* We do -- the hash value is the list itself */
220 HashList
= (PLIST_ENTRY
)HashValue
->Data
;
221 NextEntry
= HashList
->Flink
;
223 /* Iterate over it */
224 while (NextEntry
!= HashList
)
226 /* Get each protocol in the list, checking for a match */
227 EfiProtocol
= CONTAINING_RECORD(NextEntry
,
230 if (EfiProtocol
->Protocol
== Protocol
)
232 /* Match found -- add a reference and return it */
233 EfiProtocol
->ReferenceCount
++;
234 *Interface
= EfiProtocol
->Interface
;
235 return STATUS_SUCCESS
;
238 /* Try the next entry */
239 NextEntry
= NextEntry
->Flink
;
243 /* Switch to real mode for firmware call */
244 OldMode
= CurrentExecutionContext
->Mode
;
245 if (OldMode
!= BlRealMode
)
247 BlpArchSwitchContext(BlRealMode
);
250 /* Check if this is EFI 1.02 */
251 if (EfiST
->Hdr
.Revision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
253 /* Use the old call */
254 EfiStatus
= EfiBS
->HandleProtocol(Handle
,
256 (PVOID
*)&InterfaceAddress
);
260 /* Use the EFI 2.00 API instead */
261 EfiStatus
= EfiBS
->OpenProtocol(Handle
,
263 (PVOID
*)&InterfaceAddress
,
266 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
269 /* Switch back to protected mode if needed */
270 if (OldMode
!= BlRealMode
)
272 BlpArchSwitchContext(OldMode
);
275 /* Check the result, and bail out on failure */
276 Status
= EfiGetNtStatusCode(EfiStatus
);
277 if (!NT_SUCCESS(Status
))
282 /* Check what address the interface lives at, and translate it */
283 InterfaceVa
= PhysicalAddressToPtr(InterfaceAddress
);
284 if (BlMmTranslateVirtualAddress(InterfaceVa
, &TranslatedAddress
))
286 /* We expect firmware to be 1:1 mapped, fail if not */
287 if (InterfaceAddress
.QuadPart
!= TranslatedAddress
.QuadPart
)
289 return STATUS_NOT_SUPPORTED
;
294 /* Create a virtual (1:1) mapping for the interface */
295 Status
= BlMmMapPhysicalAddressEx(&InterfaceVa
,
299 if (!NT_SUCCESS(Status
))
304 /* Remember for cleanup */
305 AddressMapped
= TRUE
;
308 /* The caller now has the interface */
309 *Interface
= InterfaceVa
;
311 /* Did we already have some protocols on this handle? */
314 /* Nope, this is the first time -- so allocate the list */
315 HashList
= BlMmAllocateHeap(sizeof(*HashList
));
318 Status
= STATUS_NO_MEMORY
;
323 InitializeListHead(HashList
);
325 /* And then store it in the hash table for this handle */
326 Status
= BlHtStore(EfiProtHashTableId
,
330 if (!NT_SUCCESS(Status
))
332 BlMmFreeHeap(HashList
);
337 /* Finally, allocate a protocol tracker structure */
338 EfiProtocol
= BlMmAllocateHeap(sizeof(*EfiProtocol
));
341 Status
= STATUS_NO_MEMORY
;
345 /* And store this information in case the protocol is needed again */
346 EfiProtocol
->Protocol
= Protocol
;
347 EfiProtocol
->Interface
= *Interface
;
348 EfiProtocol
->ReferenceCount
= 1;
349 EfiProtocol
->AddressMapped
= AddressMapped
;
350 InsertTailList(HashList
, &EfiProtocol
->ListEntry
);
352 /* Passthru to success case */
353 AddressMapped
= FALSE
;
356 /* Failure path -- did we map anything ?*/
360 BlMmUnmapVirtualAddressEx(InterfaceVa
, PAGE_SIZE
);
364 /* Return the failure */
370 _In_ EFI_HANDLE Handle
,
371 _In_ EFI_GUID
*Protocol
,
372 _Outptr_ PVOID
* Interface
375 EFI_STATUS EfiStatus
;
377 BL_ARCH_MODE OldMode
;
379 /* Are we using virtual memory/ */
380 if (MmTranslationType
!= BlNone
)
382 /* We need complex tracking to make this work */
383 Status
= EfiVmOpenProtocol(Handle
, Protocol
, Interface
);
387 /* Are we in protected mode? */
388 OldMode
= CurrentExecutionContext
->Mode
;
389 if (OldMode
!= BlRealMode
)
391 /* Switch to real mode */
392 BlpArchSwitchContext(BlRealMode
);
395 /* Are we on legacy 1.02? */
396 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
398 /* Make the legacy call */
399 EfiStatus
= EfiBS
->HandleProtocol(Handle
, Protocol
, Interface
);
403 /* Use the UEFI version */
404 EfiStatus
= EfiBS
->OpenProtocol(Handle
,
409 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
411 /* Switch back to protected mode if we came from there */
412 if (OldMode
!= BlRealMode
)
414 BlpArchSwitchContext(OldMode
);
418 /* Convert the error to an NTSTATUS */
419 Status
= EfiGetNtStatusCode(EfiStatus
);
422 /* Clear the interface on failure, and return the status */
423 if (!NT_SUCCESS(Status
))
432 EfiVmpCloseProtocol (
433 _In_ EFI_HANDLE Handle
,
434 _In_ EFI_GUID
* Protocol
437 EFI_STATUS EfiStatus
;
438 BL_ARCH_MODE OldMode
;
440 /* Are we in protected mode? */
441 OldMode
= CurrentExecutionContext
->Mode
;
442 if (OldMode
!= BlRealMode
)
444 /* Switch to real mode */
445 BlpArchSwitchContext(BlRealMode
);
448 /* Are we on legacy 1.02? */
449 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
451 /* Nothing to close */
452 EfiStatus
= EFI_SUCCESS
;
456 /* Use the UEFI version */
457 EfiStatus
= EfiBS
->CloseProtocol(Handle
,
462 /* Normalize not found as success */
463 if (EfiStatus
== EFI_NOT_FOUND
)
465 EfiStatus
= EFI_SUCCESS
;
469 /* Switch back to protected mode if we came from there */
470 if (OldMode
!= BlRealMode
)
472 BlpArchSwitchContext(OldMode
);
475 /* Convert to NT status */
476 return EfiGetNtStatusCode(EfiStatus
);
480 EfiVmpFreeInterfaceEntry (
481 _In_ EFI_HANDLE Handle
,
482 _In_ PBL_EFI_PROTOCOL EfiProtocol
486 BL_HASH_ENTRY HashEntry
;
489 Status
= STATUS_SUCCESS
;
491 /* Is this the last protocol on this handle? */
492 if (IsListEmpty(&EfiProtocol
->ListEntry
))
494 /* Delete the hash table entry for this handle */
495 HashEntry
.Value
= Handle
;
496 HashEntry
.Size
= sizeof(Handle
);
497 HashEntry
.Flags
= BL_HT_VALUE_IS_INLINE
;
498 Status
= BlHtDelete(EfiProtHashTableId
, &HashEntry
);
500 /* This will free the list head itself */
501 BlMmFreeHeap(EfiProtocol
->ListEntry
.Flink
);
505 /* Simply remove this entry */
506 RemoveEntryList(&EfiProtocol
->ListEntry
);
509 /* Had we virtually mapped this protocol? */
510 if (EfiProtocol
->AddressMapped
)
513 BlMmUnmapVirtualAddressEx(EfiProtocol
->Interface
, PAGE_SIZE
);
516 /* Free the protocol entry, and return */
517 BlMmFreeHeap(EfiProtocol
);
523 _In_ EFI_HANDLE Handle
,
524 _In_ EFI_GUID
* Protocol
527 BL_HASH_ENTRY HashEntry
;
528 PLIST_ENTRY ListHead
, NextEntry
;
529 NTSTATUS Status
, CloseStatus
;
530 PBL_HASH_VALUE HashValue
;
531 PBL_EFI_PROTOCOL EfiProtocol
;
533 /* Lookup the list entry for this handle */
534 HashEntry
.Size
= sizeof(Handle
);
535 HashEntry
.Flags
= BL_HT_VALUE_IS_INLINE
;
536 HashEntry
.Value
= Handle
;
537 Status
= BlHtLookup(EfiProtHashTableId
, &HashEntry
, &HashValue
);
538 if (!NT_SUCCESS(Status
))
540 /* This handle was never used for any protocols */
541 return STATUS_INVALID_PARAMETER
;
544 /* Iterate through the list of opened protocols */
545 ListHead
= (PLIST_ENTRY
)HashValue
->Data
;
546 NextEntry
= ListHead
->Flink
;
547 while (NextEntry
!= ListHead
)
549 /* Get this protocol entry and check for a match */
550 EfiProtocol
= CONTAINING_RECORD(NextEntry
, BL_EFI_PROTOCOL
, ListEntry
);
551 if (EfiProtocol
->Protocol
== Protocol
)
553 /* Drop a reference -- was it the last one? */
554 if (EfiProtocol
->ReferenceCount
-- == 1)
556 /* Yep -- free this entry */
557 Status
= EfiVmpFreeInterfaceEntry(Handle
, EfiProtocol
);
559 /* Call firmware to close the protocol */
560 CloseStatus
= EfiVmpCloseProtocol(Handle
, Protocol
);
561 if (!NT_SUCCESS(CloseStatus
))
563 /* Override free status if close was a failure */
564 Status
= CloseStatus
;
567 /* Return final status */
573 NextEntry
= NextEntry
->Flink
;
576 /* This protocol was never opened */
577 return STATUS_INVALID_PARAMETER
;
582 _In_ EFI_HANDLE Handle
,
583 _In_ EFI_GUID
*Protocol
586 EFI_STATUS EfiStatus
;
588 BL_ARCH_MODE OldMode
;
590 /* Are we using virtual memory/ */
591 if (MmTranslationType
!= BlNone
)
593 /* We need complex tracking to make this work */
594 Status
= EfiVmCloseProtocol(Handle
, Protocol
);
598 /* Are we on legacy 1.02? */
599 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
601 /* Nothing to close */
602 EfiStatus
= EFI_SUCCESS
;
606 /* Are we in protected mode? */
607 OldMode
= CurrentExecutionContext
->Mode
;
608 if (OldMode
!= BlRealMode
)
610 /* Switch to real mode */
611 BlpArchSwitchContext(BlRealMode
);
614 /* Use the UEFI version */
615 EfiStatus
= EfiBS
->CloseProtocol(Handle
, Protocol
, EfiImageHandle
, NULL
);
617 /* Switch back to protected mode if we came from there */
618 if (OldMode
!= BlRealMode
)
620 BlpArchSwitchContext(OldMode
);
623 /* Normalize not found as success */
624 if (EfiStatus
== EFI_NOT_FOUND
)
626 EfiStatus
= EFI_SUCCESS
;
630 /* Convert the error to an NTSTATUS */
631 Status
= EfiGetNtStatusCode(EfiStatus
);
640 _In_ PWCHAR VariableName
,
641 _In_ EFI_GUID
* VendorGuid
,
642 _Out_opt_ PULONG Attributes
,
643 _Inout_ PULONG DataSize
,
647 EFI_STATUS EfiStatus
;
649 BL_ARCH_MODE OldMode
;
650 ULONG LocalAttributes
;
652 /* Are we in protected mode? */
653 OldMode
= CurrentExecutionContext
->Mode
;
654 if (OldMode
!= BlRealMode
)
656 /* FIXME: Not yet implemented */
657 EfiPrintf(L
"getvar vm path\r\n");
659 return STATUS_NOT_IMPLEMENTED
;
662 /* Call the runtime API */
663 EfiStatus
= EfiRT
->GetVariable(VariableName
,
665 (UINT32
*)&LocalAttributes
,
669 /* Switch back to protected mode if we came from there */
670 if (OldMode
!= BlRealMode
)
672 BlpArchSwitchContext(OldMode
);
675 /* Return attributes back to the caller if asked to */
678 *Attributes
= LocalAttributes
;
681 /* Convert the error to an NTSTATUS and return it */
682 Status
= EfiGetNtStatusCode(EfiStatus
);
687 BlpSecureBootEFIIsEnabled (
692 BOOLEAN SetupMode
, SecureBoot
;
695 /* Assume setup mode enabled, and no secure boot */
699 /* Get the SetupMode variable */
700 DataSize
= sizeof(SetupMode
);
701 Status
= EfiGetVariable(L
"SetupMode",
706 if (NT_SUCCESS(Status
))
708 /* If it worked, get the SecureBoot variable */
709 DataSize
= sizeof(SecureBoot
);
710 Status
= EfiGetVariable(L
"SecureBoot",
715 if (NT_SUCCESS(Status
))
717 /* In setup mode or without secureboot turned on, return failure */
718 if ((SecureBoot
!= TRUE
) || (SetupMode
))
720 Status
= STATUS_INVALID_SIGNATURE
;
723 // BlpSbdiStateFlags |= 8u;
727 /* Return secureboot status */
732 BlSecureBootIsEnabled (
733 _Out_ PBOOLEAN SecureBootEnabled
738 /* Have we checked before ? */
739 if (!BlpFirmwareChecked
)
741 /* First time checking */
742 Status
= BlpSecureBootEFIIsEnabled();
743 if NT_SUCCESS(Status
)
746 BlpFirmwareEnabled
= TRUE
;
749 /* Don't check again */
750 BlpFirmwareChecked
= TRUE
;
753 /* Return the firmware result */
754 *SecureBootEnabled
= BlpFirmwareEnabled
;
755 return STATUS_SUCCESS
;
759 BlSecureBootCheckForFactoryReset (
763 BOOLEAN SecureBootEnabled
;
767 /* Initialize locals */
769 SecureBootEnabled
= FALSE
;
771 /* Check if secureboot is enabled */
772 Status
= BlSecureBootIsEnabled(&SecureBootEnabled
);
773 if (!(NT_SUCCESS(Status
)) || !(SecureBootEnabled
))
775 /* It's not. Check if there's a revocation list */
776 Status
= EfiGetVariable(L
"RevocationList",
777 &BlpEfiSecureBootPrivateNamespace
,
781 if ((NT_SUCCESS(Status
)) || (Status
== STATUS_BUFFER_TOO_SMALL
))
783 /* We don't support this yet */
784 EfiPrintf(L
"Not yet supported\r\n");
785 Status
= STATUS_NOT_IMPLEMENTED
;
789 /* Return back to the caller */
798 BL_ARCH_MODE OldMode
;
799 EFI_STATUS EfiStatus
;
801 /* Are we in protected mode? */
802 OldMode
= CurrentExecutionContext
->Mode
;
803 if (OldMode
!= BlRealMode
)
805 /* FIXME: Not yet implemented */
806 EfiPrintf(L
"coninreset vm path\r\n");
808 return STATUS_NOT_IMPLEMENTED
;
811 /* Make the EFI call */
812 EfiStatus
= EfiConIn
->Reset(EfiConIn
, FALSE
);
814 /* Switch back to protected mode if we came from there */
815 if (OldMode
!= BlRealMode
)
817 BlpArchSwitchContext(OldMode
);
820 /* Convert the error to an NTSTATUS */
821 return EfiGetNtStatusCode(EfiStatus
);
829 BL_ARCH_MODE OldMode
;
830 EFI_STATUS EfiStatus
;
832 /* Are we in protected mode? */
833 OldMode
= CurrentExecutionContext
->Mode
;
834 if (OldMode
!= BlRealMode
)
836 /* FIXME: Not yet implemented */
837 EfiPrintf(L
"conreset vm path\r\n");
839 return STATUS_NOT_IMPLEMENTED
;
842 /* Make the EFI call */
843 EfiStatus
= EfiConInEx
->Reset(EfiConInEx
, FALSE
);
845 /* Switch back to protected mode if we came from there */
846 if (OldMode
!= BlRealMode
)
848 BlpArchSwitchContext(OldMode
);
851 /* Convert the error to an NTSTATUS */
852 return EfiGetNtStatusCode(EfiStatus
);
857 _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*ConInEx
,
858 _In_ EFI_KEY_TOGGLE_STATE
* KeyToggleState
861 BL_ARCH_MODE OldMode
;
862 EFI_STATUS EfiStatus
;
863 PHYSICAL_ADDRESS ConInExPhys
, KeyTogglePhys
;
865 /* Are we in protected mode? */
866 OldMode
= CurrentExecutionContext
->Mode
;
867 if (OldMode
!= BlRealMode
)
869 /* Translate pointers from virtual to physical */
870 BlMmTranslateVirtualAddress(ConInEx
, &ConInExPhys
);
871 ConInEx
= (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*)PhysicalAddressToPtr(ConInExPhys
);
872 BlMmTranslateVirtualAddress(KeyToggleState
, &KeyTogglePhys
);
873 KeyToggleState
= (EFI_KEY_TOGGLE_STATE
*)PhysicalAddressToPtr(KeyTogglePhys
);
875 /* Switch to real mode */
876 BlpArchSwitchContext(BlRealMode
);
879 /* Make the EFI call */
880 EfiStatus
= ConInEx
->SetState(ConInEx
, KeyToggleState
);
882 /* Switch back to protected mode if we came from there */
883 if (OldMode
!= BlRealMode
)
885 BlpArchSwitchContext(OldMode
);
888 /* Convert the error to an NTSTATUS */
889 return EfiGetNtStatusCode(EfiStatus
);
893 EfiSetWatchdogTimer (
897 BL_ARCH_MODE OldMode
;
898 EFI_STATUS EfiStatus
;
900 /* Are we in protected mode? */
901 OldMode
= CurrentExecutionContext
->Mode
;
902 if (OldMode
!= BlRealMode
)
904 /* Switch to real mode */
905 BlpArchSwitchContext(BlRealMode
);
908 /* Make the EFI call */
909 EfiStatus
= EfiBS
->SetWatchdogTimer(0, 0, 0, NULL
);
911 /* Switch back to protected mode if we came from there */
912 if (OldMode
!= BlRealMode
)
914 BlpArchSwitchContext(OldMode
);
917 /* Convert the error to an NTSTATUS */
918 return EfiGetNtStatusCode(EfiStatus
);
923 _Out_ UINTN
* MemoryMapSize
,
924 _Inout_ EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
926 _Out_ UINTN
* DescriptorSize
,
927 _Out_ UINTN
* DescriptorVersion
930 BL_ARCH_MODE OldMode
;
931 EFI_STATUS EfiStatus
;
932 PHYSICAL_ADDRESS MemoryMapSizePhysical
, MemoryMapPhysical
, MapKeyPhysical
;
933 PHYSICAL_ADDRESS DescriptorSizePhysical
, DescriptorVersionPhysical
;
935 /* Are we in protected mode? */
936 OldMode
= CurrentExecutionContext
->Mode
;
937 if (OldMode
!= BlRealMode
)
939 /* Convert all of the addresses to physical */
940 BlMmTranslateVirtualAddress(MemoryMapSize
, &MemoryMapSizePhysical
);
941 MemoryMapSize
= (UINTN
*)PhysicalAddressToPtr(MemoryMapSizePhysical
);
942 BlMmTranslateVirtualAddress(MemoryMap
, &MemoryMapPhysical
);
943 MemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)PhysicalAddressToPtr(MemoryMapPhysical
);
944 BlMmTranslateVirtualAddress(MapKey
, &MapKeyPhysical
);
945 MapKey
= (UINTN
*)PhysicalAddressToPtr(MapKeyPhysical
);
946 BlMmTranslateVirtualAddress(DescriptorSize
, &DescriptorSizePhysical
);
947 DescriptorSize
= (UINTN
*)PhysicalAddressToPtr(DescriptorSizePhysical
);
948 BlMmTranslateVirtualAddress(DescriptorVersion
, &DescriptorVersionPhysical
);
949 DescriptorVersion
= (UINTN
*)PhysicalAddressToPtr(DescriptorVersionPhysical
);
951 /* Switch to real mode */
952 BlpArchSwitchContext(BlRealMode
);
955 /* Make the EFI call */
956 EfiStatus
= EfiBS
->GetMemoryMap(MemoryMapSize
,
962 /* Switch back to protected mode if we came from there */
963 if (OldMode
!= BlRealMode
)
965 BlpArchSwitchContext(OldMode
);
968 /* Convert the error to an NTSTATUS */
969 return EfiGetNtStatusCode(EfiStatus
);
975 _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress
978 BL_ARCH_MODE OldMode
;
979 EFI_STATUS EfiStatus
;
981 /* Are we in protected mode? */
982 OldMode
= CurrentExecutionContext
->Mode
;
983 if (OldMode
!= BlRealMode
)
985 /* Switch to real mode */
986 BlpArchSwitchContext(BlRealMode
);
989 /* Make the EFI call */
990 EfiStatus
= EfiBS
->FreePages(PhysicalAddress
, Pages
);
992 /* Switch back to protected mode if we came from there */
993 if (OldMode
!= BlRealMode
)
995 BlpArchSwitchContext(OldMode
);
998 /* Convert the error to an NTSTATUS */
999 return EfiGetNtStatusCode(EfiStatus
);
1004 _In_ ULONG StallTime
1007 BL_ARCH_MODE OldMode
;
1008 EFI_STATUS EfiStatus
;
1010 /* Are we in protected mode? */
1011 OldMode
= CurrentExecutionContext
->Mode
;
1012 if (OldMode
!= BlRealMode
)
1014 /* Switch to real mode */
1015 BlpArchSwitchContext(BlRealMode
);
1018 /* Make the EFI call */
1019 EfiStatus
= EfiBS
->Stall(StallTime
);
1021 /* Switch back to protected mode if we came from there */
1022 if (OldMode
!= BlRealMode
)
1024 BlpArchSwitchContext(OldMode
);
1027 /* Convert the error to an NTSTATUS */
1028 return EfiGetNtStatusCode(EfiStatus
);
1032 EfiConOutQueryMode (
1033 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
1035 _In_ UINTN
* Columns
,
1039 BL_ARCH_MODE OldMode
;
1040 EFI_STATUS EfiStatus
;
1042 /* Are we in protected mode? */
1043 OldMode
= CurrentExecutionContext
->Mode
;
1044 if (OldMode
!= BlRealMode
)
1046 /* FIXME: Not yet implemented */
1047 EfiPrintf(L
"conqmode vm path\r\n");
1049 return STATUS_NOT_IMPLEMENTED
;
1052 /* Make the EFI call */
1053 EfiStatus
= TextInterface
->QueryMode(TextInterface
, Mode
, Columns
, Rows
);
1055 /* Switch back to protected mode if we came from there */
1056 if (OldMode
!= BlRealMode
)
1058 BlpArchSwitchContext(OldMode
);
1061 /* Convert the error to an NTSTATUS */
1062 return EfiGetNtStatusCode(EfiStatus
);
1067 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
1071 BL_ARCH_MODE OldMode
;
1072 EFI_STATUS EfiStatus
;
1074 /* Are we in protected mode? */
1075 OldMode
= CurrentExecutionContext
->Mode
;
1076 if (OldMode
!= BlRealMode
)
1078 /* FIXME: Not yet implemented */
1079 EfiPrintf(L
"setmode vm path\r\n");
1081 return STATUS_NOT_IMPLEMENTED
;
1084 /* Make the EFI call */
1085 EfiStatus
= TextInterface
->SetMode(TextInterface
, Mode
);
1087 /* Switch back to protected mode if we came from there */
1088 if (OldMode
!= BlRealMode
)
1090 BlpArchSwitchContext(OldMode
);
1093 /* Convert the error to an NTSTATUS */
1094 return EfiGetNtStatusCode(EfiStatus
);
1098 EfiConOutSetAttribute (
1099 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
1100 _In_ ULONG Attribute
1103 BL_ARCH_MODE OldMode
;
1104 EFI_STATUS EfiStatus
;
1106 /* Are we in protected mode? */
1107 OldMode
= CurrentExecutionContext
->Mode
;
1108 if (OldMode
!= BlRealMode
)
1110 /* FIXME: Not yet implemented */
1111 EfiPrintf(L
"sattr vm path\r\n");
1113 return STATUS_NOT_IMPLEMENTED
;
1116 /* Make the EFI call */
1117 EfiStatus
= TextInterface
->SetAttribute(TextInterface
, Attribute
);
1119 /* Switch back to protected mode if we came from there */
1120 if (OldMode
!= BlRealMode
)
1122 BlpArchSwitchContext(OldMode
);
1125 /* Convert the error to an NTSTATUS */
1126 return EfiGetNtStatusCode(EfiStatus
);
1130 EfiConOutSetCursorPosition (
1131 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
1136 BL_ARCH_MODE OldMode
;
1137 EFI_STATUS EfiStatus
;
1139 /* Are we in protected mode? */
1140 OldMode
= CurrentExecutionContext
->Mode
;
1141 if (OldMode
!= BlRealMode
)
1143 /* FIXME: Not yet implemented */
1144 EfiPrintf(L
"setcursor vm path\r\n");
1146 return STATUS_NOT_IMPLEMENTED
;
1149 /* Make the EFI call */
1150 EfiStatus
= TextInterface
->SetCursorPosition(TextInterface
, Column
, Row
);
1152 /* Switch back to protected mode if we came from there */
1153 if (OldMode
!= BlRealMode
)
1155 BlpArchSwitchContext(OldMode
);
1158 /* Convert the error to an NTSTATUS */
1159 return EfiGetNtStatusCode(EfiStatus
);
1163 EfiConOutEnableCursor (
1164 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
1165 _In_ BOOLEAN Visible
1168 BL_ARCH_MODE OldMode
;
1169 EFI_STATUS EfiStatus
;
1171 /* Are we in protected mode? */
1172 OldMode
= CurrentExecutionContext
->Mode
;
1173 if (OldMode
!= BlRealMode
)
1175 /* FIXME: Not yet implemented */
1176 EfiPrintf(L
"enablecurso vm path\r\n");
1178 return STATUS_NOT_IMPLEMENTED
;
1181 /* Make the EFI call */
1182 EfiStatus
= TextInterface
->EnableCursor(TextInterface
, Visible
);
1184 /* Switch back to protected mode if we came from there */
1185 if (OldMode
!= BlRealMode
)
1187 BlpArchSwitchContext(OldMode
);
1190 /* Convert the error to an NTSTATUS */
1191 return EfiGetNtStatusCode(EfiStatus
);
1195 EfiConOutOutputString (
1196 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
1200 BL_ARCH_MODE OldMode
;
1201 EFI_STATUS EfiStatus
;
1203 /* Are we in protected mode? */
1204 OldMode
= CurrentExecutionContext
->Mode
;
1205 if (OldMode
!= BlRealMode
)
1207 /* FIXME: Not yet implemented */
1208 EfiPrintf(L
"output string vm path\r\n");
1210 return STATUS_NOT_IMPLEMENTED
;
1213 /* Make the EFI call */
1214 EfiStatus
= TextInterface
->OutputString(TextInterface
, String
);
1216 /* Switch back to protected mode if we came from there */
1217 if (OldMode
!= BlRealMode
)
1219 BlpArchSwitchContext(OldMode
);
1222 /* Convert the error to an NTSTATUS */
1223 return EfiGetNtStatusCode(EfiStatus
);
1227 EfiConOutReadCurrentMode (
1228 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
1229 _Out_ EFI_SIMPLE_TEXT_OUTPUT_MODE
* Mode
1232 BL_ARCH_MODE OldMode
;
1234 /* Are we in protected mode? */
1235 OldMode
= CurrentExecutionContext
->Mode
;
1236 if (OldMode
!= BlRealMode
)
1238 /* FIXME: Not yet implemented */
1239 EfiPrintf(L
"readmode vm path\r\n");
1244 /* Make the EFI call */
1245 RtlCopyMemory(Mode
, TextInterface
->Mode
, sizeof(*Mode
));
1247 /* Switch back to protected mode if we came from there */
1248 if (OldMode
!= BlRealMode
)
1250 BlpArchSwitchContext(OldMode
);
1255 EfiGopGetFrameBuffer (
1256 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
1257 _Out_ PHYSICAL_ADDRESS
* FrameBuffer
,
1258 _Out_ UINTN
*FrameBufferSize
1261 BL_ARCH_MODE OldMode
;
1262 PHYSICAL_ADDRESS GopInterfacePhys
, FrameBufferPhys
, FrameBufferSizePhys
;
1264 /* Are we in protected mode? */
1265 OldMode
= CurrentExecutionContext
->Mode
;
1266 if (OldMode
!= BlRealMode
)
1268 /* Translate pointer to physical */
1269 BlMmTranslateVirtualAddress(GopInterface
, &GopInterfacePhys
);
1270 GopInterface
= PhysicalAddressToPtr(GopInterfacePhys
);
1272 /* Translate pointer to physical */
1273 BlMmTranslateVirtualAddress(FrameBuffer
, &FrameBufferPhys
);
1274 FrameBuffer
= PhysicalAddressToPtr(FrameBufferPhys
);
1276 /* Translate pointer to physical */
1277 BlMmTranslateVirtualAddress(FrameBufferSize
, &FrameBufferSizePhys
);
1278 FrameBufferSize
= PhysicalAddressToPtr(FrameBufferSizePhys
);
1280 /* Switch to real mode */
1281 BlpArchSwitchContext(BlRealMode
);
1284 /* Make the EFI call */
1285 FrameBuffer
->QuadPart
= GopInterface
->Mode
->FrameBufferBase
;
1286 *FrameBufferSize
= GopInterface
->Mode
->FrameBufferSize
;
1288 /* Switch back to protected mode if we came from there */
1289 if (OldMode
!= BlRealMode
)
1291 BlpArchSwitchContext(OldMode
);
1296 EfiGopGetCurrentMode (
1297 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
1299 _Out_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Information
1302 BL_ARCH_MODE OldMode
;
1303 PHYSICAL_ADDRESS GopInterfacePhys
, ModePhys
, InformationPhys
;
1305 /* Are we in protected mode? */
1306 OldMode
= CurrentExecutionContext
->Mode
;
1307 if (OldMode
!= BlRealMode
)
1309 /* Translate pointer to physical */
1310 if (!BlMmTranslateVirtualAddress(GopInterface
, &GopInterfacePhys
))
1312 return STATUS_UNSUCCESSFUL
;
1314 GopInterface
= PhysicalAddressToPtr(GopInterfacePhys
);
1316 /* Translate pointer to physical */
1317 if (!BlMmTranslateVirtualAddress(Mode
, &ModePhys
))
1319 return STATUS_UNSUCCESSFUL
;
1321 Mode
= PhysicalAddressToPtr(ModePhys
);
1323 /* Translate pointer to physical */
1324 if (!BlMmTranslateVirtualAddress(Information
, &InformationPhys
))
1326 return STATUS_UNSUCCESSFUL
;
1328 Information
= PhysicalAddressToPtr(InformationPhys
);
1330 /* Switch to real mode */
1331 BlpArchSwitchContext(BlRealMode
);
1334 /* Make the EFI call */
1335 *Mode
= GopInterface
->Mode
->Mode
;
1336 RtlCopyMemory(Information
, GopInterface
->Mode
->Info
, sizeof(*Information
));
1338 /* Switch back to protected mode if we came from there */
1339 if (OldMode
!= BlRealMode
)
1341 BlpArchSwitchContext(OldMode
);
1345 return STATUS_SUCCESS
;
1350 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
1354 BL_ARCH_MODE OldMode
;
1355 EFI_STATUS EfiStatus
;
1356 BOOLEAN ModeChanged
;
1359 /* Are we in protected mode? */
1360 OldMode
= CurrentExecutionContext
->Mode
;
1361 if (OldMode
!= BlRealMode
)
1363 /* FIXME: Not yet implemented */
1364 EfiPrintf(L
"gopsmode vm path\r\n");
1366 return STATUS_NOT_IMPLEMENTED
;
1369 /* Make the EFI call */
1370 if (Mode
== GopInterface
->Mode
->Mode
)
1372 EfiStatus
= EFI_SUCCESS
;
1373 ModeChanged
= FALSE
;
1376 EfiStatus
= GopInterface
->SetMode(GopInterface
, Mode
);
1380 /* Switch back to protected mode if we came from there */
1381 if (OldMode
!= BlRealMode
)
1383 BlpArchSwitchContext(OldMode
);
1386 /* Print out to the debugger if the mode was changed */
1387 Status
= EfiGetNtStatusCode(EfiStatus
);
1388 if ((ModeChanged
) && (NT_SUCCESS(Status
)))
1390 /* FIXME @TODO: Should be BlStatusPrint */
1391 EfiPrintf(L
"Console video mode set to 0x%x\r\n", Mode
);
1394 /* Convert the error to an NTSTATUS */
1399 EfiLocateHandleBuffer (
1400 _In_ EFI_LOCATE_SEARCH_TYPE SearchType
,
1401 _In_ EFI_GUID
*Protocol
,
1402 _Inout_ PULONG HandleCount
,
1403 _Inout_ EFI_HANDLE
** Buffer
1406 BL_ARCH_MODE OldMode
;
1407 EFI_STATUS EfiStatus
;
1410 BOOLEAN TranslateResult
;
1411 PHYSICAL_ADDRESS BufferPhys
;
1413 /* Bail out if we're missing parameters */
1414 if (!(Buffer
) || !(HandleCount
))
1416 return STATUS_INVALID_PARAMETER
;
1419 /* Check if a buffer was passed in*/
1420 InputBuffer
= *Buffer
;
1423 /* Then we should already have a buffer size*/
1424 BufferSize
= sizeof(EFI_HANDLE
) * *HandleCount
;
1428 /* Then no buffer size exists */
1432 /* Are we in protected mode? */
1433 OldMode
= CurrentExecutionContext
->Mode
;
1434 if (OldMode
!= BlRealMode
)
1436 /* Translate the input buffer from virtual to physical */
1437 TranslateResult
= BlMmTranslateVirtualAddress(InputBuffer
, &BufferPhys
);
1438 InputBuffer
= TranslateResult
? PhysicalAddressToPtr(BufferPhys
) : NULL
;
1440 /* Switch to real mode */
1441 BlpArchSwitchContext(BlRealMode
);
1444 /* Try the first time */
1445 EfiStatus
= EfiBS
->LocateHandle(SearchType
,
1451 /* Switch back to protected mode if we came from there */
1452 if (OldMode
!= BlRealMode
)
1454 BlpArchSwitchContext(OldMode
);
1457 /* Check result of first search */
1458 if (EfiStatus
== EFI_BUFFER_TOO_SMALL
)
1460 /* Did we have an existing buffer? */
1464 BlMmFreeHeap(*Buffer
);
1467 /* Allocate a new one */
1468 InputBuffer
= BlMmAllocateHeap(BufferSize
);
1469 *Buffer
= InputBuffer
;
1472 /* No space, fail */
1473 return STATUS_NO_MEMORY
;
1476 if (OldMode
!= BlRealMode
)
1478 /* Translate the input buffer from virtual to physical */
1479 TranslateResult
= BlMmTranslateVirtualAddress(InputBuffer
,
1481 InputBuffer
= TranslateResult
? PhysicalAddressToPtr(BufferPhys
) : NULL
;
1483 /* Switch to real mode */
1484 BlpArchSwitchContext(BlRealMode
);
1488 EfiStatus
= EfiBS
->LocateHandle(SearchType
,
1494 /* Switch back to protected mode if we came from there */
1495 if (OldMode
!= BlRealMode
)
1497 BlpArchSwitchContext(OldMode
);
1501 /* Return the number of handles */
1502 *HandleCount
= BufferSize
/ sizeof(EFI_HANDLE
);
1504 /* Convert the error to an NTSTATUS */
1505 return EfiGetNtStatusCode(EfiStatus
);
1510 _In_ EFI_RESET_TYPE ResetType
1513 BL_ARCH_MODE OldMode
;
1515 /* Are we in protected mode? */
1516 OldMode
= CurrentExecutionContext
->Mode
;
1517 if (OldMode
!= BlRealMode
)
1519 /* FIXME: Not yet implemented */
1520 EfiPrintf(L
"reset vm path\r\n");
1525 /* Call the EFI runtime */
1526 EfiRT
->ResetSystem(ResetType
, EFI_SUCCESS
, 0, NULL
);
1530 EfiConnectController (
1531 _In_ EFI_HANDLE ControllerHandle
1534 BL_ARCH_MODE OldMode
;
1535 EFI_STATUS EfiStatus
;
1537 /* Is this EFI 1.02? */
1538 if (EfiST
->Hdr
.Revision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
1540 /* This function didn't exist back then */
1541 return STATUS_NOT_SUPPORTED
;
1544 /* Are we in protected mode? */
1545 OldMode
= CurrentExecutionContext
->Mode
;
1546 if (OldMode
!= BlRealMode
)
1548 /* FIXME: Not yet implemented */
1549 EfiPrintf(L
"connectctrl vm path\r\n");
1551 return STATUS_NOT_IMPLEMENTED
;
1554 /* Make the EFI call */
1555 EfiStatus
= EfiBS
->ConnectController(ControllerHandle
, NULL
, NULL
, TRUE
);
1557 /* Switch back to protected mode if we came from there */
1558 if (OldMode
!= BlRealMode
)
1560 BlpArchSwitchContext(OldMode
);
1563 /* Convert the error to an NTSTATUS */
1564 return EfiGetNtStatusCode(EfiStatus
);
1571 _Inout_ EFI_PHYSICAL_ADDRESS
* Memory
1574 BL_ARCH_MODE OldMode
;
1575 EFI_STATUS EfiStatus
;
1576 PHYSICAL_ADDRESS MemoryPhysical
;
1578 /* Are we in protected mode? */
1579 OldMode
= CurrentExecutionContext
->Mode
;
1580 if (OldMode
!= BlRealMode
)
1582 /* Translate output address */
1583 BlMmTranslateVirtualAddress(Memory
, &MemoryPhysical
);
1584 Memory
= (EFI_PHYSICAL_ADDRESS
*)PhysicalAddressToPtr(MemoryPhysical
);
1586 /* Switch to real mode */
1587 BlpArchSwitchContext(BlRealMode
);
1590 /* Make the EFI call */
1591 EfiStatus
= EfiBS
->AllocatePages(Type
, EfiLoaderData
, Pages
, Memory
);
1593 /* Switch back to protected mode if we came from there */
1594 if (OldMode
!= BlRealMode
)
1596 BlpArchSwitchContext(OldMode
);
1599 /* Convert the error to an NTSTATUS */
1600 return EfiGetNtStatusCode(EfiStatus
);
1604 EfipGetSystemTable (
1605 _In_ EFI_GUID
*TableGuid
,
1606 _Out_ PPHYSICAL_ADDRESS TableAddress
1612 /* Assume failure */
1613 Status
= STATUS_NOT_FOUND
;
1615 /* Loop through the configuration tables */
1616 for (i
= 0; i
< EfiST
->NumberOfTableEntries
; i
++)
1618 /* Check if this one matches the one we want */
1619 if (RtlEqualMemory(&EfiST
->ConfigurationTable
[i
].VendorGuid
,
1621 sizeof(*TableGuid
)))
1623 /* Return its address */
1624 TableAddress
->QuadPart
= (ULONG_PTR
)EfiST
->ConfigurationTable
[i
].VendorTable
;
1625 Status
= STATUS_SUCCESS
;
1630 /* Return the search result */
1636 _Out_ PPHYSICAL_ADDRESS FoundRsdt
1641 PHYSICAL_ADDRESS RsdpAddress
, Rsdt
;
1644 /* Assume failure */
1648 /* Check if we already know it */
1649 if (EfiRsdt
.QuadPart
)
1652 *FoundRsdt
= EfiRsdt
;
1653 return STATUS_SUCCESS
;
1656 /* Otherwise, look for the ACPI 2.0 RSDP (XSDT really) */
1657 Status
= EfipGetSystemTable(&EfiRootAcpiTableGuid
, &RsdpAddress
);
1658 if (!NT_SUCCESS(Status
))
1660 /* Didn't fint it, look for the ACPI 1.0 RSDP (RSDT really) */
1661 Status
= EfipGetSystemTable(&EfiRootAcpiTable10Guid
, &RsdpAddress
);
1662 if (!NT_SUCCESS(Status
))
1669 Length
= sizeof(*Rsdp
);
1670 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1674 if (NT_SUCCESS(Status
))
1676 /* Check the revision (anything >= 2.0 is XSDT) */
1679 /* Check if the table is bigger than just its header */
1680 if (Rsdp
->Length
> Length
)
1682 /* Capture the real length */
1683 Length
= Rsdp
->Length
;
1685 /* Unmap our header mapping */
1686 BlMmUnmapVirtualAddressEx(Rsdp
, sizeof(*Rsdp
));
1688 /* And map the whole thing now */
1689 Status
= BlMmMapPhysicalAddressEx((PVOID
*)&Rsdp
,
1693 if (!NT_SUCCESS(Status
))
1699 /* Read the XSDT address from the table*/
1700 Rsdt
= Rsdp
->XsdtAddress
;
1704 /* ACPI 1.0 so just read the RSDT */
1705 Rsdt
.QuadPart
= Rsdp
->RsdtAddress
;
1708 /* Save it for later */
1711 /* And return it back */
1715 /* Check if we had mapped the RSDP */
1719 BlMmUnmapVirtualAddressEx(Rsdp
, Length
);
1722 /* Return search result back to caller */
1727 MmFwpGetOsAttributeType (
1728 _In_ ULONGLONG Attribute
1731 BL_MEMORY_ATTR OsAttribute
= 0;
1733 if (Attribute
& EFI_MEMORY_UC
)
1735 OsAttribute
= BlMemoryUncached
;
1738 if (Attribute
& EFI_MEMORY_WC
)
1740 OsAttribute
|= BlMemoryWriteCombined
;
1743 if (Attribute
& EFI_MEMORY_WT
)
1745 OsAttribute
|= BlMemoryWriteThrough
;
1748 if (Attribute
& EFI_MEMORY_WB
)
1750 OsAttribute
|= BlMemoryWriteBack
;
1753 if (Attribute
& EFI_MEMORY_UCE
)
1755 OsAttribute
|= BlMemoryUncachedExported
;
1758 if (Attribute
& EFI_MEMORY_WP
)
1760 OsAttribute
|= BlMemoryWriteProtected
;
1763 if (Attribute
& EFI_MEMORY_RP
)
1765 OsAttribute
|= BlMemoryReadProtected
;
1768 if (Attribute
& EFI_MEMORY_XP
)
1770 OsAttribute
|= BlMemoryExecuteProtected
;
1773 if (Attribute
& EFI_MEMORY_RUNTIME
)
1775 OsAttribute
|= BlMemoryRuntime
;
1782 MmFwpGetOsMemoryType (
1783 _In_ EFI_MEMORY_TYPE MemoryType
1786 BL_MEMORY_TYPE OsType
;
1792 OsType
= BlLoaderMemory
;
1795 case EfiBootServicesCode
:
1796 case EfiBootServicesData
:
1797 OsType
= BlEfiBootMemory
;
1800 case EfiRuntimeServicesCode
:
1801 OsType
= BlEfiRuntimeCodeMemory
;
1804 case EfiRuntimeServicesData
:
1805 OsType
= BlEfiRuntimeDataMemory
;
1808 case EfiConventionalMemory
:
1809 OsType
= BlConventionalMemory
;
1812 case EfiUnusableMemory
:
1813 OsType
= BlUnusableMemory
;
1816 case EfiACPIReclaimMemory
:
1817 OsType
= BlAcpiReclaimMemory
;
1820 case EfiACPIMemoryNVS
:
1821 OsType
= BlAcpiNvsMemory
;
1824 case EfiMemoryMappedIO
:
1825 OsType
= BlDeviceIoMemory
;
1828 case EfiMemoryMappedIOPortSpace
:
1829 OsType
= BlDevicePortMemory
;
1833 OsType
= BlPalMemory
;
1837 OsType
= BlReservedMemory
;
1846 _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap
,
1850 BL_LIBRARY_PARAMETERS LibraryParameters
= BlpLibraryParameters
;
1851 BOOLEAN UseEfiBuffer
, HaveRamDisk
;
1853 ULONGLONG Pages
, StartPage
, EndPage
, EfiBufferPage
;
1854 UINTN EfiMemoryMapSize
, MapKey
, DescriptorSize
, DescriptorVersion
;
1855 EFI_PHYSICAL_ADDRESS EfiBuffer
= 0;
1856 EFI_MEMORY_DESCRIPTOR
* EfiMemoryMap
;
1857 EFI_STATUS EfiStatus
;
1858 BL_ARCH_MODE OldMode
;
1859 EFI_MEMORY_DESCRIPTOR EfiDescriptor
;
1860 BL_MEMORY_TYPE MemoryType
;
1861 PBL_MEMORY_DESCRIPTOR Descriptor
;
1862 BL_MEMORY_ATTR Attribute
;
1863 PVOID LibraryBuffer
;
1865 /* Initialize EFI memory map attributes */
1866 EfiMemoryMapSize
= MapKey
= DescriptorSize
= DescriptorVersion
= 0;
1867 LibraryBuffer
= NULL
;
1869 /* Increment the nesting depth */
1870 MmDescriptorCallTreeCount
++;
1872 /* Determine if we should use EFI or our own allocator at this point */
1873 UseEfiBuffer
= Flags
& BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS
;
1874 if (!(LibraryParameters
.LibraryFlags
& BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
))
1876 UseEfiBuffer
= TRUE
;
1879 /* Bail out if we don't have a list to use */
1880 if (MemoryMap
== NULL
)
1882 Status
= STATUS_INVALID_PARAMETER
;
1886 /* Free the current descriptor list */
1887 MmMdFreeList(MemoryMap
);
1889 /* Call into EFI to get the size of the memory map */
1890 Status
= EfiGetMemoryMap(&EfiMemoryMapSize
,
1894 &DescriptorVersion
);
1895 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
1897 /* This should've failed because our buffer was too small, nothing else */
1898 if (NT_SUCCESS(Status
))
1900 Status
= STATUS_UNSUCCESSFUL
;
1905 /* Add 4 more descriptors just in case things changed */
1906 EfiMemoryMapSize
+= (4 * DescriptorSize
);
1907 Pages
= BYTES_TO_PAGES(EfiMemoryMapSize
);
1909 /* Should we use EFI to grab memory? */
1912 /* Yes -- request one more page to align up correctly */
1915 /* Grab the required pages */
1916 Status
= EfiAllocatePages(AllocateAnyPages
,
1919 if (!NT_SUCCESS(Status
))
1921 EfiPrintf(L
"EFI allocation failed: %lx\r\n", Status
);
1925 /* Free the pages for now */
1926 Status
= EfiFreePages(Pages
, EfiBuffer
);
1927 if (!NT_SUCCESS(Status
))
1933 /* Now round to the actual buffer size, removing the extra page */
1934 EfiBuffer
= ROUND_TO_PAGES(EfiBuffer
);
1936 Status
= EfiAllocatePages(AllocateAddress
,
1939 if (!NT_SUCCESS(Status
))
1945 /* Get the final aligned size and proper buffer */
1946 EfiMemoryMapSize
= EFI_PAGES_TO_SIZE(Pages
);
1947 EfiMemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)(ULONG_PTR
)EfiBuffer
;
1949 /* Switch to real mode if not already in it */
1950 OldMode
= CurrentExecutionContext
->Mode
;
1951 if (OldMode
!= BlRealMode
)
1953 BlpArchSwitchContext(BlRealMode
);
1956 /* Call EFI to get the memory map */
1957 EfiStatus
= EfiBS
->GetMemoryMap(&EfiMemoryMapSize
,
1961 &DescriptorVersion
);
1963 /* Switch back into the previous mode */
1964 if (OldMode
!= BlRealMode
)
1966 BlpArchSwitchContext(OldMode
);
1969 /* Convert the result code */
1970 Status
= EfiGetNtStatusCode(EfiStatus
);
1974 /* Round the map to pages */
1975 Pages
= BYTES_TO_PAGES(EfiMemoryMapSize
);
1977 /* Allocate a large enough buffer */
1978 Status
= MmPapAllocatePagesInRange(&LibraryBuffer
,
1985 if (!NT_SUCCESS(Status
))
1987 EfiPrintf(L
"Failed to allocate mapped VM for EFI map: %lx\r\n", Status
);
1991 /* Call EFI to get the memory map */
1992 EfiMemoryMap
= LibraryBuffer
;
1993 Status
= EfiGetMemoryMap(&EfiMemoryMapSize
,
1997 &DescriptorVersion
);
2000 /* So far so good? */
2001 if (!NT_SUCCESS(Status
))
2003 EfiPrintf(L
"Failed to get EFI memory map: %lx\r\n", Status
);
2007 /* Did we get correct data from firmware? */
2008 if (((EfiMemoryMapSize
% DescriptorSize
)) ||
2009 (DescriptorSize
< sizeof(EFI_MEMORY_DESCRIPTOR
)))
2011 EfiPrintf(L
"Incorrect descriptor size\r\n");
2012 Status
= STATUS_UNSUCCESSFUL
;
2016 /* Did we boot from a RAM disk? */
2017 if ((BlpBootDevice
->DeviceType
== LocalDevice
) &&
2018 (BlpBootDevice
->Local
.Type
== RamDiskDevice
))
2020 /* We don't handle this yet */
2021 EfiPrintf(L
"RAM boot not supported\r\n");
2022 Status
= STATUS_NOT_IMPLEMENTED
;
2027 /* We didn't, so there won't be any need to find the memory descriptor */
2028 HaveRamDisk
= FALSE
;
2031 /* Loop the EFI memory map */
2033 EfiPrintf(L
"UEFI MEMORY MAP\r\n\r\n");
2034 EfiPrintf(L
"TYPE START END ATTRIBUTES\r\n");
2035 EfiPrintf(L
"===============================================================\r\n");
2037 while (EfiMemoryMapSize
!= 0)
2039 /* Check if this is an EFI buffer, but we're not in real mode */
2040 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
2042 BlpArchSwitchContext(BlRealMode
);
2045 /* Capture it so we can go back to protected mode (if possible) */
2046 EfiDescriptor
= *EfiMemoryMap
;
2048 /* Go back to protected mode, if we had switched */
2049 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
2051 BlpArchSwitchContext(OldMode
);
2054 /* Convert to OS memory type */
2055 MemoryType
= MmFwpGetOsMemoryType(EfiDescriptor
.Type
);
2057 /* Round up or round down depending on where the memory is coming from */
2058 if (MemoryType
== BlConventionalMemory
)
2060 StartPage
= BYTES_TO_PAGES(EfiDescriptor
.PhysicalStart
);
2064 StartPage
= EfiDescriptor
.PhysicalStart
>> PAGE_SHIFT
;
2067 /* Calculate the ending page */
2068 EndPage
= StartPage
+ EfiDescriptor
.NumberOfPages
;
2070 /* If after rounding, we ended up with 0 pages, skip this */
2071 if (StartPage
== EndPage
)
2076 EfiPrintf(L
"%08X 0x%016I64X-0x%016I64X 0x%I64X\r\n",
2078 StartPage
<< PAGE_SHIFT
,
2079 EndPage
<< PAGE_SHIFT
,
2080 EfiDescriptor
.Attribute
);
2082 /* Check for any range of memory below 1MB */
2083 if (StartPage
< 0x100)
2085 /* Does this range actually contain NULL? */
2088 /* Manually create a reserved descriptof for this page */
2089 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
2090 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
2097 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2101 /* Add this descriptor into the list */
2102 Status
= MmMdAddDescriptorToList(MemoryMap
,
2104 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
2105 if (!NT_SUCCESS(Status
))
2107 EfiPrintf(L
"Failed to add zero page descriptor: %lx\r\n", Status
);
2111 /* Now handle the rest of the range, unless this was it */
2119 /* Does the range go beyond 1MB? */
2120 if (EndPage
> 0x100)
2122 /* Then create the descriptor for everything up until the megabyte */
2123 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
2124 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
2131 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2135 /* Check if this region is currently free RAM */
2136 if (Descriptor
->Type
== BlConventionalMemory
)
2138 /* Set the appropriate flag on the descriptor */
2139 Descriptor
->Flags
|= BlMemoryBelow1MB
;
2142 /* Add this descriptor into the list */
2143 Status
= MmMdAddDescriptorToList(MemoryMap
,
2145 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
2146 if (!NT_SUCCESS(Status
))
2148 EfiPrintf(L
"Failed to add 1MB descriptor: %lx\r\n", Status
);
2152 /* Now handle the rest of the range above 1MB */
2157 /* Check if we loaded from a RAM disk */
2160 /* We don't handle this yet */
2161 EfiPrintf(L
"RAM boot not supported\r\n");
2162 Status
= STATUS_NOT_IMPLEMENTED
;
2166 /* Create a descriptor for the current range */
2167 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
2168 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
2172 EndPage
- StartPage
);
2175 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2179 /* Check if this region is currently free RAM below 1MB */
2180 if ((Descriptor
->Type
== BlConventionalMemory
) && (EndPage
<= 0x100))
2182 /* Set the appropriate flag on the descriptor */
2183 Descriptor
->Flags
|= BlMemoryBelow1MB
;
2186 /* Add the descriptor to the list, requesting coalescing as asked */
2187 Status
= MmMdAddDescriptorToList(MemoryMap
,
2189 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
|
2190 ((Flags
& BL_MM_FLAG_REQUEST_COALESCING
) ?
2191 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
: 0));
2192 if (!NT_SUCCESS(Status
))
2194 EfiPrintf(L
"Failed to add full descriptor: %lx\r\n", Status
);
2199 /* Consume this descriptor, and move to the next one */
2200 EfiMemoryMapSize
-= DescriptorSize
;
2201 EfiMemoryMap
= (PVOID
)((ULONG_PTR
)EfiMemoryMap
+ DescriptorSize
);
2204 /* Check if we are using the local UEFI buffer */
2210 /* Free the EFI buffer */
2211 Status
= EfiFreePages(Pages
, EfiBuffer
);
2212 if (!NT_SUCCESS(Status
))
2214 /* Keep the pages marked 'in use' and fake success */
2215 Status
= STATUS_SUCCESS
;
2219 /* Get the base page of the EFI buffer */
2220 EfiBufferPage
= EfiBuffer
>> PAGE_SHIFT
;
2221 Pages
= (EfiBufferPage
+ Pages
) - EfiBufferPage
;
2223 /* Don't try freeing below */
2226 /* Find the current descriptor for the allocation */
2227 Descriptor
= MmMdFindDescriptorFromMdl(MemoryMap
,
2228 BL_MM_REMOVE_PHYSICAL_REGION_FLAG
,
2232 Status
= STATUS_UNSUCCESSFUL
;
2236 /* Convert it to a free descriptor */
2237 Descriptor
= MmMdInitByteGranularDescriptor(Descriptor
->Flags
,
2238 BlConventionalMemory
,
2244 Status
= STATUS_INSUFFICIENT_RESOURCES
;
2248 /* Remove the region from the memory map */
2249 Status
= MmMdRemoveRegionFromMdlEx(MemoryMap
,
2250 BL_MM_REMOVE_PHYSICAL_REGION_FLAG
,
2254 if (!NT_SUCCESS(Status
))
2256 MmMdFreeDescriptor(Descriptor
);
2260 /* Add it back as free memory */
2261 Status
= MmMdAddDescriptorToList(MemoryMap
,
2263 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
);
2266 /* Free the EFI buffer, if we had one */
2269 EfiFreePages(Pages
, EfiBuffer
);
2272 /* Free the library-allocated buffer, if we had one */
2273 if (LibraryBuffer
!= 0)
2275 MmPapFreePages(LibraryBuffer
, BL_MM_INCLUDE_MAPPED_ALLOCATED
);
2278 /* On failure, free the memory map if one was passed in */
2279 if (!NT_SUCCESS(Status
) && (MemoryMap
!= NULL
))
2281 MmMdFreeList(MemoryMap
);
2284 /* Decrement the nesting depth and return */
2285 MmDescriptorCallTreeCount
--;
2292 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
2295 NTSTATUS Status
= STATUS_SUCCESS
;
2296 EFI_KEY_TOGGLE_STATE KeyToggleState
;
2298 /* Check if we have valid firmware data */
2299 if (!(FirmwareData
) || !(FirmwareData
->Version
))
2301 return STATUS_INVALID_PARAMETER
;
2304 /* Check which boot phase we're in */
2307 /* Memory manager is ready, open the extended input protocol */
2308 Status
= EfiOpenProtocol(EfiST
->ConsoleInHandle
,
2309 &EfiSimpleTextInputExProtocol
,
2310 (PVOID
*)&EfiConInEx
);
2311 if (NT_SUCCESS(Status
))
2313 /* Set the initial key toggle state */
2314 KeyToggleState
= EFI_TOGGLE_STATE_VALID
| 40;
2315 EfiConInExSetState(EfiConInEx
, &KeyToggleState
);
2318 /* Setup the watchdog timer */
2319 EfiSetWatchdogTimer();
2323 /* Make a copy of the parameters */
2324 EfiFirmwareParameters
= &EfiFirmwareData
;
2326 /* Check which version we received */
2327 if (FirmwareData
->Version
== 1)
2329 /* FIXME: Not supported */
2330 Status
= STATUS_NOT_SUPPORTED
;
2332 else if (FirmwareData
->Version
>= BL_FIRMWARE_DESCRIPTOR_VERSION
)
2334 /* Version 2 -- save the data */
2335 EfiFirmwareData
= *FirmwareData
;
2336 EfiSystemTable
= FirmwareData
->SystemTable
;
2337 EfiImageHandle
= FirmwareData
->ImageHandle
;
2339 /* Set the EDK-II style variables as well */
2340 EfiST
= EfiSystemTable
;
2341 EfiBS
= EfiSystemTable
->BootServices
;
2342 EfiRT
= EfiSystemTable
->RuntimeServices
;
2343 EfiConOut
= EfiSystemTable
->ConOut
;
2344 EfiConIn
= EfiSystemTable
->ConIn
;
2349 /* Unknown version */
2350 Status
= STATUS_NOT_SUPPORTED
;
2354 /* Return the initialization state */
2360 _In_ PBL_FIRMWARE_DESCRIPTOR Parameters
2363 /* Make sure we got an argument */
2366 return STATUS_INVALID_PARAMETER
;
2369 /* Copy the static data */
2370 *Parameters
= *EfiFirmwareParameters
;
2371 return STATUS_SUCCESS
;
2375 BlFwEnumerateDevice (
2376 _In_ PBL_DEVICE_DESCRIPTOR Device
2380 ULONG PathProtocols
, BlockProtocols
;
2381 EFI_HANDLE
* PathArray
;
2382 EFI_HANDLE
* BlockArray
;
2384 /* Initialize locals */
2390 /* Enumeration only makes sense on disks or partitions */
2391 if ((Device
->DeviceType
!= DiskDevice
) &&
2392 (Device
->DeviceType
!= LegacyPartitionDevice
) &&
2393 (Device
->DeviceType
!= PartitionDevice
))
2395 return STATUS_NOT_SUPPORTED
;
2398 /* Enumerate the list of device paths */
2399 Status
= EfiLocateHandleBuffer(ByProtocol
,
2400 &EfiDevicePathProtocol
,
2403 if (NT_SUCCESS(Status
))
2405 /* Loop through each one */
2406 Status
= STATUS_NOT_FOUND
;
2407 while (PathProtocols
)
2409 /* Attempt to connect the driver for this device epath */
2410 Status
= EfiConnectController(PathArray
[--PathProtocols
]);
2411 if (NT_SUCCESS(Status
))
2413 /* Now enumerate any block I/O devices the driver added */
2414 Status
= EfiLocateHandleBuffer(ByProtocol
,
2415 &EfiBlockIoProtocol
,
2418 if (!NT_SUCCESS(Status
))
2423 /* Loop through each one */
2424 while (BlockProtocols
)
2426 /* Check if one of the new devices is the one we want */
2427 Status
= BlockIoEfiCompareDevice(Device
,
2428 BlockArray
[--BlockProtocols
]);
2429 if (NT_SUCCESS(Status
))
2436 /* Move on to the next device path */
2437 BlMmFreeHeap(BlockArray
);
2444 /* We're done -- free the array of device path protocols, if any */
2447 BlMmFreeHeap(PathArray
);
2450 /* We're done -- free the array of block I/O protocols, if any */
2453 BlMmFreeHeap(BlockArray
);
2456 /* Return if we found the device or not */
2461 * @name EfiGetEfiStatusCode
2463 * The EfiGetEfiStatusCode routine converts an NT Status to an EFI status.
2466 * NT Status code to be converted.
2468 * @remark Only certain, specific NT status codes are converted to EFI codes.
2470 * @return The corresponding EFI Status code, EFI_NO_MAPPING otherwise.
2474 EfiGetEfiStatusCode(
2475 _In_ NTSTATUS Status
2480 case STATUS_NOT_SUPPORTED
:
2481 return EFI_UNSUPPORTED
;
2482 case STATUS_DISK_FULL
:
2483 return EFI_VOLUME_FULL
;
2484 case STATUS_INSUFFICIENT_RESOURCES
:
2485 return EFI_OUT_OF_RESOURCES
;
2486 case STATUS_MEDIA_WRITE_PROTECTED
:
2487 return EFI_WRITE_PROTECTED
;
2488 case STATUS_DEVICE_NOT_READY
:
2489 return EFI_NOT_STARTED
;
2490 case STATUS_DEVICE_ALREADY_ATTACHED
:
2491 return EFI_ALREADY_STARTED
;
2492 case STATUS_MEDIA_CHANGED
:
2493 return EFI_MEDIA_CHANGED
;
2494 case STATUS_INVALID_PARAMETER
:
2495 return EFI_INVALID_PARAMETER
;
2496 case STATUS_ACCESS_DENIED
:
2497 return EFI_ACCESS_DENIED
;
2498 case STATUS_BUFFER_TOO_SMALL
:
2499 return EFI_BUFFER_TOO_SMALL
;
2500 case STATUS_DISK_CORRUPT_ERROR
:
2501 return EFI_VOLUME_CORRUPTED
;
2502 case STATUS_REQUEST_ABORTED
:
2504 case STATUS_NO_MEDIA
:
2505 return EFI_NO_MEDIA
;
2506 case STATUS_IO_DEVICE_ERROR
:
2507 return EFI_DEVICE_ERROR
;
2508 case STATUS_INVALID_BUFFER_SIZE
:
2509 return EFI_BAD_BUFFER_SIZE
;
2510 case STATUS_NOT_FOUND
:
2511 return EFI_NOT_FOUND
;
2512 case STATUS_DRIVER_UNABLE_TO_LOAD
:
2513 return EFI_LOAD_ERROR
;
2514 case STATUS_NO_MATCH
:
2515 return EFI_NO_MAPPING
;
2516 case STATUS_SUCCESS
:
2518 case STATUS_TIMEOUT
:
2521 return EFI_NO_MAPPING
;
2526 * @name EfiGetNtStatusCode
2528 * The EfiGetNtStatusCode routine converts an EFI Status to an NT status.
2531 * EFI Status code to be converted.
2533 * @remark Only certain, specific EFI status codes are converted to NT codes.
2535 * @return The corresponding NT Status code, STATUS_UNSUCCESSFUL otherwise.
2539 EfiGetNtStatusCode (
2540 _In_ EFI_STATUS EfiStatus
2547 return STATUS_NOT_FOUND
;
2549 return STATUS_NO_MEDIA
;
2550 case EFI_MEDIA_CHANGED
:
2551 return STATUS_MEDIA_CHANGED
;
2552 case EFI_ACCESS_DENIED
:
2553 case EFI_SECURITY_VIOLATION
:
2554 return STATUS_ACCESS_DENIED
;
2556 case EFI_NO_RESPONSE
:
2557 return STATUS_TIMEOUT
;
2558 case EFI_NO_MAPPING
:
2559 return STATUS_NO_MATCH
;
2560 case EFI_NOT_STARTED
:
2561 return STATUS_DEVICE_NOT_READY
;
2562 case EFI_ALREADY_STARTED
:
2563 return STATUS_DEVICE_ALREADY_ATTACHED
;
2565 return STATUS_REQUEST_ABORTED
;
2566 case EFI_VOLUME_FULL
:
2567 return STATUS_DISK_FULL
;
2568 case EFI_DEVICE_ERROR
:
2569 return STATUS_IO_DEVICE_ERROR
;
2570 case EFI_WRITE_PROTECTED
:
2571 return STATUS_MEDIA_WRITE_PROTECTED
;
2572 /* @FIXME: ReactOS Headers don't yet have this */
2573 //case EFI_OUT_OF_RESOURCES:
2574 //return STATUS_INSUFFICIENT_NVRAM_RESOURCES;
2575 case EFI_VOLUME_CORRUPTED
:
2576 return STATUS_DISK_CORRUPT_ERROR
;
2577 case EFI_BUFFER_TOO_SMALL
:
2578 return STATUS_BUFFER_TOO_SMALL
;
2580 return STATUS_SUCCESS
;
2581 case EFI_LOAD_ERROR
:
2582 return STATUS_DRIVER_UNABLE_TO_LOAD
;
2583 case EFI_INVALID_PARAMETER
:
2584 return STATUS_INVALID_PARAMETER
;
2585 case EFI_UNSUPPORTED
:
2586 return STATUS_NOT_SUPPORTED
;
2587 case EFI_BAD_BUFFER_SIZE
:
2588 return STATUS_INVALID_BUFFER_SIZE
;
2590 return STATUS_UNSUCCESSFUL
;