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
;
27 EFI_GUID EfiGraphicsOutputProtocol
= EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
;
28 EFI_GUID EfiUgaDrawProtocol
= EFI_UGA_DRAW_PROTOCOL_GUID
;
29 EFI_GUID EfiLoadedImageProtocol
= EFI_LOADED_IMAGE_PROTOCOL_GUID
;
30 EFI_GUID EfiDevicePathProtocol
= EFI_DEVICE_PATH_PROTOCOL_GUID
;
31 EFI_GUID EfiSimpleTextInputExProtocol
= EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID
;
33 /* FUNCTIONS *****************************************************************/
37 _In_ EFI_HANDLE Handle
,
38 _In_ EFI_GUID
*Protocol
,
39 _Out_ PVOID
* Interface
46 /* Are we using virtual memory/ */
47 if (MmTranslationType
!= BlNone
)
49 /* We need complex tracking to make this work */
50 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
51 Status
= STATUS_NOT_SUPPORTED
;
55 /* Are we in protected mode? */
56 OldMode
= CurrentExecutionContext
->Mode
;
57 if (OldMode
!= BlRealMode
)
59 /* FIXME: Not yet implemented */
60 return STATUS_NOT_IMPLEMENTED
;
63 /* Are we on legacy 1.02? */
64 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
66 /* Make the legacy call */
67 EfiStatus
= EfiBS
->HandleProtocol(Handle
, Protocol
, Interface
);
71 /* Use the UEFI version */
72 EfiStatus
= EfiBS
->OpenProtocol(Handle
,
77 EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
79 /* Switch back to protected mode if we came from there */
80 if (OldMode
!= BlRealMode
)
82 BlpArchSwitchContext(OldMode
);
86 /* Convert the error to an NTSTATUS */
87 Status
= EfiGetNtStatusCode(EfiStatus
);
90 /* Clear the interface on failure, and return the status */
91 if (!NT_SUCCESS(Status
))
101 _In_ EFI_HANDLE Handle
,
102 _In_ EFI_GUID
*Protocol
105 EFI_STATUS EfiStatus
;
107 BL_ARCH_MODE OldMode
;
109 /* Are we using virtual memory/ */
110 if (MmTranslationType
!= BlNone
)
112 /* We need complex tracking to make this work */
113 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
114 Status
= STATUS_NOT_SUPPORTED
;
118 /* Are we on legacy 1.02? */
119 if (EfiST
->FirmwareRevision
== EFI_1_02_SYSTEM_TABLE_REVISION
)
121 /* Nothing to close */
122 EfiStatus
= STATUS_SUCCESS
;
126 /* Are we in protected mode? */
127 OldMode
= CurrentExecutionContext
->Mode
;
128 if (OldMode
!= BlRealMode
)
130 /* FIXME: Not yet implemented */
131 return STATUS_NOT_IMPLEMENTED
;
134 /* Use the UEFI version */
135 EfiStatus
= EfiBS
->CloseProtocol(Handle
, Protocol
, EfiImageHandle
, NULL
);
137 /* Switch back to protected mode if we came from there */
138 if (OldMode
!= BlRealMode
)
140 BlpArchSwitchContext(OldMode
);
143 /* Normalize not found as success */
144 if (EfiStatus
== EFI_NOT_FOUND
)
146 EfiStatus
= EFI_SUCCESS
;
150 /* Convert the error to an NTSTATUS */
151 Status
= EfiGetNtStatusCode(EfiStatus
);
160 _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
*ConInEx
,
161 _In_ EFI_KEY_TOGGLE_STATE
* KeyToggleState
164 BL_ARCH_MODE OldMode
;
165 EFI_STATUS EfiStatus
;
167 /* Are we in protected mode? */
168 OldMode
= CurrentExecutionContext
->Mode
;
169 if (OldMode
!= BlRealMode
)
171 /* FIXME: Not yet implemented */
172 return STATUS_NOT_IMPLEMENTED
;
175 /* Make the EFI call */
176 EfiStatus
= ConInEx
->SetState(ConInEx
, KeyToggleState
);
178 /* Switch back to protected mode if we came from there */
179 if (OldMode
!= BlRealMode
)
181 BlpArchSwitchContext(OldMode
);
184 /* Convert the error to an NTSTATUS */
185 return EfiGetNtStatusCode(EfiStatus
);
189 EfiSetWatchdogTimer (
193 BL_ARCH_MODE OldMode
;
194 EFI_STATUS EfiStatus
;
196 /* Are we in protected mode? */
197 OldMode
= CurrentExecutionContext
->Mode
;
198 if (OldMode
!= BlRealMode
)
200 /* FIXME: Not yet implemented */
201 return STATUS_NOT_IMPLEMENTED
;
204 /* Make the EFI call */
205 EfiStatus
= EfiBS
->SetWatchdogTimer(0, 0, 0, NULL
);
207 /* Switch back to protected mode if we came from there */
208 if (OldMode
!= BlRealMode
)
210 BlpArchSwitchContext(OldMode
);
213 /* Convert the error to an NTSTATUS */
214 return EfiGetNtStatusCode(EfiStatus
);
219 _Out_ UINTN
* MemoryMapSize
,
220 _Inout_ EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
222 _Out_ UINTN
* DescriptorSize
,
223 _Out_ UINTN
* DescriptorVersion
226 BL_ARCH_MODE OldMode
;
227 EFI_STATUS EfiStatus
;
229 /* Are we in protected mode? */
230 OldMode
= CurrentExecutionContext
->Mode
;
231 if (OldMode
!= BlRealMode
)
233 /* FIXME: Not yet implemented */
234 return STATUS_NOT_IMPLEMENTED
;
237 /* Make the EFI call */
238 EfiStatus
= EfiBS
->GetMemoryMap(MemoryMapSize
,
244 /* Switch back to protected mode if we came from there */
245 if (OldMode
!= BlRealMode
)
247 BlpArchSwitchContext(OldMode
);
250 /* Convert the error to an NTSTATUS */
251 return EfiGetNtStatusCode(EfiStatus
);
257 _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress
260 BL_ARCH_MODE OldMode
;
261 EFI_STATUS EfiStatus
;
263 /* Are we in protected mode? */
264 OldMode
= CurrentExecutionContext
->Mode
;
265 if (OldMode
!= BlRealMode
)
267 /* FIXME: Not yet implemented */
268 return STATUS_NOT_IMPLEMENTED
;
271 /* Make the EFI call */
272 EfiStatus
= EfiBS
->FreePages(PhysicalAddress
, Pages
);
274 /* Switch back to protected mode if we came from there */
275 if (OldMode
!= BlRealMode
)
277 BlpArchSwitchContext(OldMode
);
280 /* Convert the error to an NTSTATUS */
281 return EfiGetNtStatusCode(EfiStatus
);
289 BL_ARCH_MODE OldMode
;
290 EFI_STATUS EfiStatus
;
292 /* Are we in protected mode? */
293 OldMode
= CurrentExecutionContext
->Mode
;
294 if (OldMode
!= BlRealMode
)
296 /* FIXME: Not yet implemented */
297 return STATUS_NOT_IMPLEMENTED
;
300 /* Make the EFI call */
301 EfiStatus
= EfiBS
->Stall(StallTime
);
303 /* Switch back to protected mode if we came from there */
304 if (OldMode
!= BlRealMode
)
306 BlpArchSwitchContext(OldMode
);
309 /* Convert the error to an NTSTATUS */
310 return EfiGetNtStatusCode(EfiStatus
);
315 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
321 BL_ARCH_MODE OldMode
;
322 EFI_STATUS EfiStatus
;
324 /* Are we in protected mode? */
325 OldMode
= CurrentExecutionContext
->Mode
;
326 if (OldMode
!= BlRealMode
)
328 /* FIXME: Not yet implemented */
329 return STATUS_NOT_IMPLEMENTED
;
332 /* Make the EFI call */
333 EfiStatus
= TextInterface
->QueryMode(TextInterface
, Mode
, Columns
, Rows
);
335 /* Switch back to protected mode if we came from there */
336 if (OldMode
!= BlRealMode
)
338 BlpArchSwitchContext(OldMode
);
341 /* Convert the error to an NTSTATUS */
342 return EfiGetNtStatusCode(EfiStatus
);
347 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
351 BL_ARCH_MODE OldMode
;
352 EFI_STATUS EfiStatus
;
354 /* Are we in protected mode? */
355 OldMode
= CurrentExecutionContext
->Mode
;
356 if (OldMode
!= BlRealMode
)
358 /* FIXME: Not yet implemented */
359 return STATUS_NOT_IMPLEMENTED
;
362 /* Make the EFI call */
363 EfiStatus
= TextInterface
->SetMode(TextInterface
, Mode
);
365 /* Switch back to protected mode if we came from there */
366 if (OldMode
!= BlRealMode
)
368 BlpArchSwitchContext(OldMode
);
371 /* Convert the error to an NTSTATUS */
372 return EfiGetNtStatusCode(EfiStatus
);
376 EfiConOutSetAttribute (
377 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
381 BL_ARCH_MODE OldMode
;
382 EFI_STATUS EfiStatus
;
384 /* Are we in protected mode? */
385 OldMode
= CurrentExecutionContext
->Mode
;
386 if (OldMode
!= BlRealMode
)
388 /* FIXME: Not yet implemented */
389 return STATUS_NOT_IMPLEMENTED
;
392 /* Make the EFI call */
393 EfiStatus
= TextInterface
->SetAttribute(TextInterface
, Attribute
);
395 /* Switch back to protected mode if we came from there */
396 if (OldMode
!= BlRealMode
)
398 BlpArchSwitchContext(OldMode
);
401 /* Convert the error to an NTSTATUS */
402 return EfiGetNtStatusCode(EfiStatus
);
406 EfiConOutSetCursorPosition (
407 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
412 BL_ARCH_MODE OldMode
;
413 EFI_STATUS EfiStatus
;
415 /* Are we in protected mode? */
416 OldMode
= CurrentExecutionContext
->Mode
;
417 if (OldMode
!= BlRealMode
)
419 /* FIXME: Not yet implemented */
420 return STATUS_NOT_IMPLEMENTED
;
423 /* Make the EFI call */
424 EfiStatus
= TextInterface
->SetCursorPosition(TextInterface
, Column
, Row
);
426 /* Switch back to protected mode if we came from there */
427 if (OldMode
!= BlRealMode
)
429 BlpArchSwitchContext(OldMode
);
432 /* Convert the error to an NTSTATUS */
433 return EfiGetNtStatusCode(EfiStatus
);
437 EfiConOutEnableCursor (
438 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
442 BL_ARCH_MODE OldMode
;
443 EFI_STATUS EfiStatus
;
445 /* Are we in protected mode? */
446 OldMode
= CurrentExecutionContext
->Mode
;
447 if (OldMode
!= BlRealMode
)
449 /* FIXME: Not yet implemented */
450 return STATUS_NOT_IMPLEMENTED
;
453 /* Make the EFI call */
454 EfiStatus
= TextInterface
->EnableCursor(TextInterface
, Visible
);
456 /* Switch back to protected mode if we came from there */
457 if (OldMode
!= BlRealMode
)
459 BlpArchSwitchContext(OldMode
);
462 /* Convert the error to an NTSTATUS */
463 return EfiGetNtStatusCode(EfiStatus
);
467 EfiConOutReadCurrentMode (
468 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE
*TextInterface
,
469 _Out_ EFI_SIMPLE_TEXT_OUTPUT_MODE
* Mode
472 BL_ARCH_MODE OldMode
;
474 /* Are we in protected mode? */
475 OldMode
= CurrentExecutionContext
->Mode
;
476 if (OldMode
!= BlRealMode
)
478 /* FIXME: Not yet implemented */
482 /* Make the EFI call */
483 RtlCopyMemory(Mode
, TextInterface
->Mode
, sizeof(*Mode
));
485 /* Switch back to protected mode if we came from there */
486 if (OldMode
!= BlRealMode
)
488 BlpArchSwitchContext(OldMode
);
493 EfiGopGetFrameBuffer (
494 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
495 _Out_ PHYSICAL_ADDRESS
* FrameBuffer
,
496 _Out_ UINTN
*FrameBufferSize
499 BL_ARCH_MODE OldMode
;
501 /* Are we in protected mode? */
502 OldMode
= CurrentExecutionContext
->Mode
;
503 if (OldMode
!= BlRealMode
)
505 /* FIXME: Not yet implemented */
509 /* Make the EFI call */
510 FrameBuffer
->QuadPart
= GopInterface
->Mode
->FrameBufferBase
;
511 *FrameBufferSize
= GopInterface
->Mode
->FrameBufferSize
;
513 /* Switch back to protected mode if we came from there */
514 if (OldMode
!= BlRealMode
)
516 BlpArchSwitchContext(OldMode
);
521 EfiGopGetCurrentMode (
522 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
524 _Out_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Information
527 BL_ARCH_MODE OldMode
;
529 /* Are we in protected mode? */
530 OldMode
= CurrentExecutionContext
->Mode
;
531 if (OldMode
!= BlRealMode
)
533 /* FIXME: Not yet implemented */
534 return STATUS_NOT_IMPLEMENTED
;
537 /* Make the EFI call */
538 *Mode
= GopInterface
->Mode
->Mode
;
539 RtlCopyMemory(Information
, GopInterface
->Mode
->Info
, sizeof(*Information
));
541 /* Switch back to protected mode if we came from there */
542 if (OldMode
!= BlRealMode
)
544 BlpArchSwitchContext(OldMode
);
548 return STATUS_SUCCESS
;
553 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL
*GopInterface
,
557 BL_ARCH_MODE OldMode
;
558 EFI_STATUS EfiStatus
;
562 /* Are we in protected mode? */
563 OldMode
= CurrentExecutionContext
->Mode
;
564 if (OldMode
!= BlRealMode
)
566 /* FIXME: Not yet implemented */
567 return STATUS_NOT_IMPLEMENTED
;
570 /* Make the EFI call */
571 if (Mode
== GopInterface
->Mode
->Mode
)
573 EfiStatus
= EFI_SUCCESS
;
577 EfiStatus
= GopInterface
->SetMode(GopInterface
, Mode
);
581 /* Switch back to protected mode if we came from there */
582 if (OldMode
!= BlRealMode
)
584 BlpArchSwitchContext(OldMode
);
587 /* Print out to the debugger if the mode was changed */
588 Status
= EfiGetNtStatusCode(EfiStatus
);
589 if ((ModeChanged
) && (NT_SUCCESS(Status
)))
591 /* FIXME @TODO: Should be BlStatusPrint */
592 EarlyPrint(L
"Console video mode set to 0x%x\r\n", Mode
);
595 /* Convert the error to an NTSTATUS */
600 EfiLocateHandleBuffer (
601 _In_ EFI_LOCATE_SEARCH_TYPE SearchType
,
602 _In_ EFI_GUID
*Protocol
,
603 _Inout_ PULONG HandleCount
,
604 _Inout_ EFI_HANDLE
** Buffer
607 BL_ARCH_MODE OldMode
;
608 EFI_STATUS EfiStatus
;
611 /* Bail out if we're missing parameters */
612 if (!(Buffer
) || !(HandleCount
))
614 return STATUS_INVALID_PARAMETER
;
617 /* Check if a buffer was passed in*/
620 /* Then we should already have a buffer size*/
621 BufferSize
= sizeof(EFI_HANDLE
) * *HandleCount
;
625 /* Then no buffer size exists */
629 /* Are we in protected mode? */
630 OldMode
= CurrentExecutionContext
->Mode
;
631 if (OldMode
!= BlRealMode
)
633 /* FIXME: Not yet implemented */
634 return STATUS_NOT_IMPLEMENTED
;
637 /* Try the first time */
638 EfiStatus
= EfiBS
->LocateHandle(SearchType
, Protocol
, NULL
, &BufferSize
, *Buffer
);
639 if (EfiStatus
== EFI_BUFFER_TOO_SMALL
)
641 /* Did we have an existing buffer? */
645 BlMmFreeHeap(*Buffer
);
648 /* Allocate a new one */
649 *Buffer
= BlMmAllocateHeap(BufferSize
);
653 return STATUS_NO_MEMORY
;
657 EfiStatus
= EfiBS
->LocateHandle(SearchType
, Protocol
, NULL
, &BufferSize
, *Buffer
);
659 /* Switch back to protected mode if we came from there */
660 if (OldMode
!= BlRealMode
)
662 BlpArchSwitchContext(OldMode
);
666 /* Return the number of handles */
667 *HandleCount
= BufferSize
/ sizeof(EFI_HANDLE
);
669 /* Convert the error to an NTSTATUS */
670 return EfiGetNtStatusCode(EfiStatus
);
677 _Inout_ EFI_PHYSICAL_ADDRESS
* Memory
680 BL_ARCH_MODE OldMode
;
681 EFI_STATUS EfiStatus
;
683 /* Are we in protected mode? */
684 OldMode
= CurrentExecutionContext
->Mode
;
685 if (OldMode
!= BlRealMode
)
687 /* FIXME: Not yet implemented */
688 return STATUS_NOT_IMPLEMENTED
;
691 /* Make the EFI call */
692 EfiStatus
= EfiBS
->AllocatePages(Type
, EfiLoaderData
, Pages
, Memory
);
694 /* Switch back to protected mode if we came from there */
695 if (OldMode
!= BlRealMode
)
697 BlpArchSwitchContext(OldMode
);
700 /* Convert the error to an NTSTATUS */
701 return EfiGetNtStatusCode(EfiStatus
);
705 MmFwpGetOsAttributeType (
706 _In_ ULONGLONG Attribute
709 BL_MEMORY_ATTR OsAttribute
= 0;
711 if (Attribute
& EFI_MEMORY_UC
)
713 OsAttribute
= BlMemoryUncached
;
716 if (Attribute
& EFI_MEMORY_WC
)
718 OsAttribute
|= BlMemoryWriteCombined
;
721 if (Attribute
& EFI_MEMORY_WT
)
723 OsAttribute
|= BlMemoryWriteThrough
;
726 if (Attribute
& EFI_MEMORY_WB
)
728 OsAttribute
|= BlMemoryWriteBack
;
731 if (Attribute
& EFI_MEMORY_UCE
)
733 OsAttribute
|= BlMemoryUncachedExported
;
736 if (Attribute
& EFI_MEMORY_WP
)
738 OsAttribute
|= BlMemoryWriteProtected
;
741 if (Attribute
& EFI_MEMORY_RP
)
743 OsAttribute
|= BlMemoryReadProtected
;
746 if (Attribute
& EFI_MEMORY_XP
)
748 OsAttribute
|= BlMemoryExecuteProtected
;
751 if (Attribute
& EFI_MEMORY_RUNTIME
)
753 OsAttribute
|= BlMemoryRuntime
;
760 MmFwpGetOsMemoryType (
761 _In_ EFI_MEMORY_TYPE MemoryType
764 BL_MEMORY_TYPE OsType
;
770 OsType
= BlLoaderMemory
;
773 case EfiBootServicesCode
:
774 case EfiBootServicesData
:
775 OsType
= BlEfiBootMemory
;
778 case EfiRuntimeServicesCode
:
779 case EfiRuntimeServicesData
:
780 OsType
= BlEfiRuntimeMemory
;
783 case EfiConventionalMemory
:
784 OsType
= BlConventionalMemory
;
787 case EfiUnusableMemory
:
788 OsType
= BlUnusableMemory
;
791 case EfiACPIReclaimMemory
:
792 OsType
= BlAcpiReclaimMemory
;
795 case EfiACPIMemoryNVS
:
796 OsType
= BlAcpiNvsMemory
;
799 case EfiMemoryMappedIO
:
800 OsType
= BlDeviceIoMemory
;
803 case EfiMemoryMappedIOPortSpace
:
804 OsType
= BlDevicePortMemory
;
808 OsType
= BlPalMemory
;
812 OsType
= BlReservedMemory
;
821 _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap
,
825 BL_LIBRARY_PARAMETERS LibraryParameters
= BlpLibraryParameters
;
826 BOOLEAN UseEfiBuffer
, HaveRamDisk
;
828 ULONGLONG Pages
, StartPage
, EndPage
;
829 UINTN EfiMemoryMapSize
, MapKey
, DescriptorSize
, DescriptorVersion
;
830 EFI_PHYSICAL_ADDRESS EfiBuffer
;
831 EFI_MEMORY_DESCRIPTOR
* EfiMemoryMap
;
832 EFI_STATUS EfiStatus
;
833 BL_ARCH_MODE OldMode
;
834 EFI_MEMORY_DESCRIPTOR EfiDescriptor
;
835 BL_MEMORY_TYPE MemoryType
;
836 PBL_MEMORY_DESCRIPTOR Descriptor
;
837 BL_MEMORY_ATTR Attribute
;
839 /* Initialize EFI memory map attributes */
840 EfiMemoryMapSize
= MapKey
= DescriptorSize
= DescriptorVersion
= 0;
842 /* Increment the nesting depth */
843 MmDescriptorCallTreeCount
++;
845 /* Determine if we should use EFI or our own allocator at this point */
846 UseEfiBuffer
= Flags
& BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS
;
847 if (!(LibraryParameters
.LibraryFlags
& BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED
))
852 /* Bail out if we don't have a list to use */
853 if (MemoryMap
== NULL
)
855 Status
= STATUS_INVALID_PARAMETER
;
859 /* Free the current descriptor list */
860 MmMdFreeList(MemoryMap
);
862 /* Call into EFI to get the size of the memory map */
863 Status
= EfiGetMemoryMap(&EfiMemoryMapSize
,
868 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
870 /* This should've failed because our buffer was too small, nothing else */
871 EarlyPrint(L
"Got strange EFI status for memory map: %lx\n", Status
);
872 if (NT_SUCCESS(Status
))
874 Status
= STATUS_UNSUCCESSFUL
;
879 /* Add 4 more descriptors just in case things changed */
880 EfiMemoryMapSize
+= (4 * DescriptorSize
);
881 Pages
= BYTES_TO_PAGES(EfiMemoryMapSize
);
882 EarlyPrint(L
"Memory map size: %lx bytes, %d pages\n", EfiMemoryMapSize
, Pages
);
884 /* Should we use EFI to grab memory? */
887 /* Yes -- request one more page to align up correctly */
890 /* Grab the required pages */
891 Status
= EfiAllocatePages(AllocateAnyPages
,
894 if (!NT_SUCCESS(Status
))
896 EarlyPrint(L
"EFI allocation failed: %lx\n", Status
);
900 /* Free the pages for now */
901 Status
= EfiFreePages(Pages
, EfiBuffer
);
902 if (!NT_SUCCESS(Status
))
908 /* Now round to the actual buffer size, removing the extra page */
909 EfiBuffer
= ROUND_TO_PAGES(EfiBuffer
);
911 Status
= EfiAllocatePages(AllocateAddress
,
914 if (!NT_SUCCESS(Status
))
920 /* Get the final aligned size and proper buffer */
921 EfiMemoryMapSize
= EFI_PAGES_TO_SIZE(Pages
);
922 EfiMemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)(ULONG_PTR
)EfiBuffer
;
924 /* Switch to real mode if not already in it */
925 OldMode
= CurrentExecutionContext
->Mode
;
926 if (OldMode
!= BlRealMode
)
928 BlpArchSwitchContext(BlRealMode
);
931 /* Call EFI to get the memory map */
932 EfiStatus
= EfiBS
->GetMemoryMap(&EfiMemoryMapSize
,
938 /* Switch back into the previous mode */
939 if (OldMode
!= BlRealMode
)
941 BlpArchSwitchContext(OldMode
);
944 /* Convert the result code */
945 Status
= EfiGetNtStatusCode(EfiStatus
);
949 /* We don't support this path yet */
950 Status
= STATUS_NOT_IMPLEMENTED
;
953 /* So far so good? */
954 if (!NT_SUCCESS(Status
))
956 EarlyPrint(L
"Failed to get EFI memory map: %lx\n", Status
);
960 /* Did we get correct data from firmware? */
961 if (((EfiMemoryMapSize
% DescriptorSize
)) ||
962 (DescriptorSize
< sizeof(EFI_MEMORY_DESCRIPTOR
)))
964 EarlyPrint(L
"Incorrect descriptor size\n");
965 Status
= STATUS_UNSUCCESSFUL
;
969 /* Did we boot from a RAM disk? */
970 if ((BlpBootDevice
->DeviceType
== LocalDevice
) &&
971 (BlpBootDevice
->Local
.Type
== RamDiskDevice
))
973 /* We don't handle this yet */
974 EarlyPrint(L
"RAM boot not supported\n");
975 Status
= STATUS_NOT_IMPLEMENTED
;
980 /* We didn't, so there won't be any need to find the memory descriptor */
984 /* Loop the EFI memory map */
986 EarlyPrint(L
"UEFI MEMORY MAP\n\n");
987 EarlyPrint(L
"TYPE START END ATTRIBUTES\n");
988 EarlyPrint(L
"===============================================================\n");
990 while (EfiMemoryMapSize
!= 0)
992 /* Check if this is an EFI buffer, but we're not in real mode */
993 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
995 BlpArchSwitchContext(BlRealMode
);
998 /* Capture it so we can go back to protected mode (if possible) */
999 EfiDescriptor
= *EfiMemoryMap
;
1001 /* Go back to protected mode, if we had switched */
1002 if ((UseEfiBuffer
) && (OldMode
!= BlRealMode
))
1004 BlpArchSwitchContext(OldMode
);
1007 /* Convert to OS memory type */
1008 MemoryType
= MmFwpGetOsMemoryType(EfiDescriptor
.Type
);
1010 /* Round up or round down depending on where the memory is coming from */
1011 if (MemoryType
== BlConventionalMemory
)
1013 StartPage
= BYTES_TO_PAGES(EfiDescriptor
.PhysicalStart
);
1017 StartPage
= EfiDescriptor
.PhysicalStart
>> PAGE_SHIFT
;
1020 /* Calculate the ending page */
1021 EndPage
= StartPage
+ EfiDescriptor
.NumberOfPages
;
1023 /* If after rounding, we ended up with 0 pages, skip this */
1024 if (StartPage
== EndPage
)
1029 EarlyPrint(L
"%08X 0x%016I64X-0x%016I64X 0x%I64X\n",
1031 StartPage
<< PAGE_SHIFT
,
1032 EndPage
<< PAGE_SHIFT
,
1033 EfiDescriptor
.Attribute
);
1035 /* Check for any range of memory below 1MB */
1036 if (StartPage
< 0x100)
1038 /* Does this range actually contain NULL? */
1041 /* Manually create a reserved descriptof for this page */
1042 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1043 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1050 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1054 /* Add this descriptor into the list */
1055 Status
= MmMdAddDescriptorToList(MemoryMap
,
1057 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1058 if (!NT_SUCCESS(Status
))
1060 EarlyPrint(L
"Failed to add zero page descriptor: %lx\n", Status
);
1064 /* Now handle the rest of the range, unless this was it */
1072 /* Does the range go beyond 1MB? */
1073 if (EndPage
> 0x100)
1075 /* Then create the descriptor for everything up until the megabyte */
1076 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1077 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1084 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1088 /* Check if this region is currently free RAM */
1089 if (Descriptor
->Type
== BlConventionalMemory
)
1091 /* Set an unknown flag on the descriptor */
1092 Descriptor
->Flags
|= 0x80000;
1095 /* Add this descriptor into the list */
1096 Status
= MmMdAddDescriptorToList(MemoryMap
,
1098 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
);
1099 if (!NT_SUCCESS(Status
))
1101 EarlyPrint(L
"Failed to add 1MB descriptor: %lx\n", Status
);
1105 /* Now handle the rest of the range above 1MB */
1110 /* Check if we loaded from a RAM disk */
1113 /* We don't handle this yet */
1114 EarlyPrint(L
"RAM boot not supported\n");
1115 Status
= STATUS_NOT_IMPLEMENTED
;
1119 /* Create a descriptor for the current range */
1120 Attribute
= MmFwpGetOsAttributeType(EfiDescriptor
.Attribute
);
1121 Descriptor
= MmMdInitByteGranularDescriptor(Attribute
,
1125 EndPage
- StartPage
);
1128 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1132 /* Check if this region is currently free RAM below 1MB */
1133 if ((Descriptor
->Type
== BlConventionalMemory
) && (EndPage
<= 0x100))
1135 /* Set an unknown flag on the descriptor */
1136 Descriptor
->Flags
|= 0x80000;
1139 /* Add the descriptor to the list, requesting coalescing as asked */
1140 Status
= MmMdAddDescriptorToList(MemoryMap
,
1142 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG
|
1143 (Flags
& BL_MM_FLAG_REQUEST_COALESCING
) ?
1144 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG
: 0);
1145 if (!NT_SUCCESS(Status
))
1147 EarlyPrint(L
"Failed to add full descriptor: %lx\n", Status
);
1152 /* Consume this descriptor, and move to the next one */
1153 EfiMemoryMapSize
-= DescriptorSize
;
1154 EfiMemoryMap
= (PVOID
)((ULONG_PTR
)EfiMemoryMap
+ DescriptorSize
);
1157 /* FIXME: @TODO: Mark the EfiBuffer as free, since we're about to free it */
1158 /* For now, just "leak" the 1-2 pages... */
1161 /* Free the EFI buffer, if we had one */
1164 EfiFreePages(Pages
, EfiBuffer
);
1167 /* On failure, free the memory map if one was passed in */
1168 if (!NT_SUCCESS(Status
) && (MemoryMap
!= NULL
))
1170 MmMdFreeList(MemoryMap
);
1173 /* Decrement the nesting depth and return */
1174 MmDescriptorCallTreeCount
--;
1181 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
1184 NTSTATUS Status
= STATUS_SUCCESS
;
1185 EFI_KEY_TOGGLE_STATE KeyToggleState
;
1187 /* Check if we have vaild firmware data */
1188 if (!(FirmwareData
) || !(FirmwareData
->Version
))
1190 return STATUS_INVALID_PARAMETER
;
1193 /* Check which boot phase we're in */
1196 /* Memory manager is ready, open the extended input protocol */
1197 Status
= EfiOpenProtocol(EfiST
->ConsoleInHandle
,
1198 &EfiSimpleTextInputExProtocol
,
1199 (PVOID
*)&EfiConInEx
);
1200 if (NT_SUCCESS(Status
))
1202 /* Set the initial key toggle state */
1203 KeyToggleState
= EFI_TOGGLE_STATE_VALID
| 40;
1204 EfiConInExSetState(EfiConInEx
, &KeyToggleState
);
1207 /* Setup the watchdog timer */
1208 EfiSetWatchdogTimer();
1212 /* Make a copy of the parameters */
1213 EfiFirmwareParameters
= &EfiFirmwareData
;
1215 /* Check which version we received */
1216 if (FirmwareData
->Version
== 1)
1218 /* FIXME: Not supported */
1219 Status
= STATUS_NOT_SUPPORTED
;
1221 else if (FirmwareData
->Version
>= 2)
1223 /* Version 2 -- save the data */
1224 EfiFirmwareData
= *FirmwareData
;
1225 EfiSystemTable
= FirmwareData
->SystemTable
;
1226 EfiImageHandle
= FirmwareData
->ImageHandle
;
1228 /* Set the EDK-II style variables as well */
1229 EfiST
= EfiSystemTable
;
1230 EfiBS
= EfiSystemTable
->BootServices
;
1231 EfiRT
= EfiSystemTable
->RuntimeServices
;
1232 EfiConOut
= EfiSystemTable
->ConOut
;
1233 EfiConIn
= EfiSystemTable
->ConIn
;
1238 /* Unknown version */
1239 Status
= STATUS_NOT_SUPPORTED
;
1243 /* Return the initialization state */