diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c index 5893461f43..4ebdcbe04d 100644 --- a/src/arch/x86/acpi.c +++ b/src/arch/x86/acpi.c @@ -307,6 +307,29 @@ static void acpi_create_tcpa(acpi_tcpa_t *tcpa) header->checksum = acpi_checksum((void *)tcpa, header->length); } +static void acpi_ssdt_write_cbtable(void) +{ + const struct cbmem_entry *cbtable; + uintptr_t base; + uint32_t size; + + cbtable = cbmem_entry_find(CBMEM_ID_CBTABLE); + if (!cbtable) + return; + base = (uintptr_t)cbmem_entry_start(cbtable); + size = cbmem_entry_size(cbtable); + + acpigen_write_device("CTBL"); + acpigen_write_coreboot_hid(COREBOOT_ACPI_ID_CBTABLE); + acpigen_write_name_integer("_UID", 0); + acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON); + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpigen_write_mem32fixed(0, base, size); + acpigen_write_resourcetemplate_footer(); + acpigen_pop_len(); +} + void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id) { unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t); @@ -323,6 +346,10 @@ void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id) ssdt->length = sizeof(acpi_header_t); acpigen_set_current((char *) current); + + /* Write object to declare coreboot tables */ + acpi_ssdt_write_cbtable(); + { struct device *dev; for (dev = all_devices; dev; dev = dev->next) diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c index 915faac802..f35fe02b6b 100644 --- a/src/arch/x86/acpigen.c +++ b/src/arch/x86/acpigen.c @@ -220,6 +220,14 @@ void acpigen_write_string(const char *string) acpigen_emit_string(string); } +void acpigen_write_coreboot_hid(enum coreboot_acpi_ids id) +{ + char hid[9]; /* CORExxxx */ + + snprintf(hid, sizeof(hid), "%.4s%04u", COREBOOT_ACPI_ID, id); + acpigen_write_name_string("_HID", hid); +} + /* * The naming conventions for ACPI namespace names are a bit tricky as * each element has to be 4 chars wide ("All names are a fixed 32 bits.") diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index 5d083698b4..21dae088d2 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -57,6 +57,12 @@ #define ACPI_TABLE_CREATOR "COREBOOT" /* Must be exactly 8 bytes long! */ #define OEM_ID "CORE " /* Must be exactly 6 bytes long! */ #define ASLC "CORE" /* Must be exactly 4 bytes long! */ +#define COREBOOT_ACPI_ID "CORE" /* ACPI ID for coreboot HIDs */ + +/* List of ACPI HID that use the coreboot ACPI ID */ +enum coreboot_acpi_ids { + COREBOOT_ACPI_ID_CBTABLE, /* CORE0000 */ +}; /* RSDP (Root System Description Pointer) */ typedef struct acpi_rsdp { diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h index 9035f27b86..f513698f26 100644 --- a/src/arch/x86/include/arch/acpigen.h +++ b/src/arch/x86/include/arch/acpigen.h @@ -63,6 +63,7 @@ void acpigen_write_name_dword(const char *name, uint32_t val); void acpigen_write_name_qword(const char *name, uint64_t val); void acpigen_write_name_byte(const char *name, uint8_t val); void acpigen_write_name_integer(const char *name, uint64_t val); +void acpigen_write_coreboot_hid(enum coreboot_acpi_ids id); void acpigen_write_scope(const char *name); void acpigen_write_method(const char *name, int nargs); void acpigen_write_device(const char *name);