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