[BOOTMGFW]:
[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 GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
16
17 PBL_FIRMWARE_DESCRIPTOR EfiFirmwareParameters;
18 BL_FIRMWARE_DESCRIPTOR EfiFirmwareData;
19 EFI_HANDLE EfiImageHandle;
20 EFI_SYSTEM_TABLE* EfiSystemTable;
21
22 EFI_SYSTEM_TABLE *EfiST;
23 EFI_BOOT_SERVICES *EfiBS;
24 EFI_RUNTIME_SERVICES *EfiRT;
25 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *EfiConOut;
26 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *EfiConIn;
27 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *EfiConInEx;
28
29 /* FUNCTIONS *****************************************************************/
30
31 NTSTATUS
32 EfiOpenProtocol (
33 _In_ EFI_HANDLE Handle,
34 _In_ EFI_GUID *Protocol,
35 _Out_ PVOID* Interface
36 )
37 {
38 EFI_STATUS EfiStatus;
39 NTSTATUS Status;
40 BL_ARCH_MODE OldMode;
41
42 /* Are we using virtual memory/ */
43 if (MmTranslationType != BlNone)
44 {
45 /* We need complex tracking to make this work */
46 //Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
47 Status = STATUS_NOT_SUPPORTED;
48 }
49 else
50 {
51 /* Are we in protected mode? */
52 OldMode = CurrentExecutionContext->Mode;
53 if (OldMode != BlRealMode)
54 {
55 /* FIXME: Not yet implemented */
56 return STATUS_NOT_IMPLEMENTED;
57 }
58
59 /* Are we on legacy 1.02? */
60 if (EfiST->FirmwareRevision == EFI_1_02_SYSTEM_TABLE_REVISION)
61 {
62 /* Make the legacy call */
63 EfiStatus = EfiBS->HandleProtocol(Handle, Protocol, Interface);
64 }
65 else
66 {
67 /* Use the UEFI version */
68 EfiStatus = EfiBS->OpenProtocol(Handle,
69 Protocol,
70 Interface,
71 EfiImageHandle,
72 NULL,
73 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
74
75 /* Switch back to protected mode if we came from there */
76 if (OldMode != BlRealMode)
77 {
78 BlpArchSwitchContext(OldMode);
79 }
80 }
81
82 /* Convert the error to an NTSTATUS */
83 Status = EfiGetNtStatusCode(EfiStatus);
84 }
85
86 /* Clear the interface on failure, and return the status */
87 if (!NT_SUCCESS(Status))
88 {
89 *Interface = NULL;
90 }
91
92 return Status;
93 }
94
95 NTSTATUS
96 EfiConInExSetState (
97 _In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *ConInEx,
98 _In_ EFI_KEY_TOGGLE_STATE* KeyToggleState
99 )
100 {
101 BL_ARCH_MODE OldMode;
102 EFI_STATUS EfiStatus;
103
104 /* Are we in protected mode? */
105 OldMode = CurrentExecutionContext->Mode;
106 if (OldMode != BlRealMode)
107 {
108 /* FIXME: Not yet implemented */
109 return STATUS_NOT_IMPLEMENTED;
110 }
111
112 /* Make the EFI call */
113 EfiStatus = ConInEx->SetState(ConInEx, KeyToggleState);
114
115 /* Switch back to protected mode if we came from there */
116 if (OldMode != BlRealMode)
117 {
118 BlpArchSwitchContext(OldMode);
119 }
120
121 /* Convert the error to an NTSTATUS */
122 return EfiGetNtStatusCode(EfiStatus);
123 }
124
125 NTSTATUS
126 EfiSetWatchdogTimer (
127 VOID
128 )
129 {
130 BL_ARCH_MODE OldMode;
131 EFI_STATUS EfiStatus;
132
133 /* Are we in protected mode? */
134 OldMode = CurrentExecutionContext->Mode;
135 if (OldMode != BlRealMode)
136 {
137 /* FIXME: Not yet implemented */
138 return STATUS_NOT_IMPLEMENTED;
139 }
140
141 /* Make the EFI call */
142 EfiStatus = EfiBS->SetWatchdogTimer(0, 0, 0, NULL);
143
144 /* Switch back to protected mode if we came from there */
145 if (OldMode != BlRealMode)
146 {
147 BlpArchSwitchContext(OldMode);
148 }
149
150 /* Convert the error to an NTSTATUS */
151 return EfiGetNtStatusCode(EfiStatus);
152 }
153
154 NTSTATUS
155 EfiGetMemoryMap (
156 _Out_ UINTN* MemoryMapSize,
157 _Inout_ EFI_MEMORY_DESCRIPTOR *MemoryMap,
158 _Out_ UINTN* MapKey,
159 _Out_ UINTN* DescriptorSize,
160 _Out_ UINTN* DescriptorVersion
161 )
162 {
163 BL_ARCH_MODE OldMode;
164 EFI_STATUS EfiStatus;
165
166 /* Are we in protected mode? */
167 OldMode = CurrentExecutionContext->Mode;
168 if (OldMode != BlRealMode)
169 {
170 /* FIXME: Not yet implemented */
171 return STATUS_NOT_IMPLEMENTED;
172 }
173
174 /* Make the EFI call */
175 EfiStatus = EfiBS->GetMemoryMap(MemoryMapSize,
176 MemoryMap,
177 MapKey,
178 DescriptorSize,
179 DescriptorVersion);
180
181 /* Switch back to protected mode if we came from there */
182 if (OldMode != BlRealMode)
183 {
184 BlpArchSwitchContext(OldMode);
185 }
186
187 /* Convert the error to an NTSTATUS */
188 return EfiGetNtStatusCode(EfiStatus);
189 }
190
191 NTSTATUS
192 EfiFreePages (
193 _In_ ULONG Pages,
194 _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress
195 )
196 {
197 BL_ARCH_MODE OldMode;
198 EFI_STATUS EfiStatus;
199
200 /* Are we in protected mode? */
201 OldMode = CurrentExecutionContext->Mode;
202 if (OldMode != BlRealMode)
203 {
204 /* FIXME: Not yet implemented */
205 return STATUS_NOT_IMPLEMENTED;
206 }
207
208 /* Make the EFI call */
209 EfiStatus = EfiBS->FreePages(PhysicalAddress, Pages);
210
211 /* Switch back to protected mode if we came from there */
212 if (OldMode != BlRealMode)
213 {
214 BlpArchSwitchContext(OldMode);
215 }
216
217 /* Convert the error to an NTSTATUS */
218 return EfiGetNtStatusCode(EfiStatus);
219 }
220
221 NTSTATUS
222 EfiAllocatePages (
223 _In_ ULONG Type,
224 _In_ ULONG Pages,
225 _Inout_ EFI_PHYSICAL_ADDRESS* Memory
226 )
227 {
228 BL_ARCH_MODE OldMode;
229 EFI_STATUS EfiStatus;
230
231 /* Are we in protected mode? */
232 OldMode = CurrentExecutionContext->Mode;
233 if (OldMode != BlRealMode)
234 {
235 /* FIXME: Not yet implemented */
236 return STATUS_NOT_IMPLEMENTED;
237 }
238
239 /* Make the EFI call */
240 EfiStatus = EfiBS->AllocatePages(Type, EfiLoaderData, Pages, Memory);
241
242 /* Switch back to protected mode if we came from there */
243 if (OldMode != BlRealMode)
244 {
245 BlpArchSwitchContext(OldMode);
246 }
247
248 /* Convert the error to an NTSTATUS */
249 return EfiGetNtStatusCode(EfiStatus);
250 }
251
252 BL_MEMORY_ATTR
253 MmFwpGetOsAttributeType (
254 _In_ ULONGLONG Attribute
255 )
256 {
257 BL_MEMORY_ATTR OsAttribute = 0;
258
259 if (Attribute & EFI_MEMORY_UC)
260 {
261 OsAttribute = BlMemoryUncached;
262 }
263
264 if (Attribute & EFI_MEMORY_WC)
265 {
266 OsAttribute |= BlMemoryWriteCombined;
267 }
268
269 if (Attribute & EFI_MEMORY_WT)
270 {
271 OsAttribute |= BlMemoryWriteThrough;
272 }
273
274 if (Attribute & EFI_MEMORY_WB)
275 {
276 OsAttribute |= BlMemoryWriteBack;
277 }
278
279 if (Attribute & EFI_MEMORY_UCE)
280 {
281 OsAttribute |= BlMemoryUncachedExported;
282 }
283
284 if (Attribute & EFI_MEMORY_WP)
285 {
286 OsAttribute |= BlMemoryWriteProtected;
287 }
288
289 if (Attribute & EFI_MEMORY_RP)
290 {
291 OsAttribute |= BlMemoryReadProtected;
292 }
293
294 if (Attribute & EFI_MEMORY_XP)
295 {
296 OsAttribute |= BlMemoryExecuteProtected;
297 }
298
299 if (Attribute & EFI_MEMORY_RUNTIME)
300 {
301 OsAttribute |= BlMemoryRuntime;
302 }
303
304 return OsAttribute;
305 }
306
307 BL_MEMORY_TYPE
308 MmFwpGetOsMemoryType (
309 _In_ EFI_MEMORY_TYPE MemoryType
310 )
311 {
312 BL_MEMORY_TYPE OsType;
313
314 switch (MemoryType)
315 {
316 case EfiLoaderCode:
317 case EfiLoaderData:
318 OsType = BlLoaderMemory;
319 break;
320
321 case EfiBootServicesCode:
322 case EfiBootServicesData:
323 OsType = BlEfiBootMemory;
324 break;
325
326 case EfiRuntimeServicesCode:
327 case EfiRuntimeServicesData:
328 OsType = BlEfiRuntimeMemory;
329 break;
330
331 case EfiConventionalMemory:
332 OsType = BlConventionalMemory;
333 break;
334
335 case EfiUnusableMemory:
336 OsType = BlUnusableMemory;
337 break;
338
339 case EfiACPIReclaimMemory:
340 OsType = BlAcpiReclaimMemory;
341 break;
342
343 case EfiACPIMemoryNVS:
344 OsType = BlAcpiNvsMemory;
345 break;
346
347 case EfiMemoryMappedIO:
348 OsType = BlDeviceIoMemory;
349 break;
350
351 case EfiMemoryMappedIOPortSpace:
352 OsType = BlDevicePortMemory;
353 break;
354
355 case EfiPalCode:
356 OsType = BlPalMemory;
357 break;
358
359 default:
360 OsType = BlReservedMemory;
361 break;
362 }
363
364 return OsType;
365 }
366
367 NTSTATUS
368 MmFwGetMemoryMap (
369 _Out_ PBL_MEMORY_DESCRIPTOR_LIST MemoryMap,
370 _In_ ULONG Flags
371 )
372 {
373 BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters;
374 BOOLEAN UseEfiBuffer, HaveRamDisk;
375 NTSTATUS Status;
376 ULONGLONG Pages, StartPage, EndPage;
377 UINTN EfiMemoryMapSize, MapKey, DescriptorSize, DescriptorVersion;
378 EFI_PHYSICAL_ADDRESS EfiBuffer;
379 EFI_MEMORY_DESCRIPTOR* EfiMemoryMap;
380 EFI_STATUS EfiStatus;
381 BL_ARCH_MODE OldMode;
382 EFI_MEMORY_DESCRIPTOR EfiDescriptor;
383 BL_MEMORY_TYPE MemoryType;
384 PBL_MEMORY_DESCRIPTOR Descriptor;
385 BL_MEMORY_ATTR Attribute;
386
387 /* Initialize EFI memory map attributes */
388 EfiMemoryMapSize = MapKey = DescriptorSize = DescriptorVersion = 0;
389
390 /* Increment the nesting depth */
391 MmDescriptorCallTreeCount++;
392
393 /* Determine if we should use EFI or our own allocator at this point */
394 UseEfiBuffer = Flags & BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS;
395 if (!(LibraryParameters.LibraryFlags & BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED))
396 {
397 UseEfiBuffer = TRUE;
398 }
399
400 /* Bail out if we don't have a list to use */
401 if (MemoryMap == NULL)
402 {
403 Status = STATUS_INVALID_PARAMETER;
404 goto Quickie;
405 }
406
407 /* Free the current descriptor list */
408 MmMdFreeList(MemoryMap);
409
410 /* Call into EFI to get the size of the memory map */
411 Status = EfiGetMemoryMap(&EfiMemoryMapSize,
412 NULL,
413 &MapKey,
414 &DescriptorSize,
415 &DescriptorVersion);
416 if (Status != STATUS_BUFFER_TOO_SMALL)
417 {
418 /* This should've failed because our buffer was too small, nothing else */
419 EarlyPrint(L"Got strange EFI status for memory map: %lx\n", Status);
420 if (NT_SUCCESS(Status))
421 {
422 Status = STATUS_UNSUCCESSFUL;
423 }
424 goto Quickie;
425 }
426
427 /* Add 4 more descriptors just in case things changed */
428 EfiMemoryMapSize += (4 * DescriptorSize);
429 Pages = BYTES_TO_PAGES(EfiMemoryMapSize);
430 EarlyPrint(L"Memory map size: %lx bytes, %d pages\n", EfiMemoryMapSize, Pages);
431
432 /* Should we use EFI to grab memory? */
433 if (UseEfiBuffer)
434 {
435 /* Yes -- request one more page to align up correctly */
436 Pages++;
437
438 /* Grab the required pages */
439 Status = EfiAllocatePages(AllocateAnyPages,
440 Pages,
441 &EfiBuffer);
442 if (!NT_SUCCESS(Status))
443 {
444 EarlyPrint(L"EFI allocation failed: %lx\n", Status);
445 goto Quickie;
446 }
447
448 /* Free the pages for now */
449 Status = EfiFreePages(Pages, EfiBuffer);
450 if (!NT_SUCCESS(Status))
451 {
452 EfiBuffer = 0;
453 goto Quickie;
454 }
455
456 /* Now round to the actual buffer size, removing the extra page */
457 EfiBuffer = ROUND_TO_PAGES(EfiBuffer);
458 Pages--;
459 Status = EfiAllocatePages(AllocateAddress,
460 Pages,
461 &EfiBuffer);
462 if (!NT_SUCCESS(Status))
463 {
464 EfiBuffer = 0;
465 goto Quickie;
466 }
467
468 /* Get the final aligned size and proper buffer */
469 EfiMemoryMapSize = EFI_PAGES_TO_SIZE(Pages);
470 EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR*)(ULONG_PTR)EfiBuffer;
471
472 /* Switch to real mode if not already in it */
473 OldMode = CurrentExecutionContext->Mode;
474 if (OldMode != BlRealMode)
475 {
476 BlpArchSwitchContext(BlRealMode);
477 }
478
479 /* Call EFI to get the memory map */
480 EfiStatus = EfiBS->GetMemoryMap(&EfiMemoryMapSize,
481 EfiMemoryMap,
482 &MapKey,
483 &DescriptorSize,
484 &DescriptorVersion);
485
486 /* Switch back into the previous mode */
487 if (OldMode != BlRealMode)
488 {
489 BlpArchSwitchContext(OldMode);
490 }
491
492 /* Convert the result code */
493 Status = EfiGetNtStatusCode(EfiStatus);
494 }
495 else
496 {
497 /* We don't support this path yet */
498 Status = STATUS_NOT_IMPLEMENTED;
499 }
500
501 /* So far so good? */
502 if (!NT_SUCCESS(Status))
503 {
504 EarlyPrint(L"Failed to get EFI memory map: %lx\n", Status);
505 goto Quickie;
506 }
507
508 /* Did we get correct data from firmware? */
509 if (((EfiMemoryMapSize % DescriptorSize)) ||
510 (DescriptorSize < sizeof(EFI_MEMORY_DESCRIPTOR)))
511 {
512 EarlyPrint(L"Incorrect descriptor size\n");
513 Status = STATUS_UNSUCCESSFUL;
514 goto Quickie;
515 }
516
517 /* Did we boot from a RAM disk? */
518 if ((BlpBootDevice->DeviceType == LocalDevice) &&
519 (BlpBootDevice->Local.Type == RamDiskDevice))
520 {
521 /* We don't handle this yet */
522 EarlyPrint(L"RAM boot not supported\n");
523 Status = STATUS_NOT_IMPLEMENTED;
524 goto Quickie;
525 }
526 else
527 {
528 /* We didn't, so there won't be any need to find the memory descriptor */
529 HaveRamDisk = FALSE;
530 }
531
532 /* Loop the EFI memory map */
533 #if 0
534 EarlyPrint(L"UEFI MEMORY MAP\n\n");
535 EarlyPrint(L"TYPE START END ATTRIBUTES\n");
536 EarlyPrint(L"===============================================================\n");
537 #endif
538 while (EfiMemoryMapSize != 0)
539 {
540 /* Check if this is an EFI buffer, but we're not in real mode */
541 if ((UseEfiBuffer) && (OldMode != BlRealMode))
542 {
543 BlpArchSwitchContext(BlRealMode);
544 }
545
546 /* Capture it so we can go back to protected mode (if possible) */
547 EfiDescriptor = *EfiMemoryMap;
548
549 /* Go back to protected mode, if we had switched */
550 if ((UseEfiBuffer) && (OldMode != BlRealMode))
551 {
552 BlpArchSwitchContext(OldMode);
553 }
554
555 /* Convert to OS memory type */
556 MemoryType = MmFwpGetOsMemoryType(EfiDescriptor.Type);
557
558 /* Round up or round down depending on where the memory is coming from */
559 if (MemoryType == BlConventionalMemory)
560 {
561 StartPage = BYTES_TO_PAGES(EfiDescriptor.PhysicalStart);
562 }
563 else
564 {
565 StartPage = EfiDescriptor.PhysicalStart >> PAGE_SHIFT;
566 }
567
568 /* Calculate the ending page */
569 EndPage = StartPage + EfiDescriptor.NumberOfPages;
570
571 /* If after rounding, we ended up with 0 pages, skip this */
572 if (StartPage == EndPage)
573 {
574 goto LoopAgain;
575 }
576 #if 0
577 EarlyPrint(L"%08X 0x%016I64X-0x%016I64X 0x%I64X\n",
578 MemoryType,
579 StartPage << PAGE_SHIFT,
580 EndPage << PAGE_SHIFT,
581 EfiDescriptor.Attribute);
582 #endif
583 /* Check for any range of memory below 1MB */
584 if (StartPage < 0x100)
585 {
586 /* Does this range actually contain NULL? */
587 if (StartPage == 0)
588 {
589 /* Manually create a reserved descriptof for this page */
590 Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute);
591 Descriptor = MmMdInitByteGranularDescriptor(Attribute,
592 BlReservedMemory,
593 0,
594 0,
595 1);
596 if (!Descriptor)
597 {
598 Status = STATUS_INSUFFICIENT_RESOURCES;
599 break;
600 }
601
602 /* Add this descriptor into the list */
603 Status = MmMdAddDescriptorToList(MemoryMap,
604 Descriptor,
605 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG);
606 if (!NT_SUCCESS(Status))
607 {
608 EarlyPrint(L"Failed to add zero page descriptor: %lx\n", Status);
609 break;
610 }
611
612 /* Now handle the rest of the range, unless this was it */
613 StartPage = 1;
614 if (EndPage == 1)
615 {
616 goto LoopAgain;
617 }
618 }
619
620 /* Does the range go beyond 1MB? */
621 if (EndPage > 0x100)
622 {
623 /* Then create the descriptor for everything up until the megabyte */
624 Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute);
625 Descriptor = MmMdInitByteGranularDescriptor(Attribute,
626 MemoryType,
627 StartPage,
628 0,
629 0x100 - StartPage);
630 if (!Descriptor)
631 {
632 Status = STATUS_INSUFFICIENT_RESOURCES;
633 break;
634 }
635
636 /* Check if this region is currently free RAM */
637 if (Descriptor->Type == BlConventionalMemory)
638 {
639 /* Set an unknown flag on the descriptor */
640 Descriptor->Flags |= 0x80000;
641 }
642
643 /* Add this descriptor into the list */
644 Status = MmMdAddDescriptorToList(MemoryMap,
645 Descriptor,
646 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG);
647 if (!NT_SUCCESS(Status))
648 {
649 EarlyPrint(L"Failed to add 1MB descriptor: %lx\n", Status);
650 break;
651 }
652
653 /* Now handle the rest of the range above 1MB */
654 StartPage = 0x100;
655 }
656 }
657
658 /* Check if we loaded from a RAM disk */
659 if (HaveRamDisk)
660 {
661 /* We don't handle this yet */
662 EarlyPrint(L"RAM boot not supported\n");
663 Status = STATUS_NOT_IMPLEMENTED;
664 goto Quickie;
665 }
666
667 /* Create a descriptor for the current range */
668 Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute);
669 Descriptor = MmMdInitByteGranularDescriptor(Attribute,
670 MemoryType,
671 StartPage,
672 0,
673 EndPage - StartPage);
674 if (!Descriptor)
675 {
676 Status = STATUS_INSUFFICIENT_RESOURCES;
677 break;
678 }
679
680 /* Check if this region is currently free RAM below 1MB */
681 if ((Descriptor->Type == BlConventionalMemory) && (EndPage <= 0x100))
682 {
683 /* Set an unknown flag on the descriptor */
684 Descriptor->Flags |= 0x80000;
685 }
686
687 /* Add the descriptor to the list, requesting coalescing as asked */
688 Status = MmMdAddDescriptorToList(MemoryMap,
689 Descriptor,
690 BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG |
691 (Flags & BL_MM_FLAG_REQUEST_COALESCING) ?
692 BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG : 0);
693 if (!NT_SUCCESS(Status))
694 {
695 EarlyPrint(L"Failed to add full descriptor: %lx\n", Status);
696 break;
697 }
698
699 LoopAgain:
700 /* Consume this descriptor, and move to the next one */
701 EfiMemoryMapSize -= DescriptorSize;
702 EfiMemoryMap = (PVOID)((ULONG_PTR)EfiMemoryMap + DescriptorSize);
703 }
704
705 /* FIXME: @TODO: Mark the EfiBuffer as free, since we're about to free it */
706 /* For now, just "leak" the 1-2 pages... */
707
708 Quickie:
709 /* Free the EFI buffer, if we had one */
710 if (EfiBuffer != 0)
711 {
712 EfiFreePages(Pages, EfiBuffer);
713 }
714
715 /* On failure, free the memory map if one was passed in */
716 if (!NT_SUCCESS(Status) && (MemoryMap != NULL))
717 {
718 MmMdFreeList(MemoryMap);
719 }
720
721 /* Decrement the nesting depth and return */
722 MmDescriptorCallTreeCount--;
723 return Status;
724 }
725
726 NTSTATUS
727 BlpFwInitialize (
728 _In_ ULONG Phase,
729 _In_ PBL_FIRMWARE_DESCRIPTOR FirmwareData
730 )
731 {
732 NTSTATUS Status = STATUS_SUCCESS;
733 EFI_KEY_TOGGLE_STATE KeyToggleState;
734
735 /* Check if we have vaild firmware data */
736 if (!(FirmwareData) || !(FirmwareData->Version))
737 {
738 return STATUS_INVALID_PARAMETER;
739 }
740
741 /* Check which boot phase we're in */
742 if (Phase != 0)
743 {
744 /* Memory manager is ready, open the extended input protocol */
745 Status = EfiOpenProtocol(EfiST->ConsoleInHandle,
746 &EfiSimpleTextInputExProtocol,
747 (PVOID*)&EfiConInEx);
748 if (NT_SUCCESS(Status))
749 {
750 /* Set the initial key toggle state */
751 KeyToggleState = EFI_TOGGLE_STATE_VALID | 40;
752 EfiConInExSetState(EfiST->ConsoleInHandle, &KeyToggleState);
753 }
754
755 /* Setup the watchdog timer */
756 EfiSetWatchdogTimer();
757 }
758 else
759 {
760 /* Make a copy of the parameters */
761 EfiFirmwareParameters = &EfiFirmwareData;
762
763 /* Check which version we received */
764 if (FirmwareData->Version == 1)
765 {
766 /* FIXME: Not supported */
767 Status = STATUS_NOT_SUPPORTED;
768 }
769 else if (FirmwareData->Version >= 2)
770 {
771 /* Version 2 -- save the data */
772 EfiFirmwareData = *FirmwareData;
773 EfiSystemTable = FirmwareData->SystemTable;
774 EfiImageHandle = FirmwareData->ImageHandle;
775
776 /* Set the EDK-II style variables as well */
777 EfiST = EfiSystemTable;
778 EfiBS = EfiSystemTable->BootServices;
779 EfiRT = EfiSystemTable->RuntimeServices;
780 EfiConOut = EfiSystemTable->ConOut;
781 EfiConIn = EfiSystemTable->ConIn;
782 EfiConInEx = NULL;
783 }
784 else
785 {
786 /* Unknown version */
787 Status = STATUS_NOT_SUPPORTED;
788 }
789 }
790
791 /* Return the initialization state */
792 return Status;
793 }
794