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