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