]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
Remove EFI_BDS_ARCH_PROTOCOL_INSTANCE from PlatformBdsLib.h and BdsDxe module
[mirror_edk2.git] / OvmfPkg / Library / PlatformBdsLib / BdsPlatform.c
1 /** @file
2 Platform BDS customizations.
3
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "BdsPlatform.h"
16
17
18 //
19 // BDS Platform Functions
20 //
21 VOID
22 EFIAPI
23 PlatformBdsInit (
24 VOID
25 )
26 /*++
27
28 Routine Description:
29
30 Platform Bds init. Incude the platform firmware vendor, revision
31 and so crc check.
32
33 Arguments:
34
35 Returns:
36
37 None.
38
39 --*/
40 {
41 DEBUG ((EFI_D_INFO, "PlatformBdsInit\n"));
42 }
43
44
45 EFI_STATUS
46 ConnectRootBridge (
47 VOID
48 )
49 /*++
50
51 Routine Description:
52
53 Connect RootBridge
54
55 Arguments:
56
57 None.
58
59 Returns:
60
61 EFI_SUCCESS - Connect RootBridge successfully.
62 EFI_STATUS - Connect RootBridge fail.
63
64 --*/
65 {
66 EFI_STATUS Status;
67 EFI_HANDLE RootHandle;
68
69 //
70 // Make all the PCI_IO protocols on PCI Seg 0 show up
71 //
72 BdsLibConnectDevicePath (gPlatformRootBridges[0]);
73
74 Status = gBS->LocateDevicePath (
75 &gEfiDevicePathProtocolGuid,
76 &gPlatformRootBridges[0],
77 &RootHandle
78 );
79 if (EFI_ERROR (Status)) {
80 return Status;
81 }
82
83 Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);
84 if (EFI_ERROR (Status)) {
85 return Status;
86 }
87
88 return EFI_SUCCESS;
89 }
90
91
92 EFI_STATUS
93 PrepareLpcBridgeDevicePath (
94 IN EFI_HANDLE DeviceHandle
95 )
96 /*++
97
98 Routine Description:
99
100 Add IsaKeyboard to ConIn,
101 add IsaSerial to ConOut, ConIn, ErrOut.
102 LPC Bridge: 06 01 00
103
104 Arguments:
105
106 DeviceHandle - Handle of PCIIO protocol.
107
108 Returns:
109
110 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
111 EFI_STATUS - No LPC bridge is added.
112
113 --*/
114 {
115 EFI_STATUS Status;
116 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
117 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
118 CHAR16 *DevPathStr;
119
120 DevicePath = NULL;
121 Status = gBS->HandleProtocol (
122 DeviceHandle,
123 &gEfiDevicePathProtocolGuid,
124 (VOID*)&DevicePath
125 );
126 if (EFI_ERROR (Status)) {
127 return Status;
128 }
129 TempDevicePath = DevicePath;
130
131 //
132 // Register Keyboard
133 //
134 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
135
136 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
137
138 //
139 // Register COM1
140 //
141 DevicePath = TempDevicePath;
142 gPnp16550ComPortDeviceNode.UID = 0;
143
144 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
145 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
146 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
147
148 //
149 // Print Device Path
150 //
151 DevPathStr = DevicePathToStr(DevicePath);
152 DEBUG((
153 EFI_D_INFO,
154 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
155 __LINE__,
156 gPnp16550ComPortDeviceNode.UID + 1,
157 DevPathStr
158 ));
159 FreePool(DevPathStr);
160
161 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
162 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
163 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
164
165 //
166 // Register COM2
167 //
168 DevicePath = TempDevicePath;
169 gPnp16550ComPortDeviceNode.UID = 1;
170
171 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
172 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
173 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
174
175 //
176 // Print Device Path
177 //
178 DevPathStr = DevicePathToStr(DevicePath);
179 DEBUG((
180 EFI_D_INFO,
181 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
182 __LINE__,
183 gPnp16550ComPortDeviceNode.UID + 1,
184 DevPathStr
185 ));
186 FreePool(DevPathStr);
187
188 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
189 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
190 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
191
192 return EFI_SUCCESS;
193 }
194
195 EFI_STATUS
196 GetGopDevicePath (
197 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
198 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
199 )
200 {
201 UINTN Index;
202 EFI_STATUS Status;
203 EFI_HANDLE PciDeviceHandle;
204 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
205 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
206 UINTN GopHandleCount;
207 EFI_HANDLE *GopHandleBuffer;
208
209 if (PciDevicePath == NULL || GopDevicePath == NULL) {
210 return EFI_INVALID_PARAMETER;
211 }
212
213 //
214 // Initialize the GopDevicePath to be PciDevicePath
215 //
216 *GopDevicePath = PciDevicePath;
217 TempPciDevicePath = PciDevicePath;
218
219 Status = gBS->LocateDevicePath (
220 &gEfiDevicePathProtocolGuid,
221 &TempPciDevicePath,
222 &PciDeviceHandle
223 );
224 if (EFI_ERROR (Status)) {
225 return Status;
226 }
227
228 //
229 // Try to connect this handle, so that GOP dirver could start on this
230 // device and create child handles with GraphicsOutput Protocol installed
231 // on them, then we get device paths of these child handles and select
232 // them as possible console device.
233 //
234 gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);
235
236 Status = gBS->LocateHandleBuffer (
237 ByProtocol,
238 &gEfiGraphicsOutputProtocolGuid,
239 NULL,
240 &GopHandleCount,
241 &GopHandleBuffer
242 );
243 if (!EFI_ERROR (Status)) {
244 //
245 // Add all the child handles as possible Console Device
246 //
247 for (Index = 0; Index < GopHandleCount; Index++) {
248 Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);
249 if (EFI_ERROR (Status)) {
250 continue;
251 }
252 if (CompareMem (
253 PciDevicePath,
254 TempDevicePath,
255 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
256 ) == 0) {
257 //
258 // In current implementation, we only enable one of the child handles
259 // as console device, i.e. sotre one of the child handle's device
260 // path to variable "ConOut"
261 // In futhure, we could select all child handles to be console device
262 //
263
264 *GopDevicePath = TempDevicePath;
265
266 //
267 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
268 // Add the integrity GOP device path.
269 //
270 BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath);
271 BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL);
272 }
273 }
274 gBS->FreePool (GopHandleBuffer);
275 }
276
277 return EFI_SUCCESS;
278 }
279
280 EFI_STATUS
281 PreparePciVgaDevicePath (
282 IN EFI_HANDLE DeviceHandle
283 )
284 /*++
285
286 Routine Description:
287
288 Add PCI VGA to ConOut.
289 PCI VGA: 03 00 00
290
291 Arguments:
292
293 DeviceHandle - Handle of PCIIO protocol.
294
295 Returns:
296
297 EFI_SUCCESS - PCI VGA is added to ConOut.
298 EFI_STATUS - No PCI VGA device is added.
299
300 --*/
301 {
302 EFI_STATUS Status;
303 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
304 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
305
306 DevicePath = NULL;
307 Status = gBS->HandleProtocol (
308 DeviceHandle,
309 &gEfiDevicePathProtocolGuid,
310 (VOID*)&DevicePath
311 );
312 if (EFI_ERROR (Status)) {
313 return Status;
314 }
315
316 GetGopDevicePath (DevicePath, &GopDevicePath);
317 DevicePath = GopDevicePath;
318
319 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
320
321 return EFI_SUCCESS;
322 }
323
324 EFI_STATUS
325 PreparePciSerialDevicePath (
326 IN EFI_HANDLE DeviceHandle
327 )
328 /*++
329
330 Routine Description:
331
332 Add PCI Serial to ConOut, ConIn, ErrOut.
333 PCI Serial: 07 00 02
334
335 Arguments:
336
337 DeviceHandle - Handle of PCIIO protocol.
338
339 Returns:
340
341 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
342 EFI_STATUS - No PCI Serial device is added.
343
344 --*/
345 {
346 EFI_STATUS Status;
347 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
348
349 DevicePath = NULL;
350 Status = gBS->HandleProtocol (
351 DeviceHandle,
352 &gEfiDevicePathProtocolGuid,
353 (VOID*)&DevicePath
354 );
355 if (EFI_ERROR (Status)) {
356 return Status;
357 }
358
359 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
360 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
361
362 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
363 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
364 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
365
366 return EFI_SUCCESS;
367 }
368
369 EFI_STATUS
370 DetectAndPreparePlatformPciDevicePath (
371 BOOLEAN DetectVgaOnly
372 )
373 /*++
374
375 Routine Description:
376
377 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
378
379 Arguments:
380
381 DetectVgaOnly - Only detect VGA device if it's TRUE.
382
383 Returns:
384
385 EFI_SUCCESS - PCI Device check and Console variable update successfully.
386 EFI_STATUS - PCI Device check or Console variable update fail.
387
388 --*/
389 {
390 EFI_STATUS Status;
391 UINTN HandleCount;
392 EFI_HANDLE *HandleBuffer;
393 UINTN Index;
394 EFI_PCI_IO_PROTOCOL *PciIo;
395 PCI_TYPE00 Pci;
396
397 //
398 // Start to check all the PciIo to find all possible device
399 //
400 HandleCount = 0;
401 HandleBuffer = NULL;
402 Status = gBS->LocateHandleBuffer (
403 ByProtocol,
404 &gEfiPciIoProtocolGuid,
405 NULL,
406 &HandleCount,
407 &HandleBuffer
408 );
409 if (EFI_ERROR (Status)) {
410 return Status;
411 }
412
413 for (Index = 0; Index < HandleCount; Index++) {
414 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);
415 if (EFI_ERROR (Status)) {
416 continue;
417 }
418
419 //
420 // Check for all PCI device
421 //
422 Status = PciIo->Pci.Read (
423 PciIo,
424 EfiPciIoWidthUint32,
425 0,
426 sizeof (Pci) / sizeof (UINT32),
427 &Pci
428 );
429 if (EFI_ERROR (Status)) {
430 continue;
431 }
432
433 if (!DetectVgaOnly) {
434 //
435 // Here we decide whether it is LPC Bridge
436 //
437 if ((IS_PCI_LPC (&Pci)) ||
438 ((IS_PCI_ISA_PDECODE (&Pci)) &&
439 (Pci.Hdr.VendorId == 0x8086) &&
440 (Pci.Hdr.DeviceId == 0x7000)
441 )
442 ) {
443 Status = PciIo->Attributes (
444 PciIo,
445 EfiPciIoAttributeOperationEnable,
446 EFI_PCI_DEVICE_ENABLE,
447 NULL
448 );
449 //
450 // Add IsaKeyboard to ConIn,
451 // add IsaSerial to ConOut, ConIn, ErrOut
452 //
453 DEBUG ((EFI_D_INFO, "Find the LPC Bridge device\n"));
454 PrepareLpcBridgeDevicePath (HandleBuffer[Index]);
455 continue;
456 }
457 //
458 // Here we decide which Serial device to enable in PCI bus
459 //
460 if (IS_PCI_16550SERIAL (&Pci)) {
461 //
462 // Add them to ConOut, ConIn, ErrOut.
463 //
464 DEBUG ((EFI_D_INFO, "Find the 16550 SERIAL device\n"));
465 PreparePciSerialDevicePath (HandleBuffer[Index]);
466 continue;
467 }
468 }
469
470 if ((Pci.Hdr.VendorId == 0x8086) &&
471 (Pci.Hdr.DeviceId == 0x7010)
472 ) {
473 Status = PciIo->Attributes (
474 PciIo,
475 EfiPciIoAttributeOperationEnable,
476 EFI_PCI_DEVICE_ENABLE,
477 NULL
478 );
479 }
480
481 //
482 // Here we decide which VGA device to enable in PCI bus
483 //
484 if (IS_PCI_VGA (&Pci)) {
485 //
486 // Add them to ConOut.
487 //
488 DEBUG ((EFI_D_INFO, "Find the VGA device\n"));
489 PreparePciVgaDevicePath (HandleBuffer[Index]);
490 continue;
491 }
492 }
493
494 gBS->FreePool (HandleBuffer);
495
496 return EFI_SUCCESS;
497 }
498
499
500 EFI_STATUS
501 PlatformBdsConnectConsole (
502 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
503 )
504 /*++
505
506 Routine Description:
507
508 Connect the predefined platform default console device. Always try to find
509 and enable the vga device if have.
510
511 Arguments:
512
513 PlatformConsole - Predfined platform default console device array.
514
515 Returns:
516
517 EFI_SUCCESS - Success connect at least one ConIn and ConOut
518 device, there must have one ConOut device is
519 active vga device.
520
521 EFI_STATUS - Return the status of
522 BdsLibConnectAllDefaultConsoles ()
523
524 --*/
525 {
526 EFI_STATUS Status;
527 UINTN Index;
528 EFI_DEVICE_PATH_PROTOCOL *VarConout;
529 EFI_DEVICE_PATH_PROTOCOL *VarConin;
530 UINTN DevicePathSize;
531
532 //
533 // Connect RootBridge
534 //
535 ConnectRootBridge ();
536
537 VarConout = BdsLibGetVariableAndSize (
538 VarConsoleOut,
539 &gEfiGlobalVariableGuid,
540 &DevicePathSize
541 );
542 VarConin = BdsLibGetVariableAndSize (
543 VarConsoleInp,
544 &gEfiGlobalVariableGuid,
545 &DevicePathSize
546 );
547
548 if (VarConout == NULL || VarConin == NULL) {
549 //
550 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
551 //
552 DetectAndPreparePlatformPciDevicePath (FALSE);
553
554 //
555 // Have chance to connect the platform default console,
556 // the platform default console is the minimue device group
557 // the platform should support
558 //
559 for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
560 //
561 // Update the console variable with the connect type
562 //
563 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
564 BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);
565 }
566 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
567 BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);
568 }
569 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
570 BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);
571 }
572 }
573 } else {
574 //
575 // Only detect VGA device and add them to ConOut
576 //
577 DetectAndPreparePlatformPciDevicePath (TRUE);
578 }
579
580 //
581 // Connect the all the default console with current cosole variable
582 //
583 Status = BdsLibConnectAllDefaultConsoles ();
584 if (EFI_ERROR (Status)) {
585 return Status;
586 }
587
588 return EFI_SUCCESS;
589 }
590
591
592 VOID
593 PciInitialization (
594 )
595 {
596 //
597 // Device 0 Function 0
598 //
599 PciWrite8 (PCI_LIB_ADDRESS (0,0,0,0x3c), 0x00);
600
601 //
602 // Device 1 Function 0
603 //
604 PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x3c), 0x00);
605 PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x60), 0x8b);
606 PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x61), 0x89);
607 PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x62), 0x0a);
608 PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x63), 0x89);
609 //PciWrite8 (PCI_LIB_ADDRESS (0,1,0,0x82), 0x02);
610
611 //
612 // Device 1 Function 1
613 //
614 PciWrite8 (PCI_LIB_ADDRESS (0,1,1,0x3c), 0x00);
615
616 //
617 // Device 1 Function 3
618 //
619 PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x3c), 0x0b);
620 PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x3d), 0x01);
621 PciWrite8 (PCI_LIB_ADDRESS (0,1,3,0x5f), 0x90);
622
623 //
624 // Device 2 Function 0
625 //
626 PciWrite8 (PCI_LIB_ADDRESS (0,2,0,0x3c), 0x00);
627
628 //
629 // Device 3 Function 0
630 //
631 PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3c), 0x0b);
632 PciWrite8 (PCI_LIB_ADDRESS (0,3,0,0x3d), 0x01);
633 }
634
635
636 VOID
637 PlatformBdsConnectSequence (
638 VOID
639 )
640 /*++
641
642 Routine Description:
643
644 Connect with predeined platform connect sequence,
645 the OEM/IBV can customize with their own connect sequence.
646
647 Arguments:
648
649 None.
650
651 Returns:
652
653 None.
654
655 --*/
656 {
657 UINTN Index;
658
659 DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));
660
661 Index = 0;
662
663 //
664 // Here we can get the customized platform connect sequence
665 // Notes: we can connect with new variable which record the
666 // last time boots connect device path sequence
667 //
668 while (gPlatformConnectSequence[Index] != NULL) {
669 //
670 // Build the platform boot option
671 //
672 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
673 Index++;
674 }
675
676 //
677 // Just use the simple policy to connect all devices
678 //
679 BdsLibConnectAll ();
680
681 PciInitialization ();
682 }
683
684 VOID
685 PlatformBdsGetDriverOption (
686 IN OUT LIST_ENTRY *BdsDriverLists
687 )
688 /*++
689
690 Routine Description:
691
692 Load the predefined driver option, OEM/IBV can customize this
693 to load their own drivers
694
695 Arguments:
696
697 BdsDriverLists - The header of the driver option link list.
698
699 Returns:
700
701 None.
702
703 --*/
704 {
705 DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n"));
706 return;
707 }
708
709 VOID
710 PlatformBdsDiagnostics (
711 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
712 IN BOOLEAN QuietBoot
713 )
714 /*++
715
716 Routine Description:
717
718 Perform the platform diagnostic, such like test memory. OEM/IBV also
719 can customize this fuction to support specific platform diagnostic.
720
721 Arguments:
722
723 MemoryTestLevel - The memory test intensive level
724
725 QuietBoot - Indicate if need to enable the quiet boot
726
727 Returns:
728
729 None.
730
731 --*/
732 {
733 EFI_STATUS Status;
734
735 DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));
736
737 //
738 // Here we can decide if we need to show
739 // the diagnostics screen
740 // Notes: this quiet boot code should be remove
741 // from the graphic lib
742 //
743 if (QuietBoot) {
744 EnableQuietBoot (&gEfiDefaultBmpLogoGuid);
745 //
746 // Perform system diagnostic
747 //
748 Status = BdsMemoryTest (MemoryTestLevel);
749 if (EFI_ERROR (Status)) {
750 DisableQuietBoot ();
751 }
752
753 return ;
754 }
755 //
756 // Perform system diagnostic
757 //
758 Status = BdsMemoryTest (MemoryTestLevel);
759 }
760
761
762 VOID
763 EFIAPI
764 PlatformBdsPolicyBehavior (
765 IN OUT LIST_ENTRY *DriverOptionList,
766 IN OUT LIST_ENTRY *BootOptionList
767 )
768 /*++
769
770 Routine Description:
771
772 The function will excute with as the platform policy, current policy
773 is driven by boot mode. IBV/OEM can customize this code for their specific
774 policy action.
775
776 Arguments:
777
778 DriverOptionList - The header of the driver option link list
779
780 BootOptionList - The header of the boot option link list
781
782 Returns:
783
784 None.
785
786 --*/
787 {
788 EFI_STATUS Status;
789 UINT16 Timeout;
790 EFI_EVENT UserInputDurationTime;
791 LIST_ENTRY *Link;
792 BDS_COMMON_OPTION *BootOption;
793 UINTN Index;
794 EFI_INPUT_KEY Key;
795 EFI_TPL OldTpl;
796 EFI_BOOT_MODE BootMode;
797
798 DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));
799
800 //
801 // Init the time out value
802 //
803 Timeout = PcdGet16 (PcdPlatformBootTimeOut);
804
805 //
806 // Load the driver option as the driver option list
807 //
808 PlatformBdsGetDriverOption (DriverOptionList);
809
810 //
811 // Get current Boot Mode
812 //
813 Status = BdsLibGetBootMode (&BootMode);
814 DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));
815
816 //
817 // Go the different platform policy with different boot mode
818 // Notes: this part code can be change with the table policy
819 //
820 ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
821 //
822 // Connect platform console
823 //
824 Status = PlatformBdsConnectConsole (gPlatformConsole);
825 if (EFI_ERROR (Status)) {
826 //
827 // Here OEM/IBV can customize with defined action
828 //
829 PlatformBdsNoConsoleAction ();
830 }
831 //
832 // Create a 300ms duration event to ensure user has enough input time to enter Setup
833 //
834 Status = gBS->CreateEvent (
835 EVT_TIMER,
836 0,
837 NULL,
838 NULL,
839 &UserInputDurationTime
840 );
841 ASSERT (Status == EFI_SUCCESS);
842 Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);
843 ASSERT (Status == EFI_SUCCESS);
844 //
845 // Memory test and Logo show
846 //
847 PlatformBdsDiagnostics (IGNORE, TRUE);
848
849 //
850 // Perform some platform specific connect sequence
851 //
852 PlatformBdsConnectSequence ();
853
854 //
855 // Give one chance to enter the setup if we
856 // have the time out
857 //
858 if (Timeout != 0) {
859 //PlatformBdsEnterFrontPage (Timeout, FALSE);
860 }
861
862 DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));
863 BdsLibConnectAll ();
864 BdsLibEnumerateAllBootOption (BootOptionList);
865
866 //
867 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
868 // checking code in real production tip.
869 //
870 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
871 // and do enumerate all the default boot options. But in development system board, the boot mode
872 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
873 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
874 //
875 Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
876 if (EFI_ERROR(Status)) {
877 //
878 // If cannot find "BootOrder" variable, it may be first boot.
879 // Try to connect all devices and enumerate all boot options here.
880 //
881 BdsLibConnectAll ();
882 BdsLibEnumerateAllBootOption (BootOptionList);
883 }
884
885 //
886 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
887 // BDS should still give user a chance to enter Setup
888 //
889 // Connect first boot option, and then check user input before exit
890 //
891 for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {
892 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);
893 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {
894 //
895 // skip the header of the link list, becuase it has no boot option
896 //
897 continue;
898 } else {
899 //
900 // Make sure the boot option device path connected, but ignore the BBS device path
901 //
902 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {
903 BdsLibConnectDevicePath (BootOption->DevicePath);
904 }
905 break;
906 }
907 }
908
909 //
910 // Check whether the user input after the duration time has expired
911 //
912 OldTpl = EfiGetCurrentTpl();
913 gBS->RestoreTPL (TPL_APPLICATION);
914 gBS->WaitForEvent (1, &UserInputDurationTime, &Index);
915 gBS->CloseEvent (UserInputDurationTime);
916 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
917 gBS->RaiseTPL (OldTpl);
918
919 if (!EFI_ERROR (Status)) {
920 //
921 // Enter Setup if user input
922 //
923 Timeout = 0xffff;
924 PlatformBdsEnterFrontPage (Timeout, FALSE);
925 }
926
927 return ;
928 }
929
930 VOID
931 EFIAPI
932 PlatformBdsBootSuccess (
933 IN BDS_COMMON_OPTION *Option
934 )
935 /*++
936
937 Routine Description:
938
939 Hook point after a boot attempt succeeds. We don't expect a boot option to
940 return, so the EFI 1.0 specification defines that you will default to an
941 interactive mode and stop processing the BootOrder list in this case. This
942 is alos a platform implementation and can be customized by IBV/OEM.
943
944 Arguments:
945
946 Option - Pointer to Boot Option that succeeded to boot.
947
948 Returns:
949
950 None.
951
952 --*/
953 {
954 CHAR16 *TmpStr;
955
956 DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));
957 //
958 // If Boot returned with EFI_SUCCESS and there is not in the boot device
959 // select loop then we need to pop up a UI and wait for user input.
960 //
961 TmpStr = Option->StatusString;
962 if (TmpStr != NULL) {
963 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
964 FreePool (TmpStr);
965 }
966 }
967
968 VOID
969 EFIAPI
970 PlatformBdsBootFail (
971 IN BDS_COMMON_OPTION *Option,
972 IN EFI_STATUS Status,
973 IN CHAR16 *ExitData,
974 IN UINTN ExitDataSize
975 )
976 /*++
977
978 Routine Description:
979
980 Hook point after a boot attempt fails.
981
982 Arguments:
983
984 Option - Pointer to Boot Option that failed to boot.
985
986 Status - Status returned from failed boot.
987
988 ExitData - Exit data returned from failed boot.
989
990 ExitDataSize - Exit data size returned from failed boot.
991
992 Returns:
993
994 None.
995
996 --*/
997 {
998 CHAR16 *TmpStr;
999
1000 DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));
1001
1002 //
1003 // If Boot returned with failed status then we need to pop up a UI and wait
1004 // for user input.
1005 //
1006 TmpStr = Option->StatusString;
1007 if (TmpStr != NULL) {
1008 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
1009 FreePool (TmpStr);
1010 }
1011 }
1012
1013 EFI_STATUS
1014 PlatformBdsNoConsoleAction (
1015 VOID
1016 )
1017 /*++
1018
1019 Routine Description:
1020
1021 This function is remained for IBV/OEM to do some platform action,
1022 if there no console device can be connected.
1023
1024 Arguments:
1025
1026 None.
1027
1028 Returns:
1029
1030 EFI_SUCCESS - Direct return success now.
1031
1032 --*/
1033 {
1034 DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));
1035 return EFI_SUCCESS;
1036 }
1037
1038 EFI_STATUS
1039 EFIAPI
1040 PlatformBdsLockNonUpdatableFlash (
1041 VOID
1042 )
1043 {
1044 DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));
1045 return EFI_SUCCESS;
1046 }