ACPI: slic support
Export SLIC table from file in CBFS.
Change-Id: Id0e7fe0a49b9cd50b5e43cd15030e1c2098728ec
Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-on: http://review.coreboot.org/7202
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Tested-by: build bot (Jenkins)
diff --git a/src/arch/x86/boot/acpi.c b/src/arch/x86/boot/acpi.c
index 07b67d0..bc2a0cc 100644
--- a/src/arch/x86/boot/acpi.c
+++ b/src/arch/x86/boot/acpi.c
@@ -33,6 +33,7 @@
#include <cbmem.h>
#include <cpu/x86/lapic_def.h>
#include <cpu/cpu.h>
+#include <cbfs.h>
#if CONFIG_COLLECT_TIMESTAMPS
#include <timestamp.h>
#endif
@@ -485,14 +486,14 @@
facs->version = 1; /* ACPI 1.0: 0, ACPI 2.0/3.0: 1, ACPI 4.0: 2 */
}
-void acpi_write_rsdt(acpi_rsdt_t *rsdt)
+static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id)
{
acpi_header_t *header = &(rsdt->header);
/* Fill out header fields. */
memcpy(header->signature, "RSDT", 4);
- memcpy(header->oem_id, OEM_ID, 6);
- memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+ memcpy(header->oem_id, oem_id, 6);
+ memcpy(header->oem_table_id, oem_table_id, 8);
memcpy(header->asl_compiler_id, ASLC, 4);
header->length = sizeof(acpi_rsdt_t);
@@ -504,14 +505,14 @@
header->checksum = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t));
}
-void acpi_write_xsdt(acpi_xsdt_t *xsdt)
+static void acpi_write_xsdt(acpi_xsdt_t *xsdt, char *oem_id, char *oem_table_id)
{
acpi_header_t *header = &(xsdt->header);
/* Fill out header fields. */
memcpy(header->signature, "XSDT", 4);
- memcpy(header->oem_id, OEM_ID, 6);
- memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+ memcpy(header->oem_id, oem_id, 6);
+ memcpy(header->oem_table_id, oem_table_id, 8);
memcpy(header->asl_compiler_id, ASLC, 4);
header->length = sizeof(acpi_xsdt_t);
@@ -523,12 +524,13 @@
header->checksum = acpi_checksum((void *)xsdt, sizeof(acpi_xsdt_t));
}
-void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt, acpi_xsdt_t *xsdt)
+static void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt,
+ acpi_xsdt_t *xsdt, char *oem_id)
{
memset(rsdp, 0, sizeof(acpi_rsdp_t));
memcpy(rsdp->signature, RSDP_SIG, 8);
- memcpy(rsdp->oem_id, OEM_ID, 6);
+ memcpy(rsdp->oem_id, oem_id, 6);
rsdp->length = sizeof(acpi_rsdp_t);
rsdp->rsdt_address = (u32)rsdt;
@@ -686,15 +688,15 @@
acpi_xsdt_t *xsdt;
acpi_fadt_t *fadt;
acpi_facs_t *facs;
-#if CONFIG_HAVE_ACPI_SLIC
- acpi_header_t *slic;
-#endif
+ acpi_header_t *slic_file, *slic;
acpi_header_t *ssdt;
acpi_header_t *dsdt;
acpi_mcfg_t *mcfg;
acpi_madt_t *madt;
struct device *dev;
unsigned long fw;
+ size_t slic_size;
+ char oem_id[6], oem_table_id[8];
current = start;
@@ -705,6 +707,22 @@
if (fw)
return fw;
+ slic_file = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
+ CONFIG_CBFS_PREFIX "/slic",
+ CBFS_TYPE_RAW, &slic_size);
+ if (slic_file && (slic_file->length > slic_size
+ || slic_file->length < sizeof (acpi_header_t))) {
+ slic_file = 0;
+ }
+
+ if (slic_file) {
+ memcpy(oem_id, slic_file->oem_id, 6);
+ memcpy(oem_table_id, slic_file->oem_table_id, 8);
+ } else {
+ memcpy(oem_id, OEM_ID, 6);
+ memcpy(oem_table_id, ACPI_TABLE_CREATOR, 8);
+ }
+
printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start);
/* We need at least an RSDP and an RSDT Table */
@@ -721,9 +739,9 @@
/* clear all table memory */
memset((void *) start, 0, current - start);
- acpi_write_rsdp(rsdp, rsdt, xsdt);
- acpi_write_rsdt(rsdt);
- acpi_write_xsdt(xsdt);
+ acpi_write_rsdp(rsdp, rsdt, xsdt, oem_id);
+ acpi_write_rsdt(rsdt, oem_id, oem_table_id);
+ acpi_write_xsdt(xsdt, oem_id, oem_table_id);
printk(BIOS_DEBUG, "ACPI: * FACS\n");
facs = (acpi_facs_t *) current;
@@ -764,13 +782,14 @@
acpi_create_fadt(fadt, facs, dsdt);
acpi_add_table(rsdp, fadt);
-#if CONFIG_HAVE_ACPI_SLIC
- printk(BIOS_DEBUG, "ACPI: * SLIC\n");
- slic = (acpi_header_t *)current;
- current += acpi_create_slic(current);
- ALIGN_CURRENT;
- acpi_add_table(rsdp, slic);
-#endif
+ if (slic_file) {
+ printk(BIOS_DEBUG, "ACPI: * SLIC\n");
+ slic = (acpi_header_t *)current;
+ memcpy(slic, slic_file, slic_file->length);
+ current += slic_file->length;
+ ALIGN_CURRENT;
+ acpi_add_table(rsdp, slic);
+ }
printk(BIOS_DEBUG, "ACPI: * SSDT\n");
ssdt = (acpi_header_t *)current;
diff --git a/src/arch/x86/boot/tables.c b/src/arch/x86/boot/tables.c
index ca98faa..3d64563 100644
--- a/src/arch/x86/boot/tables.c
+++ b/src/arch/x86/boot/tables.c
@@ -147,9 +147,9 @@
acpi_rsdp_t *low_rsdp = (acpi_rsdp_t *)rom_table_end,
*high_rsdp = (acpi_rsdp_t *)acpi_start;
- acpi_write_rsdp(low_rsdp,
- (acpi_rsdt_t *)(high_rsdp->rsdt_address),
- (acpi_xsdt_t *)((unsigned long)high_rsdp->xsdt_address));
+ /* Technically rsdp length varies but coreboot always
+ writes longest size available. */
+ memcpy(low_rsdp, high_rsdp, sizeof(acpi_rsdp_t));
} else {
printk(BIOS_ERR, "ERROR: Didn't find RSDP in high table.\n");
}