summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/acpi/acpi.c47
-rw-r--r--src/include/acpi/acpi.h79
2 files changed, 124 insertions, 2 deletions
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c
index 5c3fe13614..35c5ec3602 100644
--- a/src/acpi/acpi.c
+++ b/src/acpi/acpi.c
@@ -539,6 +539,51 @@ void acpi_create_srat(acpi_srat_t *srat,
header->checksum = acpi_checksum((void *)srat, header->length);
}
+int acpi_create_hmat_mpda(acpi_hmat_mpda_t *mpda, u32 initiator, u32 memory)
+{
+ memset((void *)mpda, 0, sizeof(acpi_hmat_mpda_t));
+
+ mpda->type = 0; /* Memory Proximity Domain Attributes structure */
+ mpda->length = sizeof(acpi_hmat_mpda_t);
+ /*
+ * Proximity Domain for Attached Initiator field is valid.
+ * Bit 1 and bit 2 are reserved since HMAT revision 2.
+ */
+ mpda->flags = (1 << 0);
+ mpda->proximity_domain_initiator = initiator;
+ mpda->proximity_domain_memory = memory;
+
+ return mpda->length;
+}
+
+void acpi_create_hmat(acpi_hmat_t *hmat,
+ unsigned long (*acpi_fill_hmat)(unsigned long current))
+{
+ acpi_header_t *header = &(hmat->header);
+ unsigned long current = (unsigned long)hmat + sizeof(acpi_hmat_t);
+
+ memset((void *)hmat, 0, sizeof(acpi_hmat_t));
+
+ if (!header)
+ return;
+
+ /* Fill out header fields. */
+ memcpy(header->signature, "HMAT", 4);
+ memcpy(header->oem_id, OEM_ID, 6);
+ memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+ memcpy(header->asl_compiler_id, ASLC, 4);
+
+ header->asl_compiler_revision = asl_revision;
+ header->length = sizeof(acpi_hmat_t);
+ header->revision = get_acpi_table_revision(HMAT);
+
+ current = acpi_fill_hmat(current);
+
+ /* (Re)calculate length and checksum. */
+ header->length = current - (unsigned long)hmat;
+ header->checksum = acpi_checksum((void *)hmat, header->length);
+}
+
void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
unsigned long (*acpi_fill_dmar)(unsigned long))
{
@@ -1880,6 +1925,8 @@ int get_acpi_table_revision(enum acpi_tables table)
return 2;
case SRAT: /* ACPI 2.0: 1, ACPI 3.0: 2, ACPI 4.0 upto 6.3: 3 */
return 1; /* TODO Should probably be upgraded to 2 */
+ case HMAT: /* ACPI 6.4: 2 */
+ return 2;
case DMAR:
return 1;
case SLIT: /* ACPI 2.0 upto 6.3: 1 */
diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h
index b266acf1e2..6aa6cb86e2 100644
--- a/src/include/acpi/acpi.h
+++ b/src/include/acpi/acpi.h
@@ -71,8 +71,8 @@ enum coreboot_acpi_ids {
enum acpi_tables {
/* Tables defined by ACPI and used by coreboot */
- BERT, DBG2, DMAR, DSDT, EINJ, FACS, FADT, HEST, HPET, IVRS, MADT, MCFG,
- RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT, LPIT,
+ BERT, DBG2, DMAR, DSDT, EINJ, FACS, FADT, HEST, HMAT, HPET, IVRS, MADT,
+ MCFG, RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT, LPIT,
/* Additional proprietary tables used by coreboot */
VFCT, NHLT, SPMI, CRAT
};
@@ -208,6 +208,71 @@ typedef struct acpi_mcfg_mmconfig {
u8 reserved[4];
} __packed acpi_mcfg_mmconfig_t;
+/*
+ * HMAT (Heterogeneous Memory Attribute Table)
+ * ACPI spec 6.4 section 5.2.27
+ */
+typedef struct acpi_hmat {
+ acpi_header_t header;
+ u32 resv;
+ /* Followed by HMAT table structure[n] */
+} __packed acpi_hmat_t;
+
+/* HMAT: Memory Proximity Domain Attributes structure */
+typedef struct acpi_hmat_mpda {
+ u16 type; /* Type (0) */
+ u16 resv;
+ u32 length; /* Length in bytes (40) */
+ u16 flags;
+ u16 resv1;
+ u32 proximity_domain_initiator;
+ u32 proximity_domain_memory;
+ u32 resv2;
+ u64 resv3;
+ u64 resv4;
+} __packed acpi_hmat_mpda_t;
+
+/* HMAT: System Locality Latency and Bandwidth Information structure */
+typedef struct acpi_hmat_sllbi {
+ u16 type; /* Type (1) */
+ u16 resv;
+ u32 length; /* Length in bytes */
+ u8 flags;
+ u8 data_type;
+ /*
+ * Transfer size defined as a 5-biased power of 2 exponent,
+ * when the bandwidth/latency value is achieved.
+ */
+ u8 min_transfer_size;
+ u8 resv1;
+ u32 num_initiator_domains;
+ u32 num_target_domains;
+ u32 resv2;
+ u64 entry_base_unit;
+ /* Followed by initiator proximity domain list */
+ /* Followed by target proximity domain list */
+ /* Followed by latency / bandwidth values */
+} __packed acpi_hmat_sllbi_t;
+
+/* HMAT: Memory Side Cache Information structure */
+typedef struct acpi_hmat_msci {
+ u16 type; /* Type (2) */
+ u16 resv;
+ u32 length; /* Length in bytes */
+ u32 domain; /* Proximity domain for the memory */
+ u32 resv1;
+ u64 cache_size;
+ /* Describes level, associativity, write policy, cache line size */
+ u32 cache_attributes;
+ u16 resv2;
+ /*
+ * Number of SMBIOS handlers that contribute to the
+ * memory side cache physical devices
+ */
+ u16 num_handlers;
+ /* Followed by SMBIOS handlers*/
+} __packed acpi_hmat_msci_t;
+
/* SRAT (System Resource Affinity Table) */
typedef struct acpi_srat {
acpi_header_t header;
@@ -1162,6 +1227,16 @@ void acpi_create_srat(acpi_srat_t *srat,
void acpi_create_slit(acpi_slit_t *slit,
unsigned long (*acpi_fill_slit)(unsigned long current));
+/*
+ * Create a Memory Proximity Domain Attributes structure for HMAT,
+ * given proximity domain for the attached initiaor, and
+ * proximimity domain for the memory.
+ */
+int acpi_create_hmat_mpda(acpi_hmat_mpda_t *mpda, u32 initiator, u32 memory);
+/* Create Heterogenous Memory Attribute Table */
+void acpi_create_hmat(acpi_hmat_t *hmat,
+ unsigned long (*acpi_fill_hmat)(unsigned long current));
+
void acpi_create_vfct(const struct device *device,
acpi_vfct_t *vfct,
unsigned long (*acpi_fill_vfct)(const struct device *device,