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