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
;
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%x, ", MemoryDescHob
.MemDesc
[Index
].PhysicalStart
));
191 DEBUG ((EFI_D_ERROR
, "PageNumber - 0x%x, ", MemoryDescHob
.MemDesc
[Index
].NumberOfPages
));
192 DEBUG ((EFI_D_ERROR
, "Type - 0x%x\n", MemoryDescHob
.MemDesc
[Index
].Type
));
193 if ((MemoryDescHob
.MemDesc
[Index
].Type
== EfiRuntimeServicesData
) ||
194 (MemoryDescHob
.MemDesc
[Index
].Type
== EfiRuntimeServicesCode
)) {
196 // Skip RuntimeSevicesData and RuntimeServicesCode, they are BFV
200 Status
= gDS
->AddMemorySpace (
201 EfiGcdMemoryTypeSystemMemory
,
202 MemoryDescHob
.MemDesc
[Index
].PhysicalStart
,
203 LShiftU64 (MemoryDescHob
.MemDesc
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
),
204 MemoryDescHob
.MemDesc
[Index
].Attribute
206 if (EFI_ERROR (Status
)) {
207 DEBUG ((EFI_D_ERROR
, "AddMemorySpace fail!\n"));
208 if ((MemoryDescHob
.MemDesc
[Index
].Type
== EfiACPIReclaimMemory
) ||
209 (MemoryDescHob
.MemDesc
[Index
].Type
== EfiACPIMemoryNVS
)) {
211 // For EfiACPIReclaimMemory and EfiACPIMemoryNVS, it must success.
212 // For EfiReservedMemoryType, there maybe overlap. So skip check here.
214 // ASSERT_EFI_ERROR (Status);
219 Memory
= MemoryDescHob
.MemDesc
[Index
].PhysicalStart
;
220 Status
= gBS
->AllocatePages (
222 (EFI_MEMORY_TYPE
)MemoryDescHob
.MemDesc
[Index
].Type
,
223 (UINTN
)MemoryDescHob
.MemDesc
[Index
].NumberOfPages
,
226 if (EFI_ERROR (Status
)) {
227 DEBUG ((EFI_D_ERROR
, "AllocatePages fail!\n"));
229 // For the page added, it must be allocated.
231 // ASSERT_EFI_ERROR (Status);
240 DisableUsbLegacySupport(
246 Disabble the USB legacy Support in all Ehci and Uhci.
247 This function assume all PciIo handles have been created in system.
258 EFI_HANDLE
*HandleArray
;
259 UINTN HandleArrayCount
;
261 EFI_PCI_IO_PROTOCOL
*PciIo
;
270 // Find the usb host controller
272 Status
= gBS
->LocateHandleBuffer (
274 &gEfiPciIoProtocolGuid
,
279 if (!EFI_ERROR (Status
)) {
280 for (Index
= 0; Index
< HandleArrayCount
; Index
++) {
281 Status
= gBS
->HandleProtocol (
283 &gEfiPciIoProtocolGuid
,
286 if (!EFI_ERROR (Status
)) {
288 // Find the USB host controller controller
290 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x09, 3, &Class
);
291 if (!EFI_ERROR (Status
)) {
292 if ((PCI_CLASS_SERIAL
== Class
[2]) &&
293 (PCI_CLASS_SERIAL_USB
== Class
[1])) {
294 if (PCI_CLASSC_PI_UHCI
== Class
[0]) {
296 // Found the UHCI, then disable the legacy support
299 Status
= PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0xC0, 1, &Command
);
300 } else if (PCI_CLASSC_PI_EHCI
== Class
[0]) {
302 // Found the EHCI, then disable the legacy support
304 Status
= PciIo
->Mem
.Read (
308 (UINT64
) 0x08, //EHC_HCCPARAMS_OFFSET
313 ExtendCap
= (HcCapParams
>> 8) & 0xFF;
315 // Disable the SMI in USBLEGCTLSTS firstly
317 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, ExtendCap
+ 0x4, 1, &Value
);
319 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, ExtendCap
+ 0x4, 1, &Value
);
322 // Get EHCI Ownership from legacy bios
324 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, ExtendCap
, 1, &Value
);
325 Value
|= (0x1 << 24);
326 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, ExtendCap
, 1, &Value
);
332 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, ExtendCap
, 1, &Value
);
334 if ((Value
& 0x01010000) == 0x01000000) {
346 gBS
->FreePool (HandleArray
);
353 IN EFI_BDS_ARCH_PROTOCOL_INSTANCE
*PrivateData
359 Platform Bds init. Incude the platform firmware vendor, revision
364 PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance
373 // set firmwarevendor, here can be IBV/OEM customize
375 gST
->FirmwareVendor
= AllocateRuntimeCopyPool (
376 sizeof (mFirmwareVendor
),
379 ASSERT (gST
->FirmwareVendor
!= NULL
);
381 gST
->FirmwareRevision
= 0;
384 // Fixup Tasble CRC after we updated Firmware Vendor and Revision
386 gBS
->CalculateCrc32 ((VOID
*) gST
, sizeof (EFI_SYSTEM_TABLE
), &gST
->Hdr
.CRC32
);
388 GetSystemTablesFromHob ();
393 // Append Usb Keyboard short form DevicePath into "ConInDev"
395 BdsLibUpdateConsoleVariable (
397 (EFI_DEVICE_PATH_PROTOCOL
*) &gUsbClassKeyboardDevicePath
,
403 GetPciExpressBaseAddressForRootBridge (
404 IN UINTN HostBridgeNumber
,
405 IN UINTN RootBridgeNumber
410 This routine is to get PciExpress Base Address for this RootBridge
413 HostBridgeNumber - The number of HostBridge
414 RootBridgeNumber - The number of RootBridge
417 UINT64 - PciExpressBaseAddress for this HostBridge and RootBridge
421 EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION
*PciExpressBaseAddressInfo
;
425 EFI_PEI_HOB_POINTERS GuidHob
;
428 // Get PciExpressAddressInfo Hob
430 PciExpressBaseAddressInfo
= NULL
;
432 GuidHob
.Raw
= GetFirstGuidHob (&gEfiPciExpressBaseAddressGuid
);
433 if (GuidHob
.Raw
!= NULL
) {
434 PciExpressBaseAddressInfo
= GET_GUID_HOB_DATA (GuidHob
.Guid
);
435 BufferSize
= GET_GUID_HOB_DATA_SIZE (GuidHob
.Guid
);
441 // Search the PciExpress Base Address in the Hob for current RootBridge
443 Number
= (UINT32
)(BufferSize
/ sizeof(EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION
));
444 for (Index
= 0; Index
< Number
; Index
++) {
445 if ((PciExpressBaseAddressInfo
[Index
].HostBridgeNumber
== HostBridgeNumber
) &&
446 (PciExpressBaseAddressInfo
[Index
].RootBridgeNumber
== RootBridgeNumber
)) {
447 return PciExpressBaseAddressInfo
[Index
].PciExpressBaseAddress
;
452 // Do not find the PciExpress Base Address in the Hob
458 PatchPciRootBridgeDevicePath (
459 IN UINTN HostBridgeNumber
,
460 IN UINTN RootBridgeNumber
,
461 IN PLATFORM_ROOT_BRIDGE_DEVICE_PATH
*RootBridge
464 UINT64 PciExpressBase
;
466 PciExpressBase
= GetPciExpressBaseAddressForRootBridge (HostBridgeNumber
, RootBridgeNumber
);
468 DEBUG ((EFI_D_INFO
, "Get PciExpress Address from Hob: 0x%X\n", PciExpressBase
));
470 if (PciExpressBase
!= 0) {
471 RootBridge
->PciRootBridge
.HID
= EISA_PNP_ID(0x0A08);
491 EFI_SUCCESS - Connect RootBridge successfully.
492 EFI_STATUS - Connect RootBridge fail.
497 EFI_HANDLE RootHandle
;
500 // Patch Pci Root Bridge Device Path
502 PatchPciRootBridgeDevicePath (0, 0, &gPlatformRootBridge0
);
505 // Make all the PCI_IO protocols on PCI Seg 0 show up
507 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
509 Status
= gBS
->LocateDevicePath (
510 &gEfiDevicePathProtocolGuid
,
511 &gPlatformRootBridges
[0],
514 DEBUG ((EFI_D_INFO
, "Pci Root bridge handle is 0x%X\n", RootHandle
));
516 if (EFI_ERROR (Status
)) {
520 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
521 if (EFI_ERROR (Status
)) {
529 PrepareLpcBridgeDevicePath (
530 IN EFI_HANDLE DeviceHandle
536 Add IsaKeyboard to ConIn,
537 add IsaSerial to ConOut, ConIn, ErrOut.
542 DeviceHandle - Handle of PCIIO protocol.
546 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
547 EFI_STATUS - No LPC bridge is added.
552 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
553 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
556 Status
= gBS
->HandleProtocol (
558 &gEfiDevicePathProtocolGuid
,
561 if (EFI_ERROR (Status
)) {
564 TempDevicePath
= DevicePath
;
569 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
571 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
576 DevicePath
= TempDevicePath
;
577 gPnp16550ComPortDeviceNode
.UID
= 0;
579 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
580 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
581 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
583 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
584 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
585 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
590 DevicePath
= TempDevicePath
;
591 gPnp16550ComPortDeviceNode
.UID
= 1;
593 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
594 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
595 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
597 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
598 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
599 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
606 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
607 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
612 EFI_HANDLE PciDeviceHandle
;
613 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
614 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
615 UINTN GopHandleCount
;
616 EFI_HANDLE
*GopHandleBuffer
;
618 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
619 return EFI_INVALID_PARAMETER
;
623 // Initialize the GopDevicePath to be PciDevicePath
625 *GopDevicePath
= PciDevicePath
;
626 TempPciDevicePath
= PciDevicePath
;
628 Status
= gBS
->LocateDevicePath (
629 &gEfiDevicePathProtocolGuid
,
633 if (EFI_ERROR (Status
)) {
638 // Try to connect this handle, so that GOP dirver could start on this
639 // device and create child handles with GraphicsOutput Protocol installed
640 // on them, then we get device paths of these child handles and select
641 // them as possible console device.
643 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
645 Status
= gBS
->LocateHandleBuffer (
647 &gEfiGraphicsOutputProtocolGuid
,
652 if (!EFI_ERROR (Status
)) {
654 // Add all the child handles as possible Console Device
656 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
657 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
658 if (EFI_ERROR (Status
)) {
664 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
667 // In current implementation, we only enable one of the child handles
668 // as console device, i.e. sotre one of the child handle's device
669 // path to variable "ConOut"
670 // In futhure, we could select all child handles to be console device
673 *GopDevicePath
= TempDevicePath
;
676 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
677 // Add the integrity GOP device path.
679 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
680 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
683 gBS
->FreePool (GopHandleBuffer
);
690 PreparePciVgaDevicePath (
691 IN EFI_HANDLE DeviceHandle
697 Add PCI VGA to ConOut.
702 DeviceHandle - Handle of PCIIO protocol.
706 EFI_SUCCESS - PCI VGA is added to ConOut.
707 EFI_STATUS - No PCI VGA device is added.
712 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
713 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
716 Status
= gBS
->HandleProtocol (
718 &gEfiDevicePathProtocolGuid
,
721 if (EFI_ERROR (Status
)) {
725 GetGopDevicePath (DevicePath
, &GopDevicePath
);
726 DevicePath
= GopDevicePath
;
728 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
734 PreparePciSerialDevicePath (
735 IN EFI_HANDLE DeviceHandle
741 Add PCI Serial to ConOut, ConIn, ErrOut.
746 DeviceHandle - Handle of PCIIO protocol.
750 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
751 EFI_STATUS - No PCI Serial device is added.
756 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
759 Status
= gBS
->HandleProtocol (
761 &gEfiDevicePathProtocolGuid
,
764 if (EFI_ERROR (Status
)) {
768 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
769 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
771 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
772 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
773 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
779 DetectAndPreparePlatformPciDevicePath (
780 BOOLEAN DetectVgaOnly
786 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
790 DetectVgaOnly - Only detect VGA device if it's TRUE.
794 EFI_SUCCESS - PCI Device check and Console variable update successfully.
795 EFI_STATUS - PCI Device check or Console variable update fail.
801 EFI_HANDLE
*HandleBuffer
;
803 EFI_PCI_IO_PROTOCOL
*PciIo
;
807 // Start to check all the PciIo to find all possible device
811 Status
= gBS
->LocateHandleBuffer (
813 &gEfiPciIoProtocolGuid
,
818 if (EFI_ERROR (Status
)) {
822 for (Index
= 0; Index
< HandleCount
; Index
++) {
823 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiPciIoProtocolGuid
, (VOID
*)&PciIo
);
824 if (EFI_ERROR (Status
)) {
829 // Check for all PCI device
831 Status
= PciIo
->Pci
.Read (
835 sizeof (Pci
) / sizeof (UINT32
),
838 if (EFI_ERROR (Status
)) {
842 if (!DetectVgaOnly
) {
844 // Here we decide whether it is LPC Bridge
846 if ((IS_PCI_LPC (&Pci
)) ||
847 ((IS_PCI_ISA_PDECODE (&Pci
)) && (Pci
.Hdr
.VendorId
== 0x8086) && (Pci
.Hdr
.DeviceId
== 0x7110))) {
849 // Add IsaKeyboard to ConIn,
850 // add IsaSerial to ConOut, ConIn, ErrOut
852 DEBUG ((EFI_D_INFO
, "Find the LPC Bridge device\n"));
853 PrepareLpcBridgeDevicePath (HandleBuffer
[Index
]);
857 // Here we decide which Serial device to enable in PCI bus
859 if (IS_PCI_16550SERIAL (&Pci
)) {
861 // Add them to ConOut, ConIn, ErrOut.
863 DEBUG ((EFI_D_INFO
, "Find the 16550 SERIAL device\n"));
864 PreparePciSerialDevicePath (HandleBuffer
[Index
]);
870 // Here we decide which VGA device to enable in PCI bus
872 if (IS_PCI_VGA (&Pci
)) {
874 // Add them to ConOut.
876 DEBUG ((EFI_D_INFO
, "Find the VGA device\n"));
877 PreparePciVgaDevicePath (HandleBuffer
[Index
]);
882 gBS
->FreePool (HandleBuffer
);
888 PlatformBdsConnectConsole (
889 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
895 Connect the predefined platform default console device. Always try to find
896 and enable the vga device if have.
900 PlatformConsole - Predfined platform default console device array.
904 EFI_SUCCESS - Success connect at least one ConIn and ConOut
905 device, there must have one ConOut device is
908 EFI_STATUS - Return the status of
909 BdsLibConnectAllDefaultConsoles ()
915 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
916 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
917 UINTN DevicePathSize
;
920 // Connect RootBridge
922 ConnectRootBridge ();
924 VarConout
= BdsLibGetVariableAndSize (
926 &gEfiGlobalVariableGuid
,
929 VarConin
= BdsLibGetVariableAndSize (
931 &gEfiGlobalVariableGuid
,
935 if (VarConout
== NULL
|| VarConin
== NULL
) {
937 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
939 DetectAndPreparePlatformPciDevicePath (FALSE
);
942 // Have chance to connect the platform default console,
943 // the platform default console is the minimue device group
944 // the platform should support
946 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
948 // Update the console variable with the connect type
950 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
951 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
953 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
954 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
956 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
957 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
962 // Only detect VGA device and add them to ConOut
964 DetectAndPreparePlatformPciDevicePath (TRUE
);
968 // The ConIn devices connection will start the USB bus, should disable all
969 // Usb legacy support firstly.
970 // Caution: Must ensure the PCI bus driver has been started. Since the
971 // ConnectRootBridge() will create all the PciIo protocol, it's safe here now
973 Status
= DisableUsbLegacySupport();
976 // Connect the all the default console with current cosole variable
978 Status
= BdsLibConnectAllDefaultConsoles ();
979 if (EFI_ERROR (Status
)) {
987 PlatformBdsConnectSequence (
994 Connect with predeined platform connect sequence,
995 the OEM/IBV can customize with their own connect sequence.
1012 // Here we can get the customized platform connect sequence
1013 // Notes: we can connect with new variable which record the
1014 // last time boots connect device path sequence
1016 while (gPlatformConnectSequence
[Index
] != NULL
) {
1018 // Build the platform boot option
1020 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
1027 PlatformBdsGetDriverOption (
1028 IN OUT LIST_ENTRY
*BdsDriverLists
1032 Routine Description:
1034 Load the predefined driver option, OEM/IBV can customize this
1035 to load their own drivers
1039 BdsDriverLists - The header of the driver option link list.
1052 // Here we can get the customized platform driver option
1054 while (gPlatformDriverOption
[Index
] != NULL
) {
1056 // Build the platform boot option
1058 BdsLibRegisterNewOption (BdsDriverLists
, gPlatformDriverOption
[Index
], NULL
, L
"DriverOrder");
1065 PlatformBdsDiagnostics (
1066 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
1067 IN BOOLEAN QuietBoot
1071 Routine Description:
1073 Perform the platform diagnostic, such like test memory. OEM/IBV also
1074 can customize this fuction to support specific platform diagnostic.
1078 MemoryTestLevel - The memory test intensive level
1080 QuietBoot - Indicate if need to enable the quiet boot
1091 // Here we can decide if we need to show
1092 // the diagnostics screen
1093 // Notes: this quiet boot code should be remove
1094 // from the graphic lib
1097 Status
= EnableQuietBoot (&gEfiDefaultBmpLogoGuid
);
1098 if (EFI_ERROR (Status
)) {
1099 DisableQuietBoot ();
1104 // Perform system diagnostic
1106 Status
= BdsMemoryTest (MemoryTestLevel
);
1107 if (EFI_ERROR (Status
)) {
1108 DisableQuietBoot ();
1114 // Perform system diagnostic
1116 Status
= BdsMemoryTest (MemoryTestLevel
);
1120 PlatformBdsPolicyBehavior (
1121 IN EFI_BDS_ARCH_PROTOCOL_INSTANCE
*PrivateData
,
1122 IN OUT LIST_ENTRY
*DriverOptionList
,
1123 IN OUT LIST_ENTRY
*BootOptionList
1127 Routine Description:
1129 The function will excute with as the platform policy, current policy
1130 is driven by boot mode. IBV/OEM can customize this code for their specific
1135 PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance
1137 DriverOptionList - The header of the driver option link list
1139 BootOptionList - The header of the boot option link list
1149 EFI_EVENT UserInputDurationTime
;
1151 BDS_COMMON_OPTION
*BootOption
;
1157 // Init the time out value
1159 Timeout
= BdsLibGetTimeout ();
1162 // Load the driver option as the driver option list
1164 PlatformBdsGetDriverOption (DriverOptionList
);
1167 // Get current Boot Mode
1169 Status
= BdsLibGetBootMode (&PrivateData
->BootMode
);
1170 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", PrivateData
->BootMode
));
1173 // Go the different platform policy with different boot mode
1174 // Notes: this part code can be change with the table policy
1176 ASSERT (PrivateData
->BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
1178 // Connect platform console
1180 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1181 if (EFI_ERROR (Status
)) {
1183 // Here OEM/IBV can customize with defined action
1185 PlatformBdsNoConsoleAction ();
1188 // Create a 300ms duration event to ensure user has enough input time to enter Setup
1190 Status
= gBS
->CreateEvent (
1195 &UserInputDurationTime
1197 ASSERT (Status
== EFI_SUCCESS
);
1198 Status
= gBS
->SetTimer (UserInputDurationTime
, TimerRelative
, 3000000);
1199 ASSERT (Status
== EFI_SUCCESS
);
1201 // Memory test and Logo show
1203 PlatformBdsDiagnostics (IGNORE
, TRUE
);
1206 // Perform some platform specific connect sequence
1208 PlatformBdsConnectSequence ();
1211 // Give one chance to enter the setup if we
1212 // have the time out
1214 // BUGBUG: hard code timeout to 5 second to show logo in graphic mode.
1217 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1221 //BdsLibConnectAll ();
1222 //BdsLibEnumerateAllBootOption (BootOptionList);
1225 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
1226 // checking code in real production tip.
1228 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
1229 // and do enumerate all the default boot options. But in development system board, the boot mode
1230 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
1231 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
1233 Status
= BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1234 if (EFI_ERROR(Status
)) {
1236 // If cannot find "BootOrder" variable, it may be first boot.
1237 // Try to connect all devices and enumerate all boot options here.
1239 BdsLibConnectAll ();
1240 BdsLibEnumerateAllBootOption (BootOptionList
);
1244 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
1245 // BDS should still give user a chance to enter Setup
1247 // Connect first boot option, and then check user input before exit
1249 for (Link
= BootOptionList
->ForwardLink
; Link
!= BootOptionList
;Link
= Link
->ForwardLink
) {
1250 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
1251 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
1253 // skip the header of the link list, becuase it has no boot option
1258 // Make sure the boot option device path connected, but ignore the BBS device path
1260 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
1261 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1268 // Check whether the user input after the duration time has expired
1270 OldTpl
= EfiGetCurrentTpl();
1271 gBS
->RestoreTPL (TPL_APPLICATION
);
1272 gBS
->WaitForEvent (1, &UserInputDurationTime
, &Index
);
1273 gBS
->CloseEvent (UserInputDurationTime
);
1274 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1275 gBS
->RaiseTPL (OldTpl
);
1277 if (!EFI_ERROR (Status
)) {
1279 // Enter Setup if user input
1282 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1290 PlatformBdsBootSuccess (
1291 IN BDS_COMMON_OPTION
*Option
1295 Routine Description:
1297 Hook point after a boot attempt succeeds. We don't expect a boot option to
1298 return, so the EFI 1.0 specification defines that you will default to an
1299 interactive mode and stop processing the BootOrder list in this case. This
1300 is alos a platform implementation and can be customized by IBV/OEM.
1304 Option - Pointer to Boot Option that succeeded to boot.
1315 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1316 // select loop then we need to pop up a UI and wait for user input.
1318 TmpStr
= Option
->StatusString
;
1319 if (TmpStr
!= NULL
) {
1320 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1321 gBS
->FreePool (TmpStr
);
1326 PlatformBdsBootFail (
1327 IN BDS_COMMON_OPTION
*Option
,
1328 IN EFI_STATUS Status
,
1329 IN CHAR16
*ExitData
,
1330 IN UINTN ExitDataSize
1334 Routine Description:
1336 Hook point after a boot attempt fails.
1340 Option - Pointer to Boot Option that failed to boot.
1342 Status - Status returned from failed boot.
1344 ExitData - Exit data returned from failed boot.
1346 ExitDataSize - Exit data size returned from failed boot.
1357 // If Boot returned with failed status then we need to pop up a UI and wait
1360 TmpStr
= Option
->StatusString
;
1361 if (TmpStr
!= NULL
) {
1362 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1363 gBS
->FreePool (TmpStr
);
1369 PlatformBdsNoConsoleAction (
1374 Routine Description:
1376 This function is remained for IBV/OEM to do some platform action,
1377 if there no console device can be connected.
1385 EFI_SUCCESS - Direct return success now.
1393 ConvertSystemTable (
1394 IN EFI_GUID
*TableGuid
,
1399 Routine Description:
1400 Convert ACPI Table /Smbios Table /MP Table if its location is lower than Address:0x100000
1402 As in legacy Bios, ACPI/Smbios/MP table is required to place in E/F Seg,
1403 So here we just check if the range is E/F seg,
1404 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
1407 TableGuid - Guid of the table
1408 Table - pointer to the table
1411 EFI_SUCEESS - Convert Table successfully
1421 // If match acpi guid (1.0, 2.0, or later), Convert ACPI table according to version.
1423 AcpiHeader
= (VOID
*)(UINTN
)(*(UINT64
*)(*Table
));
1425 if (CompareGuid(TableGuid
, &gEfiAcpiTableGuid
) || CompareGuid(TableGuid
, &gEfiAcpi20TableGuid
)){
1426 if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiHeader
)->Reserved
== 0x00){
1428 // If Acpi 1.0 Table, then RSDP structure doesn't contain Length field, use structure size
1430 AcpiTableLen
= sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
);
1431 } else if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiHeader
)->Reserved
>= 0x02){
1433 // If Acpi 2.0 or later, use RSDP Length fied.
1435 AcpiTableLen
= ((EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiHeader
)->Length
;
1438 // Invalid Acpi Version, return
1440 return EFI_UNSUPPORTED
;
1442 Status
= ConvertAcpiTable (AcpiTableLen
, Table
);
1447 // If matches smbios guid, convert Smbios table.
1449 if (CompareGuid(TableGuid
, &gEfiSmbiosTableGuid
)){
1450 Status
= ConvertSmbiosTable (Table
);
1455 // If the table is MP table?
1457 if (CompareGuid(TableGuid
, &gEfiMpsTableGuid
)){
1458 Status
= ConvertMpsTable (Table
);
1462 return EFI_UNSUPPORTED
;
1472 Routine Description:
1473 Caculate buffer checksum (8-bit)
1476 Buffer - Pointer to Buffer that to be caculated
1477 Length - How many bytes are to be caculated
1480 Checksum of the buffer
1488 Ptr8
= (UINT8
*) Buffer
;
1490 while (Length
> 0) {
1491 CheckSum
= (UINT8
) (CheckSum
+ *Ptr8
++);
1495 return (UINT8
)((0xFF - CheckSum
) + 1);
1505 Routine Description:
1506 Convert RSDP of ACPI Table if its location is lower than Address:0x100000
1508 As in legacy Bios, ACPI table is required to place in E/F Seg,
1509 So here we just check if the range is E/F seg,
1510 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
1513 TableLen - Acpi RSDP length
1514 Table - pointer to the table
1517 EFI_SUCEESS - Convert Table successfully
1525 EFI_PHYSICAL_ADDRESS BufferPtr
;
1528 AcpiTableOri
= (VOID
*)(UINTN
)(*(UINT64
*)(*Table
));
1529 if (((UINTN
)AcpiTableOri
< 0x100000) && ((UINTN
)AcpiTableOri
> 0xE0000)) {
1530 BufferPtr
= EFI_SYSTEM_TABLE_MAX_ADDRESS
;
1531 Status
= gBS
->AllocatePages (
1534 EFI_SIZE_TO_PAGES(TableLen
),
1537 ASSERT_EFI_ERROR (Status
);
1538 AcpiTableNew
= (VOID
*)(UINTN
)BufferPtr
;
1539 CopyMem (AcpiTableNew
, AcpiTableOri
, TableLen
);
1541 AcpiTableNew
= AcpiTableOri
;
1544 // Change configuration table Pointer
1546 *Table
= AcpiTableNew
;
1552 ConvertSmbiosTable (
1557 Routine Description:
1559 Convert Smbios Table if the Location of the SMBios Table is lower than Addres 0x100000
1561 As in legacy Bios, Smbios table is required to place in E/F Seg,
1562 So here we just check if the range is F seg,
1563 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
1565 Table - pointer to the table
1568 EFI_SUCEESS - Convert Table successfully
1573 SMBIOS_TABLE_ENTRY_POINT
*SmbiosTableNew
;
1574 SMBIOS_TABLE_ENTRY_POINT
*SmbiosTableOri
;
1576 UINT32 SmbiosEntryLen
;
1578 EFI_PHYSICAL_ADDRESS BufferPtr
;
1580 SmbiosTableNew
= NULL
;
1581 SmbiosTableOri
= NULL
;
1584 // Get Smibos configuration Table
1586 SmbiosTableOri
= (SMBIOS_TABLE_ENTRY_POINT
*)(UINTN
)(*(UINT64
*)(*Table
));
1588 if ((SmbiosTableOri
== NULL
) ||
1589 ((UINTN
)SmbiosTableOri
> 0x100000) ||
1590 ((UINTN
)SmbiosTableOri
< 0xF0000)){
1594 // Relocate the Smibos memory
1596 BufferPtr
= EFI_SYSTEM_TABLE_MAX_ADDRESS
;
1597 if (SmbiosTableOri
->SmbiosBcdRevision
!= 0x21) {
1598 SmbiosEntryLen
= SmbiosTableOri
->EntryPointLength
;
1601 // According to Smbios Spec 2.4, we should set entry point length as 0x1F if version is 2.1
1603 SmbiosEntryLen
= 0x1F;
1605 BufferLen
= SmbiosEntryLen
+ SYS_TABLE_PAD(SmbiosEntryLen
) + SmbiosTableOri
->TableLength
;
1606 Status
= gBS
->AllocatePages (
1609 EFI_SIZE_TO_PAGES(BufferLen
),
1612 ASSERT_EFI_ERROR (Status
);
1613 SmbiosTableNew
= (SMBIOS_TABLE_ENTRY_POINT
*)(UINTN
)BufferPtr
;
1620 // Get Smbios Structure table address, and make sure the start address is 32-bit align
1622 BufferPtr
+= SmbiosEntryLen
+ SYS_TABLE_PAD(SmbiosEntryLen
);
1624 (VOID
*)(UINTN
)BufferPtr
,
1625 (VOID
*)(UINTN
)(SmbiosTableOri
->TableAddress
),
1626 SmbiosTableOri
->TableLength
1628 SmbiosTableNew
->TableAddress
= (UINT32
)BufferPtr
;
1629 SmbiosTableNew
->IntermediateChecksum
= 0;
1630 SmbiosTableNew
->IntermediateChecksum
=
1631 GetBufferCheckSum ((UINT8
*)SmbiosTableNew
+ 0x10, SmbiosEntryLen
-0x10);
1633 // Change the SMBIOS pointer
1635 *Table
= SmbiosTableNew
;
1646 Routine Description:
1648 Convert MP Table if the Location of the SMBios Table is lower than Addres 0x100000
1650 As in legacy Bios, MP table is required to place in E/F Seg,
1651 So here we just check if the range is E/F seg,
1652 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
1654 Table - pointer to the table
1657 EFI_SUCEESS - Convert Table successfully
1664 EFI_LEGACY_MP_TABLE_FLOATING_POINTER
*MpsFloatingPointerOri
;
1665 EFI_LEGACY_MP_TABLE_FLOATING_POINTER
*MpsFloatingPointerNew
;
1666 EFI_LEGACY_MP_TABLE_HEADER
*MpsTableOri
;
1667 EFI_LEGACY_MP_TABLE_HEADER
*MpsTableNew
;
1671 EFI_PHYSICAL_ADDRESS BufferPtr
;
1674 // Get MP configuration Table
1676 MpsFloatingPointerOri
= (EFI_LEGACY_MP_TABLE_FLOATING_POINTER
*)(UINTN
)(*(UINT64
*)(*Table
));
1677 if (!(((UINTN
)MpsFloatingPointerOri
<= 0x100000) &&
1678 ((UINTN
)MpsFloatingPointerOri
>= 0xF0000))){
1682 // Get Floating pointer structure length
1684 FPLength
= MpsFloatingPointerOri
->Length
* 16;
1685 Data32
= FPLength
+ SYS_TABLE_PAD (FPLength
);
1686 MpsTableOri
= (EFI_LEGACY_MP_TABLE_HEADER
*)(UINTN
)(MpsFloatingPointerOri
->PhysicalAddress
);
1687 if (MpsTableOri
!= NULL
) {
1688 Data32
+= MpsTableOri
->BaseTableLength
;
1689 Data32
+= MpsTableOri
->ExtendedTableLength
;
1690 if (MpsTableOri
->OemTablePointer
!= 0x00) {
1691 Data32
+= SYS_TABLE_PAD (Data32
);
1692 Data32
+= MpsTableOri
->OemTableSize
;
1700 BufferPtr
= EFI_SYSTEM_TABLE_MAX_ADDRESS
;
1701 Status
= gBS
->AllocatePages (
1704 EFI_SIZE_TO_PAGES(Data32
),
1707 ASSERT_EFI_ERROR (Status
);
1708 MpsFloatingPointerNew
= (EFI_LEGACY_MP_TABLE_FLOATING_POINTER
*)(UINTN
)BufferPtr
;
1709 CopyMem (MpsFloatingPointerNew
, MpsFloatingPointerOri
, FPLength
);
1711 // If Mp Table exists
1713 if (MpsTableOri
!= NULL
) {
1715 // Get Mps table length, including Ext table
1717 BufferPtr
= BufferPtr
+ FPLength
+ SYS_TABLE_PAD (FPLength
);
1718 MpsTableNew
= (EFI_LEGACY_MP_TABLE_HEADER
*)(UINTN
)BufferPtr
;
1719 CopyMem (MpsTableNew
, MpsTableOri
, MpsTableOri
->BaseTableLength
+ MpsTableOri
->ExtendedTableLength
);
1721 if ((MpsTableOri
->OemTableSize
!= 0x0000) && (MpsTableOri
->OemTablePointer
!= 0x0000)){
1722 BufferPtr
+= MpsTableOri
->BaseTableLength
+ MpsTableOri
->ExtendedTableLength
;
1723 BufferPtr
+= SYS_TABLE_PAD (BufferPtr
);
1724 OemTableNew
= (VOID
*)(UINTN
)BufferPtr
;
1725 OemTableOri
= (VOID
*)(UINTN
)MpsTableOri
->OemTablePointer
;
1726 CopyMem (OemTableNew
, OemTableOri
, MpsTableOri
->OemTableSize
);
1727 MpsTableNew
->OemTablePointer
= (UINT32
)(UINTN
)OemTableNew
;
1729 MpsTableNew
->Checksum
= 0;
1730 MpsTableNew
->Checksum
= GetBufferCheckSum (MpsTableNew
, MpsTableOri
->BaseTableLength
);
1731 MpsFloatingPointerNew
->PhysicalAddress
= (UINT32
)(UINTN
)MpsTableNew
;
1732 MpsFloatingPointerNew
->Checksum
= 0;
1733 MpsFloatingPointerNew
->Checksum
= GetBufferCheckSum (MpsFloatingPointerNew
, FPLength
);
1736 // Change the pointer
1738 *Table
= MpsFloatingPointerNew
;