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