diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/acpi/acpi.c | 84 | ||||
-rw-r--r-- | src/include/acpi/acpi.h | 67 |
2 files changed, 149 insertions, 2 deletions
diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index e1d40881c2..8d81284ced 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -575,6 +575,90 @@ void acpi_create_srat(acpi_srat_t *srat, header->checksum = acpi_checksum((void *)srat, header->length); } +int acpi_create_cedt_chbs(acpi_cedt_chbs_t *chbs, u32 uid, u32 cxl_ver, u64 base) +{ + memset((void *)chbs, 0, sizeof(acpi_cedt_chbs_t)); + + chbs->type = ACPI_CEDT_STRUCTURE_CHBS; + chbs->length = sizeof(acpi_cedt_chbs_t); + chbs->uid = uid; + chbs->cxl_ver = cxl_ver; + chbs->base = base; + + /* + * CXL spec 2.0 section 9.14.1.2 "CXL CHBS" + * CXL 1.1 spec compliant host bridge: 8KB + * CXL 2.0 spec compliant host bridge: 64KB + */ + if (cxl_ver == ACPI_CEDT_CHBS_CXL_VER_1_1) + chbs->len = 8 * KiB; + else if (cxl_ver == ACPI_CEDT_CHBS_CXL_VER_2_0) + chbs->len = 64 * KiB; + else + printk(BIOS_ERR, "ACPI(%s:%s): Incorrect CXL version:%d\n", __FILE__, __func__, + cxl_ver); + + return chbs->length; +} + +int acpi_create_cedt_cfmws(acpi_cedt_cfmws_t *cfmws, u64 base_hpa, u64 window_size, u8 eniw, + u32 hbig, u16 restriction, u16 qtg_id, const u32 *interleave_target) +{ + memset((void *)cfmws, 0, sizeof(acpi_cedt_cfmws_t)); + + cfmws->type = ACPI_CEDT_STRUCTURE_CFMWS; + + u8 niw = 0; + if (eniw >= 8) + printk(BIOS_ERR, "ACPI(%s:%s): Incorrect eniw::%d\n", __FILE__, __func__, eniw); + else + /* NIW = 2 ** ENIW */ + niw = 0x1 << eniw; + /* 36 + 4 * NIW */ + cfmws->length = sizeof(acpi_cedt_cfmws_t) + 4 * niw; + + cfmws->base_hpa = base_hpa; + cfmws->window_size = window_size; + cfmws->eniw = eniw; + + // 0: Standard Modulo Arithmetic. Other values reserved. + cfmws->interleave_arithmetic = 0; + + cfmws->hbig = hbig; + cfmws->restriction = restriction; + cfmws->qtg_id = qtg_id; + memcpy(&cfmws->interleave_target, interleave_target, 4 * niw); + + return cfmws->length; +} + +void acpi_create_cedt(acpi_cedt_t *cedt, unsigned long (*acpi_fill_cedt)(unsigned long current)) +{ + acpi_header_t *header = &(cedt->header); + unsigned long current = (unsigned long)cedt + sizeof(acpi_cedt_t); + + memset((void *)cedt, 0, sizeof(acpi_cedt_t)); + + if (!header) + return; + + /* Fill out header fields. */ + memcpy(header->signature, "CEDT", 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_cedt_t); + header->revision = get_acpi_table_revision(CEDT); + + current = acpi_fill_cedt(current); + + /* (Re)calculate length and checksum. */ + header->length = current - (unsigned long)cedt; + header->checksum = acpi_checksum((void *)cedt, 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)); diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h index d7fc243c11..fa216aab59 100644 --- a/src/include/acpi/acpi.h +++ b/src/include/acpi/acpi.h @@ -72,8 +72,8 @@ enum coreboot_acpi_ids { enum acpi_tables { /* Tables defined by ACPI and used by coreboot */ - BERT, DBG2, DMAR, DSDT, EINJ, FACS, FADT, HEST, HMAT, HPET, IVRS, MADT, - MCFG, RSDP, RSDT, SLIT, SRAT, SSDT, TCPA, TPM2, XSDT, ECDT, LPIT, + BERT, CEDT, 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 }; @@ -222,6 +222,60 @@ typedef struct acpi_mcfg_mmconfig { } __packed acpi_mcfg_mmconfig_t; /* + * CEDT (CXL Early Discovery Table) + * CXL spec 2.0 section 9.14.1 + */ +typedef struct acpi_cedt { + acpi_header_t header; + /* Followed by CEDT structures[n] */ +} __packed acpi_cedt_t; + +#define ACPI_CEDT_STRUCTURE_CHBS 0 +#define ACPI_CEDT_STRUCTURE_CFMWS 1 + +#define ACPI_CEDT_CHBS_CXL_VER_1_1 0x00 +#define ACPI_CEDT_CHBS_CXL_VER_2_0 0x01 + +/* CHBS: CXL Host Bridge Structure */ +typedef struct acpi_cedt_chbs { + u8 type; /* Always 0, other values reserved */ + u8 resv1; + u16 length; /* Length in bytes (32) */ + u32 uid; /* CXL Host Bridge Unique ID */ + u32 cxl_ver; + u32 resv2; + /* + * For CXL 1.1, the base is Downstream Port Root Complex Resource Block; + * For CXL 2.0, the base is CXL Host Bridge Component Registers. + */ + u64 base; + u64 len; +} __packed acpi_cedt_chbs_t; + +#define ACPI_CEDT_CFMWS_RESTRICTION_TYPE_2_MEM (1 << 0) +#define ACPI_CEDT_CFMWS_RESTRICTION_TYPE_3_MEM (1 << 1) +#define ACPI_CEDT_CFMWS_RESTRICTION_VOLATIL (1 << 2) +#define ACPI_CEDT_CFMWS_RESTRICTION_PERSISTENT (1 << 3) +#define ACPI_CEDT_CFMWS_RESTRICTION_FIXED (1 << 4) + +/* CFMWS: CXL Fixed Memory Window Structure */ +typedef struct acpi_cedt_cfmws { + u8 type; /* Type (0) */ + u8 resv1; + u16 length; /* Length in bytes (32) */ + u32 resv2; + u64 base_hpa; /* Base of the HPA range, 256MB aligned */ + u64 window_size; /* Number of bytes this window represents */ + u8 eniw; /* Encoded Number of Interleave Ways */ + u8 interleave_arithmetic; /* Standard Modulo arithmetic (0) */ + u16 resv3; + u32 hbig; /* Host Bridge Interleave Granularity */ + u16 restriction; + u16 qtg_id; + u32 interleave_target[]; /* Interleave Target List */ +} __packed acpi_cedt_cfmws_t; + +/* * HMAT (Heterogeneous Memory Attribute Table) * ACPI spec 6.4 section 5.2.27 */ @@ -1260,6 +1314,15 @@ u8 acpi_checksum(u8 *table, u32 length); void acpi_add_table(acpi_rsdp_t *rsdp, void *table); +/* Create CXL Early Discovery Table */ +void acpi_create_cedt(acpi_cedt_t *cedt, + unsigned long (*acpi_fill_cedt)(unsigned long current)); +/* Create a CXL Host Bridge Structure for CEDT */ +int acpi_create_cedt_chbs(acpi_cedt_chbs_t *chbs, u32 uid, u32 cxl_ver, u64 base); +/* Create a CXL Fixed Memory Window Structure for CEDT */ +int acpi_create_cedt_cfmws(acpi_cedt_cfmws_t *cfmws, u64 base_hpa, u64 window_size, + u8 eniw, u32 hbig, u16 restriction, u16 qtg_id, const u32 *interleave_target); + int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic); int acpi_create_madt_ioapic(acpi_madt_ioapic_t *ioapic, u8 id, u32 addr, u32 gsi_base); |