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