]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/Library/DuetBdsLib/BdsPlatform.c
remove Bmp.h and ShellFile.h From MdeModulePkg to IntelFrameworkPkg
[mirror_edk2.git] / DuetPkg / Library / DuetBdsLib / BdsPlatform.c
CommitLineData
c69dd9df 1/*++\r
2\r
dba5c454 3Copyright (c) 2006 - 2008, Intel Corporation \r
c69dd9df 4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 BdsPlatform.c\r
15\r
16Abstract:\r
17\r
18 This file include all platform action which can be customized\r
19 by IBV/OEM.\r
20\r
21--*/\r
22\r
23#include "BdsPlatform.h"\r
24\r
25#define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0)\r
26\r
27CHAR16 mFirmwareVendor[] = L"TianoCore.org";\r
28extern BOOLEAN gConnectAllHappened;\r
29extern USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath;\r
9e65d5e9 30\r
31EFI_GUID *gTableGuidArray[] = {\r
32 &gEfiAcpi20TableGuid, &gEfiAcpiTableGuid, &gEfiSmbiosTableGuid, &gEfiMpsTableGuid\r
33 };\r
34\r
c69dd9df 35//\r
36// BDS Platform Functions\r
37//\r
38\r
39VOID\r
40GetSystemTablesFromHob (\r
41 VOID\r
42 )\r
43/*++\r
44\r
45Routine Description:\r
46 Find GUID'ed HOBs that contain EFI_PHYSICAL_ADDRESS of ACPI, SMBIOS, MPs tables\r
47\r
48Arguments:\r
49 None\r
50\r
51Returns:\r
52 None.\r
53\r
54--*/\r
55{\r
e5653d94 56 EFI_PEI_HOB_POINTERS GuidHob;\r
57 EFI_PEI_HOB_POINTERS HobStart;\r
c69dd9df 58 EFI_PHYSICAL_ADDRESS *Table;\r
59 UINTN Index;\r
c69dd9df 60\r
61 //\r
62 // Get Hob List\r
63 //\r
e5653d94 64 HobStart.Raw = GetHobList ();\r
c69dd9df 65 //\r
66 // Iteratively add ACPI Table, SMBIOS Table, MPS Table to EFI System Table\r
67 //\r
9e65d5e9 68 for (Index = 0; Index < sizeof (gTableGuidArray) / sizeof (*gTableGuidArray); ++Index) {\r
69 GuidHob.Raw = GetNextGuidHob (gTableGuidArray[Index], HobStart.Raw);\r
e5653d94 70 if (GuidHob.Raw != NULL) {\r
71 Table = GET_GUID_HOB_DATA (GuidHob.Guid);\r
c69dd9df 72 if (Table != NULL) {\r
73 //\r
74 // Check if Mps Table/Smbios Table/Acpi Table exists in E/F seg,\r
75 // According to UEFI Spec, we should make sure Smbios table, \r
76 // ACPI table and Mps tables kept in memory of specified type\r
77 //\r
9e65d5e9 78 ConvertSystemTable(gTableGuidArray[Index], (VOID**)&Table);\r
79 gBS->InstallConfigurationTable (gTableGuidArray[Index], (VOID *)Table);\r
c69dd9df 80 }\r
81 }\r
82 }\r
83\r
84 return ;\r
85}\r
86\r
87#define EFI_LDR_MEMORY_DESCRIPTOR_GUID \\r
d8bee43c 88 { 0x7701d7e5, 0x7d1d, 0x4432, {0xa4, 0x68, 0x67, 0x3d, 0xab, 0x8a, 0xde, 0x60 }}\r
c69dd9df 89\r
90EFI_GUID gEfiLdrMemoryDescriptorGuid = EFI_LDR_MEMORY_DESCRIPTOR_GUID;\r
91\r
92#pragma pack(1)\r
93\r
94typedef struct {\r
95 EFI_HOB_GUID_TYPE Hob;\r
96 UINTN MemDescCount;\r
97 EFI_MEMORY_DESCRIPTOR *MemDesc;\r
98} MEMORY_DESC_HOB;\r
99\r
100#pragma pack()\r
101\r
102#if 0\r
103VOID\r
104PrintMemoryMap (\r
105 VOID\r
106 )\r
107{\r
108 EFI_MEMORY_DESCRIPTOR *MemMap;\r
109 EFI_MEMORY_DESCRIPTOR *MemMapPtr;\r
110 UINTN MemMapSize;\r
111 UINTN MapKey, DescriptorSize;\r
112 UINTN Index;\r
113 UINT32 DescriptorVersion;\r
114 UINT64 Bytes;\r
115 EFI_STATUS Status;\r
116\r
117 MemMapSize = 0;\r
118 MemMap = NULL;\r
119 Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);\r
120 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
121 MemMapSize += EFI_PAGE_SIZE;\r
122 Status = gBS->AllocatePool (EfiBootServicesData, MemMapSize, &MemMap);\r
123 ASSERT (Status == EFI_SUCCESS);\r
124 Status = gBS->GetMemoryMap (&MemMapSize, MemMap, &MapKey, &DescriptorSize, &DescriptorVersion);\r
125 ASSERT (Status == EFI_SUCCESS);\r
126 MemMapPtr = MemMap;\r
127\r
128 ASSERT (DescriptorVersion == EFI_MEMORY_DESCRIPTOR_VERSION);\r
129\r
130 for (Index = 0; Index < MemMapSize / DescriptorSize; Index ++) {\r
131 Bytes = LShiftU64 (MemMap->NumberOfPages, 12);\r
132 DEBUG ((EFI_D_ERROR, "%lX-%lX %lX %lX %X\n",\r
133 MemMap->PhysicalStart, \r
134 MemMap->PhysicalStart + Bytes - 1,\r
135 MemMap->NumberOfPages, \r
136 MemMap->Attribute,\r
137 (UINTN)MemMap->Type));\r
138 MemMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemMap + DescriptorSize);\r
139 }\r
140\r
141 gBS->FreePool (MemMapPtr);\r
142}\r
143#endif\r
144\r
145VOID\r
146UpdateMemoryMap (\r
147 VOID\r
148 )\r
149{\r
150 EFI_STATUS Status;\r
e5653d94 151 EFI_PEI_HOB_POINTERS GuidHob;\r
c69dd9df 152 VOID *Table;\r
153 MEMORY_DESC_HOB MemoryDescHob;\r
154 UINTN Index;\r
155 EFI_PHYSICAL_ADDRESS Memory;\r
156\r
157 //\r
158 // Get Hob List\r
159 //\r
e5653d94 160 GuidHob.Raw = GetHobList();\r
161 \r
162 GuidHob.Raw = GetNextGuidHob (&gEfiLdrMemoryDescriptorGuid, GuidHob.Raw);\r
163 if (GuidHob.Raw == NULL) {\r
164 DEBUG ((EFI_D_ERROR, "Fail to get gEfiLdrMemoryDescriptorGuid from GUID HOB LIST!\n"));\r
165 return;\r
166 }\r
167 Table = GET_GUID_HOB_DATA (GuidHob.Guid);\r
168 if (Table == NULL) {\r
169 DEBUG ((EFI_D_ERROR, "Fail to get gEfiLdrMemoryDescriptorGuid from GUID HOB LIST!\n"));\r
c69dd9df 170 return;\r
171 }\r
c69dd9df 172 MemoryDescHob.MemDescCount = *(UINTN *)Table;\r
173 MemoryDescHob.MemDesc = *(EFI_MEMORY_DESCRIPTOR **)((UINTN)Table + sizeof(UINTN));\r
174\r
175 //\r
176 // Add ACPINVS, ACPIReclaim, and Reserved memory to MemoryMap\r
177 //\r
178 for (Index = 0; Index < MemoryDescHob.MemDescCount; Index++) {\r
179 if (MemoryDescHob.MemDesc[Index].PhysicalStart < 0x100000) {\r
180 continue;\r
181 }\r
d8bee43c 182 if (MemoryDescHob.MemDesc[Index].PhysicalStart >= 0x100000000ULL) {\r
c69dd9df 183 continue;\r
184 }\r
185 if ((MemoryDescHob.MemDesc[Index].Type == EfiReservedMemoryType) ||\r
186 (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData) ||\r
187 (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesCode) ||\r
188 (MemoryDescHob.MemDesc[Index].Type == EfiACPIReclaimMemory) ||\r
189 (MemoryDescHob.MemDesc[Index].Type == EfiACPIMemoryNVS)) {\r
190 DEBUG ((EFI_D_ERROR, "PhysicalStart - 0x%x, ", MemoryDescHob.MemDesc[Index].PhysicalStart));\r
191 DEBUG ((EFI_D_ERROR, "PageNumber - 0x%x, ", MemoryDescHob.MemDesc[Index].NumberOfPages));\r
192 DEBUG ((EFI_D_ERROR, "Type - 0x%x\n", MemoryDescHob.MemDesc[Index].Type));\r
193 if ((MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData) ||\r
194 (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesCode)) {\r
195 //\r
196 // Skip RuntimeSevicesData and RuntimeServicesCode, they are BFV\r
197 //\r
198 continue;\r
199 }\r
200 Status = gDS->AddMemorySpace (\r
201 EfiGcdMemoryTypeSystemMemory,\r
202 MemoryDescHob.MemDesc[Index].PhysicalStart,\r
203 LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT),\r
204 MemoryDescHob.MemDesc[Index].Attribute\r
205 );\r
206 if (EFI_ERROR (Status)) {\r
207 DEBUG ((EFI_D_ERROR, "AddMemorySpace fail!\n"));\r
208 if ((MemoryDescHob.MemDesc[Index].Type == EfiACPIReclaimMemory) ||\r
209 (MemoryDescHob.MemDesc[Index].Type == EfiACPIMemoryNVS)) {\r
210 //\r
211 // For EfiACPIReclaimMemory and EfiACPIMemoryNVS, it must success.\r
212 // For EfiReservedMemoryType, there maybe overlap. So skip check here.\r
213 //\r
214// ASSERT_EFI_ERROR (Status);\r
215 }\r
216 continue;\r
217 }\r
218\r
219 Memory = MemoryDescHob.MemDesc[Index].PhysicalStart;\r
220 Status = gBS->AllocatePages (\r
221 AllocateAddress,\r
e188a609 222 (EFI_MEMORY_TYPE)MemoryDescHob.MemDesc[Index].Type,\r
c69dd9df 223 (UINTN)MemoryDescHob.MemDesc[Index].NumberOfPages,\r
224 &Memory\r
225 );\r
226 if (EFI_ERROR (Status)) {\r
227 DEBUG ((EFI_D_ERROR, "AllocatePages fail!\n"));\r
228 //\r
229 // For the page added, it must be allocated.\r
230 //\r
231// ASSERT_EFI_ERROR (Status);\r
232 continue;\r
233 }\r
234 }\r
235 }\r
236 \r
237}\r
238\r
239EFI_STATUS\r
240DisableUsbLegacySupport(\r
241 void\r
242 )\r
243/*++\r
244\r
245Routine Description:\r
246 Disabble the USB legacy Support in all Ehci and Uhci.\r
247 This function assume all PciIo handles have been created in system.\r
248 \r
249Arguments:\r
250 None\r
251 \r
252Returns:\r
253 EFI_SUCCESS\r
254 EFI_NOT_FOUND\r
255--*/\r
256{\r
257 EFI_STATUS Status;\r
258 EFI_HANDLE *HandleArray;\r
259 UINTN HandleArrayCount;\r
260 UINTN Index;\r
261 EFI_PCI_IO_PROTOCOL *PciIo;\r
262 UINT8 Class[3];\r
263 UINT16 Command;\r
264 UINT32 HcCapParams;\r
265 UINT32 ExtendCap;\r
266 UINT32 Value;\r
267 UINT32 TimeOut;\r
268 \r
269 //\r
270 // Find the usb host controller \r
271 // \r
272 Status = gBS->LocateHandleBuffer (\r
273 ByProtocol,\r
274 &gEfiPciIoProtocolGuid,\r
275 NULL,\r
276 &HandleArrayCount,\r
277 &HandleArray\r
278 );\r
279 if (!EFI_ERROR (Status)) {\r
280 for (Index = 0; Index < HandleArrayCount; Index++) {\r
281 Status = gBS->HandleProtocol (\r
282 HandleArray[Index],\r
283 &gEfiPciIoProtocolGuid,\r
284 (VOID **)&PciIo\r
285 );\r
286 if (!EFI_ERROR (Status)) {\r
287 //\r
288 // Find the USB host controller controller\r
289 //\r
290 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);\r
291 if (!EFI_ERROR (Status)) {\r
292 if ((PCI_CLASS_SERIAL == Class[2]) &&\r
293 (PCI_CLASS_SERIAL_USB == Class[1])) {\r
294 if (PCI_CLASSC_PI_UHCI == Class[0]) {\r
295 //\r
296 // Found the UHCI, then disable the legacy support\r
297 //\r
298 Command = 0;\r
299 Status = PciIo->Pci.Write (PciIo, EfiPciIoWidthUint16, 0xC0, 1, &Command);\r
300 } else if (PCI_CLASSC_PI_EHCI == Class[0]) {\r
301 //\r
302 // Found the EHCI, then disable the legacy support\r
303 //\r
304 Status = PciIo->Mem.Read (\r
305 PciIo,\r
306 EfiPciIoWidthUint32,\r
307 0, //EHC_BAR_INDEX\r
308 (UINT64) 0x08, //EHC_HCCPARAMS_OFFSET\r
309 1,\r
310 &HcCapParams\r
311 );\r
312 \r
313 ExtendCap = (HcCapParams >> 8) & 0xFF;\r
314 //\r
315 // Disable the SMI in USBLEGCTLSTS firstly\r
316 //\r
317 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value);\r
318 Value &= 0xFFFF0000;\r
319 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ExtendCap + 0x4, 1, &Value);\r
320 \r
321 //\r
322 // Get EHCI Ownership from legacy bios\r
323 //\r
324 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);\r
325 Value |= (0x1 << 24);\r
326 PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);\r
327\r
328 TimeOut = 40;\r
329 while (TimeOut--) {\r
330 gBS->Stall (500);\r
331\r
332 PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, ExtendCap, 1, &Value);\r
333\r
334 if ((Value & 0x01010000) == 0x01000000) {\r
335 break;\r
336 }\r
337 }\r
338 }\r
339 } \r
340 }\r
341 }\r
342 }\r
343 } else {\r
344 return Status;\r
345 }\r
346 gBS->FreePool (HandleArray);\r
347 return EFI_SUCCESS;\r
348}\r
349\r
350\r
351VOID\r
352PlatformBdsInit (\r
353 IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData\r
354 )\r
355/*++\r
356\r
357Routine Description:\r
358\r
359 Platform Bds init. Incude the platform firmware vendor, revision\r
360 and so crc check.\r
361\r
362Arguments:\r
363\r
364 PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
365\r
366Returns:\r
367\r
368 None.\r
369\r
370--*/\r
371{\r
372 //\r
373 // set firmwarevendor, here can be IBV/OEM customize\r
374 //\r
375 gST->FirmwareVendor = AllocateRuntimeCopyPool (\r
376 sizeof (mFirmwareVendor),\r
377 &mFirmwareVendor\r
378 );\r
379 ASSERT (gST->FirmwareVendor != NULL);\r
380\r
381 gST->FirmwareRevision = 0;\r
382\r
383 //\r
384 // Fixup Tasble CRC after we updated Firmware Vendor and Revision\r
385 //\r
386 gBS->CalculateCrc32 ((VOID *) gST, sizeof (EFI_SYSTEM_TABLE), &gST->Hdr.CRC32);\r
e5653d94 387\r
388 GetSystemTablesFromHob ();\r
389\r
390 UpdateMemoryMap ();\r
391 \r
392 //\r
393 // Append Usb Keyboard short form DevicePath into "ConInDev" \r
394 //\r
395 BdsLibUpdateConsoleVariable (\r
396 VarConsoleInpDev,\r
397 (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath,\r
398 NULL\r
399 );\r
c69dd9df 400}\r
401\r
402UINT64\r
403GetPciExpressBaseAddressForRootBridge (\r
404 IN UINTN HostBridgeNumber,\r
405 IN UINTN RootBridgeNumber\r
406 )\r
407/*++\r
408\r
409Routine Description:\r
410 This routine is to get PciExpress Base Address for this RootBridge\r
411\r
412Arguments:\r
413 HostBridgeNumber - The number of HostBridge\r
414 RootBridgeNumber - The number of RootBridge\r
415 \r
416Returns:\r
417 UINT64 - PciExpressBaseAddress for this HostBridge and RootBridge\r
418\r
419--*/\r
420{\r
421 EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION *PciExpressBaseAddressInfo;\r
422 UINTN BufferSize;\r
423 UINT32 Index;\r
424 UINT32 Number;\r
e5653d94 425 EFI_PEI_HOB_POINTERS GuidHob;\r
c69dd9df 426\r
c69dd9df 427 //\r
428 // Get PciExpressAddressInfo Hob\r
429 //\r
5b8adaa5 430 PciExpressBaseAddressInfo = NULL;\r
431 BufferSize = 0;\r
432 GuidHob.Raw = GetFirstGuidHob (&gEfiPciExpressBaseAddressGuid);\r
433 if (GuidHob.Raw != NULL) {\r
434 PciExpressBaseAddressInfo = GET_GUID_HOB_DATA (GuidHob.Guid);\r
435 BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob.Guid);\r
436 } else {\r
e5653d94 437 return 0;\r
438 }\r
c69dd9df 439\r
440 //\r
441 // Search the PciExpress Base Address in the Hob for current RootBridge\r
442 //\r
443 Number = (UINT32)(BufferSize / sizeof(EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION));\r
444 for (Index = 0; Index < Number; Index++) {\r
445 if ((PciExpressBaseAddressInfo[Index].HostBridgeNumber == HostBridgeNumber) &&\r
446 (PciExpressBaseAddressInfo[Index].RootBridgeNumber == RootBridgeNumber)) {\r
447 return PciExpressBaseAddressInfo[Index].PciExpressBaseAddress;\r
448 }\r
449 }\r
450\r
451 //\r
452 // Do not find the PciExpress Base Address in the Hob\r
453 //\r
5b8adaa5 454 return 0; \r
c69dd9df 455}\r
456\r
457VOID\r
458PatchPciRootBridgeDevicePath (\r
459 IN UINTN HostBridgeNumber,\r
460 IN UINTN RootBridgeNumber,\r
461 IN PLATFORM_ROOT_BRIDGE_DEVICE_PATH *RootBridge\r
462 )\r
463{\r
464 UINT64 PciExpressBase;\r
465\r
466 PciExpressBase = GetPciExpressBaseAddressForRootBridge (HostBridgeNumber, RootBridgeNumber);\r
5b8adaa5 467 \r
468 DEBUG ((EFI_D_INFO, "Get PciExpress Address from Hob: 0x%X\n", PciExpressBase));\r
469 \r
c69dd9df 470 if (PciExpressBase != 0) {\r
471 RootBridge->PciRootBridge.HID = EISA_PNP_ID(0x0A08);\r
472 }\r
473}\r
474\r
475EFI_STATUS\r
476ConnectRootBridge (\r
477 VOID\r
478 )\r
479/*++\r
480\r
481Routine Description:\r
482\r
483 Connect RootBridge\r
484\r
485Arguments:\r
486\r
487 None.\r
488 \r
489Returns:\r
490\r
491 EFI_SUCCESS - Connect RootBridge successfully.\r
492 EFI_STATUS - Connect RootBridge fail.\r
493\r
494--*/\r
495{\r
496 EFI_STATUS Status;\r
497 EFI_HANDLE RootHandle;\r
498\r
499 //\r
500 // Patch Pci Root Bridge Device Path\r
501 //\r
502 PatchPciRootBridgeDevicePath (0, 0, &gPlatformRootBridge0);\r
503\r
504 //\r
505 // Make all the PCI_IO protocols on PCI Seg 0 show up\r
506 //\r
507 BdsLibConnectDevicePath (gPlatformRootBridges[0]);\r
508\r
509 Status = gBS->LocateDevicePath (\r
510 &gEfiDevicePathProtocolGuid, \r
511 &gPlatformRootBridges[0], \r
512 &RootHandle\r
513 );\r
5b8adaa5 514 DEBUG ((EFI_D_INFO, "Pci Root bridge handle is 0x%X\n", RootHandle));\r
515 \r
c69dd9df 516 if (EFI_ERROR (Status)) {\r
517 return Status;\r
518 }\r
519\r
520 Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);\r
521 if (EFI_ERROR (Status)) {\r
522 return Status;\r
523 }\r
524\r
525 return EFI_SUCCESS;\r
526}\r
527\r
528EFI_STATUS\r
529PrepareLpcBridgeDevicePath (\r
530 IN EFI_HANDLE DeviceHandle\r
531 )\r
532/*++\r
533\r
534Routine Description:\r
535\r
536 Add IsaKeyboard to ConIn,\r
537 add IsaSerial to ConOut, ConIn, ErrOut.\r
538 LPC Bridge: 06 01 00\r
539\r
540Arguments:\r
541\r
542 DeviceHandle - Handle of PCIIO protocol.\r
543 \r
544Returns:\r
545\r
546 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.\r
547 EFI_STATUS - No LPC bridge is added.\r
548\r
549--*/\r
550{\r
551 EFI_STATUS Status;\r
552 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
553 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
554\r
555 DevicePath = NULL;\r
556 Status = gBS->HandleProtocol (\r
557 DeviceHandle,\r
558 &gEfiDevicePathProtocolGuid,\r
d8bee43c 559 (VOID*)&DevicePath\r
c69dd9df 560 );\r
561 if (EFI_ERROR (Status)) {\r
562 return Status;\r
563 }\r
564 TempDevicePath = DevicePath;\r
565\r
566 //\r
567 // Register Keyboard\r
568 //\r
569 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
570\r
571 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
572\r
573 //\r
574 // Register COM1\r
575 //\r
576 DevicePath = TempDevicePath;\r
577 gPnp16550ComPortDeviceNode.UID = 0;\r
578\r
579 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
580 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
581 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
582\r
583 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
584 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
585 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
586\r
587 //\r
588 // Register COM2\r
589 //\r
590 DevicePath = TempDevicePath;\r
591 gPnp16550ComPortDeviceNode.UID = 1;\r
592\r
593 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
594 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
595 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
596\r
597 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
598 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
599 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
600\r
601 return EFI_SUCCESS;\r
602}\r
603\r
c69dd9df 604EFI_STATUS\r
605GetGopDevicePath (\r
606 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
607 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
608 )\r
609{\r
610 UINTN Index;\r
611 EFI_STATUS Status;\r
612 EFI_HANDLE PciDeviceHandle;\r
613 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
614 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;\r
615 UINTN GopHandleCount;\r
616 EFI_HANDLE *GopHandleBuffer;\r
617\r
618 if (PciDevicePath == NULL || GopDevicePath == NULL) {\r
619 return EFI_INVALID_PARAMETER;\r
620 }\r
621 \r
622 //\r
623 // Initialize the GopDevicePath to be PciDevicePath\r
624 //\r
625 *GopDevicePath = PciDevicePath;\r
626 TempPciDevicePath = PciDevicePath;\r
627\r
628 Status = gBS->LocateDevicePath (\r
629 &gEfiDevicePathProtocolGuid,\r
630 &TempPciDevicePath,\r
631 &PciDeviceHandle\r
632 );\r
633 if (EFI_ERROR (Status)) {\r
634 return Status;\r
635 }\r
636\r
637 //\r
638 // Try to connect this handle, so that GOP dirver could start on this \r
639 // device and create child handles with GraphicsOutput Protocol installed\r
640 // on them, then we get device paths of these child handles and select \r
641 // them as possible console device.\r
642 //\r
643 gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);\r
644\r
645 Status = gBS->LocateHandleBuffer (\r
646 ByProtocol,\r
647 &gEfiGraphicsOutputProtocolGuid,\r
648 NULL,\r
649 &GopHandleCount,\r
650 &GopHandleBuffer\r
651 );\r
652 if (!EFI_ERROR (Status)) {\r
653 //\r
654 // Add all the child handles as possible Console Device\r
655 //\r
656 for (Index = 0; Index < GopHandleCount; Index++) {\r
d8bee43c 657 Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
c69dd9df 658 if (EFI_ERROR (Status)) {\r
659 continue;\r
660 }\r
661 if (CompareMem (\r
662 PciDevicePath,\r
663 TempDevicePath,\r
664 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
665 ) == 0) {\r
666 //\r
667 // In current implementation, we only enable one of the child handles\r
668 // as console device, i.e. sotre one of the child handle's device\r
669 // path to variable "ConOut"\r
670 // In futhure, we could select all child handles to be console device\r
671 // \r
672\r
673 *GopDevicePath = TempDevicePath;\r
674\r
675 //\r
676 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()\r
677 // Add the integrity GOP device path.\r
678 //\r
679 BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath);\r
680 BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL);\r
681 }\r
682 }\r
683 gBS->FreePool (GopHandleBuffer);\r
684 }\r
685\r
686 return EFI_SUCCESS;\r
687}\r
c69dd9df 688\r
689EFI_STATUS\r
690PreparePciVgaDevicePath (\r
691 IN EFI_HANDLE DeviceHandle\r
692 )\r
693/*++\r
694\r
695Routine Description:\r
696\r
697 Add PCI VGA to ConOut.\r
698 PCI VGA: 03 00 00\r
699\r
700Arguments:\r
701\r
702 DeviceHandle - Handle of PCIIO protocol.\r
703 \r
704Returns:\r
705\r
706 EFI_SUCCESS - PCI VGA is added to ConOut.\r
707 EFI_STATUS - No PCI VGA device is added.\r
708\r
709--*/\r
710{\r
711 EFI_STATUS Status;\r
712 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
c69dd9df 713 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;\r
c69dd9df 714\r
715 DevicePath = NULL;\r
716 Status = gBS->HandleProtocol (\r
717 DeviceHandle,\r
718 &gEfiDevicePathProtocolGuid,\r
d8bee43c 719 (VOID*)&DevicePath\r
c69dd9df 720 );\r
721 if (EFI_ERROR (Status)) {\r
722 return Status;\r
723 }\r
724 \r
c69dd9df 725 GetGopDevicePath (DevicePath, &GopDevicePath);\r
726 DevicePath = GopDevicePath;\r
c69dd9df 727\r
728 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
729 \r
730 return EFI_SUCCESS;\r
731}\r
732\r
733EFI_STATUS\r
734PreparePciSerialDevicePath (\r
735 IN EFI_HANDLE DeviceHandle\r
736 )\r
737/*++\r
738\r
739Routine Description:\r
740\r
741 Add PCI Serial to ConOut, ConIn, ErrOut.\r
742 PCI Serial: 07 00 02\r
743\r
744Arguments:\r
745\r
746 DeviceHandle - Handle of PCIIO protocol.\r
747 \r
748Returns:\r
749\r
750 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.\r
751 EFI_STATUS - No PCI Serial device is added.\r
752\r
753--*/\r
754{\r
755 EFI_STATUS Status;\r
756 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
be768885 757 \r
c69dd9df 758 DevicePath = NULL;\r
759 Status = gBS->HandleProtocol (\r
760 DeviceHandle,\r
761 &gEfiDevicePathProtocolGuid,\r
d8bee43c 762 (VOID*)&DevicePath\r
c69dd9df 763 );\r
764 if (EFI_ERROR (Status)) {\r
765 return Status;\r
766 }\r
767\r
768 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
769 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
770\r
771 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
772 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
773 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
774 \r
775 return EFI_SUCCESS;\r
776}\r
777\r
778EFI_STATUS\r
779DetectAndPreparePlatformPciDevicePath (\r
780 BOOLEAN DetectVgaOnly\r
781 )\r
782/*++\r
783\r
784Routine Description:\r
785\r
786 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
787\r
788Arguments:\r
789\r
790 DetectVgaOnly - Only detect VGA device if it's TRUE.\r
791 \r
792Returns:\r
793\r
794 EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
795 EFI_STATUS - PCI Device check or Console variable update fail.\r
796\r
797--*/\r
798{\r
799 EFI_STATUS Status;\r
800 UINTN HandleCount;\r
801 EFI_HANDLE *HandleBuffer;\r
802 UINTN Index;\r
803 EFI_PCI_IO_PROTOCOL *PciIo;\r
804 PCI_TYPE00 Pci;\r
805\r
806 //\r
807 // Start to check all the PciIo to find all possible device\r
808 //\r
809 HandleCount = 0;\r
810 HandleBuffer = NULL;\r
811 Status = gBS->LocateHandleBuffer (\r
812 ByProtocol,\r
813 &gEfiPciIoProtocolGuid,\r
814 NULL,\r
815 &HandleCount,\r
816 &HandleBuffer\r
817 );\r
818 if (EFI_ERROR (Status)) {\r
819 return Status;\r
820 }\r
821\r
822 for (Index = 0; Index < HandleCount; Index++) {\r
d8bee43c 823 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);\r
c69dd9df 824 if (EFI_ERROR (Status)) {\r
825 continue;\r
826 }\r
827\r
828 //\r
829 // Check for all PCI device\r
830 //\r
831 Status = PciIo->Pci.Read (\r
832 PciIo,\r
833 EfiPciIoWidthUint32,\r
834 0,\r
835 sizeof (Pci) / sizeof (UINT32),\r
836 &Pci\r
837 );\r
838 if (EFI_ERROR (Status)) {\r
839 continue;\r
840 }\r
841\r
842 if (!DetectVgaOnly) {\r
843 //\r
844 // Here we decide whether it is LPC Bridge\r
845 //\r
846 if ((IS_PCI_LPC (&Pci)) ||\r
847 ((IS_PCI_ISA_PDECODE (&Pci)) && (Pci.Hdr.VendorId == 0x8086) && (Pci.Hdr.DeviceId == 0x7110))) {\r
848 //\r
849 // Add IsaKeyboard to ConIn,\r
850 // add IsaSerial to ConOut, ConIn, ErrOut\r
851 //\r
e5653d94 852 DEBUG ((EFI_D_INFO, "Find the LPC Bridge device\n"));\r
c69dd9df 853 PrepareLpcBridgeDevicePath (HandleBuffer[Index]);\r
854 continue;\r
855 }\r
856 //\r
857 // Here we decide which Serial device to enable in PCI bus \r
858 //\r
859 if (IS_PCI_16550SERIAL (&Pci)) {\r
860 //\r
861 // Add them to ConOut, ConIn, ErrOut.\r
862 //\r
e5653d94 863 DEBUG ((EFI_D_INFO, "Find the 16550 SERIAL device\n"));\r
c69dd9df 864 PreparePciSerialDevicePath (HandleBuffer[Index]);\r
865 continue;\r
866 }\r
867 }\r
868\r
869 //\r
870 // Here we decide which VGA device to enable in PCI bus \r
871 //\r
872 if (IS_PCI_VGA (&Pci)) {\r
873 //\r
874 // Add them to ConOut.\r
875 //\r
e5653d94 876 DEBUG ((EFI_D_INFO, "Find the VGA device\n"));\r
c69dd9df 877 PreparePciVgaDevicePath (HandleBuffer[Index]);\r
878 continue;\r
879 }\r
880 }\r
881 \r
882 gBS->FreePool (HandleBuffer);\r
883 \r
884 return EFI_SUCCESS;\r
885}\r
886\r
887EFI_STATUS\r
888PlatformBdsConnectConsole (\r
889 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
890 )\r
891/*++\r
892\r
893Routine Description:\r
894\r
895 Connect the predefined platform default console device. Always try to find\r
896 and enable the vga device if have.\r
897\r
898Arguments:\r
899\r
900 PlatformConsole - Predfined platform default console device array.\r
901 \r
902Returns:\r
903\r
904 EFI_SUCCESS - Success connect at least one ConIn and ConOut \r
905 device, there must have one ConOut device is \r
906 active vga device.\r
907 \r
908 EFI_STATUS - Return the status of \r
909 BdsLibConnectAllDefaultConsoles ()\r
910\r
911--*/\r
912{\r
913 EFI_STATUS Status;\r
914 UINTN Index;\r
915 EFI_DEVICE_PATH_PROTOCOL *VarConout;\r
916 EFI_DEVICE_PATH_PROTOCOL *VarConin;\r
917 UINTN DevicePathSize;\r
918\r
919 //\r
920 // Connect RootBridge\r
921 //\r
922 ConnectRootBridge ();\r
923\r
924 VarConout = BdsLibGetVariableAndSize (\r
925 VarConsoleOut,\r
926 &gEfiGlobalVariableGuid,\r
927 &DevicePathSize\r
928 );\r
929 VarConin = BdsLibGetVariableAndSize (\r
930 VarConsoleInp,\r
931 &gEfiGlobalVariableGuid,\r
932 &DevicePathSize\r
933 );\r
be768885 934 \r
c69dd9df 935 if (VarConout == NULL || VarConin == NULL) {\r
936 //\r
937 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
938 //\r
939 DetectAndPreparePlatformPciDevicePath (FALSE);\r
940\r
941 //\r
942 // Have chance to connect the platform default console,\r
943 // the platform default console is the minimue device group\r
944 // the platform should support\r
945 //\r
946 for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
947 //\r
948 // Update the console variable with the connect type\r
949 //\r
950 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
951 BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);\r
952 }\r
953 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
954 BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);\r
955 }\r
956 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
957 BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);\r
958 }\r
959 }\r
960 } else {\r
961 //\r
962 // Only detect VGA device and add them to ConOut\r
963 //\r
964 DetectAndPreparePlatformPciDevicePath (TRUE);\r
965 }\r
966 \r
967 //\r
968 // The ConIn devices connection will start the USB bus, should disable all\r
969 // Usb legacy support firstly.\r
970 // Caution: Must ensure the PCI bus driver has been started. Since the \r
971 // ConnectRootBridge() will create all the PciIo protocol, it's safe here now\r
972 //\r
973 Status = DisableUsbLegacySupport();\r
974 \r
975 //\r
976 // Connect the all the default console with current cosole variable\r
977 //\r
978 Status = BdsLibConnectAllDefaultConsoles ();\r
979 if (EFI_ERROR (Status)) {\r
980 return Status;\r
981 }\r
982\r
983 return EFI_SUCCESS;\r
984}\r
985\r
986VOID\r
987PlatformBdsConnectSequence (\r
988 VOID\r
989 )\r
990/*++\r
991\r
992Routine Description:\r
993\r
994 Connect with predeined platform connect sequence, \r
995 the OEM/IBV can customize with their own connect sequence.\r
996 \r
997Arguments:\r
998\r
999 None.\r
1000 \r
1001Returns:\r
1002\r
1003 None.\r
1004 \r
1005--*/\r
1006{\r
1007 UINTN Index;\r
1008\r
1009 Index = 0;\r
1010\r
1011 //\r
1012 // Here we can get the customized platform connect sequence\r
1013 // Notes: we can connect with new variable which record the\r
1014 // last time boots connect device path sequence\r
1015 //\r
1016 while (gPlatformConnectSequence[Index] != NULL) {\r
1017 //\r
1018 // Build the platform boot option\r
1019 //\r
1020 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
1021 Index++;\r
1022 }\r
1023\r
1024}\r
1025\r
1026VOID\r
1027PlatformBdsGetDriverOption (\r
1028 IN OUT LIST_ENTRY *BdsDriverLists\r
1029 )\r
1030/*++\r
1031\r
1032Routine Description:\r
1033\r
1034 Load the predefined driver option, OEM/IBV can customize this\r
1035 to load their own drivers\r
1036 \r
1037Arguments:\r
1038\r
1039 BdsDriverLists - The header of the driver option link list.\r
1040 \r
1041Returns:\r
1042\r
1043 None.\r
1044 \r
1045--*/\r
1046{\r
1047 UINTN Index;\r
1048\r
1049 Index = 0;\r
1050\r
1051 //\r
1052 // Here we can get the customized platform driver option\r
1053 //\r
1054 while (gPlatformDriverOption[Index] != NULL) {\r
1055 //\r
1056 // Build the platform boot option\r
1057 //\r
1058 BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");\r
1059 Index++;\r
1060 }\r
1061\r
1062}\r
1063\r
1064VOID\r
1065PlatformBdsDiagnostics (\r
1066 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
1067 IN BOOLEAN QuietBoot\r
1068 )\r
1069/*++\r
1070\r
1071Routine Description:\r
1072\r
1073 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
1074 can customize this fuction to support specific platform diagnostic.\r
1075 \r
1076Arguments:\r
1077\r
1078 MemoryTestLevel - The memory test intensive level\r
1079 \r
1080 QuietBoot - Indicate if need to enable the quiet boot\r
1081 \r
1082Returns:\r
1083\r
1084 None.\r
1085 \r
1086--*/\r
1087{\r
1088 EFI_STATUS Status;\r
1089\r
1090 //\r
1091 // Here we can decide if we need to show\r
1092 // the diagnostics screen\r
1093 // Notes: this quiet boot code should be remove\r
1094 // from the graphic lib\r
1095 //\r
1096 if (QuietBoot) {\r
dba5c454 1097 Status = EnableQuietBoot (&gEfiDefaultBmpLogoGuid);\r
ff514e29 1098 if (EFI_ERROR (Status)) {\r
1099 DisableQuietBoot ();\r
1100 return;\r
1101 }\r
1102\r
c69dd9df 1103 //\r
1104 // Perform system diagnostic\r
1105 //\r
1106 Status = BdsMemoryTest (MemoryTestLevel);\r
1107 if (EFI_ERROR (Status)) {\r
1108 DisableQuietBoot ();\r
1109 }\r
1110\r
1111 return ;\r
1112 }\r
1113 //\r
1114 // Perform system diagnostic\r
1115 //\r
1116 Status = BdsMemoryTest (MemoryTestLevel);\r
1117}\r
1118\r
1119VOID\r
1120PlatformBdsPolicyBehavior (\r
1121 IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData,\r
1122 IN OUT LIST_ENTRY *DriverOptionList,\r
1123 IN OUT LIST_ENTRY *BootOptionList\r
1124 )\r
1125/*++\r
1126\r
1127Routine Description:\r
1128\r
1129 The function will excute with as the platform policy, current policy\r
1130 is driven by boot mode. IBV/OEM can customize this code for their specific\r
1131 policy action.\r
1132 \r
1133Arguments:\r
1134\r
1135 PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
1136 \r
1137 DriverOptionList - The header of the driver option link list\r
1138 \r
1139 BootOptionList - The header of the boot option link list\r
1140 \r
1141Returns:\r
1142\r
1143 None.\r
1144 \r
1145--*/\r
1146{\r
1147 EFI_STATUS Status;\r
1148 UINT16 Timeout;\r
1149 EFI_EVENT UserInputDurationTime;\r
1150 LIST_ENTRY *Link;\r
1151 BDS_COMMON_OPTION *BootOption;\r
1152 UINTN Index;\r
1153 EFI_INPUT_KEY Key;\r
1154 EFI_TPL OldTpl;\r
1155\r
1156 //\r
1157 // Init the time out value\r
1158 //\r
6efe5f96 1159 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
c69dd9df 1160\r
1161 //\r
1162 // Load the driver option as the driver option list\r
1163 //\r
1164 PlatformBdsGetDriverOption (DriverOptionList);\r
1165\r
1166 //\r
1167 // Get current Boot Mode\r
1168 //\r
1169 Status = BdsLibGetBootMode (&PrivateData->BootMode);\r
1170 DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", PrivateData->BootMode));\r
1171\r
1172 //\r
1173 // Go the different platform policy with different boot mode\r
1174 // Notes: this part code can be change with the table policy\r
1175 //\r
1176 ASSERT (PrivateData->BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
1177 //\r
1178 // Connect platform console\r
1179 //\r
1180 Status = PlatformBdsConnectConsole (gPlatformConsole);\r
1181 if (EFI_ERROR (Status)) {\r
1182 //\r
1183 // Here OEM/IBV can customize with defined action\r
1184 //\r
1185 PlatformBdsNoConsoleAction ();\r
1186 }\r
1187 //\r
1188 // Create a 300ms duration event to ensure user has enough input time to enter Setup\r
1189 //\r
1190 Status = gBS->CreateEvent (\r
e53a6ea9 1191 EVT_TIMER,\r
c69dd9df 1192 0,\r
1193 NULL,\r
1194 NULL,\r
1195 &UserInputDurationTime\r
1196 );\r
1197 ASSERT (Status == EFI_SUCCESS);\r
1198 Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);\r
1199 ASSERT (Status == EFI_SUCCESS);\r
1200 //\r
1201 // Memory test and Logo show\r
1202 //\r
1203 PlatformBdsDiagnostics (IGNORE, TRUE);\r
1204\r
1205 //\r
1206 // Perform some platform specific connect sequence\r
1207 //\r
1208 PlatformBdsConnectSequence ();\r
1209\r
1210 //\r
1211 // Give one chance to enter the setup if we\r
1212 // have the time out\r
1213 //\r
ba992f96 1214 // BUGBUG: hard code timeout to 5 second to show logo in graphic mode.\r
1215 Timeout = 5; \r
c69dd9df 1216 if (Timeout != 0) {\r
1217 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
1218 }\r
1219\r
1220 //\r
1221 //BdsLibConnectAll ();\r
1222 //BdsLibEnumerateAllBootOption (BootOptionList); \r
1223 \r
1224 //\r
1225 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot\r
1226 // checking code in real production tip.\r
1227 // \r
1228 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device \r
1229 // and do enumerate all the default boot options. But in development system board, the boot mode \r
1230 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box\r
1231 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.\r
1232 //\r
1233 Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
1234 if (EFI_ERROR(Status)) {\r
1235 //\r
1236 // If cannot find "BootOrder" variable, it may be first boot. \r
1237 // Try to connect all devices and enumerate all boot options here.\r
1238 //\r
1239 BdsLibConnectAll ();\r
1240 BdsLibEnumerateAllBootOption (BootOptionList);\r
1241 } \r
1242\r
1243 //\r
1244 // To give the User a chance to enter Setup here, if user set TimeOut is 0.\r
1245 // BDS should still give user a chance to enter Setup\r
1246 //\r
1247 // Connect first boot option, and then check user input before exit \r
1248 //\r
1249 for (Link = BootOptionList->ForwardLink; Link != BootOptionList;Link = Link->ForwardLink) {\r
1250 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
1251 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
1252 //\r
1253 // skip the header of the link list, becuase it has no boot option\r
1254 //\r
1255 continue;\r
1256 } else {\r
1257 //\r
1258 // Make sure the boot option device path connected, but ignore the BBS device path\r
1259 //\r
1260 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
1261 BdsLibConnectDevicePath (BootOption->DevicePath);\r
1262 } \r
1263 break; \r
1264 }\r
1265 } \r
1266\r
1267 //\r
1268 // Check whether the user input after the duration time has expired \r
1269 //\r
d55eb54d 1270 OldTpl = EfiGetCurrentTpl();\r
c69dd9df 1271 gBS->RestoreTPL (TPL_APPLICATION); \r
1272 gBS->WaitForEvent (1, &UserInputDurationTime, &Index);\r
1273 gBS->CloseEvent (UserInputDurationTime);\r
1274 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
1275 gBS->RaiseTPL (OldTpl); \r
1276 \r
1277 if (!EFI_ERROR (Status)) {\r
1278 //\r
1279 // Enter Setup if user input \r
1280 //\r
1281 Timeout = 0xffff;\r
1282 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
1283 }\r
1284 \r
1285 return ;\r
1286\r
1287}\r
1288\r
1289VOID\r
1290PlatformBdsBootSuccess (\r
1291 IN BDS_COMMON_OPTION *Option\r
1292 )\r
1293/*++\r
1294\r
1295Routine Description:\r
1296 \r
1297 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
1298 return, so the EFI 1.0 specification defines that you will default to an\r
1299 interactive mode and stop processing the BootOrder list in this case. This\r
1300 is alos a platform implementation and can be customized by IBV/OEM.\r
1301\r
1302Arguments:\r
1303\r
1304 Option - Pointer to Boot Option that succeeded to boot.\r
1305\r
1306Returns:\r
1307 \r
1308 None.\r
1309\r
1310--*/\r
1311{\r
1312 CHAR16 *TmpStr;\r
1313\r
1314 //\r
1315 // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
1316 // select loop then we need to pop up a UI and wait for user input.\r
1317 //\r
1318 TmpStr = Option->StatusString;\r
1319 if (TmpStr != NULL) {\r
1320 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1321 gBS->FreePool (TmpStr);\r
1322 }\r
1323}\r
1324\r
1325VOID\r
1326PlatformBdsBootFail (\r
1327 IN BDS_COMMON_OPTION *Option,\r
1328 IN EFI_STATUS Status,\r
1329 IN CHAR16 *ExitData,\r
1330 IN UINTN ExitDataSize\r
1331 )\r
1332/*++\r
1333\r
1334Routine Description:\r
1335 \r
1336 Hook point after a boot attempt fails.\r
1337\r
1338Arguments:\r
1339 \r
1340 Option - Pointer to Boot Option that failed to boot.\r
1341\r
1342 Status - Status returned from failed boot.\r
1343\r
1344 ExitData - Exit data returned from failed boot.\r
1345\r
1346 ExitDataSize - Exit data size returned from failed boot.\r
1347\r
1348Returns:\r
1349 \r
1350 None.\r
1351\r
1352--*/\r
1353{\r
1354 CHAR16 *TmpStr;\r
1355\r
1356 //\r
1357 // If Boot returned with failed status then we need to pop up a UI and wait\r
1358 // for user input.\r
1359 //\r
1360 TmpStr = Option->StatusString;\r
1361 if (TmpStr != NULL) {\r
1362 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1363 gBS->FreePool (TmpStr);\r
1364 }\r
1365\r
1366}\r
1367\r
1368EFI_STATUS\r
1369PlatformBdsNoConsoleAction (\r
1370 VOID\r
1371 )\r
1372/*++\r
1373\r
1374Routine Description:\r
1375 \r
1376 This function is remained for IBV/OEM to do some platform action,\r
1377 if there no console device can be connected.\r
1378\r
1379Arguments:\r
1380 \r
1381 None.\r
1382 \r
1383Returns:\r
1384 \r
1385 EFI_SUCCESS - Direct return success now.\r
1386\r
1387--*/\r
1388{\r
1389 return EFI_SUCCESS;\r
1390}\r
1391\r
1392EFI_STATUS\r
1393ConvertSystemTable (\r
1394 IN EFI_GUID *TableGuid,\r
1395 IN OUT VOID **Table\r
1396 )\r
1397/*++\r
1398\r
1399Routine Description:\r
1400 Convert ACPI Table /Smbios Table /MP Table if its location is lower than Address:0x100000\r
1401 Assumption here:\r
1402 As in legacy Bios, ACPI/Smbios/MP table is required to place in E/F Seg, \r
1403 So here we just check if the range is E/F seg, \r
1404 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS\r
1405\r
1406Arguments:\r
1407 TableGuid - Guid of the table\r
1408 Table - pointer to the table \r
1409\r
1410Returns:\r
1411 EFI_SUCEESS - Convert Table successfully\r
1412 Other - Failed\r
1413\r
1414--*/\r
1415{\r
1416 EFI_STATUS Status;\r
1417 VOID *AcpiHeader;\r
1418 UINTN AcpiTableLen;\r
1419 \r
1420 //\r
1421 // If match acpi guid (1.0, 2.0, or later), Convert ACPI table according to version. \r
1422 //\r
1423 AcpiHeader = (VOID*)(UINTN)(*(UINT64 *)(*Table));\r
1424 \r
1425 if (CompareGuid(TableGuid, &gEfiAcpiTableGuid) || CompareGuid(TableGuid, &gEfiAcpi20TableGuid)){\r
1426 if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved == 0x00){\r
1427 //\r
1428 // If Acpi 1.0 Table, then RSDP structure doesn't contain Length field, use structure size\r
1429 //\r
1430 AcpiTableLen = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
1431 } else if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved >= 0x02){\r
1432 //\r
1433 // If Acpi 2.0 or later, use RSDP Length fied.\r
1434 //\r
1435 AcpiTableLen = ((EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Length;\r
1436 } else {\r
1437 //\r
1438 // Invalid Acpi Version, return\r
1439 //\r
1440 return EFI_UNSUPPORTED;\r
1441 }\r
1442 Status = ConvertAcpiTable (AcpiTableLen, Table);\r
1443 return Status; \r
1444 }\r
1445 \r
1446 //\r
1447 // If matches smbios guid, convert Smbios table.\r
1448 //\r
1449 if (CompareGuid(TableGuid, &gEfiSmbiosTableGuid)){\r
1450 Status = ConvertSmbiosTable (Table);\r
1451 return Status;\r
1452 }\r
1453 \r
1454 //\r
1455 // If the table is MP table?\r
1456 //\r
1457 if (CompareGuid(TableGuid, &gEfiMpsTableGuid)){\r
1458 Status = ConvertMpsTable (Table);\r
1459 return Status;\r
1460 }\r
1461 \r
1462 return EFI_UNSUPPORTED;\r
1463} \r
1464\r
1465UINT8\r
1466GetBufferCheckSum (\r
1467 IN VOID * Buffer,\r
1468 IN UINTN Length\r
1469 )\r
1470/*++\r
1471\r
1472Routine Description:\r
1473 Caculate buffer checksum (8-bit)\r
1474\r
1475Arguments:\r
1476 Buffer - Pointer to Buffer that to be caculated\r
1477 Length - How many bytes are to be caculated \r
1478\r
1479Returns:\r
1480 Checksum of the buffer\r
1481\r
1482--*/\r
1483{\r
1484 UINT8 CheckSum;\r
1485 UINT8 *Ptr8;\r
1486 \r
1487 CheckSum = 0;\r
1488 Ptr8 = (UINT8 *) Buffer;\r
1489 \r
1490 while (Length > 0) {\r
1491 CheckSum = (UINT8) (CheckSum + *Ptr8++);\r
1492 Length--;\r
1493 }\r
1494 \r
e188a609 1495 return (UINT8)((0xFF - CheckSum) + 1);\r
c69dd9df 1496} \r
1497\r
1498EFI_STATUS\r
1499ConvertAcpiTable (\r
1500 IN UINTN TableLen,\r
1501 IN OUT VOID **Table\r
1502 )\r
1503/*++\r
1504\r
1505Routine Description:\r
1506 Convert RSDP of ACPI Table if its location is lower than Address:0x100000\r
1507 Assumption here:\r
1508 As in legacy Bios, ACPI table is required to place in E/F Seg, \r
1509 So here we just check if the range is E/F seg, \r
1510 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS\r
1511\r
1512Arguments:\r
1513 TableLen - Acpi RSDP length\r
1514 Table - pointer to the table \r
1515\r
1516Returns:\r
1517 EFI_SUCEESS - Convert Table successfully\r
1518 Other - Failed\r
1519\r
1520--*/\r
1521{\r
1522 VOID *AcpiTableOri;\r
1523 VOID *AcpiTableNew;\r
1524 EFI_STATUS Status;\r
1525 EFI_PHYSICAL_ADDRESS BufferPtr;\r
1526\r
1527 \r
1528 AcpiTableOri = (VOID *)(UINTN)(*(UINT64*)(*Table));\r
1529 if (((UINTN)AcpiTableOri < 0x100000) && ((UINTN)AcpiTableOri > 0xE0000)) {\r
1530 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;\r
1531 Status = gBS->AllocatePages (\r
1532 AllocateMaxAddress,\r
1533 EfiACPIMemoryNVS,\r
1534 EFI_SIZE_TO_PAGES(TableLen),\r
1535 &BufferPtr\r
1536 );\r
1537 ASSERT_EFI_ERROR (Status);\r
1538 AcpiTableNew = (VOID *)(UINTN)BufferPtr;\r
1539 CopyMem (AcpiTableNew, AcpiTableOri, TableLen);\r
1540 } else {\r
1541 AcpiTableNew = AcpiTableOri;\r
1542 }\r
1543 //\r
1544 // Change configuration table Pointer\r
1545 //\r
1546 *Table = AcpiTableNew;\r
1547 \r
1548 return EFI_SUCCESS;\r
1549}\r
1550\r
1551EFI_STATUS\r
1552ConvertSmbiosTable (\r
1553 IN OUT VOID **Table\r
1554 )\r
1555/*++\r
1556\r
1557Routine Description:\r
1558\r
1559 Convert Smbios Table if the Location of the SMBios Table is lower than Addres 0x100000\r
1560 Assumption here:\r
1561 As in legacy Bios, Smbios table is required to place in E/F Seg, \r
1562 So here we just check if the range is F seg, \r
1563 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData\r
1564Arguments:\r
1565 Table - pointer to the table\r
1566\r
1567Returns:\r
1568 EFI_SUCEESS - Convert Table successfully\r
1569 Other - Failed\r
1570\r
1571--*/\r
1572{\r
1573 SMBIOS_TABLE_ENTRY_POINT *SmbiosTableNew;\r
1574 SMBIOS_TABLE_ENTRY_POINT *SmbiosTableOri;\r
1575 EFI_STATUS Status;\r
1576 UINT32 SmbiosEntryLen;\r
1577 UINT32 BufferLen;\r
1578 EFI_PHYSICAL_ADDRESS BufferPtr;\r
1579 \r
1580 SmbiosTableNew = NULL;\r
1581 SmbiosTableOri = NULL;\r
1582 \r
1583 //\r
1584 // Get Smibos configuration Table \r
1585 //\r
1586 SmbiosTableOri = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)(*(UINT64*)(*Table));\r
1587 \r
1588 if ((SmbiosTableOri == NULL) ||\r
1589 ((UINTN)SmbiosTableOri > 0x100000) ||\r
1590 ((UINTN)SmbiosTableOri < 0xF0000)){\r
1591 return EFI_SUCCESS;\r
1592 }\r
1593 //\r
1594 // Relocate the Smibos memory\r
1595 //\r
1596 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;\r
1597 if (SmbiosTableOri->SmbiosBcdRevision != 0x21) {\r
1598 SmbiosEntryLen = SmbiosTableOri->EntryPointLength;\r
1599 } else {\r
1600 //\r
1601 // According to Smbios Spec 2.4, we should set entry point length as 0x1F if version is 2.1\r
1602 //\r
1603 SmbiosEntryLen = 0x1F;\r
1604 }\r
1605 BufferLen = SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen) + SmbiosTableOri->TableLength;\r
1606 Status = gBS->AllocatePages (\r
1607 AllocateMaxAddress,\r
1608 EfiACPIMemoryNVS,\r
1609 EFI_SIZE_TO_PAGES(BufferLen),\r
1610 &BufferPtr\r
1611 );\r
1612 ASSERT_EFI_ERROR (Status);\r
1613 SmbiosTableNew = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)BufferPtr;\r
1614 CopyMem (\r
1615 SmbiosTableNew, \r
1616 SmbiosTableOri,\r
1617 SmbiosEntryLen\r
1618 );\r
1619 // \r
1620 // Get Smbios Structure table address, and make sure the start address is 32-bit align\r
1621 //\r
1622 BufferPtr += SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen);\r
1623 CopyMem (\r
1624 (VOID *)(UINTN)BufferPtr, \r
1625 (VOID *)(UINTN)(SmbiosTableOri->TableAddress),\r
1626 SmbiosTableOri->TableLength\r
1627 );\r
1628 SmbiosTableNew->TableAddress = (UINT32)BufferPtr;\r
1629 SmbiosTableNew->IntermediateChecksum = 0;\r
1630 SmbiosTableNew->IntermediateChecksum = \r
1631 GetBufferCheckSum ((UINT8*)SmbiosTableNew + 0x10, SmbiosEntryLen -0x10);\r
1632 //\r
1633 // Change the SMBIOS pointer\r
1634 //\r
1635 *Table = SmbiosTableNew;\r
1636 \r
1637 return EFI_SUCCESS; \r
1638} \r
1639\r
1640EFI_STATUS\r
1641ConvertMpsTable (\r
1642 IN OUT VOID **Table\r
1643 )\r
1644/*++\r
1645\r
1646Routine Description:\r
1647\r
1648 Convert MP Table if the Location of the SMBios Table is lower than Addres 0x100000\r
1649 Assumption here:\r
1650 As in legacy Bios, MP table is required to place in E/F Seg, \r
1651 So here we just check if the range is E/F seg, \r
1652 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData\r
1653Arguments:\r
1654 Table - pointer to the table\r
1655\r
1656Returns:\r
1657 EFI_SUCEESS - Convert Table successfully\r
1658 Other - Failed\r
1659\r
1660--*/\r
1661{\r
1662 UINT32 Data32;\r
1663 UINT32 FPLength;\r
1664 EFI_LEGACY_MP_TABLE_FLOATING_POINTER *MpsFloatingPointerOri;\r
1665 EFI_LEGACY_MP_TABLE_FLOATING_POINTER *MpsFloatingPointerNew;\r
1666 EFI_LEGACY_MP_TABLE_HEADER *MpsTableOri;\r
1667 EFI_LEGACY_MP_TABLE_HEADER *MpsTableNew;\r
1668 VOID *OemTableOri;\r
1669 VOID *OemTableNew;\r
1670 EFI_STATUS Status;\r
1671 EFI_PHYSICAL_ADDRESS BufferPtr;\r
1672 \r
1673 //\r
1674 // Get MP configuration Table \r
1675 //\r
1676 MpsFloatingPointerOri = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)(*(UINT64*)(*Table));\r
1677 if (!(((UINTN)MpsFloatingPointerOri <= 0x100000) && \r
1678 ((UINTN)MpsFloatingPointerOri >= 0xF0000))){\r
1679 return EFI_SUCCESS;\r
1680 }\r
1681 //\r
1682 // Get Floating pointer structure length\r
1683 //\r
1684 FPLength = MpsFloatingPointerOri->Length * 16;\r
1685 Data32 = FPLength + SYS_TABLE_PAD (FPLength);\r
1686 MpsTableOri = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)(MpsFloatingPointerOri->PhysicalAddress);\r
1687 if (MpsTableOri != NULL) {\r
1688 Data32 += MpsTableOri->BaseTableLength;\r
1689 Data32 += MpsTableOri->ExtendedTableLength;\r
1690 if (MpsTableOri->OemTablePointer != 0x00) {\r
1691 Data32 += SYS_TABLE_PAD (Data32);\r
1692 Data32 += MpsTableOri->OemTableSize;\r
1693 }\r
1694 } else {\r
1695 return EFI_SUCCESS;\r
1696 }\r
1697 //\r
1698 // Relocate memory\r
1699 //\r
1700 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;\r
1701 Status = gBS->AllocatePages (\r
1702 AllocateMaxAddress,\r
1703 EfiACPIMemoryNVS,\r
1704 EFI_SIZE_TO_PAGES(Data32),\r
1705 &BufferPtr\r
1706 );\r
1707 ASSERT_EFI_ERROR (Status); \r
1708 MpsFloatingPointerNew = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)BufferPtr;\r
1709 CopyMem (MpsFloatingPointerNew, MpsFloatingPointerOri, FPLength);\r
1710 //\r
1711 // If Mp Table exists\r
1712 //\r
1713 if (MpsTableOri != NULL) {\r
1714 //\r
1715 // Get Mps table length, including Ext table\r
1716 //\r
1717 BufferPtr = BufferPtr + FPLength + SYS_TABLE_PAD (FPLength);\r
1718 MpsTableNew = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)BufferPtr;\r
1719 CopyMem (MpsTableNew, MpsTableOri, MpsTableOri->BaseTableLength + MpsTableOri->ExtendedTableLength);\r
1720 \r
1721 if ((MpsTableOri->OemTableSize != 0x0000) && (MpsTableOri->OemTablePointer != 0x0000)){\r
1722 BufferPtr += MpsTableOri->BaseTableLength + MpsTableOri->ExtendedTableLength;\r
1723 BufferPtr += SYS_TABLE_PAD (BufferPtr);\r
1724 OemTableNew = (VOID *)(UINTN)BufferPtr;\r
1725 OemTableOri = (VOID *)(UINTN)MpsTableOri->OemTablePointer;\r
1726 CopyMem (OemTableNew, OemTableOri, MpsTableOri->OemTableSize);\r
1727 MpsTableNew->OemTablePointer = (UINT32)(UINTN)OemTableNew;\r
1728 }\r
1729 MpsTableNew->Checksum = 0;\r
1730 MpsTableNew->Checksum = GetBufferCheckSum (MpsTableNew, MpsTableOri->BaseTableLength);\r
1731 MpsFloatingPointerNew->PhysicalAddress = (UINT32)(UINTN)MpsTableNew;\r
1732 MpsFloatingPointerNew->Checksum = 0;\r
1733 MpsFloatingPointerNew->Checksum = GetBufferCheckSum (MpsFloatingPointerNew, FPLength);\r
1734 }\r
1735 //\r
1736 // Change the pointer\r
1737 //\r
1738 *Table = MpsFloatingPointerNew;\r
1739 \r
1740 return EFI_SUCCESS; \r
1741} \r