]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
OvmfPkg/PlatformBootManagerLib: Follow PlatformBootManagerLib interfaces
[mirror_edk2.git] / OvmfPkg / Library / PlatformBootManagerLib / BdsPlatform.c
CommitLineData
30541881
RN
1/** @file\r
2 Platform BDS customizations.\r
3\r
a7566234 4 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
30541881
RN
5 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#include <Guid/RootBridgesConnectedEventGroup.h>\r
17#include <Library/QemuBootOrderLib.h>\r
18\r
19\r
20//\r
21// Global data\r
22//\r
23\r
24VOID *mEfiDevPathNotifyReg;\r
25EFI_EVENT mEfiDevPathEvent;\r
26VOID *mEmuVariableEventReg;\r
27EFI_EVENT mEmuVariableEvent;\r
28BOOLEAN mDetectVgaOnly;\r
29UINT16 mHostBridgeDevId;\r
30\r
31//\r
32// Table of host IRQs matching PCI IRQs A-D\r
33// (for configuring PCI Interrupt Line register)\r
34//\r
35CONST UINT8 PciHostIrqs[] = {\r
36 0x0a, 0x0a, 0x0b, 0x0b\r
37};\r
38\r
39//\r
40// Array Size macro\r
41//\r
42#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))\r
43\r
44//\r
45// Type definitions\r
46//\r
47\r
48typedef\r
49EFI_STATUS\r
50(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(\r
51 IN EFI_HANDLE Handle,\r
52 IN VOID *Instance,\r
53 IN VOID *Context\r
54 );\r
55\r
56/**\r
57 @param[in] Handle - Handle of PCI device instance\r
58 @param[in] PciIo - PCI IO protocol instance\r
59 @param[in] Pci - PCI Header register block\r
60**/\r
61typedef\r
62EFI_STATUS\r
63(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(\r
64 IN EFI_HANDLE Handle,\r
65 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
66 IN PCI_TYPE00 *Pci\r
67 );\r
68\r
69\r
70//\r
71// Function prototypes\r
72//\r
73\r
74EFI_STATUS\r
75VisitAllInstancesOfProtocol (\r
76 IN EFI_GUID *Id,\r
77 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,\r
78 IN VOID *Context\r
79 );\r
80\r
81EFI_STATUS\r
82VisitAllPciInstancesOfProtocol (\r
83 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
84 );\r
85\r
86VOID\r
87InstallDevicePathCallback (\r
88 VOID\r
89 );\r
90\r
91EFI_STATUS\r
92EFIAPI\r
93ConnectRootBridge (\r
94 IN EFI_HANDLE RootBridgeHandle,\r
95 IN VOID *Instance,\r
96 IN VOID *Context\r
97 );\r
98\r
99STATIC\r
100VOID\r
101SaveS3BootScript (\r
102 VOID\r
103 );\r
104\r
105//\r
106// BDS Platform Functions\r
107//\r
108VOID\r
109EFIAPI\r
a7566234 110PlatformBootManagerBeforeConsole (\r
30541881
RN
111 VOID\r
112 )\r
113/*++\r
114\r
115Routine Description:\r
116\r
117 Platform Bds init. Incude the platform firmware vendor, revision\r
118 and so crc check.\r
119\r
120Arguments:\r
121\r
122Returns:\r
123\r
124 None.\r
125\r
126--*/\r
127{\r
128 EFI_HANDLE Handle;\r
129 EFI_STATUS Status;\r
130\r
a7566234 131 DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));\r
30541881
RN
132 InstallDevicePathCallback ();\r
133\r
134 VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,\r
135 ConnectRootBridge, NULL);\r
136\r
137 //\r
138 // Signal the ACPI platform driver that it can download QEMU ACPI tables.\r
139 //\r
140 EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid);\r
141\r
142 //\r
143 // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers\r
144 // the preparation of S3 system information. That logic has a hard dependency\r
145 // on the presence of the FACS ACPI table. Since our ACPI tables are only\r
146 // installed after PCI enumeration completes, we must not trigger the S3 save\r
147 // earlier, hence we can't signal End-of-Dxe earlier.\r
148 //\r
149 EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);\r
150\r
151 if (QemuFwCfgS3Enabled ()) {\r
152 //\r
153 // Save the boot script too. Note that this will require us to emit the\r
154 // DxeSmmReadyToLock event just below, which in turn locks down SMM.\r
155 //\r
156 SaveS3BootScript ();\r
157 }\r
158\r
159 //\r
160 // Prevent further changes to LockBoxes or SMRAM.\r
161 //\r
162 Handle = NULL;\r
163 Status = gBS->InstallProtocolInterface (&Handle,\r
164 &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,\r
165 NULL);\r
166 ASSERT_EFI_ERROR (Status);\r
167}\r
168\r
169\r
170EFI_STATUS\r
171EFIAPI\r
172ConnectRootBridge (\r
173 IN EFI_HANDLE RootBridgeHandle,\r
174 IN VOID *Instance,\r
175 IN VOID *Context\r
176 )\r
177{\r
178 EFI_STATUS Status;\r
179\r
180 //\r
181 // Make the PCI bus driver connect the root bridge, non-recursively. This\r
182 // will produce a number of child handles with PciIo on them.\r
183 //\r
184 Status = gBS->ConnectController (\r
185 RootBridgeHandle, // ControllerHandle\r
186 NULL, // DriverImageHandle\r
187 NULL, // RemainingDevicePath -- produce all\r
188 // children\r
189 FALSE // Recursive\r
190 );\r
191 return Status;\r
192}\r
193\r
194\r
195EFI_STATUS\r
196PrepareLpcBridgeDevicePath (\r
197 IN EFI_HANDLE DeviceHandle\r
198 )\r
199/*++\r
200\r
201Routine Description:\r
202\r
203 Add IsaKeyboard to ConIn,\r
204 add IsaSerial to ConOut, ConIn, ErrOut.\r
205 LPC Bridge: 06 01 00\r
206\r
207Arguments:\r
208\r
209 DeviceHandle - Handle of PCIIO protocol.\r
210\r
211Returns:\r
212\r
213 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.\r
214 EFI_STATUS - No LPC bridge is added.\r
215\r
216--*/\r
217{\r
218 EFI_STATUS Status;\r
219 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
220 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
221 CHAR16 *DevPathStr;\r
222\r
223 DevicePath = NULL;\r
224 Status = gBS->HandleProtocol (\r
225 DeviceHandle,\r
226 &gEfiDevicePathProtocolGuid,\r
227 (VOID*)&DevicePath\r
228 );\r
229 if (EFI_ERROR (Status)) {\r
230 return Status;\r
231 }\r
232 TempDevicePath = DevicePath;\r
233\r
234 //\r
235 // Register Keyboard\r
236 //\r
237 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
238\r
239 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
240\r
241 //\r
242 // Register COM1\r
243 //\r
244 DevicePath = TempDevicePath;\r
245 gPnp16550ComPortDeviceNode.UID = 0;\r
246\r
247 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
248 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
249 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
250\r
251 //\r
252 // Print Device Path\r
253 //\r
254 DevPathStr = DevicePathToStr(DevicePath);\r
255 if (DevPathStr != NULL) {\r
256 DEBUG((\r
257 EFI_D_INFO,\r
258 "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
259 __LINE__,\r
260 gPnp16550ComPortDeviceNode.UID + 1,\r
261 DevPathStr\r
262 ));\r
263 FreePool(DevPathStr);\r
264 }\r
265\r
266 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
267 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
268 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
269\r
270 //\r
271 // Register COM2\r
272 //\r
273 DevicePath = TempDevicePath;\r
274 gPnp16550ComPortDeviceNode.UID = 1;\r
275\r
276 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
277 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
278 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
279\r
280 //\r
281 // Print Device Path\r
282 //\r
283 DevPathStr = DevicePathToStr(DevicePath);\r
284 if (DevPathStr != NULL) {\r
285 DEBUG((\r
286 EFI_D_INFO,\r
287 "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
288 __LINE__,\r
289 gPnp16550ComPortDeviceNode.UID + 1,\r
290 DevPathStr\r
291 ));\r
292 FreePool(DevPathStr);\r
293 }\r
294\r
295 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
296 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
297 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
298\r
299 return EFI_SUCCESS;\r
300}\r
301\r
302EFI_STATUS\r
303GetGopDevicePath (\r
304 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
305 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
306 )\r
307{\r
308 UINTN Index;\r
309 EFI_STATUS Status;\r
310 EFI_HANDLE PciDeviceHandle;\r
311 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
312 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;\r
313 UINTN GopHandleCount;\r
314 EFI_HANDLE *GopHandleBuffer;\r
315\r
316 if (PciDevicePath == NULL || GopDevicePath == NULL) {\r
317 return EFI_INVALID_PARAMETER;\r
318 }\r
319\r
320 //\r
321 // Initialize the GopDevicePath to be PciDevicePath\r
322 //\r
323 *GopDevicePath = PciDevicePath;\r
324 TempPciDevicePath = PciDevicePath;\r
325\r
326 Status = gBS->LocateDevicePath (\r
327 &gEfiDevicePathProtocolGuid,\r
328 &TempPciDevicePath,\r
329 &PciDeviceHandle\r
330 );\r
331 if (EFI_ERROR (Status)) {\r
332 return Status;\r
333 }\r
334\r
335 //\r
336 // Try to connect this handle, so that GOP dirver could start on this\r
337 // device and create child handles with GraphicsOutput Protocol installed\r
338 // on them, then we get device paths of these child handles and select\r
339 // them as possible console device.\r
340 //\r
341 gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);\r
342\r
343 Status = gBS->LocateHandleBuffer (\r
344 ByProtocol,\r
345 &gEfiGraphicsOutputProtocolGuid,\r
346 NULL,\r
347 &GopHandleCount,\r
348 &GopHandleBuffer\r
349 );\r
350 if (!EFI_ERROR (Status)) {\r
351 //\r
352 // Add all the child handles as possible Console Device\r
353 //\r
354 for (Index = 0; Index < GopHandleCount; Index++) {\r
355 Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
356 if (EFI_ERROR (Status)) {\r
357 continue;\r
358 }\r
359 if (CompareMem (\r
360 PciDevicePath,\r
361 TempDevicePath,\r
362 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
363 ) == 0) {\r
364 //\r
365 // In current implementation, we only enable one of the child handles\r
366 // as console device, i.e. sotre one of the child handle's device\r
367 // path to variable "ConOut"\r
368 // In futhure, we could select all child handles to be console device\r
369 //\r
370\r
371 *GopDevicePath = TempDevicePath;\r
372\r
373 //\r
374 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()\r
375 // Add the integrity GOP device path.\r
376 //\r
377 BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath);\r
378 BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL);\r
379 }\r
380 }\r
381 gBS->FreePool (GopHandleBuffer);\r
382 }\r
383\r
384 return EFI_SUCCESS;\r
385}\r
386\r
387EFI_STATUS\r
388PreparePciVgaDevicePath (\r
389 IN EFI_HANDLE DeviceHandle\r
390 )\r
391/*++\r
392\r
393Routine Description:\r
394\r
395 Add PCI VGA to ConOut.\r
396 PCI VGA: 03 00 00\r
397\r
398Arguments:\r
399\r
400 DeviceHandle - Handle of PCIIO protocol.\r
401\r
402Returns:\r
403\r
404 EFI_SUCCESS - PCI VGA is added to ConOut.\r
405 EFI_STATUS - No PCI VGA device is added.\r
406\r
407--*/\r
408{\r
409 EFI_STATUS Status;\r
410 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
411 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;\r
412\r
413 DevicePath = NULL;\r
414 GopDevicePath = NULL;\r
415 Status = gBS->HandleProtocol (\r
416 DeviceHandle,\r
417 &gEfiDevicePathProtocolGuid,\r
418 (VOID*)&DevicePath\r
419 );\r
420 if (EFI_ERROR (Status)) {\r
421 return Status;\r
422 }\r
423\r
424 GetGopDevicePath (DevicePath, &GopDevicePath);\r
425 DevicePath = GopDevicePath;\r
426\r
427 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
428\r
429 return EFI_SUCCESS;\r
430}\r
431\r
432EFI_STATUS\r
433PreparePciSerialDevicePath (\r
434 IN EFI_HANDLE DeviceHandle\r
435 )\r
436/*++\r
437\r
438Routine Description:\r
439\r
440 Add PCI Serial to ConOut, ConIn, ErrOut.\r
441 PCI Serial: 07 00 02\r
442\r
443Arguments:\r
444\r
445 DeviceHandle - Handle of PCIIO protocol.\r
446\r
447Returns:\r
448\r
449 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.\r
450 EFI_STATUS - No PCI Serial device is added.\r
451\r
452--*/\r
453{\r
454 EFI_STATUS Status;\r
455 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
456\r
457 DevicePath = NULL;\r
458 Status = gBS->HandleProtocol (\r
459 DeviceHandle,\r
460 &gEfiDevicePathProtocolGuid,\r
461 (VOID*)&DevicePath\r
462 );\r
463 if (EFI_ERROR (Status)) {\r
464 return Status;\r
465 }\r
466\r
467 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
468 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
469\r
470 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
471 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
472 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
473\r
474 return EFI_SUCCESS;\r
475}\r
476\r
477EFI_STATUS\r
478VisitAllInstancesOfProtocol (\r
479 IN EFI_GUID *Id,\r
480 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction,\r
481 IN VOID *Context\r
482 )\r
483{\r
484 EFI_STATUS Status;\r
485 UINTN HandleCount;\r
486 EFI_HANDLE *HandleBuffer;\r
487 UINTN Index;\r
488 VOID *Instance;\r
489\r
490 //\r
491 // Start to check all the PciIo to find all possible device\r
492 //\r
493 HandleCount = 0;\r
494 HandleBuffer = NULL;\r
495 Status = gBS->LocateHandleBuffer (\r
496 ByProtocol,\r
497 Id,\r
498 NULL,\r
499 &HandleCount,\r
500 &HandleBuffer\r
501 );\r
502 if (EFI_ERROR (Status)) {\r
503 return Status;\r
504 }\r
505\r
506 for (Index = 0; Index < HandleCount; Index++) {\r
507 Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);\r
508 if (EFI_ERROR (Status)) {\r
509 continue;\r
510 }\r
511\r
512 Status = (*CallBackFunction) (\r
513 HandleBuffer[Index],\r
514 Instance,\r
515 Context\r
516 );\r
517 }\r
518\r
519 gBS->FreePool (HandleBuffer);\r
520\r
521 return EFI_SUCCESS;\r
522}\r
523\r
524\r
525EFI_STATUS\r
526EFIAPI\r
527VisitingAPciInstance (\r
528 IN EFI_HANDLE Handle,\r
529 IN VOID *Instance,\r
530 IN VOID *Context\r
531 )\r
532{\r
533 EFI_STATUS Status;\r
534 EFI_PCI_IO_PROTOCOL *PciIo;\r
535 PCI_TYPE00 Pci;\r
536\r
537 PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;\r
538\r
539 //\r
540 // Check for all PCI device\r
541 //\r
542 Status = PciIo->Pci.Read (\r
543 PciIo,\r
544 EfiPciIoWidthUint32,\r
545 0,\r
546 sizeof (Pci) / sizeof (UINT32),\r
547 &Pci\r
548 );\r
549 if (EFI_ERROR (Status)) {\r
550 return Status;\r
551 }\r
552\r
553 return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (\r
554 Handle,\r
555 PciIo,\r
556 &Pci\r
557 );\r
558\r
559}\r
560\r
561\r
562\r
563EFI_STATUS\r
564VisitAllPciInstances (\r
565 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
566 )\r
567{\r
568 return VisitAllInstancesOfProtocol (\r
569 &gEfiPciIoProtocolGuid,\r
570 VisitingAPciInstance,\r
571 (VOID*)(UINTN) CallBackFunction\r
572 );\r
573}\r
574\r
575\r
576/**\r
577 Do platform specific PCI Device check and add them to\r
578 ConOut, ConIn, ErrOut.\r
579\r
580 @param[in] Handle - Handle of PCI device instance\r
581 @param[in] PciIo - PCI IO protocol instance\r
582 @param[in] Pci - PCI Header register block\r
583\r
584 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
585 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
586\r
587**/\r
588EFI_STATUS\r
589EFIAPI\r
590DetectAndPreparePlatformPciDevicePath (\r
591 IN EFI_HANDLE Handle,\r
592 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
593 IN PCI_TYPE00 *Pci\r
594 )\r
595{\r
596 EFI_STATUS Status;\r
597\r
598 Status = PciIo->Attributes (\r
599 PciIo,\r
600 EfiPciIoAttributeOperationEnable,\r
601 EFI_PCI_DEVICE_ENABLE,\r
602 NULL\r
603 );\r
604 ASSERT_EFI_ERROR (Status);\r
605\r
606 if (!mDetectVgaOnly) {\r
607 //\r
608 // Here we decide whether it is LPC Bridge\r
609 //\r
610 if ((IS_PCI_LPC (Pci)) ||\r
611 ((IS_PCI_ISA_PDECODE (Pci)) &&\r
612 (Pci->Hdr.VendorId == 0x8086) &&\r
613 (Pci->Hdr.DeviceId == 0x7000)\r
614 )\r
615 ) {\r
616 //\r
617 // Add IsaKeyboard to ConIn,\r
618 // add IsaSerial to ConOut, ConIn, ErrOut\r
619 //\r
620 DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));\r
621 PrepareLpcBridgeDevicePath (Handle);\r
622 return EFI_SUCCESS;\r
623 }\r
624 //\r
625 // Here we decide which Serial device to enable in PCI bus\r
626 //\r
627 if (IS_PCI_16550SERIAL (Pci)) {\r
628 //\r
629 // Add them to ConOut, ConIn, ErrOut.\r
630 //\r
631 DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));\r
632 PreparePciSerialDevicePath (Handle);\r
633 return EFI_SUCCESS;\r
634 }\r
635 }\r
636\r
637 //\r
638 // Here we decide which VGA device to enable in PCI bus\r
639 //\r
640 if (IS_PCI_VGA (Pci)) {\r
641 //\r
642 // Add them to ConOut.\r
643 //\r
644 DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));\r
645 PreparePciVgaDevicePath (Handle);\r
646 return EFI_SUCCESS;\r
647 }\r
648\r
649 return Status;\r
650}\r
651\r
652\r
653/**\r
654 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
655\r
656 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.\r
657\r
658 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
659 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
660\r
661**/\r
662EFI_STATUS\r
663DetectAndPreparePlatformPciDevicePaths (\r
664 BOOLEAN DetectVgaOnly\r
665 )\r
666{\r
667 mDetectVgaOnly = DetectVgaOnly;\r
668 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\r
669}\r
670\r
671\r
672EFI_STATUS\r
673PlatformBdsConnectConsole (\r
674 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
675 )\r
676/*++\r
677\r
678Routine Description:\r
679\r
680 Connect the predefined platform default console device. Always try to find\r
681 and enable the vga device if have.\r
682\r
683Arguments:\r
684\r
685 PlatformConsole - Predfined platform default console device array.\r
686\r
687Returns:\r
688\r
689 EFI_SUCCESS - Success connect at least one ConIn and ConOut\r
690 device, there must have one ConOut device is\r
691 active vga device.\r
692\r
693 EFI_STATUS - Return the status of\r
694 BdsLibConnectAllDefaultConsoles ()\r
695\r
696--*/\r
697{\r
698 EFI_STATUS Status;\r
699 UINTN Index;\r
700 EFI_DEVICE_PATH_PROTOCOL *VarConout;\r
701 EFI_DEVICE_PATH_PROTOCOL *VarConin;\r
702 UINTN DevicePathSize;\r
703\r
704 //\r
705 // Connect RootBridge\r
706 //\r
707 VarConout = BdsLibGetVariableAndSize (\r
708 VarConsoleOut,\r
709 &gEfiGlobalVariableGuid,\r
710 &DevicePathSize\r
711 );\r
712 VarConin = BdsLibGetVariableAndSize (\r
713 VarConsoleInp,\r
714 &gEfiGlobalVariableGuid,\r
715 &DevicePathSize\r
716 );\r
717\r
718 if (VarConout == NULL || VarConin == NULL) {\r
719 //\r
720 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
721 //\r
722 DetectAndPreparePlatformPciDevicePaths (FALSE);\r
723\r
724 //\r
725 // Have chance to connect the platform default console,\r
726 // the platform default console is the minimue device group\r
727 // the platform should support\r
728 //\r
729 for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
730 //\r
731 // Update the console variable with the connect type\r
732 //\r
733 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
734 BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);\r
735 }\r
736 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
737 BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);\r
738 }\r
739 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
740 BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);\r
741 }\r
742 }\r
743 } else {\r
744 //\r
745 // Only detect VGA device and add them to ConOut\r
746 //\r
747 DetectAndPreparePlatformPciDevicePaths (TRUE);\r
748 }\r
749\r
750 //\r
751 // Connect the all the default console with current cosole variable\r
752 //\r
753 Status = BdsLibConnectAllDefaultConsoles ();\r
754 if (EFI_ERROR (Status)) {\r
755 return Status;\r
756 }\r
757\r
758 return EFI_SUCCESS;\r
759}\r
760\r
761\r
762/**\r
763 Configure PCI Interrupt Line register for applicable devices\r
764 Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq()\r
765\r
766 @param[in] Handle - Handle of PCI device instance\r
767 @param[in] PciIo - PCI IO protocol instance\r
768 @param[in] PciHdr - PCI Header register block\r
769\r
770 @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully.\r
771\r
772**/\r
773EFI_STATUS\r
774EFIAPI\r
775SetPciIntLine (\r
776 IN EFI_HANDLE Handle,\r
777 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
778 IN PCI_TYPE00 *PciHdr\r
779 )\r
780{\r
781 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
782 EFI_DEVICE_PATH_PROTOCOL *DevPath;\r
783 UINTN RootSlot;\r
784 UINTN Idx;\r
785 UINT8 IrqLine;\r
786 EFI_STATUS Status;\r
787 UINT32 RootBusNumber;\r
788\r
789 Status = EFI_SUCCESS;\r
790\r
791 if (PciHdr->Device.InterruptPin != 0) {\r
792\r
793 DevPathNode = DevicePathFromHandle (Handle);\r
794 ASSERT (DevPathNode != NULL);\r
795 DevPath = DevPathNode;\r
796\r
797 RootBusNumber = 0;\r
798 if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH &&\r
799 DevicePathSubType (DevPathNode) == ACPI_DP &&\r
800 ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) {\r
801 RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID;\r
802 }\r
803\r
804 //\r
805 // Compute index into PciHostIrqs[] table by walking\r
806 // the device path and adding up all device numbers\r
807 //\r
808 Status = EFI_NOT_FOUND;\r
809 RootSlot = 0;\r
810 Idx = PciHdr->Device.InterruptPin - 1;\r
811 while (!IsDevicePathEnd (DevPathNode)) {\r
812 if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&\r
813 DevicePathSubType (DevPathNode) == HW_PCI_DP) {\r
814\r
815 Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
816\r
817 //\r
818 // Unlike SeaBIOS, which starts climbing from the leaf device\r
819 // up toward the root, we traverse the device path starting at\r
820 // the root moving toward the leaf node.\r
821 // The slot number of the top-level parent bridge is needed for\r
822 // Q35 cases with more than 24 slots on the root bus.\r
823 //\r
824 if (Status != EFI_SUCCESS) {\r
825 Status = EFI_SUCCESS;\r
826 RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
827 }\r
828 }\r
829\r
830 DevPathNode = NextDevicePathNode (DevPathNode);\r
831 }\r
832 if (EFI_ERROR (Status)) {\r
833 return Status;\r
834 }\r
835 if (RootBusNumber == 0 && RootSlot == 0) {\r
836 DEBUG((\r
837 EFI_D_ERROR,\r
838 "%a: PCI host bridge (00:00.0) should have no interrupts!\n",\r
839 __FUNCTION__\r
840 ));\r
841 ASSERT (FALSE);\r
842 }\r
843\r
844 //\r
845 // Final PciHostIrqs[] index calculation depends on the platform\r
846 // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()\r
847 //\r
848 switch (mHostBridgeDevId) {\r
849 case INTEL_82441_DEVICE_ID:\r
850 Idx -= 1;\r
851 break;\r
852 case INTEL_Q35_MCH_DEVICE_ID:\r
853 //\r
854 // SeaBIOS contains the following comment:\r
855 // "Slots 0-24 rotate slot:pin mapping similar to piix above, but\r
856 // with a different starting index - see q35-acpi-dsdt.dsl.\r
857 //\r
858 // Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"\r
859 //\r
860 if (RootSlot > 24) {\r
861 //\r
862 // in this case, subtract back out RootSlot from Idx\r
863 // (SeaBIOS never adds it to begin with, but that would make our\r
864 // device path traversal loop above too awkward)\r
865 //\r
866 Idx -= RootSlot;\r
867 }\r
868 break;\r
869 default:\r
870 ASSERT (FALSE); // should never get here\r
871 }\r
872 Idx %= ARRAY_SIZE (PciHostIrqs);\r
873 IrqLine = PciHostIrqs[Idx];\r
874\r
875 DEBUG_CODE_BEGIN ();\r
876 {\r
877 CHAR16 *DevPathString;\r
878 STATIC CHAR16 Fallback[] = L"<failed to convert>";\r
879 UINTN Segment, Bus, Device, Function;\r
880\r
881 DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE);\r
882 if (DevPathString == NULL) {\r
883 DevPathString = Fallback;\r
884 }\r
885 Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
886 ASSERT_EFI_ERROR (Status);\r
887\r
888 DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,\r
889 (UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString,\r
890 IrqLine));\r
891\r
892 if (DevPathString != Fallback) {\r
893 FreePool (DevPathString);\r
894 }\r
895 }\r
896 DEBUG_CODE_END ();\r
897\r
898 //\r
899 // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]\r
900 //\r
901 Status = PciIo->Pci.Write (\r
902 PciIo,\r
903 EfiPciIoWidthUint8,\r
904 PCI_INT_LINE_OFFSET,\r
905 1,\r
906 &IrqLine\r
907 );\r
908 }\r
909\r
910 return Status;\r
911}\r
912\r
913\r
914VOID\r
915PciAcpiInitialization (\r
916 )\r
917{\r
918 UINTN Pmba;\r
919\r
920 //\r
921 // Query Host Bridge DID to determine platform type\r
922 //\r
923 mHostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);\r
924 switch (mHostBridgeDevId) {\r
925 case INTEL_82441_DEVICE_ID:\r
926 Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);\r
927 //\r
928 // 00:01.0 ISA Bridge (PIIX4) LNK routing targets\r
929 //\r
930 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A\r
931 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B\r
932 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C\r
933 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D\r
934 break;\r
935 case INTEL_Q35_MCH_DEVICE_ID:\r
936 Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);\r
937 //\r
938 // 00:1f.0 LPC Bridge (Q35) LNK routing targets\r
939 //\r
940 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A\r
941 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B\r
942 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C\r
943 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D\r
944 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E\r
945 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F\r
946 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G\r
947 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H\r
948 break;\r
949 default:\r
950 DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
951 __FUNCTION__, mHostBridgeDevId));\r
952 ASSERT (FALSE);\r
953 return;\r
954 }\r
955\r
956 //\r
957 // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices\r
958 //\r
959 VisitAllPciInstances (SetPciIntLine);\r
960\r
961 //\r
962 // Set ACPI SCI_EN bit in PMCNTRL\r
963 //\r
964 IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);\r
965}\r
966\r
967\r
968EFI_STATUS\r
969EFIAPI\r
970ConnectRecursivelyIfPciMassStorage (\r
971 IN EFI_HANDLE Handle,\r
972 IN EFI_PCI_IO_PROTOCOL *Instance,\r
973 IN PCI_TYPE00 *PciHeader\r
974 )\r
975{\r
976 EFI_STATUS Status;\r
977 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
978 CHAR16 *DevPathStr;\r
979\r
980 if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {\r
981 DevicePath = NULL;\r
982 Status = gBS->HandleProtocol (\r
983 Handle,\r
984 &gEfiDevicePathProtocolGuid,\r
985 (VOID*)&DevicePath\r
986 );\r
987 if (EFI_ERROR (Status)) {\r
988 return Status;\r
989 }\r
990\r
991 //\r
992 // Print Device Path\r
993 //\r
994 DevPathStr = DevicePathToStr (DevicePath);\r
995 if (DevPathStr != NULL) {\r
996 DEBUG((\r
997 EFI_D_INFO,\r
998 "Found Mass Storage device: %s\n",\r
999 DevPathStr\r
1000 ));\r
1001 FreePool(DevPathStr);\r
1002 }\r
1003\r
1004 Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
1005 if (EFI_ERROR (Status)) {\r
1006 return Status;\r
1007 }\r
1008\r
1009 }\r
1010\r
1011 return EFI_SUCCESS;\r
1012}\r
1013\r
1014\r
1015/**\r
1016 This notification function is invoked when the\r
1017 EMU Variable FVB has been changed.\r
1018\r
1019 @param Event The event that occured\r
1020 @param Context For EFI compatiblity. Not used.\r
1021\r
1022**/\r
1023VOID\r
1024EFIAPI\r
1025EmuVariablesUpdatedCallback (\r
1026 IN EFI_EVENT Event,\r
1027 IN VOID *Context\r
1028 )\r
1029{\r
1030 DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));\r
1031 UpdateNvVarsOnFileSystem ();\r
1032}\r
1033\r
1034\r
1035EFI_STATUS\r
1036EFIAPI\r
1037VisitingFileSystemInstance (\r
1038 IN EFI_HANDLE Handle,\r
1039 IN VOID *Instance,\r
1040 IN VOID *Context\r
1041 )\r
1042{\r
1043 EFI_STATUS Status;\r
1044 STATIC BOOLEAN ConnectedToFileSystem = FALSE;\r
1045\r
1046 if (ConnectedToFileSystem) {\r
1047 return EFI_ALREADY_STARTED;\r
1048 }\r
1049\r
1050 Status = ConnectNvVarsToFileSystem (Handle);\r
1051 if (EFI_ERROR (Status)) {\r
1052 return Status;\r
1053 }\r
1054\r
1055 ConnectedToFileSystem = TRUE;\r
1056 mEmuVariableEvent =\r
1057 EfiCreateProtocolNotifyEvent (\r
1058 &gEfiDevicePathProtocolGuid,\r
1059 TPL_CALLBACK,\r
1060 EmuVariablesUpdatedCallback,\r
1061 NULL,\r
1062 &mEmuVariableEventReg\r
1063 );\r
1064 PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);\r
1065\r
1066 return EFI_SUCCESS;\r
1067}\r
1068\r
1069\r
1070VOID\r
1071PlatformBdsRestoreNvVarsFromHardDisk (\r
1072 )\r
1073{\r
1074 VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);\r
1075 VisitAllInstancesOfProtocol (\r
1076 &gEfiSimpleFileSystemProtocolGuid,\r
1077 VisitingFileSystemInstance,\r
1078 NULL\r
1079 );\r
1080\r
1081}\r
1082\r
1083\r
1084VOID\r
1085PlatformBdsConnectSequence (\r
1086 VOID\r
1087 )\r
1088/*++\r
1089\r
1090Routine Description:\r
1091\r
1092 Connect with predeined platform connect sequence,\r
1093 the OEM/IBV can customize with their own connect sequence.\r
1094\r
1095Arguments:\r
1096\r
1097 None.\r
1098\r
1099Returns:\r
1100\r
1101 None.\r
1102\r
1103--*/\r
1104{\r
1105 UINTN Index;\r
1106\r
1107 DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));\r
1108\r
1109 Index = 0;\r
1110\r
1111 //\r
1112 // Here we can get the customized platform connect sequence\r
1113 // Notes: we can connect with new variable which record the\r
1114 // last time boots connect device path sequence\r
1115 //\r
1116 while (gPlatformConnectSequence[Index] != NULL) {\r
1117 //\r
1118 // Build the platform boot option\r
1119 //\r
1120 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
1121 Index++;\r
1122 }\r
1123\r
1124 //\r
1125 // Just use the simple policy to connect all devices\r
1126 //\r
1127 BdsLibConnectAll ();\r
1128\r
1129 PciAcpiInitialization ();\r
1130\r
1131 //\r
1132 // Clear the logo after all devices are connected.\r
1133 //\r
1134 gST->ConOut->ClearScreen (gST->ConOut);\r
1135}\r
1136\r
1137VOID\r
1138PlatformBdsGetDriverOption (\r
1139 IN OUT LIST_ENTRY *BdsDriverLists\r
1140 )\r
1141/*++\r
1142\r
1143Routine Description:\r
1144\r
1145 Load the predefined driver option, OEM/IBV can customize this\r
1146 to load their own drivers\r
1147\r
1148Arguments:\r
1149\r
1150 BdsDriverLists - The header of the driver option link list.\r
1151\r
1152Returns:\r
1153\r
1154 None.\r
1155\r
1156--*/\r
1157{\r
1158 DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n"));\r
1159 return;\r
1160}\r
1161\r
1162VOID\r
1163PlatformBdsDiagnostics (\r
1164 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
1165 IN BOOLEAN QuietBoot,\r
1166 IN BASEM_MEMORY_TEST BaseMemoryTest\r
1167 )\r
1168/*++\r
1169\r
1170Routine Description:\r
1171\r
1172 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
1173 can customize this fuction to support specific platform diagnostic.\r
1174\r
1175Arguments:\r
1176\r
1177 MemoryTestLevel - The memory test intensive level\r
1178\r
1179 QuietBoot - Indicate if need to enable the quiet boot\r
1180\r
1181 BaseMemoryTest - A pointer to BaseMemoryTest()\r
1182\r
1183Returns:\r
1184\r
1185 None.\r
1186\r
1187--*/\r
1188{\r
1189 EFI_STATUS Status;\r
1190\r
1191 DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));\r
1192\r
1193 //\r
1194 // Here we can decide if we need to show\r
1195 // the diagnostics screen\r
1196 // Notes: this quiet boot code should be remove\r
1197 // from the graphic lib\r
1198 //\r
1199 if (QuietBoot) {\r
1200 EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
1201 //\r
1202 // Perform system diagnostic\r
1203 //\r
1204 Status = BaseMemoryTest (MemoryTestLevel);\r
1205 if (EFI_ERROR (Status)) {\r
1206 DisableQuietBoot ();\r
1207 }\r
1208\r
1209 return ;\r
1210 }\r
1211 //\r
1212 // Perform system diagnostic\r
1213 //\r
1214 Status = BaseMemoryTest (MemoryTestLevel);\r
1215}\r
1216\r
1217\r
1218/**\r
1219 Save the S3 boot script.\r
1220\r
1221 Note that DxeSmmReadyToLock must be signaled after this function returns;\r
1222 otherwise the script wouldn't be saved actually.\r
1223**/\r
1224STATIC\r
1225VOID\r
1226SaveS3BootScript (\r
1227 VOID\r
1228 )\r
1229{\r
1230 EFI_STATUS Status;\r
1231 EFI_S3_SAVE_STATE_PROTOCOL *BootScript;\r
1232 STATIC CONST UINT8 Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };\r
1233\r
1234 Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,\r
1235 (VOID **) &BootScript);\r
1236 ASSERT_EFI_ERROR (Status);\r
1237\r
1238 //\r
1239 // Despite the opcode documentation in the PI spec, the protocol\r
1240 // implementation embeds a deep copy of the info in the boot script, rather\r
1241 // than storing just a pointer to runtime or NVS storage.\r
1242 //\r
1243 Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE,\r
1244 (UINT32) sizeof Info,\r
1245 (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);\r
1246 ASSERT_EFI_ERROR (Status);\r
1247}\r
1248\r
1249\r
1250VOID\r
1251EFIAPI\r
a7566234
RN
1252PlatformBootManagerAfterConsole (\r
1253 VOID\r
30541881
RN
1254 )\r
1255/*++\r
1256\r
1257Routine Description:\r
1258\r
1259 The function will excute with as the platform policy, current policy\r
1260 is driven by boot mode. IBV/OEM can customize this code for their specific\r
1261 policy action.\r
1262\r
30541881
RN
1263--*/\r
1264{\r
1265 EFI_STATUS Status;\r
1266 EFI_BOOT_MODE BootMode;\r
1267\r
a7566234 1268 DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));\r
30541881
RN
1269\r
1270 if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {\r
1271 DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "\r
1272 "from disk since flash variables appear to be supported.\n"));\r
1273 } else {\r
1274 //\r
1275 // Try to restore variables from the hard disk early so\r
1276 // they can be used for the other BDS connect operations.\r
1277 //\r
1278 PlatformBdsRestoreNvVarsFromHardDisk ();\r
1279 }\r
1280\r
1281 //\r
1282 // Load the driver option as the driver option list\r
1283 //\r
1284 PlatformBdsGetDriverOption (DriverOptionList);\r
1285\r
1286 //\r
1287 // Get current Boot Mode\r
1288 //\r
1289 Status = BdsLibGetBootMode (&BootMode);\r
1290 DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
1291\r
1292 //\r
1293 // Go the different platform policy with different boot mode\r
1294 // Notes: this part code can be change with the table policy\r
1295 //\r
1296 ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
1297 //\r
1298 // Connect platform console\r
1299 //\r
1300 Status = PlatformBdsConnectConsole (gPlatformConsole);\r
1301 if (EFI_ERROR (Status)) {\r
1302 //\r
1303 // Here OEM/IBV can customize with defined action\r
1304 //\r
1305 PlatformBdsNoConsoleAction ();\r
1306 }\r
1307\r
1308 //\r
1309 // Memory test and Logo show\r
1310 //\r
1311 PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
1312\r
1313 //\r
1314 // Perform some platform specific connect sequence\r
1315 //\r
1316 PlatformBdsConnectSequence ();\r
1317\r
1318 //\r
1319 // Process QEMU's -kernel command line option\r
1320 //\r
1321 TryRunningQemuKernel ();\r
1322\r
1323 DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));\r
1324 BdsLibConnectAll ();\r
1325 BdsLibEnumerateAllBootOption (BootOptionList);\r
1326\r
1327 SetBootOrderFromQemu (BootOptionList);\r
1328 //\r
1329 // The BootOrder variable may have changed, reload the in-memory list with\r
1330 // it.\r
1331 //\r
1332 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
1333\r
1334 PlatformBdsEnterFrontPage (GetFrontPageTimeoutFromQemu(), TRUE);\r
1335}\r
1336\r
1337VOID\r
1338EFIAPI\r
1339PlatformBdsBootSuccess (\r
1340 IN BDS_COMMON_OPTION *Option\r
1341 )\r
1342/*++\r
1343\r
1344Routine Description:\r
1345\r
1346 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
1347 return, so the EFI 1.0 specification defines that you will default to an\r
1348 interactive mode and stop processing the BootOrder list in this case. This\r
1349 is alos a platform implementation and can be customized by IBV/OEM.\r
1350\r
1351Arguments:\r
1352\r
1353 Option - Pointer to Boot Option that succeeded to boot.\r
1354\r
1355Returns:\r
1356\r
1357 None.\r
1358\r
1359--*/\r
1360{\r
1361 CHAR16 *TmpStr;\r
1362\r
1363 DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));\r
1364 //\r
1365 // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
1366 // select loop then we need to pop up a UI and wait for user input.\r
1367 //\r
1368 TmpStr = Option->StatusString;\r
1369 if (TmpStr != NULL) {\r
1370 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1371 FreePool (TmpStr);\r
1372 }\r
1373}\r
1374\r
1375VOID\r
1376EFIAPI\r
1377PlatformBdsBootFail (\r
1378 IN BDS_COMMON_OPTION *Option,\r
1379 IN EFI_STATUS Status,\r
1380 IN CHAR16 *ExitData,\r
1381 IN UINTN ExitDataSize\r
1382 )\r
1383/*++\r
1384\r
1385Routine Description:\r
1386\r
1387 Hook point after a boot attempt fails.\r
1388\r
1389Arguments:\r
1390\r
1391 Option - Pointer to Boot Option that failed to boot.\r
1392\r
1393 Status - Status returned from failed boot.\r
1394\r
1395 ExitData - Exit data returned from failed boot.\r
1396\r
1397 ExitDataSize - Exit data size returned from failed boot.\r
1398\r
1399Returns:\r
1400\r
1401 None.\r
1402\r
1403--*/\r
1404{\r
1405 CHAR16 *TmpStr;\r
1406\r
1407 DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));\r
1408\r
1409 //\r
1410 // If Boot returned with failed status then we need to pop up a UI and wait\r
1411 // for user input.\r
1412 //\r
1413 TmpStr = Option->StatusString;\r
1414 if (TmpStr != NULL) {\r
1415 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1416 FreePool (TmpStr);\r
1417 }\r
1418}\r
1419\r
1420EFI_STATUS\r
1421PlatformBdsNoConsoleAction (\r
1422 VOID\r
1423 )\r
1424/*++\r
1425\r
1426Routine Description:\r
1427\r
1428 This function is remained for IBV/OEM to do some platform action,\r
1429 if there no console device can be connected.\r
1430\r
1431Arguments:\r
1432\r
1433 None.\r
1434\r
1435Returns:\r
1436\r
1437 EFI_SUCCESS - Direct return success now.\r
1438\r
1439--*/\r
1440{\r
1441 DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));\r
1442 return EFI_SUCCESS;\r
1443}\r
1444\r
1445VOID\r
1446EFIAPI\r
1447PlatformBdsLockNonUpdatableFlash (\r
1448 VOID\r
1449 )\r
1450{\r
1451 DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
1452 return;\r
1453}\r
1454\r
1455\r
1456/**\r
1457 This notification function is invoked when an instance of the\r
1458 EFI_DEVICE_PATH_PROTOCOL is produced.\r
1459\r
1460 @param Event The event that occured\r
1461 @param Context For EFI compatiblity. Not used.\r
1462\r
1463**/\r
1464VOID\r
1465EFIAPI\r
1466NotifyDevPath (\r
1467 IN EFI_EVENT Event,\r
1468 IN VOID *Context\r
1469 )\r
1470{\r
1471 EFI_HANDLE Handle;\r
1472 EFI_STATUS Status;\r
1473 UINTN BufferSize;\r
1474 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
1475 ATAPI_DEVICE_PATH *Atapi;\r
1476\r
1477 //\r
1478 // Examine all new handles\r
1479 //\r
1480 for (;;) {\r
1481 //\r
1482 // Get the next handle\r
1483 //\r
1484 BufferSize = sizeof (Handle);\r
1485 Status = gBS->LocateHandle (\r
1486 ByRegisterNotify,\r
1487 NULL,\r
1488 mEfiDevPathNotifyReg,\r
1489 &BufferSize,\r
1490 &Handle\r
1491 );\r
1492\r
1493 //\r
1494 // If not found, we're done\r
1495 //\r
1496 if (EFI_NOT_FOUND == Status) {\r
1497 break;\r
1498 }\r
1499\r
1500 if (EFI_ERROR (Status)) {\r
1501 continue;\r
1502 }\r
1503\r
1504 //\r
1505 // Get the DevicePath protocol on that handle\r
1506 //\r
1507 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);\r
1508 ASSERT_EFI_ERROR (Status);\r
1509\r
1510 while (!IsDevicePathEnd (DevPathNode)) {\r
1511 //\r
1512 // Find the handler to dump this device path node\r
1513 //\r
1514 if (\r
1515 (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&\r
1516 (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)\r
1517 ) {\r
1518 Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;\r
1519 PciOr16 (\r
1520 PCI_LIB_ADDRESS (\r
1521 0,\r
1522 1,\r
1523 1,\r
1524 (Atapi->PrimarySecondary == 1) ? 0x42: 0x40\r
1525 ),\r
1526 BIT15\r
1527 );\r
1528 }\r
1529\r
1530 //\r
1531 // Next device path node\r
1532 //\r
1533 DevPathNode = NextDevicePathNode (DevPathNode);\r
1534 }\r
1535 }\r
1536\r
1537 return;\r
1538}\r
1539\r
1540\r
1541VOID\r
1542InstallDevicePathCallback (\r
1543 VOID\r
1544 )\r
1545{\r
1546 DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));\r
1547 mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
1548 &gEfiDevicePathProtocolGuid,\r
1549 TPL_CALLBACK,\r
1550 NotifyDevPath,\r
1551 NULL,\r
1552 &mEfiDevPathNotifyReg\r
1553 );\r
1554}\r
1555\r
a7566234
RN
1556/**\r
1557 This function is called each second during the boot manager waits the timeout.\r
1558\r
1559 @param TimeoutRemain The remaining timeout.\r
1560**/\r
1561VOID\r
1562EFIAPI\r
1563PlatformBootManagerWaitCallback (\r
1564 UINT16 TimeoutRemain\r
1565 )\r
1566{\r
1567}\r
1568\r
30541881
RN
1569/**\r
1570 Lock the ConsoleIn device in system table. All key\r
1571 presses will be ignored until the Password is typed in. The only way to\r
1572 disable the password is to type it in to a ConIn device.\r
1573\r
1574 @param Password Password used to lock ConIn device.\r
1575\r
1576 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
1577 @retval EFI_UNSUPPORTED Password not found\r
1578\r
1579**/\r
1580EFI_STATUS\r
1581EFIAPI\r
1582LockKeyboards (\r
1583 IN CHAR16 *Password\r
1584 )\r
1585{\r
1586 return EFI_UNSUPPORTED;\r
1587}\r
1588\r