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