]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
OVMF: Add support for saving the NV variables to disk following each SetVariable...
[mirror_edk2.git] / OvmfPkg / Library / PlatformBdsLib / BdsPlatform.c
CommitLineData
49ba9447 1/** @file\r
2 Platform BDS customizations.\r
3\r
7d9cf3f2 4 Copyright (c) 2004 - 2009, Intel Corporation. <BR>\r
49ba9447 5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "BdsPlatform.h"\r
16\r
17\r
40f2c454 18//\r
19// Global data\r
20//\r
21\r
22VOID *mEfiDevPathNotifyReg;\r
23EFI_EVENT mEfiDevPathEvent;\r
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
554DetectAndPreparePlatformPciDevicePath (\r
555 IN EFI_HANDLE Handle,\r
556 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
557 IN PCI_TYPE00 *Pci\r
558 )\r
559{\r
560 EFI_STATUS Status;\r
561\r
562 Status = PciIo->Attributes (\r
563 PciIo,\r
564 EfiPciIoAttributeOperationEnable,\r
565 EFI_PCI_DEVICE_ENABLE,\r
566 NULL\r
567 );\r
568 ASSERT_EFI_ERROR (Status);\r
569\r
570 if (!mDetectVgaOnly) {\r
571 //\r
572 // Here we decide whether it is LPC Bridge\r
573 //\r
574 if ((IS_PCI_LPC (Pci)) ||\r
575 ((IS_PCI_ISA_PDECODE (Pci)) &&\r
576 (Pci->Hdr.VendorId == 0x8086) &&\r
577 (Pci->Hdr.DeviceId == 0x7000)\r
578 )\r
579 ) {\r
49ba9447 580 //\r
e955462b 581 // Add IsaKeyboard to ConIn,\r
582 // add IsaSerial to ConOut, ConIn, ErrOut\r
49ba9447 583 //\r
e955462b 584 DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));\r
585 PrepareLpcBridgeDevicePath (Handle);\r
586 return EFI_SUCCESS;\r
49ba9447 587 }\r
49ba9447 588 //\r
e955462b 589 // Here we decide which Serial device to enable in PCI bus\r
49ba9447 590 //\r
e955462b 591 if (IS_PCI_16550SERIAL (Pci)) {\r
49ba9447 592 //\r
e955462b 593 // Add them to ConOut, ConIn, ErrOut.\r
49ba9447 594 //\r
e955462b 595 DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));\r
596 PreparePciSerialDevicePath (Handle);\r
597 return EFI_SUCCESS;\r
49ba9447 598 }\r
599 }\r
600\r
e955462b 601 //\r
602 // Here we decide which VGA device to enable in PCI bus\r
603 //\r
604 if (IS_PCI_VGA (Pci)) {\r
605 //\r
606 // Add them to ConOut.\r
607 //\r
608 DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));\r
609 PreparePciVgaDevicePath (Handle);\r
610 return EFI_SUCCESS;\r
611 }\r
49ba9447 612\r
e955462b 613 return Status;\r
614}\r
615\r
616\r
617/**\r
618 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
619\r
620 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.\r
621\r
622 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
623 @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
624\r
625**/\r
626EFI_STATUS\r
627DetectAndPreparePlatformPciDevicePaths (\r
628 BOOLEAN DetectVgaOnly\r
629 )\r
630{\r
631 mDetectVgaOnly = DetectVgaOnly;\r
632 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\r
49ba9447 633}\r
634\r
635\r
636EFI_STATUS\r
637PlatformBdsConnectConsole (\r
638 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
639 )\r
640/*++\r
641\r
642Routine Description:\r
643\r
644 Connect the predefined platform default console device. Always try to find\r
645 and enable the vga device if have.\r
646\r
647Arguments:\r
648\r
649 PlatformConsole - Predfined platform default console device array.\r
650\r
651Returns:\r
652\r
653 EFI_SUCCESS - Success connect at least one ConIn and ConOut\r
654 device, there must have one ConOut device is\r
655 active vga device.\r
656\r
657 EFI_STATUS - Return the status of\r
658 BdsLibConnectAllDefaultConsoles ()\r
659\r
660--*/\r
661{\r
662 EFI_STATUS Status;\r
663 UINTN Index;\r
664 EFI_DEVICE_PATH_PROTOCOL *VarConout;\r
665 EFI_DEVICE_PATH_PROTOCOL *VarConin;\r
666 UINTN DevicePathSize;\r
667\r
668 //\r
669 // Connect RootBridge\r
670 //\r
49ba9447 671 VarConout = BdsLibGetVariableAndSize (\r
672 VarConsoleOut,\r
673 &gEfiGlobalVariableGuid,\r
674 &DevicePathSize\r
675 );\r
676 VarConin = BdsLibGetVariableAndSize (\r
677 VarConsoleInp,\r
678 &gEfiGlobalVariableGuid,\r
679 &DevicePathSize\r
680 );\r
681\r
682 if (VarConout == NULL || VarConin == NULL) {\r
683 //\r
684 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
685 //\r
e955462b 686 DetectAndPreparePlatformPciDevicePaths (FALSE);\r
49ba9447 687\r
688 //\r
689 // Have chance to connect the platform default console,\r
690 // the platform default console is the minimue device group\r
691 // the platform should support\r
692 //\r
693 for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
694 //\r
695 // Update the console variable with the connect type\r
696 //\r
697 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
698 BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);\r
699 }\r
700 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
701 BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);\r
702 }\r
703 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
704 BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);\r
705 }\r
706 }\r
707 } else {\r
708 //\r
709 // Only detect VGA device and add them to ConOut\r
710 //\r
e955462b 711 DetectAndPreparePlatformPciDevicePaths (TRUE);\r
49ba9447 712 }\r
713\r
714 //\r
715 // Connect the all the default console with current cosole variable\r
716 //\r
717 Status = BdsLibConnectAllDefaultConsoles ();\r
718 if (EFI_ERROR (Status)) {\r
719 return Status;\r
720 }\r
721\r
722 return EFI_SUCCESS;\r
723}\r
724\r
725\r
726VOID\r
727PciInitialization (\r
728 )\r
729{\r
730 //\r
40f2c454 731 // Bus 0, Device 0, Function 0 - Host to PCI Bridge\r
732 //\r
733 PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);\r
734\r
735 //\r
736 // Bus 0, Device 1, Function 0 - PCI to ISA Bridge\r
49ba9447 737 //\r
40f2c454 738 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);\r
739 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b);\r
740 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x09);\r
741 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0b);\r
742 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x09);\r
49ba9447 743\r
744 //\r
40f2c454 745 // Bus 0, Device 1, Function 1 - IDE Controller\r
49ba9447 746 //\r
40f2c454 747 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);\r
748 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);\r
49ba9447 749\r
750 //\r
40f2c454 751 // Bus 0, Device 1, Function 3 - Power Managment Controller\r
49ba9447 752 //\r
40f2c454 753 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x0b);\r
754 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01);\r
49ba9447 755\r
756 //\r
40f2c454 757 // Bus 0, Device 2, Function 0 - Video Controller\r
49ba9447 758 //\r
40f2c454 759 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);\r
49ba9447 760\r
761 //\r
40f2c454 762 // Bus 0, Device 3, Function 0 - Network Controller\r
49ba9447 763 //\r
40f2c454 764 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);\r
765 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01);\r
49ba9447 766\r
767 //\r
40f2c454 768 // Bus 0, Device 4, Function 0 - RAM Memory\r
49ba9447 769 //\r
40f2c454 770 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x09);\r
771 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3d), 0x01);\r
49ba9447 772}\r
773\r
774\r
14b21de9 775EFI_STATUS\r
776EFIAPI\r
777ConnectRecursivelyIfPciMassStorage (\r
778 IN EFI_HANDLE Handle,\r
779 IN EFI_PCI_IO_PROTOCOL *Instance,\r
780 IN PCI_TYPE00 *PciHeader\r
781 )\r
782{\r
783 EFI_STATUS Status;\r
784 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
785 CHAR16 *DevPathStr;\r
786\r
787 if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {\r
788 DevicePath = NULL;\r
789 Status = gBS->HandleProtocol (\r
790 Handle,\r
791 &gEfiDevicePathProtocolGuid,\r
792 (VOID*)&DevicePath\r
793 );\r
794 if (EFI_ERROR (Status)) {\r
795 return Status;\r
796 }\r
797\r
798 //\r
799 // Print Device Path\r
800 //\r
801 DevPathStr = DevicePathToStr (DevicePath);\r
802 DEBUG((\r
803 EFI_D_INFO,\r
804 "Found Mass Storage device: %s\n",\r
805 DevPathStr\r
806 ));\r
807 FreePool(DevPathStr);\r
808\r
809 Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
810 if (EFI_ERROR (Status)) {\r
811 return Status;\r
812 }\r
813\r
814 }\r
815\r
816 return EFI_SUCCESS;\r
817}\r
818\r
819\r
9607962d 820/**\r
821 This notification function is invoked when the\r
822 EMU Variable FVB has been changed.\r
823\r
824 @param Event The event that occured\r
825 @param Context For EFI compatiblity. Not used.\r
826\r
827**/\r
828VOID\r
829EFIAPI\r
830EmuVariablesUpdatedCallback (\r
831 IN EFI_EVENT Event,\r
832 IN VOID *Context\r
833 )\r
834{\r
835 DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));\r
836 UpdateNvVarsOnFileSystem ();\r
837}\r
838\r
839\r
14b21de9 840EFI_STATUS\r
841EFIAPI\r
842VisitingFileSystemInstance (\r
843 IN EFI_HANDLE Handle,\r
844 IN VOID *Instance,\r
845 IN VOID *Context\r
846 )\r
847{\r
848 EFI_STATUS Status;\r
849 STATIC BOOLEAN ConnectedToFileSystem = FALSE;\r
850\r
851 if (ConnectedToFileSystem) {\r
852 return EFI_ALREADY_STARTED;\r
853 }\r
854\r
855 Status = ConnectNvVarsToFileSystem (Handle);\r
856 if (EFI_ERROR (Status)) {\r
857 return Status;\r
858 }\r
859\r
860 ConnectedToFileSystem = TRUE;\r
9607962d 861 mEmuVariableEvent =\r
862 EfiCreateProtocolNotifyEvent (\r
863 &gEfiDevicePathProtocolGuid,\r
864 TPL_CALLBACK,\r
865 EmuVariablesUpdatedCallback,\r
866 NULL,\r
867 &mEmuVariableEventReg\r
868 );\r
869 PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);\r
870\r
14b21de9 871 return EFI_SUCCESS;\r
872}\r
873\r
874\r
875VOID\r
876PlatformBdsRestoreNvVarsFromHardDisk (\r
877 )\r
878{\r
879 VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);\r
880 VisitAllInstancesOfProtocol (\r
881 &gEfiSimpleFileSystemProtocolGuid,\r
882 VisitingFileSystemInstance,\r
883 NULL\r
884 );\r
885 \r
886}\r
887\r
888\r
49ba9447 889VOID\r
890PlatformBdsConnectSequence (\r
891 VOID\r
892 )\r
893/*++\r
894\r
895Routine Description:\r
896\r
897 Connect with predeined platform connect sequence,\r
898 the OEM/IBV can customize with their own connect sequence.\r
899\r
900Arguments:\r
901\r
902 None.\r
903\r
904Returns:\r
905\r
906 None.\r
907\r
908--*/\r
909{\r
910 UINTN Index;\r
911\r
912 DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));\r
913\r
914 Index = 0;\r
915\r
916 //\r
917 // Here we can get the customized platform connect sequence\r
918 // Notes: we can connect with new variable which record the\r
919 // last time boots connect device path sequence\r
920 //\r
921 while (gPlatformConnectSequence[Index] != NULL) {\r
922 //\r
923 // Build the platform boot option\r
924 //\r
925 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
926 Index++;\r
927 }\r
928\r
929 //\r
930 // Just use the simple policy to connect all devices\r
931 //\r
932 BdsLibConnectAll ();\r
933\r
934 PciInitialization ();\r
40f2c454 935\r
936 //\r
937 // Clear the logo after all devices are connected.\r
938 //\r
939 gST->ConOut->ClearScreen (gST->ConOut);\r
49ba9447 940}\r
941\r
942VOID\r
943PlatformBdsGetDriverOption (\r
944 IN OUT LIST_ENTRY *BdsDriverLists\r
945 )\r
946/*++\r
947\r
948Routine Description:\r
949\r
950 Load the predefined driver option, OEM/IBV can customize this\r
951 to load their own drivers\r
952\r
953Arguments:\r
954\r
955 BdsDriverLists - The header of the driver option link list.\r
956\r
957Returns:\r
958\r
959 None.\r
960\r
961--*/\r
962{\r
963 DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n"));\r
964 return;\r
965}\r
966\r
967VOID\r
968PlatformBdsDiagnostics (\r
969 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
d18476d0 970 IN BOOLEAN QuietBoot,\r
971 IN BASEM_MEMORY_TEST BaseMemoryTest\r
49ba9447 972 )\r
973/*++\r
974\r
975Routine Description:\r
976\r
977 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
978 can customize this fuction to support specific platform diagnostic.\r
979\r
980Arguments:\r
981\r
982 MemoryTestLevel - The memory test intensive level\r
983\r
984 QuietBoot - Indicate if need to enable the quiet boot\r
985\r
d18476d0 986 BaseMemoryTest - A pointer to BaseMemoryTest()\r
987\r
49ba9447 988Returns:\r
989\r
990 None.\r
991\r
992--*/\r
993{\r
994 EFI_STATUS Status;\r
995\r
996 DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));\r
997\r
998 //\r
999 // Here we can decide if we need to show\r
1000 // the diagnostics screen\r
1001 // Notes: this quiet boot code should be remove\r
1002 // from the graphic lib\r
1003 //\r
1004 if (QuietBoot) {\r
d46f3632 1005 EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
49ba9447 1006 //\r
1007 // Perform system diagnostic\r
1008 //\r
d18476d0 1009 Status = BaseMemoryTest (MemoryTestLevel);\r
49ba9447 1010 if (EFI_ERROR (Status)) {\r
1011 DisableQuietBoot ();\r
1012 }\r
1013\r
1014 return ;\r
1015 }\r
1016 //\r
1017 // Perform system diagnostic\r
1018 //\r
d18476d0 1019 Status = BaseMemoryTest (MemoryTestLevel);\r
49ba9447 1020}\r
1021\r
1022\r
1023VOID\r
1024EFIAPI\r
1025PlatformBdsPolicyBehavior (\r
49ba9447 1026 IN OUT LIST_ENTRY *DriverOptionList,\r
d18476d0 1027 IN OUT LIST_ENTRY *BootOptionList,\r
1028 IN PROCESS_CAPSULES ProcessCapsules,\r
1029 IN BASEM_MEMORY_TEST BaseMemoryTest\r
49ba9447 1030 )\r
1031/*++\r
1032\r
1033Routine Description:\r
1034\r
1035 The function will excute with as the platform policy, current policy\r
1036 is driven by boot mode. IBV/OEM can customize this code for their specific\r
1037 policy action.\r
1038\r
1039Arguments:\r
1040\r
49ba9447 1041 DriverOptionList - The header of the driver option link list\r
1042\r
1043 BootOptionList - The header of the boot option link list\r
1044\r
d18476d0 1045 ProcessCapsules - A pointer to ProcessCapsules()\r
1046\r
1047 BaseMemoryTest - A pointer to BaseMemoryTest()\r
1048\r
49ba9447 1049Returns:\r
1050\r
1051 None.\r
1052\r
1053--*/\r
1054{\r
1055 EFI_STATUS Status;\r
1056 UINT16 Timeout;\r
1057 EFI_EVENT UserInputDurationTime;\r
1058 LIST_ENTRY *Link;\r
1059 BDS_COMMON_OPTION *BootOption;\r
1060 UINTN Index;\r
1061 EFI_INPUT_KEY Key;\r
1062 EFI_TPL OldTpl;\r
370ec7f1 1063 EFI_BOOT_MODE BootMode;\r
49ba9447 1064\r
1065 DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
1066\r
14b21de9 1067 ConnectRootBridge ();\r
1068\r
1069 //\r
1070 // Try to restore variables from the hard disk early so\r
1071 // they can be used for the other BDS connect operations.\r
1072 //\r
1073 PlatformBdsRestoreNvVarsFromHardDisk ();\r
1074\r
49ba9447 1075 //\r
1076 // Init the time out value\r
1077 //\r
1078 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
1079\r
1080 //\r
1081 // Load the driver option as the driver option list\r
1082 //\r
1083 PlatformBdsGetDriverOption (DriverOptionList);\r
1084\r
1085 //\r
1086 // Get current Boot Mode\r
1087 //\r
370ec7f1 1088 Status = BdsLibGetBootMode (&BootMode);\r
1089 DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
49ba9447 1090\r
1091 //\r
1092 // Go the different platform policy with different boot mode\r
1093 // Notes: this part code can be change with the table policy\r
1094 //\r
370ec7f1 1095 ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
49ba9447 1096 //\r
1097 // Connect platform console\r
1098 //\r
1099 Status = PlatformBdsConnectConsole (gPlatformConsole);\r
1100 if (EFI_ERROR (Status)) {\r
1101 //\r
1102 // Here OEM/IBV can customize with defined action\r
1103 //\r
1104 PlatformBdsNoConsoleAction ();\r
1105 }\r
1106 //\r
1107 // Create a 300ms duration event to ensure user has enough input time to enter Setup\r
1108 //\r
1109 Status = gBS->CreateEvent (\r
1110 EVT_TIMER,\r
1111 0,\r
1112 NULL,\r
1113 NULL,\r
1114 &UserInputDurationTime\r
1115 );\r
1116 ASSERT (Status == EFI_SUCCESS);\r
1117 Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);\r
1118 ASSERT (Status == EFI_SUCCESS);\r
1119 //\r
1120 // Memory test and Logo show\r
1121 //\r
d18476d0 1122 PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
49ba9447 1123\r
1124 //\r
1125 // Perform some platform specific connect sequence\r
1126 //\r
1127 PlatformBdsConnectSequence ();\r
1128\r
1129 //\r
1130 // Give one chance to enter the setup if we\r
1131 // have the time out\r
1132 //\r
1133 if (Timeout != 0) {\r
1134 //PlatformBdsEnterFrontPage (Timeout, FALSE);\r
1135 }\r
1136\r
1137 DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));\r
1138 BdsLibConnectAll ();\r
1139 BdsLibEnumerateAllBootOption (BootOptionList);\r
1140\r
1141 //\r
1142 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot\r
1143 // checking code in real production tip.\r
1144 //\r
1145 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device\r
1146 // and do enumerate all the default boot options. But in development system board, the boot mode\r
1147 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box\r
1148 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.\r
1149 //\r
1150 Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
1151 if (EFI_ERROR(Status)) {\r
1152 //\r
1153 // If cannot find "BootOrder" variable, it may be first boot.\r
1154 // Try to connect all devices and enumerate all boot options here.\r
1155 //\r
1156 BdsLibConnectAll ();\r
1157 BdsLibEnumerateAllBootOption (BootOptionList);\r
1158 }\r
1159\r
1160 //\r
1161 // To give the User a chance to enter Setup here, if user set TimeOut is 0.\r
1162 // BDS should still give user a chance to enter Setup\r
1163 //\r
1164 // Connect first boot option, and then check user input before exit\r
1165 //\r
1166 for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {\r
1167 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
1168 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
1169 //\r
1170 // skip the header of the link list, becuase it has no boot option\r
1171 //\r
1172 continue;\r
1173 } else {\r
1174 //\r
1175 // Make sure the boot option device path connected, but ignore the BBS device path\r
1176 //\r
1177 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
1178 BdsLibConnectDevicePath (BootOption->DevicePath);\r
1179 }\r
1180 break;\r
1181 }\r
1182 }\r
1183\r
1184 //\r
1185 // Check whether the user input after the duration time has expired\r
1186 //\r
1187 OldTpl = EfiGetCurrentTpl();\r
1188 gBS->RestoreTPL (TPL_APPLICATION);\r
1189 gBS->WaitForEvent (1, &UserInputDurationTime, &Index);\r
1190 gBS->CloseEvent (UserInputDurationTime);\r
1191 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
1192 gBS->RaiseTPL (OldTpl);\r
1193\r
1194 if (!EFI_ERROR (Status)) {\r
1195 //\r
1196 // Enter Setup if user input\r
1197 //\r
1198 Timeout = 0xffff;\r
1199 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
1200 }\r
1201\r
1202 return ;\r
1203}\r
1204\r
1205VOID\r
1206EFIAPI\r
1207PlatformBdsBootSuccess (\r
1208 IN BDS_COMMON_OPTION *Option\r
1209 )\r
1210/*++\r
1211\r
1212Routine Description:\r
1213\r
1214 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
1215 return, so the EFI 1.0 specification defines that you will default to an\r
1216 interactive mode and stop processing the BootOrder list in this case. This\r
1217 is alos a platform implementation and can be customized by IBV/OEM.\r
1218\r
1219Arguments:\r
1220\r
1221 Option - Pointer to Boot Option that succeeded to boot.\r
1222\r
1223Returns:\r
1224\r
1225 None.\r
1226\r
1227--*/\r
1228{\r
1229 CHAR16 *TmpStr;\r
1230\r
1231 DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));\r
1232 //\r
1233 // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
1234 // select loop then we need to pop up a UI and wait for user input.\r
1235 //\r
1236 TmpStr = Option->StatusString;\r
1237 if (TmpStr != NULL) {\r
1238 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1239 FreePool (TmpStr);\r
1240 }\r
1241}\r
1242\r
1243VOID\r
1244EFIAPI\r
1245PlatformBdsBootFail (\r
1246 IN BDS_COMMON_OPTION *Option,\r
1247 IN EFI_STATUS Status,\r
1248 IN CHAR16 *ExitData,\r
1249 IN UINTN ExitDataSize\r
1250 )\r
1251/*++\r
1252\r
1253Routine Description:\r
1254\r
1255 Hook point after a boot attempt fails.\r
1256\r
1257Arguments:\r
1258\r
1259 Option - Pointer to Boot Option that failed to boot.\r
1260\r
1261 Status - Status returned from failed boot.\r
1262\r
1263 ExitData - Exit data returned from failed boot.\r
1264\r
1265 ExitDataSize - Exit data size returned from failed boot.\r
1266\r
1267Returns:\r
1268\r
1269 None.\r
1270\r
1271--*/\r
1272{\r
1273 CHAR16 *TmpStr;\r
1274\r
1275 DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));\r
1276\r
1277 //\r
1278 // If Boot returned with failed status then we need to pop up a UI and wait\r
1279 // for user input.\r
1280 //\r
1281 TmpStr = Option->StatusString;\r
1282 if (TmpStr != NULL) {\r
1283 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1284 FreePool (TmpStr);\r
1285 }\r
1286}\r
1287\r
1288EFI_STATUS\r
1289PlatformBdsNoConsoleAction (\r
1290 VOID\r
1291 )\r
1292/*++\r
1293\r
1294Routine Description:\r
1295\r
1296 This function is remained for IBV/OEM to do some platform action,\r
1297 if there no console device can be connected.\r
1298\r
1299Arguments:\r
1300\r
1301 None.\r
1302\r
1303Returns:\r
1304\r
1305 EFI_SUCCESS - Direct return success now.\r
1306\r
1307--*/\r
1308{\r
1309 DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));\r
1310 return EFI_SUCCESS;\r
1311}\r
1312\r
24cdd14e 1313VOID\r
49ba9447 1314EFIAPI\r
1315PlatformBdsLockNonUpdatableFlash (\r
1316 VOID\r
1317 )\r
1318{\r
1319 DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
24cdd14e 1320 return;\r
49ba9447 1321}\r
40f2c454 1322\r
1323\r
1324/**\r
1325 This notification function is invoked when an instance of the\r
1326 EFI_DEVICE_PATH_PROTOCOL is produced.\r
1327\r
1328 @param Event The event that occured\r
1329 @param Context For EFI compatiblity. Not used.\r
1330\r
1331**/\r
1332VOID\r
1333EFIAPI\r
1334NotifyDevPath (\r
1335 IN EFI_EVENT Event,\r
1336 IN VOID *Context\r
1337 )\r
1338{\r
1339 EFI_HANDLE Handle;\r
1340 EFI_STATUS Status;\r
1341 UINTN BufferSize;\r
1342 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
1343 ATAPI_DEVICE_PATH *Atapi;\r
1344\r
1345 //\r
1346 // Examine all new handles\r
1347 //\r
1348 for (;;) {\r
1349 //\r
1350 // Get the next handle\r
1351 //\r
1352 BufferSize = sizeof (Handle);\r
1353 Status = gBS->LocateHandle (\r
1354 ByRegisterNotify,\r
1355 NULL,\r
1356 mEfiDevPathNotifyReg,\r
1357 &BufferSize,\r
1358 &Handle\r
1359 );\r
1360\r
1361 //\r
1362 // If not found, we're done\r
1363 //\r
1364 if (EFI_NOT_FOUND == Status) {\r
1365 break;\r
1366 }\r
1367\r
1368 if (EFI_ERROR (Status)) {\r
1369 continue;\r
1370 }\r
1371\r
1372 //\r
1373 // Get the DevicePath protocol on that handle\r
1374 //\r
1375 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);\r
1376 ASSERT_EFI_ERROR (Status);\r
1377\r
1378 while (!IsDevicePathEnd (DevPathNode)) {\r
1379 //\r
1380 // Find the handler to dump this device path node\r
1381 //\r
1382 if (\r
1383 (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&\r
1384 (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)\r
1385 ) {\r
1386 Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;\r
1387 PciOr16 (\r
1388 PCI_LIB_ADDRESS (\r
1389 0,\r
1390 1,\r
1391 1,\r
1392 (Atapi->PrimarySecondary == 1) ? 0x42: 0x40\r
1393 ),\r
1394 BIT15\r
1395 );\r
1396 }\r
1397\r
1398 //\r
1399 // Next device path node\r
1400 //\r
1401 DevPathNode = NextDevicePathNode (DevPathNode);\r
1402 }\r
1403 }\r
1404\r
1405 return;\r
1406}\r
1407\r
1408\r
1409VOID\r
1410InstallDevicePathCallback (\r
1411 VOID\r
1412 )\r
1413{\r
1414 DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));\r
1415 mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
1416 &gEfiDevicePathProtocolGuid,\r
1417 TPL_CALLBACK,\r
1418 NotifyDevPath,\r
1419 NULL,\r
1420 &mEfiDevPathNotifyReg\r
1421 );\r
1422}\r
1423\r
24cdd14e
LG
1424/**\r
1425 Lock the ConsoleIn device in system table. All key\r
1426 presses will be ignored until the Password is typed in. The only way to\r
1427 disable the password is to type it in to a ConIn device.\r
1428\r
1429 @param Password Password used to lock ConIn device.\r
1430\r
1431 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
1432 @retval EFI_UNSUPPORTED Password not found\r
1433\r
1434**/\r
1435EFI_STATUS\r
1436EFIAPI\r
1437LockKeyboards (\r
1438 IN CHAR16 *Password\r
1439 )\r
1440{\r
1441 return EFI_UNSUPPORTED;\r
1442}\r
5106d422 1443\r
1444\r
1445STATIC\r
1446VOID\r
1447LoadVideoRom (\r
ccd4b7da 1448 VOID\r
5106d422 1449 )\r
1450{\r
1451 PCI_DATA_STRUCTURE *Pcir;\r
1452 UINTN RomSize;\r
1453\r
1454 //\r
1455 // The virtual machines sometimes load the video rom image\r
1456 // directly at the legacy video BIOS location of C000:0000,\r
1457 // and do not implement the PCI expansion ROM feature.\r
1458 //\r
1459 Pcir = (PCI_DATA_STRUCTURE *) (UINTN) 0xc0000;\r
1460 RomSize = Pcir->ImageLength * 512;\r
1461 PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize);\r
1462}\r
1463\r
1464\r
1465STATIC\r
1466EFI_STATUS\r
1467PciRomLoadEfiDriversFromRomImage (\r
1468 IN EFI_PHYSICAL_ADDRESS Rom,\r
1469 IN UINTN RomSize\r
1470 )\r
1471{\r
1472 CHAR16 *FileName;\r
1473 EFI_PCI_EXPANSION_ROM_HEADER *EfiRomHeader;\r
1474 PCI_DATA_STRUCTURE *Pcir;\r
1475 UINTN ImageIndex;\r
1476 UINTN RomOffset;\r
1477 UINT32 ImageSize;\r
1478 UINT16 ImageOffset;\r
1479 EFI_HANDLE ImageHandle;\r
1480 EFI_STATUS Status;\r
1481 EFI_STATUS retStatus;\r
1482 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
1483 BOOLEAN SkipImage;\r
1484 UINT32 DestinationSize;\r
1485 UINT32 ScratchSize;\r
1486 UINT8 *Scratch;\r
1487 VOID *ImageBuffer;\r
1488 VOID *DecompressedImageBuffer;\r
1489 UINT32 ImageLength;\r
1490 EFI_DECOMPRESS_PROTOCOL *Decompress;\r
1491\r
1492 FileName = L"PciRomInMemory";\r
1493\r
1494 //FileName = L"PciRom Addr=0000000000000000";\r
1495 //HexToString (&FileName[12], Rom, 16);\r
1496\r
1497 ImageIndex = 0;\r
1498 retStatus = EFI_NOT_FOUND;\r
1499 RomOffset = (UINTN) Rom;\r
1500\r
1501 do {\r
1502\r
1503 EfiRomHeader = (EFI_PCI_EXPANSION_ROM_HEADER *) (UINTN) RomOffset;\r
1504\r
1505 if (EfiRomHeader->Signature != 0xaa55) {\r
1506 return retStatus;\r
1507 }\r
1508\r
1509 Pcir = (PCI_DATA_STRUCTURE *) (UINTN) (RomOffset + EfiRomHeader->PcirOffset);\r
1510 ImageSize = Pcir->ImageLength * 512;\r
1511\r
1512 if ((Pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE) &&\r
1513 (EfiRomHeader->EfiSignature == EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE) ) {\r
1514\r
1515 if ((EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) ||\r
1516 (EfiRomHeader->EfiSubsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) ) {\r
1517\r
1518 ImageOffset = EfiRomHeader->EfiImageHeaderOffset;\r
1519 ImageSize = EfiRomHeader->InitializationSize * 512;\r
1520\r
1521 ImageBuffer = (VOID *) (UINTN) (RomOffset + ImageOffset);\r
1522 ImageLength = ImageSize - ImageOffset;\r
1523 DecompressedImageBuffer = NULL;\r
1524\r
1525 //\r
1526 // decompress here if needed\r
1527 //\r
1528 SkipImage = FALSE;\r
1529 if (EfiRomHeader->CompressionType > EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
1530 SkipImage = TRUE;\r
1531 }\r
1532\r
1533 if (EfiRomHeader->CompressionType == EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED) {\r
1534 Status = gBS->LocateProtocol (&gEfiDecompressProtocolGuid, NULL, (VOID **) &Decompress);\r
1535 if (EFI_ERROR (Status)) {\r
1536 SkipImage = TRUE;\r
1537 } else {\r
1538 SkipImage = TRUE;\r
1539 Status = Decompress->GetInfo (\r
1540 Decompress,\r
1541 ImageBuffer,\r
1542 ImageLength,\r
1543 &DestinationSize,\r
1544 &ScratchSize\r
1545 );\r
1546 if (!EFI_ERROR (Status)) {\r
1547 DecompressedImageBuffer = NULL;\r
1548 DecompressedImageBuffer = AllocatePool (DestinationSize);\r
1549 if (DecompressedImageBuffer != NULL) {\r
1550 Scratch = AllocatePool (ScratchSize);\r
1551 if (Scratch != NULL) {\r
1552 Status = Decompress->Decompress (\r
1553 Decompress,\r
1554 ImageBuffer,\r
1555 ImageLength,\r
1556 DecompressedImageBuffer,\r
1557 DestinationSize,\r
1558 Scratch,\r
1559 ScratchSize\r
1560 );\r
1561 if (!EFI_ERROR (Status)) {\r
1562 ImageBuffer = DecompressedImageBuffer;\r
1563 ImageLength = DestinationSize;\r
1564 SkipImage = FALSE;\r
1565 }\r
1566\r
1567 gBS->FreePool (Scratch);\r
1568 }\r
1569 }\r
1570 }\r
1571 }\r
1572 }\r
1573\r
1574 if (!SkipImage) {\r
1575\r
1576 //\r
1577 // load image and start image\r
1578 //\r
1579\r
1580 FilePath = FileDevicePath (NULL, FileName);\r
1581\r
1582 Status = gBS->LoadImage (\r
1583 FALSE,\r
1584 gImageHandle,\r
1585 FilePath,\r
1586 ImageBuffer,\r
1587 ImageLength,\r
1588 &ImageHandle\r
1589 );\r
1590 if (!EFI_ERROR (Status)) {\r
1591 Status = gBS->StartImage (ImageHandle, NULL, NULL);\r
1592 if (!EFI_ERROR (Status)) {\r
1593 retStatus = Status;\r
1594 }\r
1595 }\r
1596 if (FilePath != NULL) {\r
1597 gBS->FreePool (FilePath);\r
1598 }\r
1599 }\r
1600\r
1601 if (DecompressedImageBuffer != NULL) {\r
1602 gBS->FreePool (DecompressedImageBuffer);\r
1603 }\r
1604\r
1605 }\r
1606 }\r
1607\r
1608 RomOffset = RomOffset + ImageSize;\r
1609 ImageIndex++;\r
1610 } while (((Pcir->Indicator & 0x80) == 0x00) && ((RomOffset - (UINTN) Rom) < RomSize));\r
1611\r
1612 return retStatus;\r
1613}\r
1614\r
1615\r