]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/Library/DuetBdsLib/BdsPlatform.c
Add UINT64 type cast when AND/OR with UINT64 Supports.
[mirror_edk2.git] / DuetPkg / Library / DuetBdsLib / BdsPlatform.c
CommitLineData
c69dd9df 1/*++\r
2\r
db4d3fa1 3Copyright (c) 2006 - 2011, 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
724 DevicePath = NULL;\r
725 Status = gBS->HandleProtocol (\r
726 DeviceHandle,\r
727 &gEfiDevicePathProtocolGuid,\r
d8bee43c 728 (VOID*)&DevicePath\r
c69dd9df 729 );\r
730 if (EFI_ERROR (Status)) {\r
731 return Status;\r
732 }\r
733 \r
c69dd9df 734 GetGopDevicePath (DevicePath, &GopDevicePath);\r
735 DevicePath = GopDevicePath;\r
c69dd9df 736\r
737 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
738 \r
739 return EFI_SUCCESS;\r
740}\r
741\r
742EFI_STATUS\r
743PreparePciSerialDevicePath (\r
744 IN EFI_HANDLE DeviceHandle\r
745 )\r
746/*++\r
747\r
748Routine Description:\r
749\r
750 Add PCI Serial to ConOut, ConIn, ErrOut.\r
751 PCI Serial: 07 00 02\r
752\r
753Arguments:\r
754\r
755 DeviceHandle - Handle of PCIIO protocol.\r
756 \r
757Returns:\r
758\r
759 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.\r
760 EFI_STATUS - No PCI Serial device is added.\r
761\r
762--*/\r
763{\r
764 EFI_STATUS Status;\r
765 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
be768885 766 \r
c69dd9df 767 DevicePath = NULL;\r
768 Status = gBS->HandleProtocol (\r
769 DeviceHandle,\r
770 &gEfiDevicePathProtocolGuid,\r
d8bee43c 771 (VOID*)&DevicePath\r
c69dd9df 772 );\r
773 if (EFI_ERROR (Status)) {\r
774 return Status;\r
775 }\r
776\r
777 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
778 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
779\r
780 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);\r
781 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);\r
782 BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);\r
783 \r
784 return EFI_SUCCESS;\r
785}\r
786\r
787EFI_STATUS\r
788DetectAndPreparePlatformPciDevicePath (\r
789 BOOLEAN DetectVgaOnly\r
790 )\r
791/*++\r
792\r
793Routine Description:\r
794\r
795 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
796\r
797Arguments:\r
798\r
799 DetectVgaOnly - Only detect VGA device if it's TRUE.\r
800 \r
801Returns:\r
802\r
803 EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
804 EFI_STATUS - PCI Device check or Console variable update fail.\r
805\r
806--*/\r
807{\r
808 EFI_STATUS Status;\r
809 UINTN HandleCount;\r
810 EFI_HANDLE *HandleBuffer;\r
811 UINTN Index;\r
812 EFI_PCI_IO_PROTOCOL *PciIo;\r
813 PCI_TYPE00 Pci;\r
814\r
815 //\r
816 // Start to check all the PciIo to find all possible device\r
817 //\r
818 HandleCount = 0;\r
819 HandleBuffer = NULL;\r
820 Status = gBS->LocateHandleBuffer (\r
821 ByProtocol,\r
822 &gEfiPciIoProtocolGuid,\r
823 NULL,\r
824 &HandleCount,\r
825 &HandleBuffer\r
826 );\r
827 if (EFI_ERROR (Status)) {\r
828 return Status;\r
829 }\r
830\r
831 for (Index = 0; Index < HandleCount; Index++) {\r
d8bee43c 832 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);\r
c69dd9df 833 if (EFI_ERROR (Status)) {\r
834 continue;\r
835 }\r
836\r
837 //\r
838 // Check for all PCI device\r
839 //\r
840 Status = PciIo->Pci.Read (\r
841 PciIo,\r
842 EfiPciIoWidthUint32,\r
843 0,\r
844 sizeof (Pci) / sizeof (UINT32),\r
845 &Pci\r
846 );\r
847 if (EFI_ERROR (Status)) {\r
848 continue;\r
849 }\r
850\r
851 if (!DetectVgaOnly) {\r
852 //\r
853 // Here we decide whether it is LPC Bridge\r
854 //\r
855 if ((IS_PCI_LPC (&Pci)) ||\r
856 ((IS_PCI_ISA_PDECODE (&Pci)) && (Pci.Hdr.VendorId == 0x8086) && (Pci.Hdr.DeviceId == 0x7110))) {\r
857 //\r
858 // Add IsaKeyboard to ConIn,\r
859 // add IsaSerial to ConOut, ConIn, ErrOut\r
860 //\r
e5653d94 861 DEBUG ((EFI_D_INFO, "Find the LPC Bridge device\n"));\r
c69dd9df 862 PrepareLpcBridgeDevicePath (HandleBuffer[Index]);\r
863 continue;\r
864 }\r
865 //\r
866 // Here we decide which Serial device to enable in PCI bus \r
867 //\r
868 if (IS_PCI_16550SERIAL (&Pci)) {\r
869 //\r
870 // Add them to ConOut, ConIn, ErrOut.\r
871 //\r
e5653d94 872 DEBUG ((EFI_D_INFO, "Find the 16550 SERIAL device\n"));\r
c69dd9df 873 PreparePciSerialDevicePath (HandleBuffer[Index]);\r
874 continue;\r
875 }\r
876 }\r
877\r
878 //\r
879 // Here we decide which VGA device to enable in PCI bus \r
880 //\r
881 if (IS_PCI_VGA (&Pci)) {\r
882 //\r
883 // Add them to ConOut.\r
884 //\r
e5653d94 885 DEBUG ((EFI_D_INFO, "Find the VGA device\n"));\r
c69dd9df 886 PreparePciVgaDevicePath (HandleBuffer[Index]);\r
887 continue;\r
888 }\r
889 }\r
890 \r
891 gBS->FreePool (HandleBuffer);\r
892 \r
893 return EFI_SUCCESS;\r
894}\r
895\r
896EFI_STATUS\r
897PlatformBdsConnectConsole (\r
898 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
899 )\r
900/*++\r
901\r
902Routine Description:\r
903\r
904 Connect the predefined platform default console device. Always try to find\r
905 and enable the vga device if have.\r
906\r
907Arguments:\r
908\r
909 PlatformConsole - Predfined platform default console device array.\r
910 \r
911Returns:\r
912\r
913 EFI_SUCCESS - Success connect at least one ConIn and ConOut \r
914 device, there must have one ConOut device is \r
915 active vga device.\r
916 \r
917 EFI_STATUS - Return the status of \r
918 BdsLibConnectAllDefaultConsoles ()\r
919\r
920--*/\r
921{\r
922 EFI_STATUS Status;\r
923 UINTN Index;\r
924 EFI_DEVICE_PATH_PROTOCOL *VarConout;\r
925 EFI_DEVICE_PATH_PROTOCOL *VarConin;\r
926 UINTN DevicePathSize;\r
927\r
928 //\r
929 // Connect RootBridge\r
930 //\r
931 ConnectRootBridge ();\r
932\r
933 VarConout = BdsLibGetVariableAndSize (\r
934 VarConsoleOut,\r
935 &gEfiGlobalVariableGuid,\r
936 &DevicePathSize\r
937 );\r
938 VarConin = BdsLibGetVariableAndSize (\r
939 VarConsoleInp,\r
940 &gEfiGlobalVariableGuid,\r
941 &DevicePathSize\r
942 );\r
be768885 943 \r
c69dd9df 944 if (VarConout == NULL || VarConin == NULL) {\r
945 //\r
946 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
947 //\r
948 DetectAndPreparePlatformPciDevicePath (FALSE);\r
949\r
950 //\r
951 // Have chance to connect the platform default console,\r
952 // the platform default console is the minimue device group\r
953 // the platform should support\r
954 //\r
955 for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
956 //\r
957 // Update the console variable with the connect type\r
958 //\r
959 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
960 BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);\r
961 }\r
962 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
963 BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);\r
964 }\r
965 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
966 BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);\r
967 }\r
968 }\r
969 } else {\r
970 //\r
971 // Only detect VGA device and add them to ConOut\r
972 //\r
973 DetectAndPreparePlatformPciDevicePath (TRUE);\r
974 }\r
975 \r
976 //\r
977 // The ConIn devices connection will start the USB bus, should disable all\r
978 // Usb legacy support firstly.\r
979 // Caution: Must ensure the PCI bus driver has been started. Since the \r
980 // ConnectRootBridge() will create all the PciIo protocol, it's safe here now\r
981 //\r
982 Status = DisableUsbLegacySupport();\r
983 \r
984 //\r
985 // Connect the all the default console with current cosole variable\r
986 //\r
987 Status = BdsLibConnectAllDefaultConsoles ();\r
988 if (EFI_ERROR (Status)) {\r
989 return Status;\r
990 }\r
991\r
992 return EFI_SUCCESS;\r
993}\r
994\r
995VOID\r
996PlatformBdsConnectSequence (\r
997 VOID\r
998 )\r
999/*++\r
1000\r
1001Routine Description:\r
1002\r
1003 Connect with predeined platform connect sequence, \r
1004 the OEM/IBV can customize with their own connect sequence.\r
1005 \r
1006Arguments:\r
1007\r
1008 None.\r
1009 \r
1010Returns:\r
1011\r
1012 None.\r
1013 \r
1014--*/\r
1015{\r
1016 UINTN Index;\r
1017\r
1018 Index = 0;\r
1019\r
1020 //\r
1021 // Here we can get the customized platform connect sequence\r
1022 // Notes: we can connect with new variable which record the\r
1023 // last time boots connect device path sequence\r
1024 //\r
1025 while (gPlatformConnectSequence[Index] != NULL) {\r
1026 //\r
1027 // Build the platform boot option\r
1028 //\r
1029 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
1030 Index++;\r
1031 }\r
1032\r
1033}\r
1034\r
1035VOID\r
1036PlatformBdsGetDriverOption (\r
1037 IN OUT LIST_ENTRY *BdsDriverLists\r
1038 )\r
1039/*++\r
1040\r
1041Routine Description:\r
1042\r
1043 Load the predefined driver option, OEM/IBV can customize this\r
1044 to load their own drivers\r
1045 \r
1046Arguments:\r
1047\r
1048 BdsDriverLists - The header of the driver option link list.\r
1049 \r
1050Returns:\r
1051\r
1052 None.\r
1053 \r
1054--*/\r
1055{\r
1056 UINTN Index;\r
1057\r
1058 Index = 0;\r
1059\r
1060 //\r
1061 // Here we can get the customized platform driver option\r
1062 //\r
1063 while (gPlatformDriverOption[Index] != NULL) {\r
1064 //\r
1065 // Build the platform boot option\r
1066 //\r
1067 BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");\r
1068 Index++;\r
1069 }\r
1070\r
1071}\r
1072\r
1073VOID\r
1074PlatformBdsDiagnostics (\r
1075 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
03a2bbf3 1076 IN BOOLEAN QuietBoot,\r
1077 IN BASEM_MEMORY_TEST BaseMemoryTest\r
c69dd9df 1078 )\r
1079/*++\r
1080\r
1081Routine Description:\r
1082\r
1083 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
1084 can customize this fuction to support specific platform diagnostic.\r
1085 \r
1086Arguments:\r
1087\r
1088 MemoryTestLevel - The memory test intensive level\r
1089 \r
1090 QuietBoot - Indicate if need to enable the quiet boot\r
03a2bbf3 1091\r
1092 BaseMemoryTest - A pointer to BdsMemoryTest()\r
c69dd9df 1093 \r
1094Returns:\r
1095\r
1096 None.\r
1097 \r
1098--*/\r
1099{\r
1100 EFI_STATUS Status;\r
1101\r
1102 //\r
1103 // Here we can decide if we need to show\r
1104 // the diagnostics screen\r
1105 // Notes: this quiet boot code should be remove\r
1106 // from the graphic lib\r
1107 //\r
1108 if (QuietBoot) {\r
d46f3632 1109 Status = EnableQuietBoot (PcdGetPtr(PcdLogoFile));\r
ff514e29 1110 if (EFI_ERROR (Status)) {\r
1111 DisableQuietBoot ();\r
1112 return;\r
1113 }\r
1114\r
c69dd9df 1115 //\r
1116 // Perform system diagnostic\r
1117 //\r
03a2bbf3 1118 Status = BaseMemoryTest (MemoryTestLevel);\r
c69dd9df 1119 if (EFI_ERROR (Status)) {\r
1120 DisableQuietBoot ();\r
1121 }\r
1122\r
1123 return ;\r
1124 }\r
1125 //\r
1126 // Perform system diagnostic\r
1127 //\r
03a2bbf3 1128 Status = BaseMemoryTest (MemoryTestLevel);\r
c69dd9df 1129}\r
1130\r
1131VOID\r
20fac443 1132EFIAPI\r
c69dd9df 1133PlatformBdsPolicyBehavior (\r
c69dd9df 1134 IN OUT LIST_ENTRY *DriverOptionList,\r
03a2bbf3 1135 IN OUT LIST_ENTRY *BootOptionList,\r
1136 IN PROCESS_CAPSULES ProcessCapsules,\r
1137 IN BASEM_MEMORY_TEST BaseMemoryTest\r
c69dd9df 1138 )\r
1139/*++\r
1140\r
1141Routine Description:\r
1142\r
1143 The function will excute with as the platform policy, current policy\r
1144 is driven by boot mode. IBV/OEM can customize this code for their specific\r
1145 policy action.\r
1146 \r
1147Arguments:\r
1148\r
c69dd9df 1149 DriverOptionList - The header of the driver option link list\r
1150 \r
1151 BootOptionList - The header of the boot option link list\r
1152 \r
1153Returns:\r
1154\r
1155 None.\r
1156 \r
1157--*/\r
1158{\r
1159 EFI_STATUS Status;\r
1160 UINT16 Timeout;\r
1161 EFI_EVENT UserInputDurationTime;\r
c69dd9df 1162 UINTN Index;\r
1163 EFI_INPUT_KEY Key;\r
20fac443 1164 EFI_BOOT_MODE BootMode;\r
c69dd9df 1165\r
1166 //\r
1167 // Init the time out value\r
1168 //\r
6efe5f96 1169 Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
c69dd9df 1170\r
1171 //\r
1172 // Load the driver option as the driver option list\r
1173 //\r
1174 PlatformBdsGetDriverOption (DriverOptionList);\r
1175\r
1176 //\r
1177 // Get current Boot Mode\r
1178 //\r
20fac443 1179 Status = BdsLibGetBootMode (&BootMode);\r
1180 DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
c69dd9df 1181\r
1182 //\r
1183 // Go the different platform policy with different boot mode\r
1184 // Notes: this part code can be change with the table policy\r
1185 //\r
20fac443 1186 ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
c69dd9df 1187 //\r
1188 // Connect platform console\r
1189 //\r
1190 Status = PlatformBdsConnectConsole (gPlatformConsole);\r
1191 if (EFI_ERROR (Status)) {\r
1192 //\r
1193 // Here OEM/IBV can customize with defined action\r
1194 //\r
1195 PlatformBdsNoConsoleAction ();\r
1196 }\r
1197 //\r
1198 // Create a 300ms duration event to ensure user has enough input time to enter Setup\r
1199 //\r
1200 Status = gBS->CreateEvent (\r
e53a6ea9 1201 EVT_TIMER,\r
c69dd9df 1202 0,\r
1203 NULL,\r
1204 NULL,\r
1205 &UserInputDurationTime\r
1206 );\r
1207 ASSERT (Status == EFI_SUCCESS);\r
1208 Status = gBS->SetTimer (UserInputDurationTime, TimerRelative, 3000000);\r
1209 ASSERT (Status == EFI_SUCCESS);\r
1210 //\r
1211 // Memory test and Logo show\r
1212 //\r
03a2bbf3 1213 PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);\r
c69dd9df 1214\r
1215 //\r
1216 // Perform some platform specific connect sequence\r
1217 //\r
1218 PlatformBdsConnectSequence ();\r
1219\r
1220 //\r
1221 // Give one chance to enter the setup if we\r
1222 // have the time out\r
1223 //\r
ba992f96 1224 // BUGBUG: hard code timeout to 5 second to show logo in graphic mode.\r
1225 Timeout = 5; \r
c69dd9df 1226 if (Timeout != 0) {\r
1227 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
1228 }\r
1229\r
1230 //\r
1231 //BdsLibConnectAll ();\r
1232 //BdsLibEnumerateAllBootOption (BootOptionList); \r
1233 \r
1234 //\r
1235 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot\r
1236 // checking code in real production tip.\r
1237 // \r
1238 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device \r
1239 // and do enumerate all the default boot options. But in development system board, the boot mode \r
1240 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box\r
1241 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.\r
1242 //\r
1243 Status = BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
1244 if (EFI_ERROR(Status)) {\r
1245 //\r
1246 // If cannot find "BootOrder" variable, it may be first boot. \r
1247 // Try to connect all devices and enumerate all boot options here.\r
1248 //\r
1249 BdsLibConnectAll ();\r
1250 BdsLibEnumerateAllBootOption (BootOptionList);\r
1251 } \r
1252\r
1253 //\r
1254 // To give the User a chance to enter Setup here, if user set TimeOut is 0.\r
1255 // BDS should still give user a chance to enter Setup\r
c69dd9df 1256 // Check whether the user input after the duration time has expired \r
1257 //\r
c69dd9df 1258 gBS->WaitForEvent (1, &UserInputDurationTime, &Index);\r
1259 gBS->CloseEvent (UserInputDurationTime);\r
1260 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
c69dd9df 1261 \r
1262 if (!EFI_ERROR (Status)) {\r
1263 //\r
1264 // Enter Setup if user input \r
1265 //\r
1266 Timeout = 0xffff;\r
1267 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
1268 }\r
1269 \r
1270 return ;\r
1271\r
1272}\r
1273\r
1274VOID\r
20fac443 1275EFIAPI\r
c69dd9df 1276PlatformBdsBootSuccess (\r
1277 IN BDS_COMMON_OPTION *Option\r
1278 )\r
1279/*++\r
1280\r
1281Routine Description:\r
1282 \r
1283 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
1284 return, so the EFI 1.0 specification defines that you will default to an\r
1285 interactive mode and stop processing the BootOrder list in this case. This\r
1286 is alos a platform implementation and can be customized by IBV/OEM.\r
1287\r
1288Arguments:\r
1289\r
1290 Option - Pointer to Boot Option that succeeded to boot.\r
1291\r
1292Returns:\r
1293 \r
1294 None.\r
1295\r
1296--*/\r
1297{\r
1298 CHAR16 *TmpStr;\r
1299\r
1300 //\r
1301 // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
1302 // select loop then we need to pop up a UI and wait for user input.\r
1303 //\r
1304 TmpStr = Option->StatusString;\r
1305 if (TmpStr != NULL) {\r
1306 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1307 gBS->FreePool (TmpStr);\r
1308 }\r
1309}\r
1310\r
1311VOID\r
20fac443 1312EFIAPI\r
c69dd9df 1313PlatformBdsBootFail (\r
1314 IN BDS_COMMON_OPTION *Option,\r
1315 IN EFI_STATUS Status,\r
1316 IN CHAR16 *ExitData,\r
1317 IN UINTN ExitDataSize\r
1318 )\r
1319/*++\r
1320\r
1321Routine Description:\r
1322 \r
1323 Hook point after a boot attempt fails.\r
1324\r
1325Arguments:\r
1326 \r
1327 Option - Pointer to Boot Option that failed to boot.\r
1328\r
1329 Status - Status returned from failed boot.\r
1330\r
1331 ExitData - Exit data returned from failed boot.\r
1332\r
1333 ExitDataSize - Exit data size returned from failed boot.\r
1334\r
1335Returns:\r
1336 \r
1337 None.\r
1338\r
1339--*/\r
1340{\r
1341 CHAR16 *TmpStr;\r
1342\r
1343 //\r
1344 // If Boot returned with failed status then we need to pop up a UI and wait\r
1345 // for user input.\r
1346 //\r
1347 TmpStr = Option->StatusString;\r
1348 if (TmpStr != NULL) {\r
1349 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
1350 gBS->FreePool (TmpStr);\r
1351 }\r
1352\r
1353}\r
1354\r
1355EFI_STATUS\r
1356PlatformBdsNoConsoleAction (\r
1357 VOID\r
1358 )\r
1359/*++\r
1360\r
1361Routine Description:\r
1362 \r
1363 This function is remained for IBV/OEM to do some platform action,\r
1364 if there no console device can be connected.\r
1365\r
1366Arguments:\r
1367 \r
1368 None.\r
1369 \r
1370Returns:\r
1371 \r
1372 EFI_SUCCESS - Direct return success now.\r
1373\r
1374--*/\r
1375{\r
1376 return EFI_SUCCESS;\r
1377}\r
1378\r
1379EFI_STATUS\r
1380ConvertSystemTable (\r
1381 IN EFI_GUID *TableGuid,\r
1382 IN OUT VOID **Table\r
1383 )\r
1384/*++\r
1385\r
1386Routine Description:\r
1387 Convert ACPI Table /Smbios Table /MP Table if its location is lower than Address:0x100000\r
1388 Assumption here:\r
1389 As in legacy Bios, ACPI/Smbios/MP table is required to place in E/F Seg, \r
1390 So here we just check if the range is E/F seg, \r
1391 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS\r
1392\r
1393Arguments:\r
1394 TableGuid - Guid of the table\r
1395 Table - pointer to the table \r
1396\r
1397Returns:\r
1398 EFI_SUCEESS - Convert Table successfully\r
1399 Other - Failed\r
1400\r
1401--*/\r
1402{\r
1403 EFI_STATUS Status;\r
1404 VOID *AcpiHeader;\r
1405 UINTN AcpiTableLen;\r
1406 \r
1407 //\r
1408 // If match acpi guid (1.0, 2.0, or later), Convert ACPI table according to version. \r
1409 //\r
1410 AcpiHeader = (VOID*)(UINTN)(*(UINT64 *)(*Table));\r
1411 \r
1412 if (CompareGuid(TableGuid, &gEfiAcpiTableGuid) || CompareGuid(TableGuid, &gEfiAcpi20TableGuid)){\r
1413 if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved == 0x00){\r
1414 //\r
1415 // If Acpi 1.0 Table, then RSDP structure doesn't contain Length field, use structure size\r
1416 //\r
1417 AcpiTableLen = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);\r
1418 } else if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved >= 0x02){\r
1419 //\r
1420 // If Acpi 2.0 or later, use RSDP Length fied.\r
1421 //\r
1422 AcpiTableLen = ((EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Length;\r
1423 } else {\r
1424 //\r
1425 // Invalid Acpi Version, return\r
1426 //\r
1427 return EFI_UNSUPPORTED;\r
1428 }\r
1429 Status = ConvertAcpiTable (AcpiTableLen, Table);\r
1430 return Status; \r
1431 }\r
1432 \r
1433 //\r
1434 // If matches smbios guid, convert Smbios table.\r
1435 //\r
1436 if (CompareGuid(TableGuid, &gEfiSmbiosTableGuid)){\r
1437 Status = ConvertSmbiosTable (Table);\r
1438 return Status;\r
1439 }\r
1440 \r
1441 //\r
1442 // If the table is MP table?\r
1443 //\r
1444 if (CompareGuid(TableGuid, &gEfiMpsTableGuid)){\r
1445 Status = ConvertMpsTable (Table);\r
1446 return Status;\r
1447 }\r
1448 \r
1449 return EFI_UNSUPPORTED;\r
1450} \r
1451\r
c69dd9df 1452\r
1453EFI_STATUS\r
1454ConvertAcpiTable (\r
1455 IN UINTN TableLen,\r
1456 IN OUT VOID **Table\r
1457 )\r
1458/*++\r
1459\r
1460Routine Description:\r
1461 Convert RSDP of ACPI Table if its location is lower than Address:0x100000\r
1462 Assumption here:\r
1463 As in legacy Bios, ACPI table is required to place in E/F Seg, \r
1464 So here we just check if the range is E/F seg, \r
1465 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS\r
1466\r
1467Arguments:\r
1468 TableLen - Acpi RSDP length\r
1469 Table - pointer to the table \r
1470\r
1471Returns:\r
1472 EFI_SUCEESS - Convert Table successfully\r
1473 Other - Failed\r
1474\r
1475--*/\r
1476{\r
1477 VOID *AcpiTableOri;\r
1478 VOID *AcpiTableNew;\r
1479 EFI_STATUS Status;\r
1480 EFI_PHYSICAL_ADDRESS BufferPtr;\r
1481\r
1482 \r
1483 AcpiTableOri = (VOID *)(UINTN)(*(UINT64*)(*Table));\r
1484 if (((UINTN)AcpiTableOri < 0x100000) && ((UINTN)AcpiTableOri > 0xE0000)) {\r
1485 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;\r
1486 Status = gBS->AllocatePages (\r
1487 AllocateMaxAddress,\r
1488 EfiACPIMemoryNVS,\r
1489 EFI_SIZE_TO_PAGES(TableLen),\r
1490 &BufferPtr\r
1491 );\r
1492 ASSERT_EFI_ERROR (Status);\r
1493 AcpiTableNew = (VOID *)(UINTN)BufferPtr;\r
1494 CopyMem (AcpiTableNew, AcpiTableOri, TableLen);\r
1495 } else {\r
1496 AcpiTableNew = AcpiTableOri;\r
1497 }\r
1498 //\r
1499 // Change configuration table Pointer\r
1500 //\r
1501 *Table = AcpiTableNew;\r
1502 \r
1503 return EFI_SUCCESS;\r
1504}\r
1505\r
1506EFI_STATUS\r
1507ConvertSmbiosTable (\r
1508 IN OUT VOID **Table\r
1509 )\r
1510/*++\r
1511\r
1512Routine Description:\r
1513\r
1514 Convert Smbios Table if the Location of the SMBios Table is lower than Addres 0x100000\r
1515 Assumption here:\r
1516 As in legacy Bios, Smbios table is required to place in E/F Seg, \r
1517 So here we just check if the range is F seg, \r
1518 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData\r
1519Arguments:\r
1520 Table - pointer to the table\r
1521\r
1522Returns:\r
1523 EFI_SUCEESS - Convert Table successfully\r
1524 Other - Failed\r
1525\r
1526--*/\r
1527{\r
1528 SMBIOS_TABLE_ENTRY_POINT *SmbiosTableNew;\r
1529 SMBIOS_TABLE_ENTRY_POINT *SmbiosTableOri;\r
1530 EFI_STATUS Status;\r
1531 UINT32 SmbiosEntryLen;\r
1532 UINT32 BufferLen;\r
1533 EFI_PHYSICAL_ADDRESS BufferPtr;\r
1534 \r
1535 SmbiosTableNew = NULL;\r
1536 SmbiosTableOri = NULL;\r
1537 \r
1538 //\r
1539 // Get Smibos configuration Table \r
1540 //\r
1541 SmbiosTableOri = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)(*(UINT64*)(*Table));\r
1542 \r
1543 if ((SmbiosTableOri == NULL) ||\r
1544 ((UINTN)SmbiosTableOri > 0x100000) ||\r
1545 ((UINTN)SmbiosTableOri < 0xF0000)){\r
1546 return EFI_SUCCESS;\r
1547 }\r
1548 //\r
1549 // Relocate the Smibos memory\r
1550 //\r
1551 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;\r
1552 if (SmbiosTableOri->SmbiosBcdRevision != 0x21) {\r
1553 SmbiosEntryLen = SmbiosTableOri->EntryPointLength;\r
1554 } else {\r
1555 //\r
1556 // According to Smbios Spec 2.4, we should set entry point length as 0x1F if version is 2.1\r
1557 //\r
1558 SmbiosEntryLen = 0x1F;\r
1559 }\r
1560 BufferLen = SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen) + SmbiosTableOri->TableLength;\r
1561 Status = gBS->AllocatePages (\r
1562 AllocateMaxAddress,\r
1563 EfiACPIMemoryNVS,\r
1564 EFI_SIZE_TO_PAGES(BufferLen),\r
1565 &BufferPtr\r
1566 );\r
1567 ASSERT_EFI_ERROR (Status);\r
1568 SmbiosTableNew = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)BufferPtr;\r
1569 CopyMem (\r
1570 SmbiosTableNew, \r
1571 SmbiosTableOri,\r
1572 SmbiosEntryLen\r
1573 );\r
1574 // \r
1575 // Get Smbios Structure table address, and make sure the start address is 32-bit align\r
1576 //\r
1577 BufferPtr += SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen);\r
1578 CopyMem (\r
1579 (VOID *)(UINTN)BufferPtr, \r
1580 (VOID *)(UINTN)(SmbiosTableOri->TableAddress),\r
1581 SmbiosTableOri->TableLength\r
1582 );\r
1583 SmbiosTableNew->TableAddress = (UINT32)BufferPtr;\r
1584 SmbiosTableNew->IntermediateChecksum = 0;\r
1585 SmbiosTableNew->IntermediateChecksum = \r
86608df4 1586 CalculateCheckSum8 ((UINT8*)SmbiosTableNew + 0x10, SmbiosEntryLen -0x10);\r
c69dd9df 1587 //\r
1588 // Change the SMBIOS pointer\r
1589 //\r
1590 *Table = SmbiosTableNew;\r
1591 \r
1592 return EFI_SUCCESS; \r
1593} \r
1594\r
1595EFI_STATUS\r
1596ConvertMpsTable (\r
1597 IN OUT VOID **Table\r
1598 )\r
1599/*++\r
1600\r
1601Routine Description:\r
1602\r
1603 Convert MP Table if the Location of the SMBios Table is lower than Addres 0x100000\r
1604 Assumption here:\r
1605 As in legacy Bios, MP table is required to place in E/F Seg, \r
1606 So here we just check if the range is E/F seg, \r
1607 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData\r
1608Arguments:\r
1609 Table - pointer to the table\r
1610\r
1611Returns:\r
1612 EFI_SUCEESS - Convert Table successfully\r
1613 Other - Failed\r
1614\r
1615--*/\r
1616{\r
1617 UINT32 Data32;\r
1618 UINT32 FPLength;\r
1619 EFI_LEGACY_MP_TABLE_FLOATING_POINTER *MpsFloatingPointerOri;\r
1620 EFI_LEGACY_MP_TABLE_FLOATING_POINTER *MpsFloatingPointerNew;\r
1621 EFI_LEGACY_MP_TABLE_HEADER *MpsTableOri;\r
1622 EFI_LEGACY_MP_TABLE_HEADER *MpsTableNew;\r
1623 VOID *OemTableOri;\r
1624 VOID *OemTableNew;\r
1625 EFI_STATUS Status;\r
1626 EFI_PHYSICAL_ADDRESS BufferPtr;\r
1627 \r
1628 //\r
1629 // Get MP configuration Table \r
1630 //\r
1631 MpsFloatingPointerOri = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)(*(UINT64*)(*Table));\r
1632 if (!(((UINTN)MpsFloatingPointerOri <= 0x100000) && \r
1633 ((UINTN)MpsFloatingPointerOri >= 0xF0000))){\r
1634 return EFI_SUCCESS;\r
1635 }\r
1636 //\r
1637 // Get Floating pointer structure length\r
1638 //\r
1639 FPLength = MpsFloatingPointerOri->Length * 16;\r
1640 Data32 = FPLength + SYS_TABLE_PAD (FPLength);\r
1641 MpsTableOri = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)(MpsFloatingPointerOri->PhysicalAddress);\r
1642 if (MpsTableOri != NULL) {\r
1643 Data32 += MpsTableOri->BaseTableLength;\r
1644 Data32 += MpsTableOri->ExtendedTableLength;\r
1645 if (MpsTableOri->OemTablePointer != 0x00) {\r
1646 Data32 += SYS_TABLE_PAD (Data32);\r
1647 Data32 += MpsTableOri->OemTableSize;\r
1648 }\r
1649 } else {\r
1650 return EFI_SUCCESS;\r
1651 }\r
1652 //\r
1653 // Relocate memory\r
1654 //\r
1655 BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;\r
1656 Status = gBS->AllocatePages (\r
1657 AllocateMaxAddress,\r
1658 EfiACPIMemoryNVS,\r
1659 EFI_SIZE_TO_PAGES(Data32),\r
1660 &BufferPtr\r
1661 );\r
1662 ASSERT_EFI_ERROR (Status); \r
1663 MpsFloatingPointerNew = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)BufferPtr;\r
1664 CopyMem (MpsFloatingPointerNew, MpsFloatingPointerOri, FPLength);\r
1665 //\r
1666 // If Mp Table exists\r
1667 //\r
1668 if (MpsTableOri != NULL) {\r
1669 //\r
1670 // Get Mps table length, including Ext table\r
1671 //\r
1672 BufferPtr = BufferPtr + FPLength + SYS_TABLE_PAD (FPLength);\r
1673 MpsTableNew = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)BufferPtr;\r
1674 CopyMem (MpsTableNew, MpsTableOri, MpsTableOri->BaseTableLength + MpsTableOri->ExtendedTableLength);\r
1675 \r
1676 if ((MpsTableOri->OemTableSize != 0x0000) && (MpsTableOri->OemTablePointer != 0x0000)){\r
1677 BufferPtr += MpsTableOri->BaseTableLength + MpsTableOri->ExtendedTableLength;\r
1678 BufferPtr += SYS_TABLE_PAD (BufferPtr);\r
1679 OemTableNew = (VOID *)(UINTN)BufferPtr;\r
1680 OemTableOri = (VOID *)(UINTN)MpsTableOri->OemTablePointer;\r
1681 CopyMem (OemTableNew, OemTableOri, MpsTableOri->OemTableSize);\r
1682 MpsTableNew->OemTablePointer = (UINT32)(UINTN)OemTableNew;\r
1683 }\r
1684 MpsTableNew->Checksum = 0;\r
ea7beacb 1685 MpsTableNew->Checksum = CalculateCheckSum8 ((UINT8*)MpsTableNew, MpsTableOri->BaseTableLength);\r
c69dd9df 1686 MpsFloatingPointerNew->PhysicalAddress = (UINT32)(UINTN)MpsTableNew;\r
1687 MpsFloatingPointerNew->Checksum = 0;\r
ea7beacb 1688 MpsFloatingPointerNew->Checksum = CalculateCheckSum8 ((UINT8*)MpsFloatingPointerNew, FPLength);\r
c69dd9df 1689 }\r
1690 //\r
1691 // Change the pointer\r
1692 //\r
1693 *Table = MpsFloatingPointerNew;\r
1694 \r
1695 return EFI_SUCCESS; \r
1696} \r
24cdd14e
LG
1697 \r
1698/**\r
1699 Lock the ConsoleIn device in system table. All key\r
1700 presses will be ignored until the Password is typed in. The only way to\r
1701 disable the password is to type it in to a ConIn device.\r
1702\r
1703 @param Password Password used to lock ConIn device.\r
1704\r
1705 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.\r
1706 @retval EFI_UNSUPPORTED Password not found\r
1707\r
1708**/\r
1709EFI_STATUS\r
1710EFIAPI\r
1711LockKeyboards (\r
1712 IN CHAR16 *Password\r
1713 )\r
1714{\r
1715 return EFI_UNSUPPORTED;\r
1716}\r
1717\r
1718/**\r
1719 This function locks platform flash that is not allowed to be updated during normal boot path.\r
1720 The flash layout is platform specific.\r
1721\r
1722 **/\r
1723VOID\r
1724EFIAPI\r
1725PlatformBdsLockNonUpdatableFlash (\r
1726 VOID\r
1727 )\r
1728{\r
1729 return;\r
1730}\r