/** @file
Copyright (c) 2018, Intel Corporation. All rights reserved.
Copyright (c) 2021, American Megatrends International LLC.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
//
// Statements that include other files
//
//
// Statements that include other header files
//
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "Register/PchRegsUsb.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
extern BOOLEAN mCpuOrderSorted;
typedef struct {
char *Pathname; /* Full pathname (from root) to the object */
unsigned short ParentOpcode; /* AML opcode for the parent object */
unsigned long NamesegOffset; /* Offset of last nameseg in the parent namepath */
unsigned char Opcode; /* AML opcode for the data */
unsigned long Offset; /* Offset for the data */
unsigned long long Value; /* Original value of the data (as applicable) */
} AML_OFFSET_TABLE_ENTRY;
extern AML_OFFSET_TABLE_ENTRY *mAmlOffsetTablePointer;
extern AML_OFFSET_TABLE_ENTRY DSDT_PLATWFP__OffsetTable[];
#define AML_NAME_OP 0x08
#define AML_NAME_PREFIX_SIZE 0x06
#define AML_NAME_DWORD_SIZE 0x0C
#define MEM_ADDR_SHFT_VAL 26 // For 64 MB granularity
#pragma pack(1)
typedef struct {
UINT8 DescriptorType;
UINT16 ResourceLength;
UINT8 ResourceType;
UINT8 Flags;
UINT8 SpecificFlags;
UINT64 Granularity;
UINT64 Minimum;
UINT64 Maximum;
UINT64 TranslationOffset;
UINT64 AddressLength;
} AML_RESOURCE_ADDRESS64;
typedef struct {
UINT8 DescriptorType;
UINT16 ResourceLength;
UINT8 ResourceType;
UINT8 Flags;
UINT8 SpecificFlags;
UINT32 Granularity;
UINT32 Minimum;
UINT32 Maximum;
UINT32 TranslationOffset;
UINT32 AddressLength;
} AML_RESOURCE_ADDRESS32;
typedef struct {
UINT8 DescriptorType;
UINT16 ResourceLength;
UINT8 ResourceType;
UINT8 Flags;
UINT8 SpecificFlags;
UINT16 Granularity;
UINT16 Minimum;
UINT16 Maximum;
UINT16 TranslationOffset;
UINT16 AddressLength;
} AML_RESOURCE_ADDRESS16;
#pragma pack()
#define PCIE_PORT_4_DEV 0x00
#define PCIE_PORT_5_DEV 0x00
#define PORTS_PER_SOCKET 0x0F
#define PCIE_PORT_ALL_FUNC 0x00
typedef struct _PCIE_PORT_INFO {
UINT8 Device;
UINT8 Stack;
} PCIE_PORT_INFO;
#pragma optimize("",off)
extern BIOS_ACPI_PARAM *mAcpiParameter;
extern struct SystemMemoryMapHob *mSystemMemoryMap;
extern EFI_IIO_UDS_PROTOCOL *mIioUds;
extern SOCKET_MP_LINK_CONFIGURATION mSocketMpLinkConfiguration;
extern SOCKET_IIO_CONFIGURATION mSocketIioConfiguration;
extern SOCKET_POWERMANAGEMENT_CONFIGURATION mSocketPowermanagementConfiguration;
extern UINT32 mNumOfBitShift;
AML_OFFSET_TABLE_ENTRY *mAmlOffsetTablePointer = DSDT_PLATWFP__OffsetTable;
/**
Update the DSDT table
@param *TableHeader - The table to be set
@retval EFI_SUCCESS - DSDT updated
@retval EFI_INVALID_PARAMETER - DSDT not updated
**/
EFI_STATUS
PatchDsdtTable (
IN OUT EFI_ACPI_COMMON_HEADER *Table
)
{
PCIE_PORT_INFO PCIEPortDefaults[] = {
// DMI/PCIE 0
{ PCIE_PORT_0_DEV, IIO_CSTACK },
//IOU0
{ PCIE_PORT_1A_DEV, IIO_PSTACK0 },
{ PCIE_PORT_1B_DEV, IIO_PSTACK0 },
{ PCIE_PORT_1C_DEV, IIO_PSTACK0 },
{ PCIE_PORT_1D_DEV, IIO_PSTACK0 },
//IOU1
{ PCIE_PORT_2A_DEV, IIO_PSTACK1 },
{ PCIE_PORT_2B_DEV, IIO_PSTACK1 },
{ PCIE_PORT_2C_DEV, IIO_PSTACK1 },
{ PCIE_PORT_2D_DEV, IIO_PSTACK1 },
//IOU2
{ PCIE_PORT_3A_DEV, IIO_PSTACK2 },
{ PCIE_PORT_3B_DEV, IIO_PSTACK2 },
{ PCIE_PORT_3C_DEV, IIO_PSTACK2 },
{ PCIE_PORT_3D_DEV, IIO_PSTACK2 },
//MCP0 and MCP1
{ PCIE_PORT_4_DEV, IIO_PSTACK3 },
{ PCIE_PORT_5_DEV, IIO_PSTACK4 }
};
EFI_STATUS Status;
UINT8 *DsdtPointer;
UINT32 *Signature;
UINT32 Fixes, NodeIndex;
UINT8 Counter;
UINT16 i; // DSDT_PLATEXRP_OffsetTable LUT entries extends beyond 256!
UINT64 MemoryBaseLimit = 0;
UINT64 PciHGPEAddr = 0;
UINT64 BusDevFunc = 0;
UINT64 PcieHpBus = 0;
UINT64 PcieHpDev = 0;
UINT64 PcieHpFunc= 0;
UINT8 PortCount = 0;
UINT8 StackNumBus = 0;
UINT8 StackNumIo = 0;
UINT8 StackNumMem32 = 0;
UINT8 StackNumMem64 = 0;
UINT8 StackNumVgaIo0 = 1; // Start looking for Stack 1
UINT8 StackNumVgaIo1 = 1; // Start looking for Stack 1
UINT8 StackNumVgaMmioL = 0;
UINT8 Stack = 0;
UINT8 CurrSkt = 0, CurrStack = 0;
UINT64 IioBusIndex = 0;
UINT8 BusBase = 0, BusLimit = 0;
UINT16 IoBase = 0, IoLimit = 0;
UINT32 MemBase32 = 0, MemLimit32 = 0;
UINT64 MemBase64 = 0, MemLimit64 = 0;
AML_RESOURCE_ADDRESS16 *AmlResourceAddress16Pointer;
AML_RESOURCE_ADDRESS32 *AmlResourceAddress32Pointer;
AML_RESOURCE_ADDRESS64 *AmlResourceAddress64Pointer;
EFI_ACPI_DESCRIPTION_HEADER *TableHeader;
Status = EFI_SUCCESS;
TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *)Table;
if (mAmlOffsetTablePointer == NULL) return EFI_INVALID_PARAMETER;
mAcpiParameter->MemoryBoardBitMask = 0;
for(Counter = 0; Counter < mSystemMemoryMap->numberEntries; Counter++) {
NodeIndex = mSystemMemoryMap->Element[Counter].NodeId;
if((mAcpiParameter->MemoryBoardBitMask) & (1 << NodeIndex)){
MemoryBaseLimit = mAcpiParameter->MemoryBoardRange[NodeIndex] + LShiftU64(mSystemMemoryMap->Element[Counter].ElementSize, MEM_ADDR_SHFT_VAL);
mAcpiParameter->MemoryBoardRange[NodeIndex] = MemoryBaseLimit;
} else {
mAcpiParameter->MemoryBoardBitMask |= 1 << NodeIndex;
MemoryBaseLimit = LShiftU64(mSystemMemoryMap->Element[Counter].BaseAddress, 30);
mAcpiParameter->MemoryBoardBase[NodeIndex] = MemoryBaseLimit;
MemoryBaseLimit = LShiftU64((mSystemMemoryMap->Element[Counter].BaseAddress + mSystemMemoryMap->Element[Counter].ElementSize), MEM_ADDR_SHFT_VAL);
mAcpiParameter->MemoryBoardRange[NodeIndex] = MemoryBaseLimit;
}
}
//
// Mark all spare memory controllers as 1 in MemSpareMask bitmap.
//
mAcpiParameter->MemSpareMask = ~mAcpiParameter->MemoryBoardBitMask;
mAcpiParameter->IioPresentBitMask = 0;
mAcpiParameter->SocketBitMask = 0;
for (Counter = 0; Counter < MAX_SOCKET; Counter++) {
if (!mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Counter].Valid) continue;
mAcpiParameter->SocketBitMask |= 1 << Counter;
mAcpiParameter->IioPresentBitMask |= LShiftU64(mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Counter].stackPresentBitmap, (Counter * 8));
for (Stack = 0; Stack < MAX_IIO_STACK; Stack++) {
mAcpiParameter->BusBase[Counter * MAX_IIO_STACK + Stack] = mIioUds->IioUdsPtr->PlatformData.IIO_resource[Counter].StackRes[Stack].BusBase;
}
}
PciHGPEAddr = mIioUds->IioUdsPtr->PlatformData.PciExpressBase + 0x188;
BusDevFunc = 0x00;
PcieHpBus = 0;
PcieHpDev = 0;
PcieHpFunc = 0;
Fixes = 0;
//
// Loop through the AML looking for values that we must fix up.
//
for (i = 0; mAmlOffsetTablePointer[i].Pathname != 0; i++) {
//
// Point to offset in DSDT for current item in AmlOffsetTable.
//
DsdtPointer = (UINT8 *) (TableHeader) + mAmlOffsetTablePointer[i].Offset;
if (mAmlOffsetTablePointer[i].Opcode == AML_DWORD_PREFIX) {
//
// If Opcode is 0x0C, then operator is Name() or OperationRegion().
// (TableHeader + AmlOffsetTable.Offset) is at offset for value to change.
//
// The assert below confirms that AML structure matches the offsets table.
// If not then patching the AML would just corrupt it and result in OS failure.
// If you encounter this assert something went wrong in *.offset.h files
// generation. Remove the files and rebuild.
//
ASSERT(DsdtPointer[-1] == mAmlOffsetTablePointer[i].Opcode);
//
// AmlOffsetTable.Value has FIX tag, so check that to decide what to modify.
//
Signature = (UINT32 *) (&mAmlOffsetTablePointer[i].Value);
switch (*Signature) {
//
// PSYS - "FIX0" OperationRegion() in Acpi\AcpiTables\Dsdt\CommonPlatform.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '0')):
DEBUG ((DEBUG_INFO, "FIX0 - 0x%x\n", mAcpiParameter));
* (UINT32 *) DsdtPointer = (UINT32) (UINTN) mAcpiParameter;
Fixes++;
break;
//
// "FIX8" OperationRegion() in Acpi\AcpiTables\Dsdt\PcieHp.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '8')):
Stack = PCIEPortDefaults[PortCount % PORTS_PER_SOCKET].Stack;
PcieHpBus = mIioUds->IioUdsPtr->PlatformData.IIO_resource[IioBusIndex].StackRes[Stack].BusBase;
PcieHpDev = PCIEPortDefaults[PortCount % PORTS_PER_SOCKET].Device;
PcieHpFunc = PCIE_PORT_ALL_FUNC;
//DEBUG((DEBUG_ERROR,"IioBus = %x, hpDev = %x, HpFunc= %x\n",IioBusIndex, PcieHpDev,PcieHpFunc));
PciHGPEAddr &= ~(0xFFFF000); // clear bus device func numbers
BusDevFunc = (PcieHpBus << 8) | (PcieHpDev << 3) | PcieHpFunc;
* (UINT32 *) DsdtPointer = (UINT32) (UINTN) (PciHGPEAddr + (BusDevFunc << 12));
//DEBUG((DEBUG_ERROR,", BusDevFunc= %x, PortCount = %x\n",BusDevFunc, PortCount));
PortCount++;
Fixes++;
break;
default:
break;
}
} else if (mAmlOffsetTablePointer[i].Opcode == AML_INDEX_OP) {
//
// If Opcode is 0x88, then operator is WORDBusNumber() or WORDIO().
// (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURCE_ADDRESS16 to change values.
//
AmlResourceAddress16Pointer = (AML_RESOURCE_ADDRESS16 *) (DsdtPointer);
//
// The assert below confirms that AML structure matches the offsets table.
// If not then patching the AML would just corrupt it and result in OS failure.
// If you encounter this assert something went wrong in *.offset.h files
// generation. Remove the files and rebuild.
//
ASSERT(AmlResourceAddress16Pointer->DescriptorType == mAmlOffsetTablePointer[i].Opcode);
//
// Last 4 chars of AmlOffsetTable.Pathname has FIX tag.
//
Signature = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 4);
switch (*Signature) {
//
// "FIX1" BUS resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi and PCXX.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '1')):
CurrSkt = StackNumBus / MAX_IIO_STACK;
CurrStack = StackNumBus % MAX_IIO_STACK;
BusBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[CurrSkt].StackRes[CurrStack].BusBase;
BusLimit = mIioUds->IioUdsPtr->PlatformData.IIO_resource[CurrSkt].StackRes[CurrStack].BusLimit;
AmlResourceAddress16Pointer->Granularity = 0;
if (BusLimit > BusBase) {
AmlResourceAddress16Pointer->Minimum = (UINT16) BusBase;
AmlResourceAddress16Pointer->Maximum = (UINT16) BusLimit;
AmlResourceAddress16Pointer->AddressLength = (UINT16) (BusLimit - BusBase + 1);
}
//DEBUG((DEBUG_ERROR,", FIX1 BusBase = 0x%x, BusLimit = 0x%x\n",BusBase, BusLimit));
StackNumBus++;
Fixes++;
break;
//
// "FIX2" IO resource for for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi and PCXX.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '2')):
AmlResourceAddress16Pointer->Granularity = 0;
CurrSkt = StackNumIo / MAX_IIO_STACK;
CurrStack = StackNumIo % MAX_IIO_STACK;
IoBase = mIioUds->IioUdsPtr->PlatformData.IIO_resource[CurrSkt].StackRes[CurrStack].PciResourceIoBase;
IoLimit = mIioUds->IioUdsPtr->PlatformData.IIO_resource[CurrSkt].StackRes[CurrStack].PciResourceIoLimit;
if (IoLimit > IoBase) {
AmlResourceAddress16Pointer->Minimum = (UINT16) IoBase;
AmlResourceAddress16Pointer->Maximum = (UINT16) IoLimit;
AmlResourceAddress16Pointer->AddressLength = (UINT16) (IoLimit - IoBase + 1);
}
//DEBUG((DEBUG_ERROR,", FIX2 IoBase = 0x%x, IoLimit = 0x%x\n",IoBase, IoLimit));
StackNumIo++;
Fixes++;
break;
//
// "FIX6" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '6')):
AmlResourceAddress16Pointer->Granularity = 0;
CurrSkt = StackNumVgaIo0 / MAX_IIO_STACK;
CurrStack = StackNumVgaIo0 % MAX_IIO_STACK;
if ((mSocketMpLinkConfiguration.LegacyVgaSoc == CurrSkt) &&
(mSocketMpLinkConfiguration.LegacyVgaStack == CurrStack)){
AmlResourceAddress16Pointer->Minimum = (UINT16) 0x03b0;
AmlResourceAddress16Pointer->Maximum = (UINT16) 0x03bb;
AmlResourceAddress16Pointer->AddressLength = (UINT16) 0x000C;
}
StackNumVgaIo0++;
Fixes++;
break;
//
// "FIX7" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '7')):
AmlResourceAddress16Pointer->Granularity = 0;
CurrSkt = StackNumVgaIo1 / MAX_IIO_STACK;
CurrStack = StackNumVgaIo1 % MAX_IIO_STACK;
if ((mSocketMpLinkConfiguration.LegacyVgaSoc == CurrSkt) &&
(mSocketMpLinkConfiguration.LegacyVgaStack == CurrStack)) {
AmlResourceAddress16Pointer->Minimum = (UINT16) 0x03c0;
AmlResourceAddress16Pointer->Maximum = (UINT16) 0x03df;
AmlResourceAddress16Pointer->AddressLength = (UINT16) 0x0020;
}
StackNumVgaIo1++;
Fixes++;
break;
default:
break;
}
} else if (mAmlOffsetTablePointer[i].Opcode == AML_SIZE_OF_OP) {
//
// If Opcode is 0x87, then operator is DWORDMemory().
// (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURCE_ADDRESS32 to change values.
//
AmlResourceAddress32Pointer = (AML_RESOURCE_ADDRESS32 *) (DsdtPointer);
//
// The assert below confirms that AML structure matches the offsets table.
// If not then patching the AML would just corrupt it and result in OS failure.
// If you encounter this assert something went wrong in *.offset.h files
// generation. Remove the files and rebuild.
//
ASSERT(AmlResourceAddress32Pointer->DescriptorType == mAmlOffsetTablePointer[i].Opcode);
//
// Last 4 chars of AmlOffsetTable.Pathname has FIX tag.
//
Signature = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 4);
switch (*Signature) {
//
// "FIX3" PCI32 resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi and PCXX.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '3')):
AmlResourceAddress32Pointer->Granularity = 0;
CurrSkt = StackNumMem32 / MAX_IIO_STACK;
CurrStack = StackNumMem32 % MAX_IIO_STACK;
MemBase32 = mIioUds->IioUdsPtr->PlatformData.IIO_resource[CurrSkt].StackRes[CurrStack].PciResourceMem32Base;
MemLimit32 = mIioUds->IioUdsPtr->PlatformData.IIO_resource[CurrSkt].StackRes[CurrStack].PciResourceMem32Limit;
if (MemLimit32 > MemBase32) {
AmlResourceAddress32Pointer->Minimum = (UINT32) MemBase32;
AmlResourceAddress32Pointer->Maximum = (UINT32) MemLimit32;
AmlResourceAddress32Pointer->AddressLength = (UINT32) (MemLimit32 - MemBase32 + 1);
}
//DEBUG((DEBUG_ERROR,", FIX3 MemBase32 = 0x%08x, MemLimit32 = 0x%08x\n",MemBase32, MemLimit32));
StackNumMem32++;
Fixes++;
break;
//
// "FIX5" IO resource for PCXX in Acpi\AcpiTables\Dsdt\PCXX.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '5')):
AmlResourceAddress32Pointer->Granularity = 0;
CurrSkt = StackNumVgaMmioL / MAX_IIO_STACK;
CurrStack = StackNumVgaMmioL % MAX_IIO_STACK;
if ((mSocketMpLinkConfiguration.LegacyVgaSoc == CurrSkt) &&
(mSocketMpLinkConfiguration.LegacyVgaStack == CurrStack)) {
AmlResourceAddress32Pointer->Minimum = 0x000a0000;
AmlResourceAddress32Pointer->Maximum = 0x000bffff;
AmlResourceAddress32Pointer->AddressLength = 0x00020000;
}
StackNumVgaMmioL++;
Fixes++;
break;
default:
break;
}
} else if (mAmlOffsetTablePointer[i].Opcode == AML_CREATE_DWORD_FIELD_OP) {
//
// If Opcode is 0x8A, then operator is QWORDMemory().
// (TableHeader + AmlOffsetTable.Offset) must be cast to AML_RESOURCE_ADDRESS64 to change values.
//
AmlResourceAddress64Pointer = (AML_RESOURCE_ADDRESS64 *) (DsdtPointer);
//
// The assert below confirms that AML structure matches the offsets table.
// If not then patching the AML would just corrupt it and result in OS failure.
// If you encounter this assert something went wrong in *.offset.h files
// generation. Remove the files and rebuild.
//
ASSERT(AmlResourceAddress64Pointer->DescriptorType == mAmlOffsetTablePointer[i].Opcode);
//
// Last 4 chars of AmlOffsetTable.Pathname has FIX tag.
//
Signature = (UINT32 *) (mAmlOffsetTablePointer[i].Pathname + AsciiStrLen(mAmlOffsetTablePointer[i].Pathname) - 4);
switch (*Signature) {
//
// "FIX4" PCI64 resource for PCXX in Acpi\AcpiTables\Dsdt\SysBus.asi and PCXX.asi
//
case (SIGNATURE_32 ('F', 'I', 'X', '4')):
DEBUG((DEBUG_ERROR,"Pci64BitResourceAllocation = 0x%x\n",mSocketIioConfiguration.Pci64BitResourceAllocation));
if (mSocketIioConfiguration.Pci64BitResourceAllocation) {
AmlResourceAddress64Pointer->Granularity = 0;
CurrSkt = StackNumMem64 / MAX_IIO_STACK;
CurrStack = StackNumMem64 % MAX_IIO_STACK;
MemBase64 = mIioUds->IioUdsPtr->PlatformData.IIO_resource[CurrSkt].StackRes[CurrStack].PciResourceMem64Base;
MemLimit64 = mIioUds->IioUdsPtr->PlatformData.IIO_resource[CurrSkt].StackRes[CurrStack].PciResourceMem64Limit;
if (MemLimit64 > MemBase64) {
AmlResourceAddress64Pointer->Minimum = (UINT64) MemBase64;
AmlResourceAddress64Pointer->Maximum = (UINT64) MemLimit64;
AmlResourceAddress64Pointer->AddressLength = (UINT64) (MemLimit64 - MemBase64 + 1);
}
DEBUG((DEBUG_ERROR,", FIX4 MemBase64 = 0x%x, MemLimit64 = 0x%x\n",MemBase64, MemLimit64));
StackNumMem64++;
Fixes++;
}
break;
default:
break;
}
}
}
//return Status;
return EFI_SUCCESS;
}