src/acpi: Add initial support for HMAT
Add initial HMAT (Heterogeneous Memory Attribute Table) support based on ACPI spec 6.4 section 5.2.27. Add functions to create HMAT table (revision 2) and create HMAT Memory Proximity Domain Attribute (MPDA) Structure. TESTED=Simulated HMAT table creation on OCP DeltaLake server, dumped the HMAT table and exmained the content. HMAT table and one MPDA structure are added. OCP Delatake server is based on Intel CooperLake Scalable Processor which does not support CXL (Compute Express Link). Therefore solution level testing is not done. Signed-off-by: Jonathan Zhang <jonzhang@fb.com> Change-Id: I5ee60ff990c3cea799c5cbdf7eead818b1bb4f9b Reviewed-on: https://review.coreboot.org/c/coreboot/+/52047 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
parent
08ba703791
commit
2a4e1f4b47
|
@ -539,6 +539,51 @@ void acpi_create_srat(acpi_srat_t *srat,
|
||||||
header->checksum = acpi_checksum((void *)srat, header->length);
|
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,
|
void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags,
|
||||||
unsigned long (*acpi_fill_dmar)(unsigned long))
|
unsigned long (*acpi_fill_dmar)(unsigned long))
|
||||||
{
|
{
|
||||||
|
@ -1880,6 +1925,8 @@ int get_acpi_table_revision(enum acpi_tables table)
|
||||||
return 2;
|
return 2;
|
||||||
case SRAT: /* ACPI 2.0: 1, ACPI 3.0: 2, ACPI 4.0 upto 6.3: 3 */
|
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 */
|
return 1; /* TODO Should probably be upgraded to 2 */
|
||||||
|
case HMAT: /* ACPI 6.4: 2 */
|
||||||
|
return 2;
|
||||||
case DMAR:
|
case DMAR:
|
||||||
return 1;
|
return 1;
|
||||||
case SLIT: /* ACPI 2.0 upto 6.3: 1 */
|
case SLIT: /* ACPI 2.0 upto 6.3: 1 */
|
||||||
|
|
|
@ -71,8 +71,8 @@ enum coreboot_acpi_ids {
|
||||||
|
|
||||||
enum acpi_tables {
|
enum acpi_tables {
|
||||||
/* Tables defined by ACPI and used by coreboot */
|
/* Tables defined by ACPI and used by coreboot */
|
||||||
BERT, DBG2, DMAR, DSDT, EINJ, FACS, FADT, HEST, HPET, IVRS, MADT, MCFG,
|
BERT, DBG2, DMAR, DSDT, EINJ, FACS, FADT, HEST, HMAT, HPET, IVRS, MADT,
|
||||||
RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT, LPIT,
|
MCFG, RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT, LPIT,
|
||||||
/* Additional proprietary tables used by coreboot */
|
/* Additional proprietary tables used by coreboot */
|
||||||
VFCT, NHLT, SPMI, CRAT
|
VFCT, NHLT, SPMI, CRAT
|
||||||
};
|
};
|
||||||
|
@ -208,6 +208,71 @@ typedef struct acpi_mcfg_mmconfig {
|
||||||
u8 reserved[4];
|
u8 reserved[4];
|
||||||
} __packed acpi_mcfg_mmconfig_t;
|
} __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) */
|
/* SRAT (System Resource Affinity Table) */
|
||||||
typedef struct acpi_srat {
|
typedef struct acpi_srat {
|
||||||
acpi_header_t header;
|
acpi_header_t header;
|
||||||
|
@ -1162,6 +1227,16 @@ void acpi_create_srat(acpi_srat_t *srat,
|
||||||
void acpi_create_slit(acpi_slit_t *slit,
|
void acpi_create_slit(acpi_slit_t *slit,
|
||||||
unsigned long (*acpi_fill_slit)(unsigned long current));
|
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,
|
void acpi_create_vfct(const struct device *device,
|
||||||
acpi_vfct_t *vfct,
|
acpi_vfct_t *vfct,
|
||||||
unsigned long (*acpi_fill_vfct)(const struct device *device,
|
unsigned long (*acpi_fill_vfct)(const struct device *device,
|
||||||
|
|
Loading…
Reference in New Issue