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