aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Zhang <jonzhang@fb.com>2022-05-11 13:11:20 -0700
committerMartin L Roth <gaumless@gmail.com>2022-11-20 17:35:04 +0000
commit3dcafa8774f215e75b2d13157c1431339e33146c (patch)
tree11ca21e52e8309ba69c781c855e0ba808e671e82 /src
parentb7f92a0b6a0f776d00cf7843156034c22f403c78 (diff)
acpi: Add initial support for CEDT
Add initial CEDT (CXL Early Discovery Table) support based on CXL spec 2.0 section 9.14.1. Add functions to create CEDT table (revision 1), and create CEDT CXL Host Bridge Structure (CHBS) and CXL Fixed Memory Windows Structure (CFMWS). TESTED=Create CEDT table on Intel Archer City CRB, dumped the CEDT table and examined the content. Signed-off-by: Jonathan Zhang <jonzhang@fb.com> Change-Id: I4fbce78efc86ad9f2468c37b4827a6dadbdc6802 Reviewed-on: https://review.coreboot.org/c/coreboot/+/64263 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-by: Marc Jones <marc@marcjonesconsulting.com>
Diffstat (limited to 'src')
-rw-r--r--src/acpi/acpi.c84
-rw-r--r--src/include/acpi/acpi.h67
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);