]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
OvmfPkg: consolidate POWER_MGMT_REGISTER_PIIX4() on "I440FxPiix4.h" macros
[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
752 UINTN RootSlot;\r
753 UINTN Idx;\r
754 UINT8 IrqLine;\r
755 EFI_STATUS Status;\r
756\r
757 Status = EFI_SUCCESS;\r
758\r
759 if (PciHdr->Device.InterruptPin != 0) {\r
760\r
761 DevPathNode = DevicePathFromHandle (Handle);\r
762 ASSERT (DevPathNode != NULL);\r
763\r
764 //\r
765 // Compute index into PciHostIrqs[] table by walking\r
766 // the device path and adding up all device numbers\r
767 //\r
768 Status = EFI_NOT_FOUND;\r
769 RootSlot = 0;\r
770 Idx = PciHdr->Device.InterruptPin - 1;\r
771 while (!IsDevicePathEnd (DevPathNode)) {\r
772 if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&\r
773 DevicePathSubType (DevPathNode) == HW_PCI_DP) {\r
774\r
775 Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
776\r
777 //\r
778 // Unlike SeaBIOS, which starts climbing from the leaf device\r
779 // up toward the root, we traverse the device path starting at\r
780 // the root moving toward the leaf node.\r
781 // The slot number of the top-level parent bridge is needed for\r
782 // Q35 cases with more than 24 slots on the root bus.\r
783 //\r
784 if (Status != EFI_SUCCESS) {\r
785 Status = EFI_SUCCESS;\r
786 RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
787 }\r
788 }\r
789\r
790 DevPathNode = NextDevicePathNode (DevPathNode);\r
791 }\r
792 if (EFI_ERROR (Status)) {\r
793 return Status;\r
794 }\r
795 if (RootSlot == 0) {\r
796 DEBUG((\r
797 EFI_D_ERROR,\r
798 "%a: PCI host bridge (00:00.0) should have no interrupts!\n",\r
799 __FUNCTION__\r
800 ));\r
801 ASSERT (FALSE);\r
802 }\r
803\r
804 //\r
805 // Final PciHostIrqs[] index calculation depends on the platform\r
806 // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()\r
807 //\r
808 switch (mHostBridgeDevId) {\r
809 case INTEL_82441_DEVICE_ID:\r
810 Idx -= 1;\r
811 break;\r
812 case INTEL_Q35_MCH_DEVICE_ID:\r
813 //\r
814 // SeaBIOS contains the following comment:\r
815 // "Slots 0-24 rotate slot:pin mapping similar to piix above, but\r
816 // with a different starting index - see q35-acpi-dsdt.dsl.\r
817 //\r
818 // Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"\r
819 //\r
820 if (RootSlot > 24) {\r
821 //\r
822 // in this case, subtract back out RootSlot from Idx\r
823 // (SeaBIOS never adds it to begin with, but that would make our\r
824 // device path traversal loop above too awkward)\r
825 //\r
826 Idx -= RootSlot;\r
827 }\r
828 break;\r
829 default:\r
830 ASSERT (FALSE); // should never get here\r
831 }\r
832 Idx %= ARRAY_SIZE (PciHostIrqs);\r
833 IrqLine = PciHostIrqs[Idx];\r
834\r
835 //\r
836 // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]\r
837 //\r
838 Status = PciIo->Pci.Write (\r
839 PciIo,\r
840 EfiPciIoWidthUint8,\r
841 PCI_INT_LINE_OFFSET,\r
842 1,\r
843 &IrqLine\r
844 );\r
845 }\r
846\r
847 return Status;\r
848}\r
849\r
850\r
49ba9447 851VOID\r
2e70cf8a 852PciAcpiInitialization (\r
49ba9447 853 )\r
854{\r
2e70cf8a 855 UINTN Pmba;\r
49ba9447 856\r
857 //\r
2e70cf8a 858 // Query Host Bridge DID to determine platform type\r
49ba9447 859 //\r
5218c279
GS
860 mHostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);\r
861 switch (mHostBridgeDevId) {\r
2e70cf8a 862 case INTEL_82441_DEVICE_ID:\r
da372167 863 Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);\r
2e70cf8a
GS
864 //\r
865 // 00:01.0 ISA Bridge (PIIX4) LNK routing targets\r
866 //\r
867 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A\r
868 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B\r
869 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C\r
870 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D\r
871 break;\r
872 case INTEL_Q35_MCH_DEVICE_ID:\r
bc9d05d6 873 Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);\r
2e70cf8a
GS
874 //\r
875 // 00:1f.0 LPC Bridge (Q35) LNK routing targets\r
876 //\r
877 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A\r
878 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B\r
879 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C\r
880 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D\r
881 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E\r
882 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F\r
883 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G\r
884 PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H\r
885 break;\r
886 default:\r
887 DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
5218c279 888 __FUNCTION__, mHostBridgeDevId));\r
2e70cf8a
GS
889 ASSERT (FALSE);\r
890 return;\r
891 }\r
49ba9447 892\r
9b167857 893 //\r
5218c279 894 // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices\r
9b167857 895 //\r
5218c279 896 VisitAllPciInstances (SetPciIntLine);\r
2e70cf8a
GS
897\r
898 //\r
5218c279 899 // Set ACPI SCI_EN bit in PMCNTRL\r
2e70cf8a 900 //\r
5218c279 901 IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);\r
9b167857 902}\r
903\r
904\r
14b21de9 905EFI_STATUS\r
906EFIAPI\r
907ConnectRecursivelyIfPciMassStorage (\r
908 IN EFI_HANDLE Handle,\r
909 IN EFI_PCI_IO_PROTOCOL *Instance,\r
910 IN PCI_TYPE00 *PciHeader\r
911 )\r
912{\r
913 EFI_STATUS Status;\r
914 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
915 CHAR16 *DevPathStr;\r
916\r
917 if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {\r
918 DevicePath = NULL;\r
919 Status = gBS->HandleProtocol (\r
920 Handle,\r
921 &gEfiDevicePathProtocolGuid,\r
922 (VOID*)&DevicePath\r
923 );\r
924 if (EFI_ERROR (Status)) {\r
925 return Status;\r
926 }\r
927\r
928 //\r
929 // Print Device Path\r
930 //\r
931 DevPathStr = DevicePathToStr (DevicePath);\r
863986b3
RN
932 if (DevPathStr != NULL) {\r
933 DEBUG((\r
934 EFI_D_INFO,\r
935 "Found Mass Storage device: %s\n",\r
936 DevPathStr\r
937 ));\r
938 FreePool(DevPathStr);\r
939 }\r
14b21de9 940\r
941 Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
942 if (EFI_ERROR (Status)) {\r
943 return Status;\r
944 }\r
945\r
946 }\r
947\r
948 return EFI_SUCCESS;\r
949}\r
950\r
951\r
9607962d 952/**\r
953 This notification function is invoked when the\r
954 EMU Variable FVB has been changed.\r
955\r
956 @param Event The event that occured\r
957 @param Context For EFI compatiblity. Not used.\r
958\r
959**/\r
960VOID\r
961EFIAPI\r
962EmuVariablesUpdatedCallback (\r
963 IN EFI_EVENT Event,\r
964 IN VOID *Context\r
965 )\r
966{\r
967 DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));\r
968 UpdateNvVarsOnFileSystem ();\r
969}\r
970\r
971\r
14b21de9 972EFI_STATUS\r
973EFIAPI\r
974VisitingFileSystemInstance (\r
975 IN EFI_HANDLE Handle,\r
976 IN VOID *Instance,\r
977 IN VOID *Context\r
978 )\r
979{\r
980 EFI_STATUS Status;\r
981 STATIC BOOLEAN ConnectedToFileSystem = FALSE;\r
982\r
983 if (ConnectedToFileSystem) {\r
984 return EFI_ALREADY_STARTED;\r
985 }\r
986\r
987 Status = ConnectNvVarsToFileSystem (Handle);\r
988 if (EFI_ERROR (Status)) {\r
989 return Status;\r
990 }\r
991\r
992 ConnectedToFileSystem = TRUE;\r
9607962d 993 mEmuVariableEvent =\r
994 EfiCreateProtocolNotifyEvent (\r
995 &gEfiDevicePathProtocolGuid,\r
996 TPL_CALLBACK,\r
997 EmuVariablesUpdatedCallback,\r
998 NULL,\r
999 &mEmuVariableEventReg\r
1000 );\r
1001 PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);\r
1002\r
14b21de9 1003 return EFI_SUCCESS;\r
1004}\r
1005\r
1006\r
1007VOID\r
1008PlatformBdsRestoreNvVarsFromHardDisk (\r
1009 )\r
1010{\r
1011 VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);\r
1012 VisitAllInstancesOfProtocol (\r
1013 &gEfiSimpleFileSystemProtocolGuid,\r
1014 VisitingFileSystemInstance,\r
1015 NULL\r
1016 );\r
3d131d1a 1017\r
14b21de9 1018}\r
1019\r
1020\r
49ba9447 1021VOID\r
1022PlatformBdsConnectSequence (\r
1023 VOID\r
1024 )\r
1025/*++\r
1026\r
1027Routine Description:\r
1028\r
1029 Connect with predeined platform connect sequence,\r
1030 the OEM/IBV can customize with their own connect sequence.\r
1031\r
1032Arguments:\r
1033\r
1034 None.\r
1035\r
1036Returns:\r
1037\r
1038 None.\r
1039\r
1040--*/\r
1041{\r
1042 UINTN Index;\r
1043\r
1044 DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));\r
1045\r
1046 Index = 0;\r
1047\r
1048 //\r
1049 // Here we can get the customized platform connect sequence\r
1050 // Notes: we can connect with new variable which record the\r
1051 // last time boots connect device path sequence\r
1052 //\r
1053 while (gPlatformConnectSequence[Index] != NULL) {\r
1054 //\r
1055 // Build the platform boot option\r
1056 //\r
1057 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
1058 Index++;\r
1059 }\r
1060\r
1061 //\r
1062 // Just use the simple policy to connect all devices\r
1063 //\r
1064 BdsLibConnectAll ();\r
1065\r
2e70cf8a 1066 PciAcpiInitialization ();\r
40f2c454 1067\r
1068 //\r
1069 // Clear the logo after all devices are connected.\r
1070 //\r
1071 gST->ConOut->ClearScreen (gST->ConOut);\r
49ba9447 1072}\r
1073\r
1074VOID\r
1075PlatformBdsGetDriverOption (\r
1076 IN OUT LIST_ENTRY *BdsDriverLists\r
1077 )\r
1078/*++\r
1079\r
1080Routine Description:\r
1081\r
1082 Load the predefined driver option, OEM/IBV can customize this\r
1083 to load their own drivers\r
1084\r
1085Arguments:\r
1086\r
1087 BdsDriverLists - The header of the driver option link list.\r
1088\r
1089Returns:\r
1090\r
1091 None.\r
1092\r
1093--*/\r
1094{\r
1095 DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n"));\r
1096 return;\r
1097}\r
1098\r
1099VOID\r
1100PlatformBdsDiagnostics (\r
1101 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
d18476d0 1102 IN BOOLEAN QuietBoot,\r
1103 IN BASEM_MEMORY_TEST BaseMemoryTest\r
49ba9447 1104 )\r
1105/*++\r
1106\r
1107Routine Description:\r
1108\r
1109 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
1110 can customize this fuction to support specific platform diagnostic.\r
1111\r
1112Arguments:\r
1113\r
1114 MemoryTestLevel - The memory test intensive level\r
1115\r
1116 QuietBoot - Indicate if need to enable the quiet boot\r
1117\r
d18476d0 1118 BaseMemoryTest - A pointer to BaseMemoryTest()\r
1119\r
49ba9447 1120Returns:\r
1121\r
1122 None.\r
1123\r
1124--*/\r
1125{\r
1126 EFI_STATUS Status;\r
1127\r
1128 DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));\r
1129\r
1130 //\r
1131 // Here we can decide if we need to show\r
1132 // the diagnostics screen\r
1133 // Notes: this quiet boot code should be remove\r
1134 // from the graphic lib\r
1135 //\r
1136 if (QuietBoot) {\r
d46f3632 1137 EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
49ba9447 1138 //\r
1139 // Perform system diagnostic\r
1140 //\r
d18476d0 1141 Status = BaseMemoryTest (MemoryTestLevel);\r
49ba9447 1142 if (EFI_ERROR (Status)) {\r
1143 DisableQuietBoot ();\r
1144 }\r
1145\r
1146 return ;\r
1147 }\r
1148 //\r
1149 // Perform system diagnostic\r
1150 //\r
d18476d0 1151 Status = BaseMemoryTest (MemoryTestLevel);\r
49ba9447 1152}\r
1153\r
1154\r
1155VOID\r
1156EFIAPI\r
1157PlatformBdsPolicyBehavior (\r
49ba9447 1158 IN OUT LIST_ENTRY *DriverOptionList,\r
d18476d0 1159 IN OUT LIST_ENTRY *BootOptionList,\r
1160 IN PROCESS_CAPSULES ProcessCapsules,\r
1161 IN BASEM_MEMORY_TEST BaseMemoryTest\r
49ba9447 1162 )\r
1163/*++\r
1164\r
1165Routine Description:\r
1166\r
1167 The function will excute with as the platform policy, current policy\r
1168 is driven by boot mode. IBV/OEM can customize this code for their specific\r
1169 policy action.\r
1170\r
1171Arguments:\r
1172\r
49ba9447 1173 DriverOptionList - The header of the driver option link list\r
1174\r
1175 BootOptionList - The header of the boot option link list\r
1176\r
d18476d0 1177 ProcessCapsules - A pointer to ProcessCapsules()\r
1178\r
1179 BaseMemoryTest - A pointer to BaseMemoryTest()\r
1180\r
49ba9447 1181Returns:\r
1182\r
1183 None.\r
1184\r
1185--*/\r
1186{\r
1187 EFI_STATUS Status;\r
370ec7f1 1188 EFI_BOOT_MODE BootMode;\r
49ba9447 1189\r
1190 DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
1191\r
14b21de9 1192 ConnectRootBridge ();\r
1193\r
2590861a
LE
1194 if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {\r
1195 DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "\r
1196 "from disk since flash variables appear to be supported.\n"));\r
1197 } else {\r
1198 //\r
1199 // Try to restore variables from the hard disk early so\r
1200 // they can be used for the other BDS connect operations.\r
1201 //\r
1202 PlatformBdsRestoreNvVarsFromHardDisk ();\r
1203 }\r
14b21de9 1204\r
49ba9447 1205 //\r
1206 // Load the driver option as the driver option list\r
1207 //\r
1208 PlatformBdsGetDriverOption (DriverOptionList);\r
1209\r
1210 //\r
1211 // Get current Boot Mode\r
1212 //\r
370ec7f1 1213 Status = BdsLibGetBootMode (&BootMode);\r
1214 DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
49ba9447 1215\r
1216 //\r
1217 // Go the different platform policy with different boot mode\r
1218 // Notes: this part code can be change with the table policy\r
1219 //\r
370ec7f1 1220 ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
49ba9447 1221 //\r
1222 // Connect platform console\r
1223 //\r
1224 Status = PlatformBdsConnectConsole (gPlatformConsole);\r
1225 if (EFI_ERROR (Status)) {\r
1226 //\r
1227 // Here OEM/IBV can customize with defined action\r
1228 //\r
1229 PlatformBdsNoConsoleAction ();\r
1230 }\r
b1220e28 1231\r
49ba9447 1232 //\r
1233 // Memory test and Logo show\r
1234 //\r
d18476d0 1235 PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
49ba9447 1236\r
1237 //\r
1238 // Perform some platform specific connect sequence\r
1239 //\r
1240 PlatformBdsConnectSequence ();\r
1241\r
52fba289 1242 //\r
1243 // Process QEMU's -kernel command line option\r
1244 //\r
1245 TryRunningQemuKernel ();\r
1246\r
49ba9447 1247 DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));\r
1248 BdsLibConnectAll ();\r
1249 BdsLibEnumerateAllBootOption (BootOptionList);\r
1250\r
2cd086a6 1251 SetBootOrderFromQemu (BootOptionList);\r
49ba9447 1252 //\r
de5ae37b
LE
1253 // The BootOrder variable may have changed, reload the in-memory list with\r
1254 // it.\r
49ba9447 1255 //\r
de5ae37b 1256 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
49ba9447 1257\r
ea444a3e 1258 PlatformBdsEnterFrontPage (GetFrontPageTimeoutFromQemu(), TRUE);\r
49ba9447 1259}\r
1260\r
1261VOID\r
1262EFIAPI\r
1263PlatformBdsBootSuccess (\r
1264 IN BDS_COMMON_OPTION *Option\r
1265 )\r
1266/*++\r
1267\r
1268Routine Description:\r
1269\r
1270 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
1271 return, so the EFI 1.0 specification defines that you will default to an\r
1272 interactive mode and stop processing the BootOrder list in this case. This\r
1273 is alos a platform implementation and can be customized by IBV/OEM.\r
1274\r
1275Arguments:\r
1276\r
1277 Option - Pointer to Boot Option that succeeded to boot.\r
1278\r
1279Returns:\r
1280\r
1281 None.\r
1282\r
1283--*/\r
1284{\r
1285 CHAR16 *TmpStr;\r
1286\r
1287 DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));\r
1288 //\r
1289 // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
1290 // select loop then we need to pop up a UI and wait for user input.\r
1291 //\r
1292 TmpStr = Option->StatusString;\r
1293 if (TmpStr != NULL) {\r
1294 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1295 FreePool (TmpStr);\r
1296 }\r
1297}\r
1298\r
1299VOID\r
1300EFIAPI\r
1301PlatformBdsBootFail (\r
1302 IN BDS_COMMON_OPTION *Option,\r
1303 IN EFI_STATUS Status,\r
1304 IN CHAR16 *ExitData,\r
1305 IN UINTN ExitDataSize\r
1306 )\r
1307/*++\r
1308\r
1309Routine Description:\r
1310\r
1311 Hook point after a boot attempt fails.\r
1312\r
1313Arguments:\r
1314\r
1315 Option - Pointer to Boot Option that failed to boot.\r
1316\r
1317 Status - Status returned from failed boot.\r
1318\r
1319 ExitData - Exit data returned from failed boot.\r
1320\r
1321 ExitDataSize - Exit data size returned from failed boot.\r
1322\r
1323Returns:\r
1324\r
1325 None.\r
1326\r
1327--*/\r
1328{\r
1329 CHAR16 *TmpStr;\r
1330\r
1331 DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));\r
1332\r
1333 //\r
1334 // If Boot returned with failed status then we need to pop up a UI and wait\r
1335 // for user input.\r
1336 //\r
1337 TmpStr = Option->StatusString;\r
1338 if (TmpStr != NULL) {\r
1339 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1340 FreePool (TmpStr);\r
1341 }\r
1342}\r
1343\r
1344EFI_STATUS\r
1345PlatformBdsNoConsoleAction (\r
1346 VOID\r
1347 )\r
1348/*++\r
1349\r
1350Routine Description:\r
1351\r
1352 This function is remained for IBV/OEM to do some platform action,\r
1353 if there no console device can be connected.\r
1354\r
1355Arguments:\r
1356\r
1357 None.\r
1358\r
1359Returns:\r
1360\r
1361 EFI_SUCCESS - Direct return success now.\r
1362\r
1363--*/\r
1364{\r
1365 DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));\r
1366 return EFI_SUCCESS;\r
1367}\r
1368\r
24cdd14e 1369VOID\r
49ba9447 1370EFIAPI\r
1371PlatformBdsLockNonUpdatableFlash (\r
1372 VOID\r
1373 )\r
1374{\r
1375 DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
24cdd14e 1376 return;\r
49ba9447 1377}\r
40f2c454 1378\r
1379\r
1380/**\r
1381 This notification function is invoked when an instance of the\r
1382 EFI_DEVICE_PATH_PROTOCOL is produced.\r
1383\r
1384 @param Event The event that occured\r
1385 @param Context For EFI compatiblity. Not used.\r
1386\r
1387**/\r
1388VOID\r
1389EFIAPI\r
1390NotifyDevPath (\r
1391 IN EFI_EVENT Event,\r
1392 IN VOID *Context\r
1393 )\r
1394{\r
1395 EFI_HANDLE Handle;\r
1396 EFI_STATUS Status;\r
1397 UINTN BufferSize;\r
1398 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
1399 ATAPI_DEVICE_PATH *Atapi;\r
1400\r
1401 //\r
1402 // Examine all new handles\r
1403 //\r
1404 for (;;) {\r
1405 //\r
1406 // Get the next handle\r
1407 //\r
1408 BufferSize = sizeof (Handle);\r
1409 Status = gBS->LocateHandle (\r
1410 ByRegisterNotify,\r
1411 NULL,\r
1412 mEfiDevPathNotifyReg,\r
1413 &BufferSize,\r
1414 &Handle\r
1415 );\r
1416\r
1417 //\r
1418 // If not found, we're done\r
1419 //\r
1420 if (EFI_NOT_FOUND == Status) {\r
1421 break;\r
1422 }\r
1423\r
1424 if (EFI_ERROR (Status)) {\r
1425 continue;\r
1426 }\r
1427\r
1428 //\r
1429 // Get the DevicePath protocol on that handle\r
1430 //\r
1431 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);\r
1432 ASSERT_EFI_ERROR (Status);\r
1433\r
1434 while (!IsDevicePathEnd (DevPathNode)) {\r
1435 //\r
1436 // Find the handler to dump this device path node\r
1437 //\r
1438 if (\r
1439 (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&\r
1440 (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)\r
1441 ) {\r
1442 Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;\r
1443 PciOr16 (\r
1444 PCI_LIB_ADDRESS (\r
1445 0,\r
1446 1,\r
1447 1,\r
1448 (Atapi->PrimarySecondary == 1) ? 0x42: 0x40\r
1449 ),\r
1450 BIT15\r
1451 );\r
1452 }\r
1453\r
1454 //\r
1455 // Next device path node\r
1456 //\r
1457 DevPathNode = NextDevicePathNode (DevPathNode);\r
1458 }\r
1459 }\r
1460\r
1461 return;\r
1462}\r
1463\r
1464\r
1465VOID\r
1466InstallDevicePathCallback (\r
1467 VOID\r
1468 )\r
1469{\r
1470 DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));\r
1471 mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
1472 &gEfiDevicePathProtocolGuid,\r
1473 TPL_CALLBACK,\r
1474 NotifyDevPath,\r
1475 NULL,\r
1476 &mEfiDevPathNotifyReg\r
1477 );\r
1478}\r
1479\r
24cdd14e
LG
1480/**\r
1481 Lock the ConsoleIn device in system table. All key\r
1482 presses will be ignored until the Password is typed in. The only way to\r
1483 disable the password is to type it in to a ConIn device.\r
1484\r
1485 @param Password Password used to lock ConIn device.\r
1486\r
1487 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
1488 @retval EFI_UNSUPPORTED Password not found\r
1489\r
1490**/\r
1491EFI_STATUS\r
1492EFIAPI\r
1493LockKeyboards (\r
1494 IN CHAR16 *Password\r
1495 )\r
1496{\r
1497 return EFI_UNSUPPORTED;\r
1498}\r
5106d422 1499\r