summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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);