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