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