diff --git a/src/arch/x86/boot/acpi.c b/src/arch/x86/boot/acpi.c index 48260fc162..a7a638ffa4 100644 --- a/src/arch/x86/boot/acpi.c +++ b/src/arch/x86/boot/acpi.c @@ -250,6 +250,61 @@ void acpi_create_mcfg(acpi_mcfg_t *mcfg) header->checksum = acpi_checksum((void *)mcfg, header->length); } +static void *get_tcpa_log(u32 *size) +{ + const struct cbmem_entry *ce; + const u32 tcpa_default_log_len = 0x10000; + void *lasa; + ce = cbmem_entry_find(CBMEM_ID_TCPA_LOG); + if (ce) { + lasa = cbmem_entry_start(ce); + *size = cbmem_entry_size(ce); + printk(BIOS_DEBUG, "TCPA log found at %p\n", lasa); + return lasa; + } + lasa = cbmem_add(CBMEM_ID_TCPA_LOG, tcpa_default_log_len); + if (!lasa) { + printk(BIOS_ERR, "TCPA log creation failed\n"); + return NULL; + } + + printk(BIOS_DEBUG, "TCPA log created at %p\n", lasa); + memset (lasa, 0, tcpa_default_log_len); + + *size = tcpa_default_log_len; + return lasa; +} + +static void acpi_create_tcpa(acpi_tcpa_t *tcpa) +{ + acpi_header_t *header = &(tcpa->header); + u32 tcpa_log_len; + void *lasa; + + memset((void *)tcpa, 0, sizeof(acpi_tcpa_t)); + + lasa = get_tcpa_log(&tcpa_log_len); + if (!lasa) { + return; + } + + /* Fill out header fields. */ + memcpy(header->signature, "TCPA", 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->length = sizeof(acpi_tcpa_t); + header->revision = 2; + + tcpa->platform_class = 0; + tcpa->laml = tcpa_log_len; + tcpa->lasa = (u32) lasa; + + /* Calculate checksum. */ + header->checksum = acpi_checksum((void *)tcpa, header->length); +} + void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id) { unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t); @@ -688,6 +743,7 @@ unsigned long write_acpi_tables(unsigned long start) acpi_header_t *ssdt; acpi_header_t *dsdt; acpi_mcfg_t *mcfg; + acpi_tcpa_t *tcpa; acpi_madt_t *madt; struct device *dev; unsigned long fw; @@ -805,6 +861,15 @@ unsigned long write_acpi_tables(unsigned long start) acpi_add_table(rsdp, mcfg); } + printk(BIOS_DEBUG, "ACPI: * TCPA\n"); + tcpa = (acpi_tcpa_t *) current; + acpi_create_tcpa(tcpa); + if (tcpa->header.length >= sizeof(acpi_tcpa_t)) { + current += tcpa->header.length; + ALIGN_CURRENT; + acpi_add_table(rsdp, tcpa); + } + printk(BIOS_DEBUG, "ACPI: * MADT\n"); madt = (acpi_madt_t *) current; diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index 245599fa9d..10db820409 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -129,6 +129,13 @@ typedef struct acpi_mcfg { u8 reserved[8]; } __attribute__ ((packed)) acpi_mcfg_t; +typedef struct acpi_tcpa { + struct acpi_table_header header; + u16 platform_class; + u32 laml; + u64 lasa; +} __attribute__ ((packed)) acpi_tcpa_t; + typedef struct acpi_mcfg_mmconfig { u32 base_address; u32 base_reserved; diff --git a/src/include/cbmem.h b/src/include/cbmem.h index 5fd67afa4c..afee873f42 100644 --- a/src/include/cbmem.h +++ b/src/include/cbmem.h @@ -79,6 +79,7 @@ #define CBMEM_ID_VBOOT_HANDOFF 0x780074f0 #define CBMEM_ID_VBOOT_WORKBUF 0x78007343 #define CBMEM_ID_WIFI_CALIBRATION 0x57494649 +#define CBMEM_ID_TCPA_LOG 0x54435041 #ifndef __ASSEMBLER__ #include