Skip to content

Commit

Permalink
Add support for Arm's MPAM ACPI table version 2
Browse files Browse the repository at this point in the history
Complies with ACPI for Memory System Resource Partitioning and
Monitoring 2.0 [1]. Document number: DEN0065, as of December 2022.

Support for all types of MPAM resources. No support yet for:
1) MPAM PCC Interface Type
2) The optional Resource-specific data per MSC node, introduced in v2 of the
MPAM ACPI spec.

[1] https://developer.arm.com/documentation/den0065/latest

Signed-off-by: Hesham Almatary <hesham.almatary@huawei.com>
  • Loading branch information
hesham-huawei committed Jan 31, 2023
1 parent d9a0d78 commit 005e24b
Show file tree
Hide file tree
Showing 12 changed files with 629 additions and 0 deletions.
1 change: 1 addition & 0 deletions source/common/ahtable.c
Expand Up @@ -232,6 +232,7 @@ const AH_TABLE AcpiGbl_SupportedTables[] =
{ACPI_SIG_MADT, "Multiple APIC Description Table (MADT)"},
{ACPI_SIG_MCFG, "Memory Mapped Configuration Table"},
{ACPI_SIG_MCHI, "Management Controller Host Interface Table"},
{ACPI_SIG_MPAM, "Memory System Resource Partitioning and Monitoring Table"},
{ACPI_SIG_MPST, "Memory Power State Table"},
{ACPI_SIG_MSCT, "Maximum System Characteristics Table"},
{ACPI_SIG_MSDM, "Microsoft Data Management Table"},
Expand Down
27 changes: 27 additions & 0 deletions source/common/dmtable.c
Expand Up @@ -425,6 +425,17 @@ static const char *AcpiDmMadtSubnames[] =
"Types 80-FF are used for OEM data" /* Reserved for OEM data */
};

static const char *AcpiDmMpamSubnames[] =
{
"Processor cache", /* ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE */
"Memory", /* ACPI_MPAM_LOCATION_TYPE_MEMORY */
"SMMU", /* ACPI_MPAM_LOCATION_TYPE_SMMU */
"Memory-side cache", /* ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE */
"ACPI device", /* ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE */
"Interconnect", /* ACPI_MPAM_LOCATION_TYPE_INTERCONNECT */
"Unknown" /* ACPI_MPAM_LOCATION_TYPE_UNKNOWN */
};

static const char *AcpiDmNfitSubnames[] =
{
"System Physical Address Range", /* ACPI_NFIT_TYPE_SYSTEM_ADDRESS */
Expand Down Expand Up @@ -700,6 +711,7 @@ const ACPI_DMTABLE_DATA AcpiDmTableData[] =
{ACPI_SIG_MADT, NULL, AcpiDmDumpMadt, DtCompileMadt, TemplateMadt},
{ACPI_SIG_MCFG, NULL, AcpiDmDumpMcfg, DtCompileMcfg, TemplateMcfg},
{ACPI_SIG_MCHI, AcpiDmTableInfoMchi, NULL, NULL, TemplateMchi},
{ACPI_SIG_MPAM, NULL, AcpiDmDumpMpam, DtCompileMpam, TemplateMpam},
{ACPI_SIG_MPST, AcpiDmTableInfoMpst, AcpiDmDumpMpst, DtCompileMpst, TemplateMpst},
{ACPI_SIG_MSCT, NULL, AcpiDmDumpMsct, DtCompileMsct, TemplateMsct},
{ACPI_SIG_MSDM, NULL, AcpiDmDumpSlic, DtCompileSlic, TemplateMsdm},
Expand Down Expand Up @@ -1128,6 +1140,7 @@ AcpiDmDumpTable (
case ACPI_DMT_IVRS_DE:
case ACPI_DMT_GTDT:
case ACPI_DMT_MADT:
case ACPI_DMT_MPAM_LOCATOR:
case ACPI_DMT_NHLT1:
case ACPI_DMT_NHLT1a:
case ACPI_DMT_NHLT1b:
Expand Down Expand Up @@ -1890,6 +1903,20 @@ AcpiDmDumpTable (
AcpiDmMadtSubnames[Temp8]);
break;

case ACPI_DMT_MPAM_LOCATOR:

/* MPAM subtable locator types */

Temp8 = *Target;
if (Temp8 > ACPI_MPAM_LOCATION_TYPE_INTERCONNECT)
{
Temp8 = ACPI_MPAM_LOCATION_TYPE_INTERCONNECT + 1;
}

AcpiOsPrintf (UINT8_FORMAT, *Target,
AcpiDmMpamSubnames[Temp8]);
break;

case ACPI_DMT_NFIT:

/* NFIT subtable types */
Expand Down
118 changes: 118 additions & 0 deletions source/common/dmtbdump2.c
Expand Up @@ -1129,6 +1129,124 @@ AcpiDmDumpMcfg (
}
}

/*******************************************************************************
*
* FUNCTION: AcpiDmDumpMpam
*
* PARAMETERS: Table - A MPAM table
*
* RETURN: None
*
* DESCRIPTION: Format the contents of a MPAM table
*
******************************************************************************/

void
AcpiDmDumpMpam (
ACPI_TABLE_HEADER *Table)
{
ACPI_STATUS Status;
ACPI_MPAM_MSC_NODE *MpamMscNode;
ACPI_MPAM_RESOURCE_NODE *MpamResourceNode;
ACPI_DMTABLE_INFO *InfoTable;
UINT32 Offset = sizeof(ACPI_TABLE_HEADER);
UINT32 MpamResourceNodeLength = 0;

while (Offset < Table->Length)
{
MpamMscNode = ACPI_ADD_PTR (ACPI_MPAM_MSC_NODE, Table, Offset);

/* Subtable: MSC */
Status = AcpiDmDumpTable (MpamMscNode->Length, 0, MpamMscNode, 0,
AcpiDmTableInfoMpam0);
if (ACPI_FAILURE (Status))
{
return;
}

/* Offset the start of the array of resources */
Offset += sizeof(ACPI_MPAM_MSC_NODE);

/* Subtable: MSC RIS(es) */
for (int ResourceIdx = 0; ResourceIdx < MpamMscNode->NumResouceNodes; ResourceIdx++)
{
MpamResourceNode = ACPI_ADD_PTR (ACPI_MPAM_RESOURCE_NODE, Table, Offset);

MpamResourceNodeLength = sizeof(ACPI_MPAM_RESOURCE_NODE) +
MpamResourceNode->NumFunctionalDeps * sizeof(ACPI_MPAM_FUNC_DEPS);

Offset += MpamResourceNodeLength;

/* Subtable: MSC RIS */
Status = AcpiDmDumpTable (MpamResourceNodeLength, 0, MpamResourceNode, 0,
AcpiDmTableInfoMpam1);
if (ACPI_FAILURE (Status))
{
return;
}

switch (MpamResourceNode->LocatorType)
{
case ACPI_MPAM_LOCATION_TYPE_PROCESSOR_CACHE:
InfoTable = AcpiDmTableInfoMpam1A;
break;
case ACPI_MPAM_LOCATION_TYPE_MEMORY:
InfoTable = AcpiDmTableInfoMpam1B;
break;
case ACPI_MPAM_LOCATION_TYPE_SMMU:
InfoTable = AcpiDmTableInfoMpam1C;
break;
case ACPI_MPAM_LOCATION_TYPE_MEMORY_CACHE:
InfoTable = AcpiDmTableInfoMpam1D;
break;
case ACPI_MPAM_LOCATION_TYPE_ACPI_DEVICE:
InfoTable = AcpiDmTableInfoMpam1E;
break;
case ACPI_MPAM_LOCATION_TYPE_INTERCONNECT:
InfoTable = AcpiDmTableInfoMpam1F;
break;
case ACPI_MPAM_LOCATION_TYPE_UNKNOWN:
InfoTable = AcpiDmTableInfoMpam1G;
default:
AcpiOsPrintf ("\n**** Unknown MPAM locator type 0x%X\n",
MpamResourceNode->LocatorType);
return;
}

/* Subtable: MSC Resource Locator(s) */
Status = AcpiDmDumpTable (sizeof(ACPI_MPAM_RESOURCE_LOCATOR), 0,
&MpamResourceNode->Locator, 0, InfoTable);
if (ACPI_FAILURE (Status))
{
return;
}

/* Get the number of functional dependencies of an RIS */
Status = AcpiDmDumpTable (sizeof(UINT32), 0, &MpamResourceNode->NumFunctionalDeps, 0,
AcpiDmTableInfoMpam1Deps);
if (ACPI_FAILURE (Status))
{
return;
}

/* Subtable: MSC functional dependencies */
for (int funcDep = 0; funcDep < MpamResourceNode->NumFunctionalDeps; funcDep++)
{
Status = AcpiDmDumpTable (sizeof(ACPI_MPAM_FUNC_DEPS), 0,
&MpamResourceNode->NumFunctionalDeps, 0, AcpiDmTableInfoMpam2);
if (ACPI_FAILURE (Status))
{
return;
}
}

AcpiOsPrintf ("\n\n");
}

}

return;
}

/*******************************************************************************
*
Expand Down
127 changes: 127 additions & 0 deletions source/common/dmtbinfo2.c
Expand Up @@ -979,6 +979,133 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMchi[] =
ACPI_DMT_TERMINATOR
};

/*******************************************************************************
*
* MPAM - Memory System Resource Partitioning and Monitoring Tables
* Arm's DEN0065 MPAM ACPI 2.0. December 2022.
******************************************************************************/

/* MPAM subtables */

/* 0: MPAM Resource Node Structure - A root MSC table.
* Arm's DEN0065 MPAM ACPI 2.0. Table 4: MPAM MSC node body.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam0[] =
{
{ACPI_DMT_UINT16, ACPI_MPAM0_OFFSET (Length), "Length", 0},
{ACPI_DMT_UINT8, ACPI_MPAM0_OFFSET (InterfaceType), "Interface type", 0},
{ACPI_DMT_UINT8, ACPI_MPAM0_OFFSET (Reserved), "Reserved", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (Identifier), "Identifier", 0},
{ACPI_DMT_UINT64, ACPI_MPAM0_OFFSET (BaseAddress), "Base address", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (MMIOSize), "MMIO size", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (OverflowInterrupt), "Overflow interrupt", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (OverflowInterruptFlags), "Overflow interrupt flags", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (Reserved1), "Reserved1", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (OverflowInterruptAffinity), "Overflow interrupt affinity", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (ErrorInterrupt), "Error interrupt", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (ErrorInterruptFlags), "Error interrupt flags", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (Reserved2), "Reserved2", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (ErrorInterruptAffinity), "Error interrupt affinity", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (MaxNrdyUsec), "MAX_NRDY_USEC", 0},
{ACPI_DMT_NAME8, ACPI_MPAM0_OFFSET (HardwareIdLinkedDevice), "Hardware ID of linked device", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (InstanceIdLinkedDevice), "Instance ID of linked device", 0},
{ACPI_DMT_UINT32, ACPI_MPAM0_OFFSET (NumResouceNodes), "Number of resource nodes", 0},

ACPI_DMT_TERMINATOR
};

/* 1: MPAM Resource (RIS) Node Structure - A subtable of MSC Nodes.
* Arm's DEN0065 MPAM ACPI 2.0. Table 9: Resource node.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1[] =
{
{ACPI_DMT_UINT32, ACPI_MPAM1_OFFSET (Identifier), "Identifier", 0},
{ACPI_DMT_UINT8, ACPI_MPAM1_OFFSET (RISIndex), "RIS Index", 0},
{ACPI_DMT_UINT16, ACPI_MPAM1_OFFSET (Reserved1), "Reserved1", 0},
{ACPI_DMT_MPAM_LOCATOR, ACPI_MPAM1_OFFSET (LocatorType), "Locator type", 0},
ACPI_DMT_TERMINATOR
};

/* An RIS field part of the RIS subtable */
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1Deps[] =
{
{ACPI_DMT_UINT32, 0, "Number of functional dependencies", 0},
ACPI_DMT_TERMINATOR
};

/* 1A: MPAM Processor cache locator descriptor. A subtable of RIS.
* Arm's DEN0065 MPAM ACPI 2.0. Table 13.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1A[] =
{
{ACPI_DMT_UINT64, ACPI_MPAM1A_OFFSET (CacheReference), "Cache reference", 0},
{ACPI_DMT_UINT32, ACPI_MPAM1A_OFFSET (Reserved), "Reserved", 0},
};

/* 1B: MPAM Memory locator descriptor. A subtable of RIS.
* Arm's DEN0065 MPAM ACPI 2.0. Table 14.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1B[] =
{
{ACPI_DMT_UINT64, ACPI_MPAM1B_OFFSET (ProximityDomain), "Proximity domain", 0},
{ACPI_DMT_UINT32, ACPI_MPAM1B_OFFSET (Reserved), "Reserved", 0},
};

/* 1C: MPAM SMMU locator descriptor. A subtable of RIS.
* Arm's DEN0065 MPAM ACPI 2.0. Table 15.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1C[] =
{
{ACPI_DMT_UINT64, ACPI_MPAM1C_OFFSET (SmmuInterface), "SMMU Interface", 0},
{ACPI_DMT_UINT32, ACPI_MPAM1C_OFFSET (Reserved), "Reserved", 0},
};

/* 1D: MPAM Memory-side cache locator descriptor. A subtable of RIS.
* Arm's DEN0065 MPAM ACPI 2.0. Table 16.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1D[] =
{
{ACPI_DMT_UINT56, ACPI_MPAM1D_OFFSET (Level), "Reserved", 0},
{ACPI_DMT_UINT8, ACPI_MPAM1D_OFFSET (Level), "Level", 0},
{ACPI_DMT_UINT32, ACPI_MPAM1D_OFFSET (Reference), "Reference", 0},
};

/* 1E: MPAM ACPI device locator descriptor. A subtable of RIS.
* Arm's DEN0065 MPAM ACPI 2.0. Table 17.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1E[] =
{
{ACPI_DMT_UINT64, ACPI_MPAM1E_OFFSET (AcpiHwId), "ACPI Hardware ID", 0},
{ACPI_DMT_UINT32, ACPI_MPAM1E_OFFSET (AcpiUniqueId), "ACPI Unique ID", 0},
};

/* 1F: MPAM Interconnect locator descriptor. A subtable of RIS.
* Arm's DEN0065 MPAM ACPI 2.0. Table 18.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1F[] =
{
{ACPI_DMT_UINT64, ACPI_MPAM1F_OFFSET (InterConnectDescTblOff), "Interconnect descriptor table offset", 0},
{ACPI_DMT_UINT32, ACPI_MPAM1F_OFFSET (Reserved), "Reserved", 0},
};

/* 1G: MPAM Locator structure.
* Arm's DEN0065 MPAM ACPI 2.0. Table 12.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam1G[] =
{
{ACPI_DMT_UINT64, ACPI_MPAM1G_OFFSET (Descriptor1), "Descriptor1", 0},
{ACPI_DMT_UINT32, ACPI_MPAM1G_OFFSET (Descriptor2), "Descriptor2", 0},
};

/* 2: MPAM Functional dependency descriptor.
* Arm's DEN0065 MPAM ACPI 2.0. Table 10.
*/
ACPI_DMTABLE_INFO AcpiDmTableInfoMpam2[] =
{
{ACPI_DMT_UINT32, ACPI_MPAM2_OFFSET (Producer), "Producer", 0},
{ACPI_DMT_UINT32, ACPI_MPAM2_OFFSET (Reserved), "Reserved", 0},
};


/*******************************************************************************
*
Expand Down
5 changes: 5 additions & 0 deletions source/compiler/dtcompiler.h
Expand Up @@ -653,6 +653,10 @@ ACPI_STATUS
DtCompileMcfg (
void **PFieldList);

ACPI_STATUS
DtCompileMpam (
void **PFieldList);

ACPI_STATUS
DtCompileMpst (
void **PFieldList);
Expand Down Expand Up @@ -801,6 +805,7 @@ extern const unsigned char TemplateLpit[];
extern const unsigned char TemplateMadt[];
extern const unsigned char TemplateMcfg[];
extern const unsigned char TemplateMchi[];
extern const unsigned char TemplateMpam[];
extern const unsigned char TemplateMpst[];
extern const unsigned char TemplateMsct[];
extern const unsigned char TemplateMsdm[];
Expand Down

0 comments on commit 005e24b

Please sign in to comment.