[coreboot] Patch set updated: d3a81c2 Implemented functions for writing most of the ACPI tables

Sven Schnelle (svens@stackframe.org) gerrit at coreboot.org
Thu Aug 11 17:30:35 CEST 2011


Sven Schnelle (svens at stackframe.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/76

-gerrit

commit d3a81c2da0cbfdc4d185388c8b69d131716ddf52
Author: Cristian Măgherușan-Stanciu <cristi.magherusan at gmail.com>
Date:   Sat Jul 2 01:07:35 2011 +0300

    Implemented functions for writing most of the ACPI tables
    
    Fixed compilation failures in the SILC code, but Intel xe7501devkit
    still fails to compile due to incomplete southbrige code that does not
    implement FADT generation as of yet.
    
    Change-Id: Ib84c845d3f004708a90fd3122485f00b7d20fdbc
    Signed-off-by: Cristian Măgherușan-Stanciu <cristi.magherusan at gmail.com>
    Signed-off-by: Sven Schnelle <svens at stackframe.org>
---
 src/arch/x86/boot/acpi.c         |  244 ++++++++++++++++++++++++++++++++++----
 src/arch/x86/boot/tables.c       |   10 +-
 src/arch/x86/include/arch/acpi.h |   28 ++++-
 3 files changed, 248 insertions(+), 34 deletions(-)

diff --git a/src/arch/x86/boot/acpi.c b/src/arch/x86/boot/acpi.c
index 8be7437..97110ea 100644
--- a/src/arch/x86/boot/acpi.c
+++ b/src/arch/x86/boot/acpi.c
@@ -16,13 +16,15 @@
  */
 
 /*
- * Each system port implementing ACPI has to provide two functions:
- *
- *   write_acpi_tables()
- *   acpi_dump_apics()
- *
- * See Kontron 986LCD-M port for a good example of an ACPI implementation
- * in coreboot.
+ * Currently each system port implementing ACPI has to provide the following functions:
+ * - acpi_fill_mcfg()
+ * - acpi_fill_madt()
+ * - acpi_fill_slit()
+ * - acpi_fill_srat()
+ * Optional
+ * - acpi_fill_ssdt_generator()
+ * - acpi_patch_dsdt()
+ * - acpi_dmi_workaround()
  */
 
 #include <console/console.h>
@@ -32,6 +34,8 @@
 #include <device/pci.h>
 #include <cbmem.h>
 
+extern const unsigned char AmlCode[];
+
 u8 acpi_checksum(u8 *table, u32 length)
 {
 	u8 ret = 0;
@@ -42,16 +46,43 @@ u8 acpi_checksum(u8 *table, u32 length)
 	return -ret;
 }
 
+#if CONFIG_DEBUG_ACPI == 1
+static void dump_mem(void *start, unsigned int cnt)
+{
+	int i;
+
+	for (i = 0; i < cnt; i++) {
+		if (!(i & 0x0f))
+			printk(BIOS_DEBUG, "\n%08x:", (unsigned int)start + i);
+		if (!(i & 0x03)) {
+			printk(BIOS_DEBUG, " ");
+			if (!(i & 0x07))
+				printk(BIOS_DEBUG, " ");
+		}
+		printk(BIOS_DEBUG, " %02x", ((u8 *)start)[i]);
+	}
+	printk(BIOS_DEBUG,"\n");
+}
+#endif
+
 /**
  * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length
  * and checksum.
  */
 void acpi_add_table(acpi_rsdp_t *rsdp, void *table)
 {
+	acpi_header_t *hdr = (acpi_header_t *)table;
 	int i, entries_num;
 	acpi_rsdt_t *rsdt;
 	acpi_xsdt_t *xsdt = NULL;
 
+	printk(BIOS_DEBUG, "Adding %4.4s @ %p len %d\n", hdr->signature, table, hdr->length);
+
+	hdr->checksum = 0;
+	hdr->checksum = acpi_checksum(table, hdr->length);
+#if CONFIG_DEBUG_ACPI == 1
+	dump_mem(table, hdr->length);
+#endif
 	/* The RSDT is mandatory... */
 	rsdt = (acpi_rsdt_t *)rsdp->rsdt_address;
 
@@ -211,8 +242,6 @@ void acpi_create_madt(acpi_madt_t *madt)
 
 	/* (Re)calculate length and checksum. */
 	header->length = current - (unsigned long)madt;
-
-	header->checksum = acpi_checksum((void *)madt, header->length);
 }
 
 /* MCFG is defined in the PCI Firmware Specification 3.0. */
@@ -236,7 +265,6 @@ void acpi_create_mcfg(acpi_mcfg_t *mcfg)
 
 	/* (Re)calculate length and checksum. */
 	header->length = current - (unsigned long)mcfg;
-	header->checksum = acpi_checksum((void *)mcfg, header->length);
 }
 
 /*
@@ -249,6 +277,18 @@ unsigned long __attribute__((weak)) acpi_fill_ssdt_generator(
 	return current;
 }
 
+/* stub functions that might be implemented in the mainboard code, if needed */
+void __attribute__((weak)) acpi_patch_dsdt(
+			acpi_header_t *dsdt, unsigned long *current)
+{
+}
+
+void __attribute__((weak)) acpi_dmi_workaround(unsigned long *current)
+{
+}
+
+
+
 void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id)
 {
 	unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t);
@@ -269,7 +309,6 @@ void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id)
 
 	/* (Re)calculate length and checksum. */
 	ssdt->length = current - (unsigned long)ssdt;
-	ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length);
 }
 
 int acpi_create_srat_lapic(acpi_srat_lapic_t *lapic, u8 node, u8 apic)
@@ -324,7 +363,6 @@ void acpi_create_srat(acpi_srat_t *srat)
 
 	/* (Re)calculate length and checksum. */
 	header->length = current - (unsigned long)srat;
-	header->checksum = acpi_checksum((void *)srat, header->length);
 }
 
 /* http://h21007.www2.hp.com/portal/download/files/unprot/Itanium/slit.pdf */
@@ -348,7 +386,6 @@ void acpi_create_slit(acpi_slit_t *slit)
 
 	/* (Re)calculate length and checksum. */
 	header->length = current - (unsigned long)slit;
-	header->checksum = acpi_checksum((void *)slit, header->length);
 }
 
 /* http://www.intel.com/hardwaredesign/hpetspec_1.pdf */
@@ -390,8 +427,6 @@ void acpi_create_hpet(acpi_hpet_t *hpet)
 	hpet->min_tick = 0x90;
 #endif
 	hpet->number = 0;
-
-	header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
 }
 
 void acpi_create_facs(acpi_facs_t *facs)
@@ -409,10 +444,11 @@ void acpi_create_facs(acpi_facs_t *facs)
 	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)
+acpi_rsdt_t *acpi_write_rsdt(unsigned long *current)
 {
+	acpi_rsdt_t *rsdt = (acpi_rsdt_t *)*current;
 	acpi_header_t *header = &(rsdt->header);
-
+	memset(rsdt, 0, sizeof(acpi_rsdt_t));
 	/* Fill out header fields. */
 	memcpy(header->signature, "RSDT", 4);
 	memcpy(header->oem_id, OEM_ID, 6);
@@ -423,13 +459,14 @@ void acpi_write_rsdt(acpi_rsdt_t *rsdt)
 	header->revision = 1; /* ACPI 1.0/2.0/3.0/4.0: 1 */
 
 	/* Entries are filled in later, we come with an empty set. */
-
-	/* Fix checksum. */
-	header->checksum = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t));
+	*current += sizeof(acpi_rsdt_t);
+	*current = ALIGN(*current, 64);
+	return rsdt;
 }
 
-void acpi_write_xsdt(acpi_xsdt_t *xsdt)
+acpi_xsdt_t *acpi_write_xsdt(unsigned long *current)
 {
+	acpi_xsdt_t *xsdt = (acpi_xsdt_t *)*current;
 	acpi_header_t *header = &(xsdt->header);
 
 	/* Fill out header fields. */
@@ -443,12 +480,15 @@ void acpi_write_xsdt(acpi_xsdt_t *xsdt)
 
 	/* Entries are filled in later, we come with an empty set. */
 
-	/* Fix checksum. */
-	header->checksum = acpi_checksum((void *)xsdt, sizeof(acpi_xsdt_t));
+	*current += sizeof(acpi_xsdt_t);
+	*current = ALIGN(*current, 64);
+	return xsdt;
 }
 
-void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt, acpi_xsdt_t *xsdt)
+
+acpi_rsdp_t *acpi_write_rsdp(acpi_rsdt_t *rsdt, acpi_xsdt_t *xsdt, unsigned long *current)
 {
+	acpi_rsdp_t *rsdp = (acpi_rsdp_t *)*current;
 	memset(rsdp, 0, sizeof(acpi_rsdp_t));
 
 	memcpy(rsdp->signature, RSDP_SIG, 8);
@@ -474,6 +514,162 @@ void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt, acpi_xsdt_t *xsdt)
 	/* Calculate checksums. */
 	rsdp->checksum = acpi_checksum((void *)rsdp, 20);
 	rsdp->ext_checksum = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t));
+	*current += sizeof(acpi_rsdp_t);
+	*current = ALIGN(*current, 64);
+	return rsdp;
+}
+
+
+
+acpi_header_t *acpi_write_dsdt(acpi_rsdp_t *rsdp, const acpi_header_t *src, unsigned long *current)
+{
+	acpi_header_t *dsdt = (acpi_header_t *)*current;
+	int len = src->length;
+
+	memcpy(dsdt, src, len);
+	*current += len;
+	*current = ALIGN(*current, 64);
+	acpi_patch_dsdt(dsdt, current);
+	return dsdt;
+}
+
+acpi_facs_t *acpi_write_facs(acpi_rsdp_t *rsdp, unsigned long *current)
+{
+	acpi_facs_t *facs = (acpi_facs_t *)*current;
+	*current += sizeof(acpi_facs_t);
+	*current = ALIGN(*current, 64);
+	acpi_create_facs(facs);
+	return facs;
+}
+
+
+acpi_fadt_t *acpi_write_fadt(acpi_facs_t *facs, acpi_header_t *dsdt, acpi_rsdp_t *rsdp, unsigned long *current)
+{
+	acpi_fadt_t *fadt = (acpi_fadt_t *)*current;
+	*current += sizeof(acpi_fadt_t);
+	*current = ALIGN(*current, 64);
+	acpi_create_fadt(fadt, facs, dsdt);
+	acpi_add_table(rsdp, fadt);
+	return fadt;
+}
+
+acpi_hpet_t *acpi_write_hpet(acpi_rsdp_t *rsdp, unsigned long *current)
+{
+	acpi_hpet_t *hpet = (acpi_hpet_t *)*current;
+	hpet = (acpi_hpet_t *) *current;
+	*current += sizeof(acpi_hpet_t);
+	acpi_create_hpet(hpet);
+	*current = ALIGN(*current, 64);
+	acpi_add_table(rsdp, hpet);
+	return hpet;
+}
+
+acpi_madt_t *acpi_write_madt(acpi_rsdp_t *rsdp, unsigned long *current)
+{
+	acpi_madt_t *madt = (acpi_madt_t *)*current;
+	acpi_create_madt(madt);
+	*current += madt->header.length;
+	*current = ALIGN(*current, 64);
+	acpi_add_table(rsdp, madt);
+	return madt;
+}
+
+acpi_srat_t *acpi_write_srat(acpi_rsdp_t *rsdp, unsigned long *current)
+{
+	acpi_srat_t *srat;
+	*current = ALIGN(*current, 64);
+	srat = (acpi_srat_t *) *current;
+	acpi_create_srat(srat);
+	*current += srat->header.length;
+	acpi_add_table(rsdp, srat);
+	return srat;
+}
+
+acpi_slit_t *acpi_write_slit(acpi_rsdp_t *rsdp, unsigned long *current)
+{
+	acpi_slit_t *slit;
+	slit = (acpi_slit_t *) *current;
+	acpi_create_slit(slit);
+	*current += slit->header.length;
+	*current = ALIGN(*current, 64);
+	acpi_add_table(rsdp, slit);
+	return slit;
+}
+
+acpi_mcfg_t *acpi_write_mcfg(acpi_rsdp_t *rsdp, unsigned long *current)
+{
+	acpi_mcfg_t *mcfg = (acpi_mcfg_t *)*current;
+	acpi_create_mcfg(mcfg);
+	*current += mcfg->header.length;
+	*current = ALIGN(*current, 64);
+	acpi_add_table(rsdp, mcfg);
+	return mcfg;
+}
+
+#if CONFIG_HAVE_ACPI_SLIC
+acpi_header_t *void acpi_write_slic(acpi_rsdp_t *rsdp, unsigned long *current)
+{
+	acpi_header_t *slic = (acpi_header_t *)*current;
+	*current += acpi_create_slic(*current);
+	*current = ALIGN(*current, 64);
+	acpi_add_table(rsdp, slic);
+	return slic;
+}
+#endif
+
+
+acpi_header_t *acpi_write_ssdt_generated(acpi_rsdp_t *rsdp,  unsigned long *current)
+{
+	acpi_header_t *ssdt = (acpi_header_t *)*current;
+	acpi_create_ssdt_generator(ssdt, "DYNADATA");
+	*current += ssdt->length;
+	*current = ALIGN(*current, 64);
+	acpi_add_table(rsdp, ssdt);
+	return ssdt;
+}
+
+unsigned long acpi_write_tables(unsigned long current)
+{
+	acpi_rsdp_t *rsdp;
+	acpi_rsdt_t *rsdt;
+	acpi_fadt_t *fadt;
+	acpi_facs_t *facs;
+	acpi_xsdt_t *xsdt;
+#if CONFIG_HAVE_ACPI_SLIC
+	acpi_header_t *slic;
+#endif
+	acpi_header_t *ssdt, *dsdt;
+
+	/* Align ACPI tables to 16 bytes */
+	current = ALIGN(current, 16);
+
+	printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", current);
+
+	rsdt = acpi_write_rsdt(&current);
+	xsdt = acpi_write_xsdt(&current);
+	rsdp = acpi_write_rsdp(rsdt, xsdt, &current);
+	acpi_write_hpet(rsdp, &current);
+	acpi_write_madt(rsdp, &current);
+	acpi_write_mcfg(rsdp, &current);
+	acpi_write_srat(rsdp, &current);
+	acpi_write_slit(rsdp, &current);
+
+	dsdt = acpi_write_dsdt(rsdp, (acpi_header_t *)AmlCode, &current);
+	facs = acpi_write_facs(rsdp, &current);
+	fadt = acpi_write_fadt(facs, dsdt, rsdp, &current);
+
+#if CONFIG_HAVE_ACPI_SLIC
+	slic = acpi_write_slic(rsdp, &current);
+#endif
+
+	ssdt = acpi_write_ssdt_generated(rsdp, &current);
+
+	printk(BIOS_DEBUG, "current = %lx\n", current);
+
+	acpi_dmi_workaround(&current);
+
+	printk(BIOS_INFO, "ACPI: done.\n");
+	return current;
 }
 
 #if CONFIG_HAVE_ACPI_RESUME == 1
diff --git a/src/arch/x86/boot/tables.c b/src/arch/x86/boot/tables.c
index d816e76..2d3184a 100644
--- a/src/arch/x86/boot/tables.c
+++ b/src/arch/x86/boot/tables.c
@@ -141,7 +141,7 @@ struct lb_memory *write_tables(void)
 		unsigned long new_high_table_pointer;
 
 		rom_table_end = ALIGN(rom_table_end, 16);
-		new_high_table_pointer = write_acpi_tables(high_table_pointer);
+		new_high_table_pointer = acpi_write_tables(high_table_pointer);
 		if (new_high_table_pointer > ( high_table_pointer + MAX_ACPI_SIZE)) {
 			printk(BIOS_ERR, "ERROR: Increase ACPI size\n");
 		}
@@ -165,15 +165,15 @@ struct lb_memory *write_tables(void)
 			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));
+			unsigned long current = (unsigned long)low_rsdp;
+			acpi_write_rsdp((acpi_rsdt_t *)(high_rsdp->rsdt_address),
+					(acpi_xsdt_t *)((unsigned long)high_rsdp->xsdt_address), &current);
 		} else {
 			printk(BIOS_ERR, "ERROR: Didn't find RSDP in high table.\n");
 		}
 		rom_table_end = ALIGN(rom_table_end + sizeof(acpi_rsdp_t), 16);
 	} else {
-		rom_table_end = write_acpi_tables(rom_table_end);
+		rom_table_end = acpi_write_tables(rom_table_end);
 		rom_table_end = ALIGN(rom_table_end, 1024);
 	}
 
diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h
index 030745d..d6eabab 100644
--- a/src/arch/x86/include/arch/acpi.h
+++ b/src/arch/x86/include/arch/acpi.h
@@ -357,14 +357,15 @@ typedef struct acpi_ecdt {
 	u8 ec_id[];				/* EC ID  */
 } __attribute__ ((packed)) acpi_ecdt_t;
 
-/* These are implemented by the target port or north/southbridge. */
+/* This is implemented by the target port or north/southbridge. */
 unsigned long write_acpi_tables(unsigned long addr);
+
 unsigned long acpi_fill_madt(unsigned long current);
 unsigned long acpi_fill_mcfg(unsigned long current);
 unsigned long acpi_fill_srat(unsigned long current);
 unsigned long acpi_fill_slit(unsigned long current);
 unsigned long acpi_fill_ssdt_generator(unsigned long current,
-				       const char *oem_table_id);
+				const char *oem_table_id);
 void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id);
 void acpi_create_fadt(acpi_fadt_t *fadt,acpi_facs_t *facs, void *dsdt);
 
@@ -406,11 +407,28 @@ void acpi_create_facs(acpi_facs_t *facs);
 
 #if CONFIG_HAVE_ACPI_SLIC
 unsigned long acpi_create_slic(unsigned long current);
+acpi_header_t *acpi_write_slic(acpi_rsdp_t *rsdp, unsigned long *current);
 #endif
 
-void acpi_write_rsdt(acpi_rsdt_t *rsdt);
-void acpi_write_xsdt(acpi_xsdt_t *xsdt);
-void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt, acpi_xsdt_t *xsdt);
+acpi_rsdt_t *acpi_write_rsdt(unsigned long *current);
+acpi_xsdt_t *acpi_write_xsdt(unsigned long *current);
+acpi_rsdp_t *acpi_write_rsdp(acpi_rsdt_t *rsdt, acpi_xsdt_t *xsdt, unsigned long *current);
+acpi_header_t *acpi_write_dsdt(acpi_rsdp_t *rsdp, const acpi_header_t *dsdt, unsigned long *current);
+void acpi_patch_dsdt(acpi_header_t *dsdt, unsigned long *current);
+void acpi_dmi_workaround(unsigned long *current);
+
+acpi_facs_t *acpi_write_facs(acpi_rsdp_t *rsdp, unsigned long *current);
+acpi_fadt_t *acpi_write_fadt(acpi_facs_t *facs, acpi_header_t *dsdt, acpi_rsdp_t *rsdp, unsigned long *current);
+
+acpi_hpet_t *acpi_write_hpet(acpi_rsdp_t *rsdp, unsigned long *current);
+acpi_madt_t *acpi_write_madt(acpi_rsdp_t *rsdp, unsigned long *current);
+acpi_srat_t *acpi_write_srat(acpi_rsdp_t *rsdp, unsigned long *current);
+acpi_slit_t *acpi_write_slit(acpi_rsdp_t *rsdp, unsigned long *current);
+acpi_mcfg_t *acpi_write_mcfg(acpi_rsdp_t *rsdp, unsigned long *current);
+
+acpi_header_t *acpi_write_ssdt_generated(acpi_rsdp_t *rsdp,  unsigned long *current);
+
+unsigned long acpi_write_tables(unsigned long start);
 
 #if CONFIG_HAVE_ACPI_RESUME
 /* 0 = S0, 1 = S1 ...*/




More information about the coreboot mailing list