]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/PlatformBdsLib/BdsPlatform.c
Synchronize the build tools' binary with source files at r1645 in build tool project.
[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
741 IN BOOLEAN QuietBoot\r
742 )\r
743/*++\r
744\r
745Routine Description:\r
746\r
747 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
748 can customize this fuction to support specific platform diagnostic.\r
749\r
750Arguments:\r
751\r
752 MemoryTestLevel - The memory test intensive level\r
753\r
754 QuietBoot - Indicate if need to enable the quiet boot\r
755\r
756Returns:\r
757\r
758 None.\r
759\r
760--*/\r
761{\r
762 EFI_STATUS Status;\r
763\r
764 DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));\r
765\r
766 //\r
767 // Here we can decide if we need to show\r
768 // the diagnostics screen\r
769 // Notes: this quiet boot code should be remove\r
770 // from the graphic lib\r
771 //\r
772 if (QuietBoot) {\r
773 EnableQuietBoot (&gEfiDefaultBmpLogoGuid);\r
774 //\r
775 // Perform system diagnostic\r
776 //\r
777 Status = BdsMemoryTest (MemoryTestLevel);\r
778 if (EFI_ERROR (Status)) {\r
779 DisableQuietBoot ();\r
780 }\r
781\r
782 return ;\r
783 }\r
784 //\r
785 // Perform system diagnostic\r
786 //\r
787 Status = BdsMemoryTest (MemoryTestLevel);\r
788}\r
789\r
790\r
791VOID\r
792EFIAPI\r
793PlatformBdsPolicyBehavior (\r
49ba9447 794 IN OUT LIST_ENTRY *DriverOptionList,\r
795 IN OUT LIST_ENTRY *BootOptionList\r
796 )\r
797/*++\r
798\r
799Routine Description:\r
800\r
801 The function will excute with as the platform policy, current policy\r
802 is driven by boot mode. IBV/OEM can customize this code for their specific\r
803 policy action.\r
804\r
805Arguments:\r
806\r
49ba9447 807 DriverOptionList - The header of the driver option link list\r
808\r
809 BootOptionList - The header of the boot option link list\r
810\r
811Returns:\r
812\r
813 None.\r
814\r
815--*/\r
816{\r
817 EFI_STATUS Status;\r
818 UINT16 Timeout;\r
819 EFI_EVENT UserInputDurationTime;\r
820 LIST_ENTRY *Link;\r
821 BDS_COMMON_OPTION *BootOption;\r
822 UINTN Index;\r
823 EFI_INPUT_KEY Key;\r
824 EFI_TPL OldTpl;\r
370ec7f1 825 EFI_BOOT_MODE BootMode;\r
49ba9447 826\r
827 DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior\n"));\r
828\r
829 //\r
830 // Init the time out value\r
831 //\r
832 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
833\r
834 //\r
835 // Load the driver option as the driver option list\r
836 //\r
837 PlatformBdsGetDriverOption (DriverOptionList);\r
838\r
839 //\r
840 // Get current Boot Mode\r
841 //\r
370ec7f1 842 Status = BdsLibGetBootMode (&BootMode);\r
843 DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
49ba9447 844\r
845 //\r
846 // Go the different platform policy with different boot mode\r
847 // Notes: this part code can be change with the table policy\r
848 //\r
370ec7f1 849 ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
49ba9447 850 //\r
851 // Connect platform console\r
852 //\r
853 Status = PlatformBdsConnectConsole (gPlatformConsole);\r
854 if (EFI_ERROR (Status)) {\r
855 //\r
856 // Here OEM/IBV can customize with defined action\r
857 //\r
858 PlatformBdsNoConsoleAction ();\r
859 }\r
860 //\r
861 // Create a 300ms duration event to ensure user has enough input time to enter Setup\r
862 //\r
863 Status = gBS->CreateEvent (\r
864 EVT_TIMER,\r
865 0,\r
866 NULL,\r
867 NULL,\r
868 &UserInputDurationTime\r
869 );\r
870 ASSERT (Status == EFI_SUCCESS);\r
871 Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);\r
872 ASSERT (Status == EFI_SUCCESS);\r
873 //\r
874 // Memory test and Logo show\r
875 //\r
876 PlatformBdsDiagnostics (IGNORE, TRUE);\r
877\r
878 //\r
879 // Perform some platform specific connect sequence\r
880 //\r
881 PlatformBdsConnectSequence ();\r
882\r
883 //\r
884 // Give one chance to enter the setup if we\r
885 // have the time out\r
886 //\r
887 if (Timeout != 0) {\r
888 //PlatformBdsEnterFrontPage (Timeout, FALSE);\r
889 }\r
890\r
891 DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));\r
892 BdsLibConnectAll ();\r
893 BdsLibEnumerateAllBootOption (BootOptionList);\r
894\r
895 //\r
896 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot\r
897 // checking code in real production tip.\r
898 //\r
899 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device\r
900 // and do enumerate all the default boot options. But in development system board, the boot mode\r
901 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box\r
902 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.\r
903 //\r
904 Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
905 if (EFI_ERROR(Status)) {\r
906 //\r
907 // If cannot find "BootOrder" variable, it may be first boot.\r
908 // Try to connect all devices and enumerate all boot options here.\r
909 //\r
910 BdsLibConnectAll ();\r
911 BdsLibEnumerateAllBootOption (BootOptionList);\r
912 }\r
913\r
914 //\r
915 // To give the User a chance to enter Setup here, if user set TimeOut is 0.\r
916 // BDS should still give user a chance to enter Setup\r
917 //\r
918 // Connect first boot option, and then check user input before exit\r
919 //\r
920 for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {\r
921 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
922 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
923 //\r
924 // skip the header of the link list, becuase it has no boot option\r
925 //\r
926 continue;\r
927 } else {\r
928 //\r
929 // Make sure the boot option device path connected, but ignore the BBS device path\r
930 //\r
931 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
932 BdsLibConnectDevicePath (BootOption->DevicePath);\r
933 }\r
934 break;\r
935 }\r
936 }\r
937\r
938 //\r
939 // Check whether the user input after the duration time has expired\r
940 //\r
941 OldTpl = EfiGetCurrentTpl();\r
942 gBS->RestoreTPL (TPL_APPLICATION);\r
943 gBS->WaitForEvent (1, &UserInputDurationTime, &Index);\r
944 gBS->CloseEvent (UserInputDurationTime);\r
945 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
946 gBS->RaiseTPL (OldTpl);\r
947\r
948 if (!EFI_ERROR (Status)) {\r
949 //\r
950 // Enter Setup if user input\r
951 //\r
952 Timeout = 0xffff;\r
953 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
954 }\r
955\r
956 return ;\r
957}\r
958\r
959VOID\r
960EFIAPI\r
961PlatformBdsBootSuccess (\r
962 IN BDS_COMMON_OPTION *Option\r
963 )\r
964/*++\r
965\r
966Routine Description:\r
967\r
968 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
969 return, so the EFI 1.0 specification defines that you will default to an\r
970 interactive mode and stop processing the BootOrder list in this case. This\r
971 is alos a platform implementation and can be customized by IBV/OEM.\r
972\r
973Arguments:\r
974\r
975 Option - Pointer to Boot Option that succeeded to boot.\r
976\r
977Returns:\r
978\r
979 None.\r
980\r
981--*/\r
982{\r
983 CHAR16 *TmpStr;\r
984\r
985 DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));\r
986 //\r
987 // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
988 // select loop then we need to pop up a UI and wait for user input.\r
989 //\r
990 TmpStr = Option->StatusString;\r
991 if (TmpStr != NULL) {\r
992 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
993 FreePool (TmpStr);\r
994 }\r
995}\r
996\r
997VOID\r
998EFIAPI\r
999PlatformBdsBootFail (\r
1000 IN BDS_COMMON_OPTION *Option,\r
1001 IN EFI_STATUS Status,\r
1002 IN CHAR16 *ExitData,\r
1003 IN UINTN ExitDataSize\r
1004 )\r
1005/*++\r
1006\r
1007Routine Description:\r
1008\r
1009 Hook point after a boot attempt fails.\r
1010\r
1011Arguments:\r
1012\r
1013 Option - Pointer to Boot Option that failed to boot.\r
1014\r
1015 Status - Status returned from failed boot.\r
1016\r
1017 ExitData - Exit data returned from failed boot.\r
1018\r
1019 ExitDataSize - Exit data size returned from failed boot.\r
1020\r
1021Returns:\r
1022\r
1023 None.\r
1024\r
1025--*/\r
1026{\r
1027 CHAR16 *TmpStr;\r
1028\r
1029 DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));\r
1030\r
1031 //\r
1032 // If Boot returned with failed status then we need to pop up a UI and wait\r
1033 // for user input.\r
1034 //\r
1035 TmpStr = Option->StatusString;\r
1036 if (TmpStr != NULL) {\r
1037 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1038 FreePool (TmpStr);\r
1039 }\r
1040}\r
1041\r
1042EFI_STATUS\r
1043PlatformBdsNoConsoleAction (\r
1044 VOID\r
1045 )\r
1046/*++\r
1047\r
1048Routine Description:\r
1049\r
1050 This function is remained for IBV/OEM to do some platform action,\r
1051 if there no console device can be connected.\r
1052\r
1053Arguments:\r
1054\r
1055 None.\r
1056\r
1057Returns:\r
1058\r
1059 EFI_SUCCESS - Direct return success now.\r
1060\r
1061--*/\r
1062{\r
1063 DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));\r
1064 return EFI_SUCCESS;\r
1065}\r
1066\r
1067EFI_STATUS\r
1068EFIAPI\r
1069PlatformBdsLockNonUpdatableFlash (\r
1070 VOID\r
1071 )\r
1072{\r
1073 DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));\r
1074 return EFI_SUCCESS;\r
1075}\r
40f2c454 1076\r
1077\r
1078/**\r
1079 This notification function is invoked when an instance of the\r
1080 EFI_DEVICE_PATH_PROTOCOL is produced.\r
1081\r
1082 @param Event The event that occured\r
1083 @param Context For EFI compatiblity. Not used.\r
1084\r
1085**/\r
1086VOID\r
1087EFIAPI\r
1088NotifyDevPath (\r
1089 IN EFI_EVENT Event,\r
1090 IN VOID *Context\r
1091 )\r
1092{\r
1093 EFI_HANDLE Handle;\r
1094 EFI_STATUS Status;\r
1095 UINTN BufferSize;\r
1096 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
1097 ATAPI_DEVICE_PATH *Atapi;\r
1098\r
1099 //\r
1100 // Examine all new handles\r
1101 //\r
1102 for (;;) {\r
1103 //\r
1104 // Get the next handle\r
1105 //\r
1106 BufferSize = sizeof (Handle);\r
1107 Status = gBS->LocateHandle (\r
1108 ByRegisterNotify,\r
1109 NULL,\r
1110 mEfiDevPathNotifyReg,\r
1111 &BufferSize,\r
1112 &Handle\r
1113 );\r
1114\r
1115 //\r
1116 // If not found, we're done\r
1117 //\r
1118 if (EFI_NOT_FOUND == Status) {\r
1119 break;\r
1120 }\r
1121\r
1122 if (EFI_ERROR (Status)) {\r
1123 continue;\r
1124 }\r
1125\r
1126 //\r
1127 // Get the DevicePath protocol on that handle\r
1128 //\r
1129 Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);\r
1130 ASSERT_EFI_ERROR (Status);\r
1131\r
1132 while (!IsDevicePathEnd (DevPathNode)) {\r
1133 //\r
1134 // Find the handler to dump this device path node\r
1135 //\r
1136 if (\r
1137 (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&\r
1138 (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)\r
1139 ) {\r
1140 Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;\r
1141 PciOr16 (\r
1142 PCI_LIB_ADDRESS (\r
1143 0,\r
1144 1,\r
1145 1,\r
1146 (Atapi->PrimarySecondary == 1) ? 0x42: 0x40\r
1147 ),\r
1148 BIT15\r
1149 );\r
1150 }\r
1151\r
1152 //\r
1153 // Next device path node\r
1154 //\r
1155 DevPathNode = NextDevicePathNode (DevPathNode);\r
1156 }\r
1157 }\r
1158\r
1159 return;\r
1160}\r
1161\r
1162\r
1163VOID\r
1164InstallDevicePathCallback (\r
1165 VOID\r
1166 )\r
1167{\r
1168 DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));\r
1169 mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
1170 &gEfiDevicePathProtocolGuid,\r
1171 TPL_CALLBACK,\r
1172 NotifyDevPath,\r
1173 NULL,\r
1174 &mEfiDevPathNotifyReg\r
1175 );\r
1176}\r
1177\r