diff options
-rw-r--r-- | src/acpi/acpi.c | 47 | ||||
-rw-r--r-- | src/include/acpi/acpi.h | 79 |
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, |