3 Copyright (c) 2006 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 This file include all platform action which can be customized
23 #include "BdsPlatform.h"
25 #define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0)
27 CHAR16 mFirmwareVendor
[] = L
"TianoCore.org";
28 extern BOOLEAN gConnectAllHappened
;
29 extern USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath
;
31 EFI_GUID
*gTableGuidArray
[] = {
32 &gEfiAcpi20TableGuid
, &gEfiAcpiTableGuid
, &gEfiSmbiosTableGuid
, &gEfiMpsTableGuid
36 // BDS Platform Functions
40 GetSystemTablesFromHob (
46 Find GUID'ed HOBs that contain EFI_PHYSICAL_ADDRESS of ACPI, SMBIOS, MPs tables
56 EFI_PEI_HOB_POINTERS GuidHob
;
57 EFI_PEI_HOB_POINTERS HobStart
;
58 EFI_PHYSICAL_ADDRESS
*Table
;
64 HobStart
.Raw
= GetHobList ();
66 // Iteratively add ACPI Table, SMBIOS Table, MPS Table to EFI System Table
68 for (Index
= 0; Index
< sizeof (gTableGuidArray
) / sizeof (*gTableGuidArray
); ++Index
) {
69 GuidHob
.Raw
= GetNextGuidHob (gTableGuidArray
[Index
], HobStart
.Raw
);
70 if (GuidHob
.Raw
!= NULL
) {
71 Table
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
74 // Check if Mps Table/Smbios Table/Acpi Table exists in E/F seg,
75 // According to UEFI Spec, we should make sure Smbios table,
76 // ACPI table and Mps tables kept in memory of specified type
78 ConvertSystemTable(gTableGuidArray
[Index
], (VOID
**)&Table
);
79 gBS
->InstallConfigurationTable (gTableGuidArray
[Index
], (VOID
*)Table
);
87 #define EFI_LDR_MEMORY_DESCRIPTOR_GUID \
88 { 0x7701d7e5, 0x7d1d, 0x4432, {0xa4, 0x68, 0x67, 0x3d, 0xab, 0x8a, 0xde, 0x60 }}
90 EFI_GUID gEfiLdrMemoryDescriptorGuid
= EFI_LDR_MEMORY_DESCRIPTOR_GUID
;
95 EFI_HOB_GUID_TYPE Hob
;
97 EFI_MEMORY_DESCRIPTOR
*MemDesc
;
108 EFI_MEMORY_DESCRIPTOR
*MemMap
;
109 EFI_MEMORY_DESCRIPTOR
*MemMapPtr
;
111 UINTN MapKey
, DescriptorSize
;
113 UINT32 DescriptorVersion
;
119 Status
= gBS
->GetMemoryMap (&MemMapSize
, MemMap
, &MapKey
, &DescriptorSize
, &DescriptorVersion
);
120 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
121 MemMapSize
+= EFI_PAGE_SIZE
;
122 Status
= gBS
->AllocatePool (EfiBootServicesData
, MemMapSize
, &MemMap
);
123 ASSERT (Status
== EFI_SUCCESS
);
124 Status
= gBS
->GetMemoryMap (&MemMapSize
, MemMap
, &MapKey
, &DescriptorSize
, &DescriptorVersion
);
125 ASSERT (Status
== EFI_SUCCESS
);
128 ASSERT (DescriptorVersion
== EFI_MEMORY_DESCRIPTOR_VERSION
);
130 for (Index
= 0; Index
< MemMapSize
/ DescriptorSize
; Index
++) {
131 Bytes
= LShiftU64 (MemMap
->NumberOfPages
, 12);
132 DEBUG ((EFI_D_ERROR
, "%lX-%lX %lX %lX %X\n",
133 MemMap
->PhysicalStart
,
134 MemMap
->PhysicalStart
+ Bytes
- 1,
135 MemMap
->NumberOfPages
,
137 (UINTN
)MemMap
->Type
));
138 MemMap
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
)MemMap
+ DescriptorSize
);
141 gBS
->FreePool (MemMapPtr
);
151 EFI_PEI_HOB_POINTERS GuidHob
;
153 MEMORY_DESC_HOB MemoryDescHob
;
155 EFI_PHYSICAL_ADDRESS Memory
;
156 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor
;
160 GuidHob
.Raw
= GetHobList();
162 GuidHob
.Raw
= GetNextGuidHob (&gEfiLdrMemoryDescriptorGuid
, GuidHob
.Raw
);
163 if (GuidHob
.Raw
== NULL
) {
164 DEBUG ((EFI_D_ERROR
, "Fail to get gEfiLdrMemoryDescriptorGuid from GUID HOB LIST!\n"));
167 Table
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
169 DEBUG ((EFI_D_ERROR
, "Fail to get gEfiLdrMemoryDescriptorGuid from GUID HOB LIST!\n"));
172 MemoryDescHob
.MemDescCount
= *(UINTN
*)Table
;
173 MemoryDescHob
.MemDesc
= *(EFI_MEMORY_DESCRIPTOR
**)((UINTN
)Table
+ sizeof(UINTN
));
176 // Add ACPINVS, ACPIReclaim, and Reserved memory to MemoryMap
178 for (Index
= 0; Index
< MemoryDescHob
.MemDescCount
; Index
++) {
179 if (MemoryDescHob
.MemDesc
[Index
].PhysicalStart
< 0x100000) {
182 if (MemoryDescHob
.MemDesc
[Index
].PhysicalStart
>= 0x100000000ULL
) {
185 if ((MemoryDescHob
.MemDesc
[Index
].Type
== EfiReservedMemoryType
) ||
186 (MemoryDescHob
.MemDesc
[Index
].Type
== EfiRuntimeServicesData
) ||
187 (MemoryDescHob
.MemDesc
[Index
].Type
== EfiRuntimeServicesCode
) ||
188 (MemoryDescHob
.MemDesc
[Index
].Type
== EfiACPIReclaimMemory
) ||
189 (MemoryDescHob
.MemDesc
[Index
].Type
== EfiACPIMemoryNVS
)) {
190 DEBUG ((EFI_D_ERROR
, "PhysicalStart - 0x%016lx, ", MemoryDescHob
.MemDesc
[Index
].PhysicalStart
));
191 DEBUG ((EFI_D_ERROR
, "PageNumber - 0x%016lx, ", MemoryDescHob
.MemDesc
[Index
].NumberOfPages
));
192 DEBUG ((EFI_D_ERROR
, "Attribute - 0x%016lx, ", MemoryDescHob
.MemDesc
[Index
].Attribute
));
193 DEBUG ((EFI_D_ERROR
, "Type - 0x%08x\n", MemoryDescHob
.MemDesc
[Index
].Type
));
194 if ((MemoryDescHob
.MemDesc
[Index
].Type
== EfiRuntimeServicesData
) ||
195 (MemoryDescHob
.MemDesc
[Index
].Type
== EfiRuntimeServicesCode
)) {
197 // For RuntimeSevicesData and RuntimeServicesCode, they are BFV or DxeCore.
198 // The memory type is assigned in EfiLdr
200 Status
= gDS
->GetMemorySpaceDescriptor (MemoryDescHob
.MemDesc
[Index
].PhysicalStart
, &Descriptor
);
201 if (EFI_ERROR (Status
)) {
204 if (Descriptor
.GcdMemoryType
!= EfiGcdMemoryTypeReserved
) {
206 // BFV or tested DXE core
211 // Untested DXE Core region, free and remove
213 Status
= gDS
->FreeMemorySpace (
214 MemoryDescHob
.MemDesc
[Index
].PhysicalStart
,
215 LShiftU64 (MemoryDescHob
.MemDesc
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
)
217 if (EFI_ERROR (Status
)) {
218 DEBUG ((EFI_D_ERROR
, "FreeMemorySpace fail - %r!\n", Status
));
221 Status
= gDS
->RemoveMemorySpace (
222 MemoryDescHob
.MemDesc
[Index
].PhysicalStart
,
223 LShiftU64 (MemoryDescHob
.MemDesc
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
)
225 if (EFI_ERROR (Status
)) {
226 DEBUG ((EFI_D_ERROR
, "RemoveMemorySpace fail - %r!\n", Status
));
231 // Convert Runtime type to BootTime type
233 if (MemoryDescHob
.MemDesc
[Index
].Type
== EfiRuntimeServicesData
) {
234 MemoryDescHob
.MemDesc
[Index
].Type
= EfiBootServicesData
;
236 MemoryDescHob
.MemDesc
[Index
].Type
= EfiBootServicesCode
;
240 // PassThrough, let below code add and alloate.
244 // ACPI or reserved memory
246 Status
= gDS
->AddMemorySpace (
247 EfiGcdMemoryTypeSystemMemory
,
248 MemoryDescHob
.MemDesc
[Index
].PhysicalStart
,
249 LShiftU64 (MemoryDescHob
.MemDesc
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
),
250 MemoryDescHob
.MemDesc
[Index
].Attribute
252 if (EFI_ERROR (Status
)) {
253 DEBUG ((EFI_D_ERROR
, "AddMemorySpace fail - %r!\n", Status
));
254 if ((MemoryDescHob
.MemDesc
[Index
].Type
== EfiACPIReclaimMemory
) ||
255 (MemoryDescHob
.MemDesc
[Index
].Type
== EfiACPIMemoryNVS
)) {
257 // For EfiACPIReclaimMemory and EfiACPIMemoryNVS, it must success.
258 // For EfiReservedMemoryType, there maybe overlap. So skip check here.
260 // ASSERT_EFI_ERROR (Status);
265 Memory
= MemoryDescHob
.MemDesc
[Index
].PhysicalStart
;
266 Status
= gBS
->AllocatePages (
268 (EFI_MEMORY_TYPE
)MemoryDescHob
.MemDesc
[Index
].Type
,
269 (UINTN
)MemoryDescHob
.MemDesc
[Index
].NumberOfPages
,
272 if (EFI_ERROR (Status
)) {
273 DEBUG ((EFI_D_ERROR
, "AllocatePages fail - %r!\n", Status
));
275 // For the page added, it must be allocated.
277 // ASSERT_EFI_ERROR (Status);
286 DisableUsbLegacySupport(
292 Disabble the USB legacy Support in all Ehci and Uhci.
293 This function assume all PciIo handles have been created in system.
304 EFI_HANDLE
*HandleArray
;
305 UINTN HandleArrayCount
;
307 EFI_PCI_IO_PROTOCOL
*PciIo
;
316 // Find the usb host controller
318 Status
= gBS
->LocateHandleBuffer (
320 &gEfiPciIoProtocolGuid
,
325 if (!EFI_ERROR (Status
)) {
326 for (Index
= 0; Index
< HandleArrayCount
; Index
++) {
327 Status
= gBS
->HandleProtocol (
329 &gEfiPciIoProtocolGuid
,
332 if (!EFI_ERROR (Status
)) {
334 // Find the USB host controller controller
336 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x09, 3, &Class
);
337 if (!EFI_ERROR (Status
)) {
338 if ((PCI_CLASS_SERIAL
== Class
[2]) &&
339 (PCI_CLASS_SERIAL_USB
== Class
[1])) {
340 if (PCI_CLASSC_PI_UHCI
== Class
[0]) {
342 // Found the UHCI, then disable the legacy support
345 Status
= PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0xC0, 1, &Command
);
346 } else if (PCI_CLASSC_PI_EHCI
== Class
[0]) {
348 // Found the EHCI, then disable the legacy support
350 Status
= PciIo
->Mem
.Read (
354 (UINT64
) 0x08, //EHC_HCCPARAMS_OFFSET
359 ExtendCap
= (HcCapParams
>> 8) & 0xFF;
361 // Disable the SMI in USBLEGCTLSTS firstly
363 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, ExtendCap
+ 0x4, 1, &Value
);
365 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, ExtendCap
+ 0x4, 1, &Value
);
368 // Get EHCI Ownership from legacy bios
370 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, ExtendCap
, 1, &Value
);
371 Value
|= (0x1 << 24);
372 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, ExtendCap
, 1, &Value
);
378 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, ExtendCap
, 1, &Value
);
380 if ((Value
& 0x01010000) == 0x01000000) {
392 gBS
->FreePool (HandleArray
);
406 Platform Bds init. Incude the platform firmware vendor, revision
418 // set firmwarevendor, here can be IBV/OEM customize
420 gST
->FirmwareVendor
= AllocateRuntimeCopyPool (
421 sizeof (mFirmwareVendor
),
424 ASSERT (gST
->FirmwareVendor
!= NULL
);
426 gST
->FirmwareRevision
= 0;
429 // Fixup Tasble CRC after we updated Firmware Vendor and Revision
431 gBS
->CalculateCrc32 ((VOID
*) gST
, sizeof (EFI_SYSTEM_TABLE
), &gST
->Hdr
.CRC32
);
433 GetSystemTablesFromHob ();
438 // Append Usb Keyboard short form DevicePath into "ConInDev"
440 BdsLibUpdateConsoleVariable (
442 (EFI_DEVICE_PATH_PROTOCOL
*) &gUsbClassKeyboardDevicePath
,
448 GetPciExpressBaseAddressForRootBridge (
449 IN UINTN HostBridgeNumber
,
450 IN UINTN RootBridgeNumber
455 This routine is to get PciExpress Base Address for this RootBridge
458 HostBridgeNumber - The number of HostBridge
459 RootBridgeNumber - The number of RootBridge
462 UINT64 - PciExpressBaseAddress for this HostBridge and RootBridge
466 EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION
*PciExpressBaseAddressInfo
;
470 EFI_PEI_HOB_POINTERS GuidHob
;
473 // Get PciExpressAddressInfo Hob
475 PciExpressBaseAddressInfo
= NULL
;
477 GuidHob
.Raw
= GetFirstGuidHob (&gEfiPciExpressBaseAddressGuid
);
478 if (GuidHob
.Raw
!= NULL
) {
479 PciExpressBaseAddressInfo
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
480 BufferSize
= GET_GUID_HOB_DATA_SIZE (GuidHob
.Guid
);
486 // Search the PciExpress Base Address in the Hob for current RootBridge
488 Number
= (UINT32
)(BufferSize
/ sizeof(EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION
));
489 for (Index
= 0; Index
< Number
; Index
++) {
490 if ((PciExpressBaseAddressInfo
[Index
].HostBridgeNumber
== HostBridgeNumber
) &&
491 (PciExpressBaseAddressInfo
[Index
].RootBridgeNumber
== RootBridgeNumber
)) {
492 return PciExpressBaseAddressInfo
[Index
].PciExpressBaseAddress
;
497 // Do not find the PciExpress Base Address in the Hob
503 PatchPciRootBridgeDevicePath (
504 IN UINTN HostBridgeNumber
,
505 IN UINTN RootBridgeNumber
,
506 IN PLATFORM_ROOT_BRIDGE_DEVICE_PATH
*RootBridge
509 UINT64 PciExpressBase
;
511 PciExpressBase
= GetPciExpressBaseAddressForRootBridge (HostBridgeNumber
, RootBridgeNumber
);
513 DEBUG ((EFI_D_INFO
, "Get PciExpress Address from Hob: 0x%X\n", PciExpressBase
));
515 if (PciExpressBase
!= 0) {
516 RootBridge
->PciRootBridge
.HID
= EISA_PNP_ID(0x0A08);
536 EFI_SUCCESS - Connect RootBridge successfully.
537 EFI_STATUS - Connect RootBridge fail.
542 EFI_HANDLE RootHandle
;
545 // Patch Pci Root Bridge Device Path
547 PatchPciRootBridgeDevicePath (0, 0, &gPlatformRootBridge0
);
550 // Make all the PCI_IO protocols on PCI Seg 0 show up
552 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
554 Status
= gBS
->LocateDevicePath (
555 &gEfiDevicePathProtocolGuid
,
556 &gPlatformRootBridges
[0],
559 DEBUG ((EFI_D_INFO
, "Pci Root bridge handle is 0x%X\n", RootHandle
));
561 if (EFI_ERROR (Status
)) {
565 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
566 if (EFI_ERROR (Status
)) {
574 PrepareLpcBridgeDevicePath (
575 IN EFI_HANDLE DeviceHandle
581 Add IsaKeyboard to ConIn,
582 add IsaSerial to ConOut, ConIn, ErrOut.
587 DeviceHandle - Handle of PCIIO protocol.
591 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
592 EFI_STATUS - No LPC bridge is added.
597 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
598 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
601 Status
= gBS
->HandleProtocol (
603 &gEfiDevicePathProtocolGuid
,
606 if (EFI_ERROR (Status
)) {
609 TempDevicePath
= DevicePath
;
614 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
616 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
621 DevicePath
= TempDevicePath
;
622 gPnp16550ComPortDeviceNode
.UID
= 0;
624 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
625 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
626 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
628 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
629 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
630 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
635 DevicePath
= TempDevicePath
;
636 gPnp16550ComPortDeviceNode
.UID
= 1;
638 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
639 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
640 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
642 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
643 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
644 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
651 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
652 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
657 EFI_HANDLE PciDeviceHandle
;
658 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
659 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
660 UINTN GopHandleCount
;
661 EFI_HANDLE
*GopHandleBuffer
;
663 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
664 return EFI_INVALID_PARAMETER
;
668 // Initialize the GopDevicePath to be PciDevicePath
670 *GopDevicePath
= PciDevicePath
;
671 TempPciDevicePath
= PciDevicePath
;
673 Status
= gBS
->LocateDevicePath (
674 &gEfiDevicePathProtocolGuid
,
678 if (EFI_ERROR (Status
)) {
683 // Try to connect this handle, so that GOP dirver could start on this
684 // device and create child handles with GraphicsOutput Protocol installed
685 // on them, then we get device paths of these child handles and select
686 // them as possible console device.
688 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
690 Status
= gBS
->LocateHandleBuffer (
692 &gEfiGraphicsOutputProtocolGuid
,
697 if (!EFI_ERROR (Status
)) {
699 // Add all the child handles as possible Console Device
701 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
702 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
703 if (EFI_ERROR (Status
)) {
709 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
712 // In current implementation, we only enable one of the child handles
713 // as console device, i.e. sotre one of the child handle's device
714 // path to variable "ConOut"
715 // In futhure, we could select all child handles to be console device
718 *GopDevicePath
= TempDevicePath
;
721 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
722 // Add the integrity GOP device path.
724 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
725 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
728 gBS
->FreePool (GopHandleBuffer
);
735 PreparePciVgaDevicePath (
736 IN EFI_HANDLE DeviceHandle
742 Add PCI VGA to ConOut.
747 DeviceHandle - Handle of PCIIO protocol.
751 EFI_SUCCESS - PCI VGA is added to ConOut.
752 EFI_STATUS - No PCI VGA device is added.
757 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
758 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
761 Status
= gBS
->HandleProtocol (
763 &gEfiDevicePathProtocolGuid
,
766 if (EFI_ERROR (Status
)) {
770 GetGopDevicePath (DevicePath
, &GopDevicePath
);
771 DevicePath
= GopDevicePath
;
773 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
779 PreparePciSerialDevicePath (
780 IN EFI_HANDLE DeviceHandle
786 Add PCI Serial to ConOut, ConIn, ErrOut.
791 DeviceHandle - Handle of PCIIO protocol.
795 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
796 EFI_STATUS - No PCI Serial device is added.
801 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
804 Status
= gBS
->HandleProtocol (
806 &gEfiDevicePathProtocolGuid
,
809 if (EFI_ERROR (Status
)) {
813 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
814 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
816 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
817 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
818 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
824 DetectAndPreparePlatformPciDevicePath (
825 BOOLEAN DetectVgaOnly
831 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
835 DetectVgaOnly - Only detect VGA device if it's TRUE.
839 EFI_SUCCESS - PCI Device check and Console variable update successfully.
840 EFI_STATUS - PCI Device check or Console variable update fail.
846 EFI_HANDLE
*HandleBuffer
;
848 EFI_PCI_IO_PROTOCOL
*PciIo
;
852 // Start to check all the PciIo to find all possible device
856 Status
= gBS
->LocateHandleBuffer (
858 &gEfiPciIoProtocolGuid
,
863 if (EFI_ERROR (Status
)) {
867 for (Index
= 0; Index
< HandleCount
; Index
++) {
868 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiPciIoProtocolGuid
, (VOID
*)&PciIo
);
869 if (EFI_ERROR (Status
)) {
874 // Check for all PCI device
876 Status
= PciIo
->Pci
.Read (
880 sizeof (Pci
) / sizeof (UINT32
),
883 if (EFI_ERROR (Status
)) {
887 if (!DetectVgaOnly
) {
889 // Here we decide whether it is LPC Bridge
891 if ((IS_PCI_LPC (&Pci
)) ||
892 ((IS_PCI_ISA_PDECODE (&Pci
)) && (Pci
.Hdr
.VendorId
== 0x8086) && (Pci
.Hdr
.DeviceId
== 0x7110))) {
894 // Add IsaKeyboard to ConIn,
895 // add IsaSerial to ConOut, ConIn, ErrOut
897 DEBUG ((EFI_D_INFO
, "Find the LPC Bridge device\n"));
898 PrepareLpcBridgeDevicePath (HandleBuffer
[Index
]);
902 // Here we decide which Serial device to enable in PCI bus
904 if (IS_PCI_16550SERIAL (&Pci
)) {
906 // Add them to ConOut, ConIn, ErrOut.
908 DEBUG ((EFI_D_INFO
, "Find the 16550 SERIAL device\n"));
909 PreparePciSerialDevicePath (HandleBuffer
[Index
]);
915 // Here we decide which VGA device to enable in PCI bus
917 if (IS_PCI_VGA (&Pci
)) {
919 // Add them to ConOut.
921 DEBUG ((EFI_D_INFO
, "Find the VGA device\n"));
922 PreparePciVgaDevicePath (HandleBuffer
[Index
]);
927 gBS
->FreePool (HandleBuffer
);
933 PlatformBdsConnectConsole (
934 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
940 Connect the predefined platform default console device. Always try to find
941 and enable the vga device if have.
945 PlatformConsole - Predfined platform default console device array.
949 EFI_SUCCESS - Success connect at least one ConIn and ConOut
950 device, there must have one ConOut device is
953 EFI_STATUS - Return the status of
954 BdsLibConnectAllDefaultConsoles ()
960 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
961 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
962 UINTN DevicePathSize
;
965 // Connect RootBridge
967 ConnectRootBridge ();
969 VarConout
= BdsLibGetVariableAndSize (
971 &gEfiGlobalVariableGuid
,
974 VarConin
= BdsLibGetVariableAndSize (
976 &gEfiGlobalVariableGuid
,
980 if (VarConout
== NULL
|| VarConin
== NULL
) {
982 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
984 DetectAndPreparePlatformPciDevicePath (FALSE
);
987 // Have chance to connect the platform default console,
988 // the platform default console is the minimue device group
989 // the platform should support
991 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
993 // Update the console variable with the connect type
995 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
996 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
998 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
999 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
1001 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
1002 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
1007 // Only detect VGA device and add them to ConOut
1009 DetectAndPreparePlatformPciDevicePath (TRUE
);
1013 // The ConIn devices connection will start the USB bus, should disable all
1014 // Usb legacy support firstly.
1015 // Caution: Must ensure the PCI bus driver has been started. Since the
1016 // ConnectRootBridge() will create all the PciIo protocol, it's safe here now
1018 Status
= DisableUsbLegacySupport();
1021 // Connect the all the default console with current cosole variable
1023 Status
= BdsLibConnectAllDefaultConsoles ();
1024 if (EFI_ERROR (Status
)) {
1032 PlatformBdsConnectSequence (
1037 Routine Description:
1039 Connect with predeined platform connect sequence,
1040 the OEM/IBV can customize with their own connect sequence.
1057 // Here we can get the customized platform connect sequence
1058 // Notes: we can connect with new variable which record the
1059 // last time boots connect device path sequence
1061 while (gPlatformConnectSequence
[Index
] != NULL
) {
1063 // Build the platform boot option
1065 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
1072 PlatformBdsGetDriverOption (
1073 IN OUT LIST_ENTRY
*BdsDriverLists
1077 Routine Description:
1079 Load the predefined driver option, OEM/IBV can customize this
1080 to load their own drivers
1084 BdsDriverLists - The header of the driver option link list.
1097 // Here we can get the customized platform driver option
1099 while (gPlatformDriverOption
[Index
] != NULL
) {
1101 // Build the platform boot option
1103 BdsLibRegisterNewOption (BdsDriverLists
, gPlatformDriverOption
[Index
], NULL
, L
"DriverOrder");
1110 PlatformBdsDiagnostics (
1111 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
1112 IN BOOLEAN QuietBoot
1116 Routine Description:
1118 Perform the platform diagnostic, such like test memory. OEM/IBV also
1119 can customize this fuction to support specific platform diagnostic.
1123 MemoryTestLevel - The memory test intensive level
1125 QuietBoot - Indicate if need to enable the quiet boot
1136 // Here we can decide if we need to show
1137 // the diagnostics screen
1138 // Notes: this quiet boot code should be remove
1139 // from the graphic lib
1142 Status
= EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1143 if (EFI_ERROR (Status
)) {
1144 DisableQuietBoot ();
1149 // Perform system diagnostic
1151 Status
= BdsMemoryTest (MemoryTestLevel
);
1152 if (EFI_ERROR (Status
)) {
1153 DisableQuietBoot ();
1159 // Perform system diagnostic
1161 Status
= BdsMemoryTest (MemoryTestLevel
);
1166 PlatformBdsPolicyBehavior (
1167 IN OUT LIST_ENTRY
*DriverOptionList
,
1168 IN OUT LIST_ENTRY
*BootOptionList
1172 Routine Description:
1174 The function will excute with as the platform policy, current policy
1175 is driven by boot mode. IBV/OEM can customize this code for their specific
1180 DriverOptionList - The header of the driver option link list
1182 BootOptionList - The header of the boot option link list
1192 EFI_EVENT UserInputDurationTime
;
1194 BDS_COMMON_OPTION
*BootOption
;
1198 EFI_BOOT_MODE BootMode
;
1201 // Init the time out value
1203 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
1206 // Load the driver option as the driver option list
1208 PlatformBdsGetDriverOption (DriverOptionList
);
1211 // Get current Boot Mode
1213 Status
= BdsLibGetBootMode (&BootMode
);
1214 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", BootMode
));
1217 // Go the different platform policy with different boot mode
1218 // Notes: this part code can be change with the table policy
1220 ASSERT (BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
1222 // Connect platform console
1224 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1225 if (EFI_ERROR (Status
)) {
1227 // Here OEM/IBV can customize with defined action
1229 PlatformBdsNoConsoleAction ();
1232 // Create a 300ms duration event to ensure user has enough input time to enter Setup
1234 Status
= gBS
->CreateEvent (
1239 &UserInputDurationTime
1241 ASSERT (Status
== EFI_SUCCESS
);
1242 Status
= gBS
->SetTimer (UserInputDurationTime
, TimerRelative
, 3000000);
1243 ASSERT (Status
== EFI_SUCCESS
);
1245 // Memory test and Logo show
1247 PlatformBdsDiagnostics (IGNORE
, TRUE
);
1250 // Perform some platform specific connect sequence
1252 PlatformBdsConnectSequence ();
1255 // Give one chance to enter the setup if we
1256 // have the time out
1258 // BUGBUG: hard code timeout to 5 second to show logo in graphic mode.
1261 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1265 //BdsLibConnectAll ();
1266 //BdsLibEnumerateAllBootOption (BootOptionList);
1269 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
1270 // checking code in real production tip.
1272 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
1273 // and do enumerate all the default boot options. But in development system board, the boot mode
1274 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
1275 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
1277 Status
= BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1278 if (EFI_ERROR(Status
)) {
1280 // If cannot find "BootOrder" variable, it may be first boot.
1281 // Try to connect all devices and enumerate all boot options here.
1283 BdsLibConnectAll ();
1284 BdsLibEnumerateAllBootOption (BootOptionList
);
1288 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
1289 // BDS should still give user a chance to enter Setup
1291 // Connect first boot option, and then check user input before exit
1293 for (Link
= BootOptionList
->ForwardLink
; Link
!= BootOptionList
;Link
= Link
->ForwardLink
) {
1294 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
1295 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
1297 // skip the header of the link list, becuase it has no boot option
1302 // Make sure the boot option device path connected, but ignore the BBS device path
1304 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
1305 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1312 // Check whether the user input after the duration time has expired
1314 OldTpl
= EfiGetCurrentTpl();
1315 gBS
->RestoreTPL (TPL_APPLICATION
);
1316 gBS
->WaitForEvent (1, &UserInputDurationTime
, &Index
);
1317 gBS
->CloseEvent (UserInputDurationTime
);
1318 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1319 gBS
->RaiseTPL (OldTpl
);
1321 if (!EFI_ERROR (Status
)) {
1323 // Enter Setup if user input
1326 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1335 PlatformBdsBootSuccess (
1336 IN BDS_COMMON_OPTION
*Option
1340 Routine Description:
1342 Hook point after a boot attempt succeeds. We don't expect a boot option to
1343 return, so the EFI 1.0 specification defines that you will default to an
1344 interactive mode and stop processing the BootOrder list in this case. This
1345 is alos a platform implementation and can be customized by IBV/OEM.
1349 Option - Pointer to Boot Option that succeeded to boot.
1360 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1361 // select loop then we need to pop up a UI and wait for user input.
1363 TmpStr
= Option
->StatusString
;
1364 if (TmpStr
!= NULL
) {
1365 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1366 gBS
->FreePool (TmpStr
);
1372 PlatformBdsBootFail (
1373 IN BDS_COMMON_OPTION
*Option
,
1374 IN EFI_STATUS Status
,
1375 IN CHAR16
*ExitData
,
1376 IN UINTN ExitDataSize
1380 Routine Description:
1382 Hook point after a boot attempt fails.
1386 Option - Pointer to Boot Option that failed to boot.
1388 Status - Status returned from failed boot.
1390 ExitData - Exit data returned from failed boot.
1392 ExitDataSize - Exit data size returned from failed boot.
1403 // If Boot returned with failed status then we need to pop up a UI and wait
1406 TmpStr
= Option
->StatusString
;
1407 if (TmpStr
!= NULL
) {
1408 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1409 gBS
->FreePool (TmpStr
);
1415 PlatformBdsNoConsoleAction (
1420 Routine Description:
1422 This function is remained for IBV/OEM to do some platform action,
1423 if there no console device can be connected.
1431 EFI_SUCCESS - Direct return success now.
1439 ConvertSystemTable (
1440 IN EFI_GUID
*TableGuid
,
1445 Routine Description:
1446 Convert ACPI Table /Smbios Table /MP Table if its location is lower than Address:0x100000
1448 As in legacy Bios, ACPI/Smbios/MP table is required to place in E/F Seg,
1449 So here we just check if the range is E/F seg,
1450 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
1453 TableGuid - Guid of the table
1454 Table - pointer to the table
1457 EFI_SUCEESS - Convert Table successfully
1467 // If match acpi guid (1.0, 2.0, or later), Convert ACPI table according to version.
1469 AcpiHeader
= (VOID
*)(UINTN
)(*(UINT64
*)(*Table
));
1471 if (CompareGuid(TableGuid
, &gEfiAcpiTableGuid
) || CompareGuid(TableGuid
, &gEfiAcpi20TableGuid
)){
1472 if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiHeader
)->Reserved
== 0x00){
1474 // If Acpi 1.0 Table, then RSDP structure doesn't contain Length field, use structure size
1476 AcpiTableLen
= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1477 } else if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiHeader
)->Reserved
>= 0x02){
1479 // If Acpi 2.0 or later, use RSDP Length fied.
1481 AcpiTableLen
= ((EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiHeader
)->Length
;
1484 // Invalid Acpi Version, return
1486 return EFI_UNSUPPORTED
;
1488 Status
= ConvertAcpiTable (AcpiTableLen
, Table
);
1493 // If matches smbios guid, convert Smbios table.
1495 if (CompareGuid(TableGuid
, &gEfiSmbiosTableGuid
)){
1496 Status
= ConvertSmbiosTable (Table
);
1501 // If the table is MP table?
1503 if (CompareGuid(TableGuid
, &gEfiMpsTableGuid
)){
1504 Status
= ConvertMpsTable (Table
);
1508 return EFI_UNSUPPORTED
;
1519 Routine Description:
1520 Convert RSDP of ACPI Table if its location is lower than Address:0x100000
1522 As in legacy Bios, ACPI table is required to place in E/F Seg,
1523 So here we just check if the range is E/F seg,
1524 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
1527 TableLen - Acpi RSDP length
1528 Table - pointer to the table
1531 EFI_SUCEESS - Convert Table successfully
1539 EFI_PHYSICAL_ADDRESS BufferPtr
;
1542 AcpiTableOri
= (VOID
*)(UINTN
)(*(UINT64
*)(*Table
));
1543 if (((UINTN
)AcpiTableOri
< 0x100000) && ((UINTN
)AcpiTableOri
> 0xE0000)) {
1544 BufferPtr
= EFI_SYSTEM_TABLE_MAX_ADDRESS
;
1545 Status
= gBS
->AllocatePages (
1548 EFI_SIZE_TO_PAGES(TableLen
),
1551 ASSERT_EFI_ERROR (Status
);
1552 AcpiTableNew
= (VOID
*)(UINTN
)BufferPtr
;
1553 CopyMem (AcpiTableNew
, AcpiTableOri
, TableLen
);
1555 AcpiTableNew
= AcpiTableOri
;
1558 // Change configuration table Pointer
1560 *Table
= AcpiTableNew
;
1566 ConvertSmbiosTable (
1571 Routine Description:
1573 Convert Smbios Table if the Location of the SMBios Table is lower than Addres 0x100000
1575 As in legacy Bios, Smbios table is required to place in E/F Seg,
1576 So here we just check if the range is F seg,
1577 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
1579 Table - pointer to the table
1582 EFI_SUCEESS - Convert Table successfully
1587 SMBIOS_TABLE_ENTRY_POINT
*SmbiosTableNew
;
1588 SMBIOS_TABLE_ENTRY_POINT
*SmbiosTableOri
;
1590 UINT32 SmbiosEntryLen
;
1592 EFI_PHYSICAL_ADDRESS BufferPtr
;
1594 SmbiosTableNew
= NULL
;
1595 SmbiosTableOri
= NULL
;
1598 // Get Smibos configuration Table
1600 SmbiosTableOri
= (SMBIOS_TABLE_ENTRY_POINT
*)(UINTN
)(*(UINT64
*)(*Table
));
1602 if ((SmbiosTableOri
== NULL
) ||
1603 ((UINTN
)SmbiosTableOri
> 0x100000) ||
1604 ((UINTN
)SmbiosTableOri
< 0xF0000)){
1608 // Relocate the Smibos memory
1610 BufferPtr
= EFI_SYSTEM_TABLE_MAX_ADDRESS
;
1611 if (SmbiosTableOri
->SmbiosBcdRevision
!= 0x21) {
1612 SmbiosEntryLen
= SmbiosTableOri
->EntryPointLength
;
1615 // According to Smbios Spec 2.4, we should set entry point length as 0x1F if version is 2.1
1617 SmbiosEntryLen
= 0x1F;
1619 BufferLen
= SmbiosEntryLen
+ SYS_TABLE_PAD(SmbiosEntryLen
) + SmbiosTableOri
->TableLength
;
1620 Status
= gBS
->AllocatePages (
1623 EFI_SIZE_TO_PAGES(BufferLen
),
1626 ASSERT_EFI_ERROR (Status
);
1627 SmbiosTableNew
= (SMBIOS_TABLE_ENTRY_POINT
*)(UINTN
)BufferPtr
;
1634 // Get Smbios Structure table address, and make sure the start address is 32-bit align
1636 BufferPtr
+= SmbiosEntryLen
+ SYS_TABLE_PAD(SmbiosEntryLen
);
1638 (VOID
*)(UINTN
)BufferPtr
,
1639 (VOID
*)(UINTN
)(SmbiosTableOri
->TableAddress
),
1640 SmbiosTableOri
->TableLength
1642 SmbiosTableNew
->TableAddress
= (UINT32
)BufferPtr
;
1643 SmbiosTableNew
->IntermediateChecksum
= 0;
1644 SmbiosTableNew
->IntermediateChecksum
=
1645 CalculateCheckSum8 ((UINT8
*)SmbiosTableNew
+ 0x10, SmbiosEntryLen
-0x10);
1647 // Change the SMBIOS pointer
1649 *Table
= SmbiosTableNew
;
1660 Routine Description:
1662 Convert MP Table if the Location of the SMBios Table is lower than Addres 0x100000
1664 As in legacy Bios, MP table is required to place in E/F Seg,
1665 So here we just check if the range is E/F seg,
1666 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
1668 Table - pointer to the table
1671 EFI_SUCEESS - Convert Table successfully
1678 EFI_LEGACY_MP_TABLE_FLOATING_POINTER
*MpsFloatingPointerOri
;
1679 EFI_LEGACY_MP_TABLE_FLOATING_POINTER
*MpsFloatingPointerNew
;
1680 EFI_LEGACY_MP_TABLE_HEADER
*MpsTableOri
;
1681 EFI_LEGACY_MP_TABLE_HEADER
*MpsTableNew
;
1685 EFI_PHYSICAL_ADDRESS BufferPtr
;
1688 // Get MP configuration Table
1690 MpsFloatingPointerOri
= (EFI_LEGACY_MP_TABLE_FLOATING_POINTER
*)(UINTN
)(*(UINT64
*)(*Table
));
1691 if (!(((UINTN
)MpsFloatingPointerOri
<= 0x100000) &&
1692 ((UINTN
)MpsFloatingPointerOri
>= 0xF0000))){
1696 // Get Floating pointer structure length
1698 FPLength
= MpsFloatingPointerOri
->Length
* 16;
1699 Data32
= FPLength
+ SYS_TABLE_PAD (FPLength
);
1700 MpsTableOri
= (EFI_LEGACY_MP_TABLE_HEADER
*)(UINTN
)(MpsFloatingPointerOri
->PhysicalAddress
);
1701 if (MpsTableOri
!= NULL
) {
1702 Data32
+= MpsTableOri
->BaseTableLength
;
1703 Data32
+= MpsTableOri
->ExtendedTableLength
;
1704 if (MpsTableOri
->OemTablePointer
!= 0x00) {
1705 Data32
+= SYS_TABLE_PAD (Data32
);
1706 Data32
+= MpsTableOri
->OemTableSize
;
1714 BufferPtr
= EFI_SYSTEM_TABLE_MAX_ADDRESS
;
1715 Status
= gBS
->AllocatePages (
1718 EFI_SIZE_TO_PAGES(Data32
),
1721 ASSERT_EFI_ERROR (Status
);
1722 MpsFloatingPointerNew
= (EFI_LEGACY_MP_TABLE_FLOATING_POINTER
*)(UINTN
)BufferPtr
;
1723 CopyMem (MpsFloatingPointerNew
, MpsFloatingPointerOri
, FPLength
);
1725 // If Mp Table exists
1727 if (MpsTableOri
!= NULL
) {
1729 // Get Mps table length, including Ext table
1731 BufferPtr
= BufferPtr
+ FPLength
+ SYS_TABLE_PAD (FPLength
);
1732 MpsTableNew
= (EFI_LEGACY_MP_TABLE_HEADER
*)(UINTN
)BufferPtr
;
1733 CopyMem (MpsTableNew
, MpsTableOri
, MpsTableOri
->BaseTableLength
+ MpsTableOri
->ExtendedTableLength
);
1735 if ((MpsTableOri
->OemTableSize
!= 0x0000) && (MpsTableOri
->OemTablePointer
!= 0x0000)){
1736 BufferPtr
+= MpsTableOri
->BaseTableLength
+ MpsTableOri
->ExtendedTableLength
;
1737 BufferPtr
+= SYS_TABLE_PAD (BufferPtr
);
1738 OemTableNew
= (VOID
*)(UINTN
)BufferPtr
;
1739 OemTableOri
= (VOID
*)(UINTN
)MpsTableOri
->OemTablePointer
;
1740 CopyMem (OemTableNew
, OemTableOri
, MpsTableOri
->OemTableSize
);
1741 MpsTableNew
->OemTablePointer
= (UINT32
)(UINTN
)OemTableNew
;
1743 MpsTableNew
->Checksum
= 0;
1744 MpsTableNew
->Checksum
= CalculateCheckSum8 ((UINT8
*)MpsTableNew
, MpsTableOri
->BaseTableLength
);
1745 MpsFloatingPointerNew
->PhysicalAddress
= (UINT32
)(UINTN
)MpsTableNew
;
1746 MpsFloatingPointerNew
->Checksum
= 0;
1747 MpsFloatingPointerNew
->Checksum
= CalculateCheckSum8 ((UINT8
*)MpsFloatingPointerNew
, FPLength
);
1750 // Change the pointer
1752 *Table
= MpsFloatingPointerNew
;