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