[BOOTLIB]: Add support for initializing the input console object.
[reactos.git] / reactos / boot / environ / lib / firmware / efi / firmware.c
1 /*
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)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "bl.h"
12
13 /* DATA VARIABLES ************************************************************/
14
15 PBL_FIRMWARE_DESCRIPTOR EfiFirmwareParameters;
16 BL_FIRMWARE_DESCRIPTOR EfiFirmwareData;
17 EFI_HANDLE EfiImageHandle;
18 EFI_SYSTEM_TABLE* EfiSystemTable;
19
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
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;
32 EFI_GUID EfiBlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID;
33
34 WCHAR BlScratchBuffer[8192];
35
36 /* FUNCTIONS *****************************************************************/
37
38 EFI_DEVICE_PATH *
39 EfiIsDevicePathParent (
40 _In_ EFI_DEVICE_PATH *DevicePath1,
41 _In_ EFI_DEVICE_PATH *DevicePath2
42 )
43 {
44 USHORT Length1, Length2;
45
46 /* Loop each element of the device path */
47 while (!IsDevicePathEndType(DevicePath1) && !IsDevicePathEndType(DevicePath2))
48 {
49 /* Check if the element has a different length */
50 Length1 = DevicePathNodeLength(DevicePath1);
51 Length2 = DevicePathNodeLength(DevicePath2);
52 if (Length1 != Length2)
53 {
54 /* Then they're not related */
55 return NULL;
56 }
57
58 /* Check if the rest of the element data matches */
59 if (RtlCompareMemory(DevicePath1, DevicePath2, Length1) != Length1)
60 {
61 /* Nope, not related */
62 return NULL;
63 }
64
65 /* Move to the next element */
66 DevicePath1 = NextDevicePathNode(DevicePath1);
67 DevicePath2 = NextDevicePathNode(DevicePath2);
68 }
69
70 /* If the last element in path 1 is empty, then path 2 is the child (deeper) */
71 if (!IsDevicePathEndType(DevicePath1))
72 {
73 return DevicePath2;
74 }
75
76 /* If the last element in path 2 is empty, then path 1 is the child (deeper) */
77 if (!IsDevicePathEndType(DevicePath2))
78 {
79 return DevicePath1;
80 }
81
82 /* They're both the end, so they're identical, so there's no parent */
83 return NULL;
84 }
85
86 EFI_DEVICE_PATH*
87 EfiGetLeafNode (
88 _In_ EFI_DEVICE_PATH *DevicePath
89 )
90 {
91 EFI_DEVICE_PATH *NextDevicePath;
92
93 /* Make sure we're not already at the end */
94 if (!IsDevicePathEndType(DevicePath))
95 {
96 /* Grab the next node element, and keep going until the end */
97 for (NextDevicePath = NextDevicePathNode(DevicePath);
98 !IsDevicePathEndType(NextDevicePath);
99 NextDevicePath = NextDevicePathNode(NextDevicePath))
100 {
101 /* Save the current node we're at */
102 DevicePath = NextDevicePath;
103 }
104 }
105
106 /* This now contains the deepeest (leaf) node */
107 return DevicePath;
108 }
109
110 VOID
111 EfiPrintf (
112 _In_ PWCHAR Format,
113 ...
114 )
115 {
116 va_list args;
117 va_start(args, Format);
118
119 /* Capture the buffer in our scratch pad, and NULL-terminate */
120 vsnwprintf(BlScratchBuffer, RTL_NUMBER_OF(BlScratchBuffer) - 1, Format, args);
121 BlScratchBuffer[RTL_NUMBER_OF(BlScratchBuffer) - 1] = UNICODE_NULL;
122
123 /* Check which mode we're in */
124 if (CurrentExecutionContext->Mode == BlRealMode)
125 {
126 /* Call EFI directly */
127 EfiConOut->OutputString(EfiConOut, BlScratchBuffer);
128 }
129 else
130 {
131 /* FIXME: @TODO: Not yet supported */
132 }
133
134 /* All done */
135 va_end(args);
136 }
137
138 NTSTATUS
139 EfiOpenProtocol (
140 _In_ EFI_HANDLE Handle,
141 _In_ EFI_GUID *Protocol,
142 _Out_ PVOID* Interface
143 )
144 {
145 EFI_STATUS EfiStatus;
146 NTSTATUS Status;
147 BL_ARCH_MODE OldMode;
148
149 /* Are we using virtual memory/ */
150 if (MmTranslationType != BlNone)
151 {
152 /* We need complex tracking to make this work */
153 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
154 Status = STATUS_NOT_SUPPORTED;
155 }
156 else
157 {
158 /* Are we in protected mode? */
159 OldMode = CurrentExecutionContext->Mode;
160 if (OldMode != BlRealMode)
161 {
162 /* FIXME: Not yet implemented */
163 return STATUS_NOT_IMPLEMENTED;
164 }
165
166 /* Are we on legacy 1.02? */
167 if (EfiST->FirmwareRevision == EFI_1_02_SYSTEM_TABLE_REVISION)
168 {
169 /* Make the legacy call */
170 EfiStatus = EfiBS->HandleProtocol(Handle, Protocol, Interface);
171 }
172 else
173 {
174 /* Use the UEFI version */
175 EfiStatus = EfiBS->OpenProtocol(Handle,
176 Protocol,
177 Interface,
178 EfiImageHandle,
179 NULL,
180 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
181
182 /* Switch back to protected mode if we came from there */
183 if (OldMode != BlRealMode)
184 {
185 BlpArchSwitchContext(OldMode);
186 }
187 }
188
189 /* Convert the error to an NTSTATUS */
190 Status = EfiGetNtStatusCode(EfiStatus);
191 }
192
193 /* Clear the interface on failure, and return the status */
194 if (!NT_SUCCESS(Status))
195 {
196 *Interface = NULL;
197 }
198
199 return Status;
200 }
201
202 NTSTATUS
203 EfiCloseProtocol (
204 _In_ EFI_HANDLE Handle,
205 _In_ EFI_GUID *Protocol
206 )
207 {
208 EFI_STATUS EfiStatus;
209 NTSTATUS Status;
210 BL_ARCH_MODE OldMode;
211
212 /* Are we using virtual memory/ */
213 if (MmTranslationType != BlNone)
214 {
215 /* We need complex tracking to make this work */
216 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
217 Status = STATUS_NOT_SUPPORTED;
218 }
219 else
220 {
221 /* Are we on legacy 1.02? */
222 if (EfiST->FirmwareRevision == EFI_1_02_SYSTEM_TABLE_REVISION)
223 {
224 /* Nothing to close */
225 EfiStatus = STATUS_SUCCESS;
226 }
227 else
228 {
229 /* Are we in protected mode? */
230 OldMode = CurrentExecutionContext->Mode;
231 if (OldMode != BlRealMode)
232 {
233 /* FIXME: Not yet implemented */
234 return STATUS_NOT_IMPLEMENTED;
235 }
236
237 /* Use the UEFI version */
238 EfiStatus = EfiBS->CloseProtocol(Handle, Protocol, EfiImageHandle, NULL);
239
240 /* Switch back to protected mode if we came from there */
241 if (OldMode != BlRealMode)
242 {
243 BlpArchSwitchContext(OldMode);
244 }
245
246 /* Normalize not found as success */
247 if (EfiStatus == EFI_NOT_FOUND)
248 {
249 EfiStatus = EFI_SUCCESS;
250 }
251 }
252
253 /* Convert the error to an NTSTATUS */
254 Status = EfiGetNtStatusCode(EfiStatus);
255 }
256
257 /* All done */
258 return Status;
259 }
260
261 NTSTATUS
262 EfiConInReset (
263 VOID
264 )
265 {
266 BL_ARCH_MODE OldMode;
267 EFI_STATUS EfiStatus;
268
269 /* Are we in protected mode? */
270 OldMode = CurrentExecutionContext->Mode;
271 if (OldMode != BlRealMode)
272 {
273 /* FIXME: Not yet implemented */
274 return STATUS_NOT_IMPLEMENTED;
275 }
276
277 /* Make the EFI call */
278 EfiStatus = EfiConIn->Reset(EfiConIn, FALSE);
279
280 /* Switch back to protected mode if we came from there */
281 if (OldMode != BlRealMode)
282 {
283 BlpArchSwitchContext(OldMode);
284 }
285
286 /* Convert the error to an NTSTATUS */
287 return EfiGetNtStatusCode(EfiStatus);
288 }
289
290 NTSTATUS
291 EfiConInExReset (
292 VOID
293 )
294 {
295 BL_ARCH_MODE OldMode;
296 EFI_STATUS EfiStatus;
297
298 /* Are we in protected mode? */
299 OldMode = CurrentExecutionContext->Mode;
300 if (OldMode != BlRealMode)
301 {
302 /* FIXME: Not yet implemented */
303 return STATUS_NOT_IMPLEMENTED;
304 }
305
306 /* Make the EFI call */
307 EfiStatus = EfiConInEx->Reset(EfiConInEx, FALSE);
308
309 /* Switch back to protected mode if we came from there */
310 if (OldMode != BlRealMode)
311 {
312 BlpArchSwitchContext(OldMode);
313 }
314
315 /* Convert the error to an NTSTATUS */
316 return EfiGetNtStatusCode(EfiStatus);
317 }
318
319 NTSTATUS
320 EfiConInExSetState (
321 _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *ConInEx,
322 _In_ EFI_KEY_TOGGLE_STATE* KeyToggleState
323 )
324 {
325 BL_ARCH_MODE OldMode;
326 EFI_STATUS EfiStatus;
327
328 /* Are we in protected mode? */
329 OldMode = CurrentExecutionContext->Mode;
330 if (OldMode != BlRealMode)
331 {
332 /* FIXME: Not yet implemented */
333 return STATUS_NOT_IMPLEMENTED;
334 }
335
336 /* Make the EFI call */
337 EfiStatus = ConInEx->SetState(ConInEx, KeyToggleState);
338
339 /* Switch back to protected mode if we came from there */
340 if (OldMode != BlRealMode)
341 {
342 BlpArchSwitchContext(OldMode);
343 }
344
345 /* Convert the error to an NTSTATUS */
346 return EfiGetNtStatusCode(EfiStatus);
347 }
348
349 NTSTATUS
350 EfiSetWatchdogTimer (
351 VOID
352 )
353 {
354 BL_ARCH_MODE OldMode;
355 EFI_STATUS EfiStatus;
356
357 /* Are we in protected mode? */
358 OldMode = CurrentExecutionContext->Mode;
359 if (OldMode != BlRealMode)
360 {
361 /* FIXME: Not yet implemented */
362 return STATUS_NOT_IMPLEMENTED;
363 }
364
365 /* Make the EFI call */
366 EfiStatus = EfiBS->SetWatchdogTimer(0, 0, 0, NULL);
367
368 /* Switch back to protected mode if we came from there */
369 if (OldMode != BlRealMode)
370 {
371 BlpArchSwitchContext(OldMode);
372 }
373
374 /* Convert the error to an NTSTATUS */
375 return EfiGetNtStatusCode(EfiStatus);
376 }
377
378 NTSTATUS
379 EfiGetMemoryMap (
380 _Out_ UINTN* MemoryMapSize,
381 _Inout_ EFI_MEMORY_DESCRIPTOR *MemoryMap,
382 _Out_ UINTN* MapKey,
383 _Out_ UINTN* DescriptorSize,
384 _Out_ UINTN* DescriptorVersion
385 )
386 {
387 BL_ARCH_MODE OldMode;
388 EFI_STATUS EfiStatus;
389
390 /* Are we in protected mode? */
391 OldMode = CurrentExecutionContext->Mode;
392 if (OldMode != BlRealMode)
393 {
394 /* FIXME: Not yet implemented */
395 return STATUS_NOT_IMPLEMENTED;
396 }
397
398 /* Make the EFI call */
399 EfiStatus = EfiBS->GetMemoryMap(MemoryMapSize,
400 MemoryMap,
401 MapKey,
402 DescriptorSize,
403 DescriptorVersion);
404
405 /* Switch back to protected mode if we came from there */
406 if (OldMode != BlRealMode)
407 {
408 BlpArchSwitchContext(OldMode);
409 }
410
411 /* Convert the error to an NTSTATUS */
412 return EfiGetNtStatusCode(EfiStatus);
413 }
414
415 NTSTATUS
416 EfiFreePages (
417 _In_ ULONG Pages,
418 _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress
419 )
420 {
421 BL_ARCH_MODE OldMode;
422 EFI_STATUS EfiStatus;
423
424 /* Are we in protected mode? */
425 OldMode = CurrentExecutionContext->Mode;
426 if (OldMode != BlRealMode)
427 {
428 /* FIXME: Not yet implemented */
429 return STATUS_NOT_IMPLEMENTED;
430 }
431
432 /* Make the EFI call */
433 EfiStatus = EfiBS->FreePages(PhysicalAddress, Pages);
434
435 /* Switch back to protected mode if we came from there */
436 if (OldMode != BlRealMode)
437 {
438 BlpArchSwitchContext(OldMode);
439 }
440
441 /* Convert the error to an NTSTATUS */
442 return EfiGetNtStatusCode(EfiStatus);
443 }
444
445 NTSTATUS
446 EfiStall (
447 _In_ ULONG StallTime
448 )
449 {
450 BL_ARCH_MODE OldMode;
451 EFI_STATUS EfiStatus;
452
453 /* Are we in protected mode? */
454 OldMode = CurrentExecutionContext->Mode;
455 if (OldMode != BlRealMode)
456 {
457 /* FIXME: Not yet implemented */
458 return STATUS_NOT_IMPLEMENTED;
459 }
460
461 /* Make the EFI call */
462 EfiStatus = EfiBS->Stall(StallTime);
463
464 /* Switch back to protected mode if we came from there */
465 if (OldMode != BlRealMode)
466 {
467 BlpArchSwitchContext(OldMode);
468 }
469
470 /* Convert the error to an NTSTATUS */
471 return EfiGetNtStatusCode(EfiStatus);
472 }
473
474 NTSTATUS
475 EfiConOutQueryMode (
476 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
477 _In_ ULONG Mode,
478 _In_ UINTN* Columns,
479 _In_ UINTN* Rows
480 )
481 {
482 BL_ARCH_MODE OldMode;
483 EFI_STATUS EfiStatus;
484
485 /* Are we in protected mode? */
486 OldMode = CurrentExecutionContext->Mode;
487 if (OldMode != BlRealMode)
488 {
489 /* FIXME: Not yet implemented */
490 return STATUS_NOT_IMPLEMENTED;
491 }
492
493 /* Make the EFI call */
494 EfiStatus = TextInterface->QueryMode(TextInterface, Mode, Columns, Rows);
495
496 /* Switch back to protected mode if we came from there */
497 if (OldMode != BlRealMode)
498 {
499 BlpArchSwitchContext(OldMode);
500 }
501
502 /* Convert the error to an NTSTATUS */
503 return EfiGetNtStatusCode(EfiStatus);
504 }
505
506 NTSTATUS
507 EfiConOutSetMode (
508 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
509 _In_ ULONG Mode
510 )
511 {
512 BL_ARCH_MODE OldMode;
513 EFI_STATUS EfiStatus;
514
515 /* Are we in protected mode? */
516 OldMode = CurrentExecutionContext->Mode;
517 if (OldMode != BlRealMode)
518 {
519 /* FIXME: Not yet implemented */
520 return STATUS_NOT_IMPLEMENTED;
521 }
522
523 /* Make the EFI call */
524 EfiStatus = TextInterface->SetMode(TextInterface, Mode);
525
526 /* Switch back to protected mode if we came from there */
527 if (OldMode != BlRealMode)
528 {
529 BlpArchSwitchContext(OldMode);
530 }
531
532 /* Convert the error to an NTSTATUS */
533 return EfiGetNtStatusCode(EfiStatus);
534 }
535
536 NTSTATUS
537 EfiConOutSetAttribute (
538 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
539 _In_ ULONG Attribute
540 )
541 {
542 BL_ARCH_MODE OldMode;
543 EFI_STATUS EfiStatus;
544
545 /* Are we in protected mode? */
546 OldMode = CurrentExecutionContext->Mode;
547 if (OldMode != BlRealMode)
548 {
549 /* FIXME: Not yet implemented */
550 return STATUS_NOT_IMPLEMENTED;
551 }
552
553 /* Make the EFI call */
554 EfiStatus = TextInterface->SetAttribute(TextInterface, Attribute);
555
556 /* Switch back to protected mode if we came from there */
557 if (OldMode != BlRealMode)
558 {
559 BlpArchSwitchContext(OldMode);
560 }
561
562 /* Convert the error to an NTSTATUS */
563 return EfiGetNtStatusCode(EfiStatus);
564 }
565
566 NTSTATUS
567 EfiConOutSetCursorPosition (
568 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
569 _In_ ULONG Column,
570 _In_ ULONG Row
571 )
572 {
573 BL_ARCH_MODE OldMode;
574 EFI_STATUS EfiStatus;
575
576 /* Are we in protected mode? */
577 OldMode = CurrentExecutionContext->Mode;
578 if (OldMode != BlRealMode)
579 {
580 /* FIXME: Not yet implemented */
581 return STATUS_NOT_IMPLEMENTED;
582 }
583
584 /* Make the EFI call */
585 EfiStatus = TextInterface->SetCursorPosition(TextInterface, Column, Row);
586
587 /* Switch back to protected mode if we came from there */
588 if (OldMode != BlRealMode)
589 {
590 BlpArchSwitchContext(OldMode);
591 }
592
593 /* Convert the error to an NTSTATUS */
594 return EfiGetNtStatusCode(EfiStatus);
595 }
596
597 NTSTATUS
598 EfiConOutEnableCursor (
599 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
600 _In_ BOOLEAN Visible
601 )
602 {
603 BL_ARCH_MODE OldMode;
604 EFI_STATUS EfiStatus;
605
606 /* Are we in protected mode? */
607 OldMode = CurrentExecutionContext->Mode;
608 if (OldMode != BlRealMode)
609 {
610 /* FIXME: Not yet implemented */
611 return STATUS_NOT_IMPLEMENTED;
612 }
613
614 /* Make the EFI call */
615 EfiStatus = TextInterface->EnableCursor(TextInterface, Visible);
616
617 /* Switch back to protected mode if we came from there */
618 if (OldMode != BlRealMode)
619 {
620 BlpArchSwitchContext(OldMode);
621 }
622
623 /* Convert the error to an NTSTATUS */
624 return EfiGetNtStatusCode(EfiStatus);
625 }
626
627 VOID
628 EfiConOutReadCurrentMode (
629 _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
630 _Out_ EFI_SIMPLE_TEXT_OUTPUT_MODE* Mode
631 )
632 {
633 BL_ARCH_MODE OldMode;
634
635 /* Are we in protected mode? */
636 OldMode = CurrentExecutionContext->Mode;
637 if (OldMode != BlRealMode)
638 {
639 /* FIXME: Not yet implemented */
640 return;
641 }
642
643 /* Make the EFI call */
644 RtlCopyMemory(Mode, TextInterface->Mode, sizeof(*Mode));
645
646 /* Switch back to protected mode if we came from there */
647 if (OldMode != BlRealMode)
648 {
649 BlpArchSwitchContext(OldMode);
650 }
651 }
652
653 VOID
654 EfiGopGetFrameBuffer (
655 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
656 _Out_ PHYSICAL_ADDRESS* FrameBuffer,
657 _Out_ UINTN *FrameBufferSize
658 )
659 {
660 BL_ARCH_MODE OldMode;
661
662 /* Are we in protected mode? */
663 OldMode = CurrentExecutionContext->Mode;
664 if (OldMode != BlRealMode)
665 {
666 /* FIXME: Not yet implemented */
667 return;
668 }
669
670 /* Make the EFI call */
671 FrameBuffer->QuadPart = GopInterface->Mode->FrameBufferBase;
672 *FrameBufferSize = GopInterface->Mode->FrameBufferSize;
673
674 /* Switch back to protected mode if we came from there */
675 if (OldMode != BlRealMode)
676 {
677 BlpArchSwitchContext(OldMode);
678 }
679 }
680
681 NTSTATUS
682 EfiGopGetCurrentMode (
683 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
684 _Out_ UINTN* Mode,
685 _Out_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Information
686 )
687 {
688 BL_ARCH_MODE OldMode;
689
690 /* Are we in protected mode? */
691 OldMode = CurrentExecutionContext->Mode;
692 if (OldMode != BlRealMode)
693 {
694 /* FIXME: Not yet implemented */
695 return STATUS_NOT_IMPLEMENTED;
696 }
697
698 /* Make the EFI call */
699 *Mode = GopInterface->Mode->Mode;
700 RtlCopyMemory(Information, GopInterface->Mode->Info, sizeof(*Information));
701
702 /* Switch back to protected mode if we came from there */
703 if (OldMode != BlRealMode)
704 {
705 BlpArchSwitchContext(OldMode);
706 }
707
708 /* Return back */
709 return STATUS_SUCCESS;
710 }
711
712 NTSTATUS
713 EfiGopSetMode (
714 _In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
715 _In_ ULONG Mode
716 )
717 {
718 BL_ARCH_MODE OldMode;
719 EFI_STATUS EfiStatus;
720 BOOLEAN ModeChanged;
721 NTSTATUS Status;
722
723 /* Are we in protected mode? */
724 OldMode = CurrentExecutionContext->Mode;
725 if (OldMode != BlRealMode)
726 {
727 /* FIXME: Not yet implemented */
728 return STATUS_NOT_IMPLEMENTED;
729 }
730
731 /* Make the EFI call */
732 if (Mode == GopInterface->Mode->Mode)
733 {
734 EfiStatus = EFI_SUCCESS;
735 ModeChanged = FALSE;
736 }
737 {
738 EfiStatus = GopInterface->SetMode(GopInterface, Mode);
739 ModeChanged = TRUE;
740 }
741
742 /* Switch back to protected mode if we came from there */
743 if (OldMode != BlRealMode)
744 {
745 BlpArchSwitchContext(OldMode);
746 }
747
748 /* Print out to the debugger if the mode was changed */
749 Status = EfiGetNtStatusCode(EfiStatus);
750 if ((ModeChanged) && (NT_SUCCESS(Status)))
751 {
752 /* FIXME @TODO: Should be BlStatusPrint */
753 EfiPrintf(L"Console video mode set to 0x%x\r\r\n", Mode);
754 }
755
756 /* Convert the error to an NTSTATUS */
757 return Status;
758 }
759
760 NTSTATUS
761 EfiLocateHandleBuffer (
762 _In_ EFI_LOCATE_SEARCH_TYPE SearchType,
763 _In_ EFI_GUID *Protocol,
764 _Inout_ PULONG HandleCount,
765 _Inout_ EFI_HANDLE** Buffer
766 )
767 {
768 BL_ARCH_MODE OldMode;
769 EFI_STATUS EfiStatus;
770 UINTN BufferSize;
771
772 /* Bail out if we're missing parameters */
773 if (!(Buffer) || !(HandleCount))
774 {
775 return STATUS_INVALID_PARAMETER;
776 }
777
778 /* Check if a buffer was passed in*/
779 if (*Buffer)
780 {
781 /* Then we should already have a buffer size*/
782 BufferSize = sizeof(EFI_HANDLE) * *HandleCount;
783 }
784 else
785 {
786 /* Then no buffer size exists */
787 BufferSize = 0;
788 }
789
790 /* Are we in protected mode? */
791 OldMode = CurrentExecutionContext->Mode;
792 if (OldMode != BlRealMode)
793 {
794 /* FIXME: Not yet implemented */
795 return STATUS_NOT_IMPLEMENTED;
796 }
797
798 /* Try the first time */
799 EfiStatus = EfiBS->LocateHandle(SearchType, Protocol, NULL, &BufferSize, *Buffer);
800 if (EfiStatus == EFI_BUFFER_TOO_SMALL)
801 {
802 /* Did we have an existing buffer? */
803 if (*Buffer)
804 {
805 /* Free it */
806 BlMmFreeHeap(*Buffer);
807 }
808
809 /* Allocate a new one */
810 *Buffer = BlMmAllocateHeap(BufferSize);
811 if (!(*Buffer))
812 {
813 /* No space, fail */
814 return STATUS_NO_MEMORY;
815 }
816
817 /* Try again */
818 EfiStatus = EfiBS->LocateHandle(SearchType, Protocol, NULL, &BufferSize, *Buffer);
819
820 /* Switch back to protected mode if we came from there */
821 if (OldMode != BlRealMode)
822 {
823 BlpArchSwitchContext(OldMode);
824 }
825 }
826
827 /* Return the number of handles */
828 *HandleCount = BufferSize / sizeof(EFI_HANDLE);
829
830 /* Convert the error to an NTSTATUS */
831 return EfiGetNtStatusCode(EfiStatus);
832 }
833
834 VOID
835 EfiResetSystem (
836 _In_ EFI_RESET_TYPE ResetType
837 )
838 {
839 BL_ARCH_MODE OldMode;
840
841 /* Are we in protected mode? */
842 OldMode = CurrentExecutionContext->Mode;
843 if (OldMode != BlRealMode)
844 {
845 /* FIXME: Not yet implemented */
846 return;
847 }
848
849 /* Call the EFI runtime */
850 EfiRT->ResetSystem(ResetType, EFI_SUCCESS, 0, NULL);
851 }
852
853 NTSTATUS
854 EfiAllocatePages (
855 _In_ ULONG Type,
856 _In_ ULONG Pages,
857 _Inout_ EFI_PHYSICAL_ADDRESS* Memory
858 )
859 {
860 BL_ARCH_MODE OldMode;
861 EFI_STATUS EfiStatus;
862
863 /* Are we in protected mode? */
864 OldMode = CurrentExecutionContext->Mode;
865 if (OldMode != BlRealMode)
866 {
867 /* FIXME: Not yet implemented */
868 return STATUS_NOT_IMPLEMENTED;
869 }
870
871 /* Make the EFI call */
872 EfiStatus = EfiBS->AllocatePages(Type, EfiLoaderData, Pages, Memory);
873
874 /* Switch back to protected mode if we came from there */
875 if (OldMode != BlRealMode)
876 {
877 BlpArchSwitchContext(OldMode);
878 }
879
880 /* Convert the error to an NTSTATUS */
881 return EfiGetNtStatusCode(EfiStatus);
882 }
883
884 BL_MEMORY_ATTR
885 MmFwpGetOsAttributeType (
886 _In_ ULONGLONG Attribute
887 )
888 {
889 BL_MEMORY_ATTR OsAttribute = 0;
890
891 if (Attribute & EFI_MEMORY_UC)
892 {
893 OsAttribute = BlMemoryUncached;
894 }
895
896 if (Attribute & EFI_MEMORY_WC)
897 {
898 OsAttribute |= BlMemoryWriteCombined;
899 }
900
901 if (Attribute & EFI_MEMORY_WT)
902 {
903 OsAttribute |= BlMemoryWriteThrough;
904 }
905
906 if (Attribute & EFI_MEMORY_WB)
907 {
908 OsAttribute |= BlMemoryWriteBack;
909 }
910
911 if (Attribute & EFI_MEMORY_UCE)
912 {
913 OsAttribute |= BlMemoryUncachedExported;
914 }
915
916 if (Attribute & EFI_MEMORY_WP)
917 {
918 OsAttribute |= BlMemoryWriteProtected;
919 }
920
921 if (Attribute & EFI_MEMORY_RP)
922 {
923 OsAttribute |= BlMemoryReadProtected;
924 }
925
926 if (Attribute & EFI_MEMORY_XP)
927 {
928 OsAttribute |= BlMemoryExecuteProtected;
929 }
930
931 if (Attribute & EFI_MEMORY_RUNTIME)
932 {
933 OsAttribute |= BlMemoryRuntime;
934 }
935
936 return OsAttribute;
937 }
938
939 BL_MEMORY_TYPE
940 MmFwpGetOsMemoryType (
941 _In_ EFI_MEMORY_TYPE MemoryType
942 )
943 {
944 BL_MEMORY_TYPE OsType;
945
946 switch (MemoryType)
947 {
948 case EfiLoaderCode:
949 case EfiLoaderData:
950 OsType = BlLoaderMemory;
951 break;
952
953 case EfiBootServicesCode:
954 case EfiBootServicesData:
955 OsType = BlEfiBootMemory;
956 break;
957
958 case EfiRuntimeServicesCode:
959 case EfiRuntimeServicesData:
960 OsType = BlEfiRuntimeMemory;
961 break;
962
963 case EfiConventionalMemory:
964 OsType = BlConventionalMemory;
965 break;
966
967 case EfiUnusableMemory:
968 OsType = BlUnusableMemory;
969 break;
970
971 case EfiACPIReclaimMemory:
972 OsType = BlAcpiReclaimMemory;
973 break;
974
975 case EfiACPIMemoryNVS:
976 OsType = BlAcpiNvsMemory;
977 break;
978
979 case EfiMemoryMappedIO:
980 OsType = BlDeviceIoMemory;
981 break;
982
983 case EfiMemoryMappedIOPortSpace:
984 OsType = BlDevicePortMemory;
985 break;
986
987 case EfiPalCode:
988 OsType = BlPalMemory;
989 break;
990
991 default:
992 OsType = BlReservedMemory;
993 break;
994 }
995
996 return OsType;
997 }
998
999 NTSTATUS
1000 MmFwGetMemoryMap (
1001 _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap,
1002 _In_ ULONG Flags
1003 )
1004 {
1005 BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters;
1006 BOOLEAN UseEfiBuffer, HaveRamDisk;
1007 NTSTATUS Status;
1008 ULONGLONG Pages, StartPage, EndPage;
1009 UINTN EfiMemoryMapSize, MapKey, DescriptorSize, DescriptorVersion;
1010 EFI_PHYSICAL_ADDRESS EfiBuffer;
1011 EFI_MEMORY_DESCRIPTOR* EfiMemoryMap;
1012 EFI_STATUS EfiStatus;
1013 BL_ARCH_MODE OldMode;
1014 EFI_MEMORY_DESCRIPTOR EfiDescriptor;
1015 BL_MEMORY_TYPE MemoryType;
1016 PBL_MEMORY_DESCRIPTOR Descriptor;
1017 BL_MEMORY_ATTR Attribute;
1018
1019 /* Initialize EFI memory map attributes */
1020 EfiMemoryMapSize = MapKey = DescriptorSize = DescriptorVersion = 0;
1021
1022 /* Increment the nesting depth */
1023 MmDescriptorCallTreeCount++;
1024
1025 /* Determine if we should use EFI or our own allocator at this point */
1026 UseEfiBuffer = Flags & BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS;
1027 if (!(LibraryParameters.LibraryFlags & BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED))
1028 {
1029 UseEfiBuffer = TRUE;
1030 }
1031
1032 /* Bail out if we don't have a list to use */
1033 if (MemoryMap == NULL)
1034 {
1035 Status = STATUS_INVALID_PARAMETER;
1036 goto Quickie;
1037 }
1038
1039 /* Free the current descriptor list */
1040 MmMdFreeList(MemoryMap);
1041
1042 /* Call into EFI to get the size of the memory map */
1043 Status = EfiGetMemoryMap(&EfiMemoryMapSize,
1044 NULL,
1045 &MapKey,
1046 &DescriptorSize,
1047 &DescriptorVersion);
1048 if (Status != STATUS_BUFFER_TOO_SMALL)
1049 {
1050 /* This should've failed because our buffer was too small, nothing else */
1051 EfiPrintf(L"Got strange EFI status for memory map: %lx\r\n", Status);
1052 if (NT_SUCCESS(Status))
1053 {
1054 Status = STATUS_UNSUCCESSFUL;
1055 }
1056 goto Quickie;
1057 }
1058
1059 /* Add 4 more descriptors just in case things changed */
1060 EfiMemoryMapSize += (4 * DescriptorSize);
1061 Pages = BYTES_TO_PAGES(EfiMemoryMapSize);
1062 EfiPrintf(L"Memory map size: %lx bytes, %d pages\r\n", EfiMemoryMapSize, Pages);
1063
1064 /* Should we use EFI to grab memory? */
1065 if (UseEfiBuffer)
1066 {
1067 /* Yes -- request one more page to align up correctly */
1068 Pages++;
1069
1070 /* Grab the required pages */
1071 Status = EfiAllocatePages(AllocateAnyPages,
1072 Pages,
1073 &EfiBuffer);
1074 if (!NT_SUCCESS(Status))
1075 {
1076 EfiPrintf(L"EFI allocation failed: %lx\r\n", Status);
1077 goto Quickie;
1078 }
1079
1080 /* Free the pages for now */
1081 Status = EfiFreePages(Pages, EfiBuffer);
1082 if (!NT_SUCCESS(Status))
1083 {
1084 EfiBuffer = 0;
1085 goto Quickie;
1086 }
1087
1088 /* Now round to the actual buffer size, removing the extra page */
1089 EfiBuffer = ROUND_TO_PAGES(EfiBuffer);
1090 Pages--;
1091 Status = EfiAllocatePages(AllocateAddress,
1092 Pages,
1093 &EfiBuffer);
1094 if (!NT_SUCCESS(Status))
1095 {
1096 EfiBuffer = 0;
1097 goto Quickie;
1098 }
1099
1100 /* Get the final aligned size and proper buffer */
1101 EfiMemoryMapSize = EFI_PAGES_TO_SIZE(Pages);
1102 EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR*)(ULONG_PTR)EfiBuffer;
1103
1104 /* Switch to real mode if not already in it */
1105 OldMode = CurrentExecutionContext->Mode;
1106 if (OldMode != BlRealMode)
1107 {
1108 BlpArchSwitchContext(BlRealMode);
1109 }
1110
1111 /* Call EFI to get the memory map */
1112 EfiStatus = EfiBS->GetMemoryMap(&EfiMemoryMapSize,
1113 EfiMemoryMap,
1114 &MapKey,
1115 &DescriptorSize,
1116 &DescriptorVersion);
1117
1118 /* Switch back into the previous mode */
1119 if (OldMode != BlRealMode)
1120 {
1121 BlpArchSwitchContext(OldMode);
1122 }
1123
1124 /* Convert the result code */
1125 Status = EfiGetNtStatusCode(EfiStatus);
1126 }
1127 else
1128 {
1129 /* We don't support this path yet */
1130 Status = STATUS_NOT_IMPLEMENTED;
1131 }
1132
1133 /* So far so good? */
1134 if (!NT_SUCCESS(Status))
1135 {
1136 EfiPrintf(L"Failed to get EFI memory map: %lx\r\n", Status);
1137 goto Quickie;
1138 }
1139
1140 /* Did we get correct data from firmware? */
1141 if (((EfiMemoryMapSize % DescriptorSize)) ||
1142 (DescriptorSize < sizeof(EFI_MEMORY_DESCRIPTOR)))
1143 {
1144 EfiPrintf(L"Incorrect descriptor size\r\n");
1145 Status = STATUS_UNSUCCESSFUL;
1146 goto Quickie;
1147 }
1148
1149 /* Did we boot from a RAM disk? */
1150 if ((BlpBootDevice->DeviceType == LocalDevice) &&
1151 (BlpBootDevice->Local.Type == RamDiskDevice))
1152 {
1153 /* We don't handle this yet */
1154 EfiPrintf(L"RAM boot not supported\r\n");
1155 Status = STATUS_NOT_IMPLEMENTED;
1156 goto Quickie;
1157 }
1158 else
1159 {
1160 /* We didn't, so there won't be any need to find the memory descriptor */
1161 HaveRamDisk = FALSE;
1162 }
1163
1164 /* Loop the EFI memory map */
1165 #if 0
1166 EfiPrintf(L"UEFI MEMORY MAP\n\r\n");
1167 EfiPrintf(L"TYPE START END ATTRIBUTES\r\n");
1168 EfiPrintf(L"===============================================================\r\n");
1169 #endif
1170 while (EfiMemoryMapSize != 0)
1171 {
1172 /* Check if this is an EFI buffer, but we're not in real mode */
1173 if ((UseEfiBuffer) && (OldMode != BlRealMode))
1174 {
1175 BlpArchSwitchContext(BlRealMode);
1176 }
1177
1178 /* Capture it so we can go back to protected mode (if possible) */
1179 EfiDescriptor = *EfiMemoryMap;
1180
1181 /* Go back to protected mode, if we had switched */
1182 if ((UseEfiBuffer) && (OldMode != BlRealMode))
1183 {
1184 BlpArchSwitchContext(OldMode);
1185 }
1186
1187 /* Convert to OS memory type */
1188 MemoryType = MmFwpGetOsMemoryType(EfiDescriptor.Type);
1189
1190 /* Round up or round down depending on where the memory is coming from */
1191 if (MemoryType == BlConventionalMemory)
1192 {
1193 StartPage = BYTES_TO_PAGES(EfiDescriptor.PhysicalStart);
1194 }
1195 else
1196 {
1197 StartPage = EfiDescriptor.PhysicalStart >> PAGE_SHIFT;
1198 }
1199
1200 /* Calculate the ending page */
1201 EndPage = StartPage + EfiDescriptor.NumberOfPages;
1202
1203 /* If after rounding, we ended up with 0 pages, skip this */
1204 if (StartPage == EndPage)
1205 {
1206 goto LoopAgain;
1207 }
1208 #if 0
1209 EfiPrintf(L"%08X 0x%016I64X-0x%016I64X 0x%I64X\r\n",
1210 MemoryType,
1211 StartPage << PAGE_SHIFT,
1212 EndPage << PAGE_SHIFT,
1213 EfiDescriptor.Attribute);
1214 #endif
1215 /* Check for any range of memory below 1MB */
1216 if (StartPage < 0x100)
1217 {
1218 /* Does this range actually contain NULL? */
1219 if (StartPage == 0)
1220 {
1221 /* Manually create a reserved descriptof for this page */
1222 Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute);
1223 Descriptor = MmMdInitByteGranularDescriptor(Attribute,
1224 BlReservedMemory,
1225 0,
1226 0,
1227 1);
1228 if (!Descriptor)
1229 {
1230 Status = STATUS_INSUFFICIENT_RESOURCES;
1231 break;
1232 }
1233
1234 /* Add this descriptor into the list */
1235 Status = MmMdAddDescriptorToList(MemoryMap,
1236 Descriptor,
1237 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG);
1238 if (!NT_SUCCESS(Status))
1239 {
1240 EfiPrintf(L"Failed to add zero page descriptor: %lx\r\n", Status);
1241 break;
1242 }
1243
1244 /* Now handle the rest of the range, unless this was it */
1245 StartPage = 1;
1246 if (EndPage == 1)
1247 {
1248 goto LoopAgain;
1249 }
1250 }
1251
1252 /* Does the range go beyond 1MB? */
1253 if (EndPage > 0x100)
1254 {
1255 /* Then create the descriptor for everything up until the megabyte */
1256 Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute);
1257 Descriptor = MmMdInitByteGranularDescriptor(Attribute,
1258 MemoryType,
1259 StartPage,
1260 0,
1261 0x100 - StartPage);
1262 if (!Descriptor)
1263 {
1264 Status = STATUS_INSUFFICIENT_RESOURCES;
1265 break;
1266 }
1267
1268 /* Check if this region is currently free RAM */
1269 if (Descriptor->Type == BlConventionalMemory)
1270 {
1271 /* Set the reserved flag on the descriptor */
1272 Descriptor->Flags |= BlReservedMemory;
1273 }
1274
1275 /* Add this descriptor into the list */
1276 Status = MmMdAddDescriptorToList(MemoryMap,
1277 Descriptor,
1278 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG);
1279 if (!NT_SUCCESS(Status))
1280 {
1281 EfiPrintf(L"Failed to add 1MB descriptor: %lx\r\n", Status);
1282 break;
1283 }
1284
1285 /* Now handle the rest of the range above 1MB */
1286 StartPage = 0x100;
1287 }
1288 }
1289
1290 /* Check if we loaded from a RAM disk */
1291 if (HaveRamDisk)
1292 {
1293 /* We don't handle this yet */
1294 EfiPrintf(L"RAM boot not supported\r\n");
1295 Status = STATUS_NOT_IMPLEMENTED;
1296 goto Quickie;
1297 }
1298
1299 /* Create a descriptor for the current range */
1300 Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute);
1301 Descriptor = MmMdInitByteGranularDescriptor(Attribute,
1302 MemoryType,
1303 StartPage,
1304 0,
1305 EndPage - StartPage);
1306 if (!Descriptor)
1307 {
1308 Status = STATUS_INSUFFICIENT_RESOURCES;
1309 break;
1310 }
1311
1312 /* Check if this region is currently free RAM below 1MB */
1313 if ((Descriptor->Type == BlConventionalMemory) && (EndPage <= 0x100))
1314 {
1315 /* Set the reserved flag on the descriptor */
1316 Descriptor->Flags |= BlReservedMemory;
1317 }
1318
1319 /* Add the descriptor to the list, requesting coalescing as asked */
1320 Status = MmMdAddDescriptorToList(MemoryMap,
1321 Descriptor,
1322 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG |
1323 (Flags & BL_MM_FLAG_REQUEST_COALESCING) ?
1324 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG : 0);
1325 if (!NT_SUCCESS(Status))
1326 {
1327 EfiPrintf(L"Failed to add full descriptor: %lx\r\n", Status);
1328 break;
1329 }
1330
1331 LoopAgain:
1332 /* Consume this descriptor, and move to the next one */
1333 EfiMemoryMapSize -= DescriptorSize;
1334 EfiMemoryMap = (PVOID)((ULONG_PTR)EfiMemoryMap + DescriptorSize);
1335 }
1336
1337 /* FIXME: @TODO: Mark the EfiBuffer as free, since we're about to free it */
1338 /* For now, just "leak" the 1-2 pages... */
1339
1340 Quickie:
1341 /* Free the EFI buffer, if we had one */
1342 if (EfiBuffer != 0)
1343 {
1344 EfiFreePages(Pages, EfiBuffer);
1345 }
1346
1347 /* On failure, free the memory map if one was passed in */
1348 if (!NT_SUCCESS(Status) && (MemoryMap != NULL))
1349 {
1350 MmMdFreeList(MemoryMap);
1351 }
1352
1353 /* Decrement the nesting depth and return */
1354 MmDescriptorCallTreeCount--;
1355 return Status;
1356 }
1357
1358 NTSTATUS
1359 BlpFwInitialize (
1360 _In_ ULONG Phase,
1361 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
1362 )
1363 {
1364 NTSTATUS Status = STATUS_SUCCESS;
1365 EFI_KEY_TOGGLE_STATE KeyToggleState;
1366
1367 /* Check if we have vaild firmware data */
1368 if (!(FirmwareData) || !(FirmwareData->Version))
1369 {
1370 return STATUS_INVALID_PARAMETER;
1371 }
1372
1373 /* Check which boot phase we're in */
1374 if (Phase != 0)
1375 {
1376 /* Memory manager is ready, open the extended input protocol */
1377 Status = EfiOpenProtocol(EfiST->ConsoleInHandle,
1378 &EfiSimpleTextInputExProtocol,
1379 (PVOID*)&EfiConInEx);
1380 if (NT_SUCCESS(Status))
1381 {
1382 /* Set the initial key toggle state */
1383 KeyToggleState = EFI_TOGGLE_STATE_VALID | 40;
1384 EfiConInExSetState(EfiConInEx, &KeyToggleState);
1385 }
1386
1387 /* Setup the watchdog timer */
1388 EfiSetWatchdogTimer();
1389 }
1390 else
1391 {
1392 /* Make a copy of the parameters */
1393 EfiFirmwareParameters = &EfiFirmwareData;
1394
1395 /* Check which version we received */
1396 if (FirmwareData->Version == 1)
1397 {
1398 /* FIXME: Not supported */
1399 Status = STATUS_NOT_SUPPORTED;
1400 }
1401 else if (FirmwareData->Version >= 2)
1402 {
1403 /* Version 2 -- save the data */
1404 EfiFirmwareData = *FirmwareData;
1405 EfiSystemTable = FirmwareData->SystemTable;
1406 EfiImageHandle = FirmwareData->ImageHandle;
1407
1408 /* Set the EDK-II style variables as well */
1409 EfiST = EfiSystemTable;
1410 EfiBS = EfiSystemTable->BootServices;
1411 EfiRT = EfiSystemTable->RuntimeServices;
1412 EfiConOut = EfiSystemTable->ConOut;
1413 EfiConIn = EfiSystemTable->ConIn;
1414 EfiConInEx = NULL;
1415 }
1416 else
1417 {
1418 /* Unknown version */
1419 Status = STATUS_NOT_SUPPORTED;
1420 }
1421 }
1422
1423 /* Return the initialization state */
1424 return Status;
1425 }
1426
1427
1428 /*++
1429 * @name EfiGetEfiStatusCode
1430 *
1431 * The EfiGetEfiStatusCode routine converts an NT Status to an EFI status.
1432 *
1433 * @param Status
1434 * NT Status code to be converted.
1435 *
1436 * @remark Only certain, specific NT status codes are converted to EFI codes.
1437 *
1438 * @return The corresponding EFI Status code, EFI_NO_MAPPING otherwise.
1439 *
1440 *--*/
1441 EFI_STATUS
1442 EfiGetEfiStatusCode(
1443 _In_ NTSTATUS Status
1444 )
1445 {
1446 switch (Status)
1447 {
1448 case STATUS_NOT_SUPPORTED:
1449 return EFI_UNSUPPORTED;
1450 case STATUS_DISK_FULL:
1451 return EFI_VOLUME_FULL;
1452 case STATUS_INSUFFICIENT_RESOURCES:
1453 return EFI_OUT_OF_RESOURCES;
1454 case STATUS_MEDIA_WRITE_PROTECTED:
1455 return EFI_WRITE_PROTECTED;
1456 case STATUS_DEVICE_NOT_READY:
1457 return EFI_NOT_STARTED;
1458 case STATUS_DEVICE_ALREADY_ATTACHED:
1459 return EFI_ALREADY_STARTED;
1460 case STATUS_MEDIA_CHANGED:
1461 return EFI_MEDIA_CHANGED;
1462 case STATUS_INVALID_PARAMETER:
1463 return EFI_INVALID_PARAMETER;
1464 case STATUS_ACCESS_DENIED:
1465 return EFI_ACCESS_DENIED;
1466 case STATUS_BUFFER_TOO_SMALL:
1467 return EFI_BUFFER_TOO_SMALL;
1468 case STATUS_DISK_CORRUPT_ERROR:
1469 return EFI_VOLUME_CORRUPTED;
1470 case STATUS_REQUEST_ABORTED:
1471 return EFI_ABORTED;
1472 case STATUS_NO_MEDIA:
1473 return EFI_NO_MEDIA;
1474 case STATUS_IO_DEVICE_ERROR:
1475 return EFI_DEVICE_ERROR;
1476 case STATUS_INVALID_BUFFER_SIZE:
1477 return EFI_BAD_BUFFER_SIZE;
1478 case STATUS_NOT_FOUND:
1479 return EFI_NOT_FOUND;
1480 case STATUS_DRIVER_UNABLE_TO_LOAD:
1481 return EFI_LOAD_ERROR;
1482 case STATUS_NO_MATCH:
1483 return EFI_NO_MAPPING;
1484 case STATUS_SUCCESS:
1485 return EFI_SUCCESS;
1486 case STATUS_TIMEOUT:
1487 return EFI_TIMEOUT;
1488 default:
1489 return EFI_NO_MAPPING;
1490 }
1491 }
1492
1493 /*++
1494 * @name EfiGetNtStatusCode
1495 *
1496 * The EfiGetNtStatusCode routine converts an EFI Status to an NT status.
1497 *
1498 * @param EfiStatus
1499 * EFI Status code to be converted.
1500 *
1501 * @remark Only certain, specific EFI status codes are converted to NT codes.
1502 *
1503 * @return The corresponding NT Status code, STATUS_UNSUCCESSFUL otherwise.
1504 *
1505 *--*/
1506 NTSTATUS
1507 EfiGetNtStatusCode (
1508 _In_ EFI_STATUS EfiStatus
1509 )
1510 {
1511 switch (EfiStatus)
1512 {
1513 case EFI_NOT_READY:
1514 case EFI_NOT_FOUND:
1515 return STATUS_NOT_FOUND;
1516 case EFI_NO_MEDIA:
1517 return STATUS_NO_MEDIA;
1518 case EFI_MEDIA_CHANGED:
1519 return STATUS_MEDIA_CHANGED;
1520 case EFI_ACCESS_DENIED:
1521 case EFI_SECURITY_VIOLATION:
1522 return STATUS_ACCESS_DENIED;
1523 case EFI_TIMEOUT:
1524 case EFI_NO_RESPONSE:
1525 return STATUS_TIMEOUT;
1526 case EFI_NO_MAPPING:
1527 return STATUS_NO_MATCH;
1528 case EFI_NOT_STARTED:
1529 return STATUS_DEVICE_NOT_READY;
1530 case EFI_ALREADY_STARTED:
1531 return STATUS_DEVICE_ALREADY_ATTACHED;
1532 case EFI_ABORTED:
1533 return STATUS_REQUEST_ABORTED;
1534 case EFI_VOLUME_FULL:
1535 return STATUS_DISK_FULL;
1536 case EFI_DEVICE_ERROR:
1537 return STATUS_IO_DEVICE_ERROR;
1538 case EFI_WRITE_PROTECTED:
1539 return STATUS_MEDIA_WRITE_PROTECTED;
1540 /* @FIXME: ReactOS Headers don't yet have this */
1541 //case EFI_OUT_OF_RESOURCES:
1542 //return STATUS_INSUFFICIENT_NVRAM_RESOURCES;
1543 case EFI_VOLUME_CORRUPTED:
1544 return STATUS_DISK_CORRUPT_ERROR;
1545 case EFI_BUFFER_TOO_SMALL:
1546 return STATUS_BUFFER_TOO_SMALL;
1547 case EFI_SUCCESS:
1548 return STATUS_SUCCESS;
1549 case EFI_LOAD_ERROR:
1550 return STATUS_DRIVER_UNABLE_TO_LOAD;
1551 case EFI_INVALID_PARAMETER:
1552 return STATUS_INVALID_PARAMETER;
1553 case EFI_UNSUPPORTED:
1554 return STATUS_NOT_SUPPORTED;
1555 case EFI_BAD_BUFFER_SIZE:
1556 return STATUS_INVALID_BUFFER_SIZE;
1557 default:
1558 return STATUS_UNSUCCESSFUL;
1559 }
1560 }