summaryrefslogtreecommitdiff
path: root/source/compiler/dttable2.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/compiler/dttable2.c')
-rw-r--r--source/compiler/dttable2.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/source/compiler/dttable2.c b/source/compiler/dttable2.c
index cb1732d27..ff45ff113 100644
--- a/source/compiler/dttable2.c
+++ b/source/compiler/dttable2.c
@@ -425,6 +425,163 @@ DtCompileMcfg (
return (Status);
}
+/******************************************************************************
+ *
+ * FUNCTION: DtCompileMpam
+ *
+ * PARAMETERS: List - Current field list pointer
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Compile MPAM.
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+DtCompileMpam (
+ void **List)
+{
+ ACPI_STATUS Status;
+ DT_SUBTABLE *ParentTable;
+ DT_SUBTABLE *Subtable;
+ DT_FIELD *SubtableStart;
+ DT_FIELD **PFieldList = (DT_FIELD **) List;
+ ACPI_MPAM_MSC_NODE *MpamMscNode;
+ ACPI_MPAM_RESOURCE_NODE *MpamResourceNode;
+ UINT32 FuncDepsCount;
+ UINT32 RisLength;
+ ACPI_DMTABLE_INFO *InfoTable;
+
+ ParentTable = DtPeekSubtable ();
+
+ while (*PFieldList)
+ {
+ SubtableStart = *PFieldList;
+
+ /* Main MSC Node table */
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam0,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ MpamMscNode = ACPI_CAST_PTR (ACPI_MPAM_MSC_NODE, Subtable->Buffer);
+
+ ParentTable = DtPeekSubtable ();
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ ParentTable = DtPeekSubtable ();
+
+ /*
+ * RIS(es) per MSC node have variable lengths depending on how many RISes there and
+ * any how many functional dependencies per RIS. Calculate it in order
+ * to properly set the overall MSC length.
+ */
+ RisLength = 0;
+
+ /* Iterate over RIS subtables per MSC node */
+ for (int ris = 0; ris < MpamMscNode->NumResouceNodes; ris++)
+ {
+ /* Compile RIS subtable */
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1,
+ &Subtable);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ MpamResourceNode = ACPI_CAST_PTR (ACPI_MPAM_RESOURCE_NODE, Subtable->Buffer);
+ DtInsertSubtable (ParentTable, Subtable);
+ DtPushSubtable (Subtable);
+
+ ParentTable = DtPeekSubtable ();
+
+ 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:
+ DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "Resource Locator Type");
+ return (AE_ERROR);
+ }
+
+ /* Compile Resource Locator Table */
+ Status = DtCompileTable (PFieldList, InfoTable,
+ &Subtable);
+
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+
+ /* Compile the number of functional dependencies per RIS */
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam1Deps,
+ &Subtable);
+
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ FuncDepsCount = *ACPI_CAST_PTR (UINT32, Subtable->Buffer);
+
+ RisLength += sizeof(ACPI_MPAM_RESOURCE_NODE) +
+ FuncDepsCount * sizeof(ACPI_MPAM_FUNC_DEPS);
+
+ /* Iterate over functional dependencies per RIS */
+ for (int funcDep = 0; funcDep < FuncDepsCount; funcDep++)
+ {
+ /* Compiler functional dependencies table */
+ Status = DtCompileTable (PFieldList, AcpiDmTableInfoMpam2,
+ &Subtable);
+
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+
+ DtInsertSubtable (ParentTable, Subtable);
+ }
+
+ DtPopSubtable ();
+ }
+
+ /* Check if the length of the MSC is correct and override with the correct length */
+ if (MpamMscNode->Length != sizeof(ACPI_MPAM_MSC_NODE) + RisLength)
+ {
+ MpamMscNode->Length = sizeof(ACPI_MPAM_MSC_NODE) + RisLength;
+ DbgPrint (ASL_DEBUG_OUTPUT, "Overriding MSC->Length: %X\n", MpamMscNode->Length);
+ }
+
+ DtPopSubtable ();
+ }
+
+ return (AE_OK);
+}
+
/******************************************************************************
*