Cristian Măgherușan-Stanciu (cristi.magherusan@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/76
-gerrit
commit 93c64f021d22ff5629de9d3c082e3715099d5f23 Author: Cristian Măgherușan-Stanciu cristi.magherusan@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@gmail.com --- src/arch/x86/boot/acpi.c | 248 ++++++++++++++++++++++++++++++++++++- src/arch/x86/include/arch/acpi.h | 19 +++- 2 files changed, 258 insertions(+), 9 deletions(-)
diff --git a/src/arch/x86/boot/acpi.c b/src/arch/x86/boot/acpi.c index 8be7437..6a17395 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> @@ -249,6 +251,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); @@ -476,6 +490,226 @@ void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt, acpi_xsdt_t *xsdt) rsdp->ext_checksum = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t)); }
+ + +void acpi_write_dsdt(acpi_header_t *dsdt, const unsigned char AmlCode[], unsigned long *current) +{ + printk(BIOS_DEBUG, "ACPI: * DSDT at %lx\n", *current); + dsdt = (acpi_header_t *) *current; // it will used by fadt + memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); + *current += dsdt->length; + memcpy(dsdt, &AmlCode, dsdt->length); + *current = ALIGN(*current, 64); + + acpi_patch_dsdt(dsdt, current); + + printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, dsdt->length); +} + +void acpi_write_facs(acpi_facs_t *facs, unsigned long *current) +{ + /* FACS */ // it needs 64 bit alignment + printk(BIOS_DEBUG, "ACPI: * FACS at %lx\n", *current); + facs = (acpi_facs_t *) *current; // it will be used by fadt + *current += sizeof(acpi_facs_t); + *current = ALIGN(*current, 64); + acpi_create_facs(facs); +} + + +void acpi_write_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, acpi_header_t *dsdt, acpi_rsdp_t *rsdp, unsigned long *current) +{ + printk(BIOS_DEBUG, "ACPI: * FADT at %lx\n", *current); + 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); +} + +void acpi_write_hpet(acpi_hpet_t *hpet, acpi_rsdp_t *rsdp, unsigned long *current) +{ + printk(BIOS_DEBUG, "ACPI: * HPET at %lx\n", *current); + hpet = (acpi_hpet_t *) *current; + *current += sizeof(acpi_hpet_t); + acpi_create_hpet(hpet); + *current = ALIGN(*current, 64); + acpi_add_table(rsdp, hpet); +} + +void acpi_write_madt(acpi_madt_t *madt, acpi_rsdp_t *rsdp, unsigned long *current) +{ + printk(BIOS_DEBUG, "ACPI: * MADT at %lx\n", *current); + madt = (acpi_madt_t *) *current; + acpi_create_madt(madt); + *current += madt->header.length; + *current = ALIGN(*current, 64); + acpi_add_table(rsdp, madt); +} + +void acpi_write_srat(acpi_srat_t *srat, acpi_rsdp_t *rsdp, unsigned long *current) +{ + *current = ALIGN(*current, 64); + printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", *current); + srat = (acpi_srat_t *) *current; + acpi_create_srat(srat); + *current += srat->header.length; + acpi_add_table(rsdp, srat); +} + +void acpi_write_slit(acpi_slit_t *slit, acpi_rsdp_t *rsdp, unsigned long *current) +{ + printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", *current); + slit = (acpi_slit_t *) *current; + acpi_create_slit(slit); + *current += slit->header.length; + *current = ALIGN(*current, 64); + acpi_add_table(rsdp, slit); +} +void acpi_write_mcfg(acpi_mcfg_t *mcfg, acpi_rsdp_t *rsdp, unsigned long *current) +{ + printk(BIOS_DEBUG, "ACPI: * MCFG at %lx\n", *current); + mcfg = (acpi_mcfg_t *) *current; + acpi_create_mcfg(mcfg); + *current += mcfg->header.length; + *current = ALIGN(*current, 64); + acpi_add_table(rsdp, mcfg); +} + +#if CONFIG_HAVE_ACPI_SLIC +void acpi_write_slic(acpi_header_t *slic, acpi_rsdp_t *rsdp, unsigned long *current) +{ + printk(BIOS_DEBUG, "ACPI: * SLIC\n"); + slic = (acpi_header_t *)*current; + *current += acpi_create_slic(*current); + *current = ALIGN(*current, 64); + acpi_add_table(rsdp, slic); +} +#endif + + +void acpi_write_ssdt_generated(acpi_header_t *ssdt, acpi_rsdp_t *rsdp, unsigned long *current) +{ + printk(BIOS_DEBUG, "ACPI: * SSDT\n"); + ssdt = (acpi_header_t *)*current; + + acpi_create_ssdt_generator(ssdt, "DYNADATA"); + *current += ssdt->length; + acpi_add_table(rsdp, ssdt); + *current = ALIGN(*current, 64); +} + + +#if CONFIG_DEBUG_ACPI == 1 +static void dump_mem(void *start, void *end) +{ + int i; + printk(BIOS_DEBUG,"dump_mem:"); + for (i = (unsigned int)start; i < (unsigned int)end; i++) { + if ((i & 0xf) == 0) { + printk(BIOS_DEBUG, "\n%08x:", (unsigned int)i); + } + printk(BIOS_DEBUG, " %02x", (u8)*((u8 *)i)); + } + printk(BIOS_DEBUG,"\n"); +} +#endif + +unsigned long acpi_write_tables(unsigned long start, const unsigned char AmlCode[]) +{ + unsigned long current; + acpi_rsdp_t *rsdp = NULL; + acpi_srat_t *srat = NULL; + acpi_rsdt_t *rsdt = NULL; + acpi_mcfg_t *mcfg = NULL; + acpi_hpet_t *hpet = NULL; + acpi_madt_t *madt = NULL; + acpi_fadt_t *fadt = NULL; + acpi_facs_t *facs = NULL; + acpi_xsdt_t *xsdt = NULL; +#if CONFIG_HAVE_ACPI_SLIC + acpi_header_t *slic = NULL; +#endif + acpi_slit_t *slit = NULL; + acpi_header_t *ssdt = NULL; + acpi_header_t *dsdt = NULL; + + /* Align ACPI tables to 16 bytes */ + start = ALIGN(start, 16); + current = start; + + printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", start); + + /* We need at least an RSDP and an RSDT Table */ + rsdp = (acpi_rsdp_t *) current; + current += sizeof(acpi_rsdp_t); + + current = ALIGN(current, 64); + rsdt = (acpi_rsdt_t *) current; + current += sizeof(acpi_rsdt_t); + + current = ALIGN(current, 64); + xsdt = (acpi_xsdt_t *) current; + current += sizeof(acpi_xsdt_t); + + /* 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_dsdt(dsdt, AmlCode , ¤t); + + acpi_write_facs(facs, ¤t); + acpi_write_fadt(fadt, facs, dsdt, rsdp, ¤t); + acpi_write_hpet(hpet, rsdp, ¤t); + + acpi_write_madt(madt, rsdp, ¤t); + + acpi_write_mcfg(mcfg, rsdp, ¤t); + + acpi_write_srat(srat, rsdp, ¤t); + + acpi_write_slit(slit, rsdp, ¤t); + +#if CONFIG_HAVE_ACPI_SLIC + acpi_write_slic(slic, rsdp, ¤t); +#endif + + acpi_write_ssdt_generated(ssdt, rsdp, ¤t); + + printk(BIOS_DEBUG, "current = %lx\n", current); + + acpi_dmi_workaround(¤t); + +#if CONFIG_DEBUG_ACPI == 1 + printk(BIOS_DEBUG, "rsdp\n"); + dump_mem(rsdp, ((void *)rsdp) + sizeof(acpi_rsdp_t)); + + printk(BIOS_DEBUG, "rsdt\n"); + dump_mem(rsdt, ((void *)rsdt) + sizeof(acpi_rsdt_t)); + + printk(BIOS_DEBUG, "madt\n"); + dump_mem(madt, ((void *)madt) + madt->header.length); + + printk(BIOS_DEBUG, "srat\n"); + dump_mem(srat, ((void *)srat) + srat->header.length); + + printk(BIOS_DEBUG, "slit\n"); + dump_mem(slit, ((void *)slit) + slit->header.length); + + printk(BIOS_DEBUG, "ssdt\n"); + dump_mem(ssdt, ((void *)ssdt) + ssdt->length); + + printk(BIOS_DEBUG, "fadt\n"); + dump_mem(fadt, ((void *)fadt) + fadt->header.length); +#endif + + printk(BIOS_INFO, "ACPI: done.\n"); + return current; +} + #if CONFIG_HAVE_ACPI_RESUME == 1 void suspend_resume(void) { diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index 030745d..01f4b12 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,25 @@ void acpi_create_facs(acpi_facs_t *facs);
#if CONFIG_HAVE_ACPI_SLIC unsigned long acpi_create_slic(unsigned long current); +void acpi_write_slic(acpi_header_t *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); +void acpi_write_dsdt(acpi_header_t *dsdt, const unsigned char AmlCode[], unsigned long *current); +void acpi_patch_dsdt(acpi_header_t *dsdt, unsigned long *current); +void acpi_dmi_workaround(unsigned long *current); + +void acpi_write_facs(acpi_facs_t *facs, unsigned long *current); +void acpi_write_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, acpi_header_t *dsdt, acpi_rsdp_t *rsdp, unsigned long *current); +void acpi_write_hpet(acpi_hpet_t *hpet, acpi_rsdp_t *rsdp, unsigned long *current); +void acpi_write_madt(acpi_madt_t *madt, acpi_rsdp_t *rsdp, unsigned long *current); +void acpi_write_srat(acpi_srat_t *srat, acpi_rsdp_t *rsdp, unsigned long *current); +void acpi_write_slit(acpi_slit_t *slit, acpi_rsdp_t *rsdp, unsigned long *current); +void acpi_write_ssdt_generated(acpi_header_t *ssdt, acpi_rsdp_t *rsdp, unsigned long *current); +void acpi_write_mcfg(acpi_mcfg_t *mcfg, acpi_rsdp_t *rsdp, unsigned long *current); +unsigned long acpi_write_tables(unsigned long start, const unsigned char AmlCode[]);
#if CONFIG_HAVE_ACPI_RESUME /* 0 = S0, 1 = S1 ...*/