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