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