Clean up AMD Fam14 SSDT
[coreboot.git] / src / mainboard / asrock / e350m1 / acpi_tables.c
index 593ec46eed62b1f0eb059bbc68d2f8a83d0359f9..74df922b19b98a28ccb1787536a83840c2ef8885 100644 (file)
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <cpu/x86/msr.h>
-#include <cpu/amd/mtrr.h>
-//#include <cpu/amd/amdfam10_sysconf.h>
-
-//#include "mb_sysconf.h"
 #include "agesawrapper.h"
+#include <cpu/amd/mtrr.h>
+#include <cpu/amd/amdfam14.h>
 
 #define DUMP_ACPI_TABLES 0
 
@@ -50,7 +48,29 @@ static void dump_mem(u32 start, u32 end)
 #endif
 
 extern const unsigned char AmlCode[];
-extern const unsigned char AmlCode_ssdt[];
+
+unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id)
+{
+       int lens;
+       msr_t msr;
+       char pscope[] = "\\_SB.PCI0";
+
+       lens = acpigen_write_scope(pscope);
+       msr = rdmsr(TOP_MEM);
+       lens += acpigen_write_name_dword("TOM1", msr.lo);
+       msr = rdmsr(TOP_MEM2);
+       /*
+        * Since XP only implements parts of ACPI 2.0, we can't use a qword
+        * here.
+        * See http://www.acpi.info/presentations/S01USMOBS169_OS%2520new.ppt
+        * slide 22ff.
+        * Shift value right by 20 bit to make it fit into 32bit,
+        * giving us 1MB granularity and a limit of almost 4Exabyte of memory.
+        */
+       lens += acpigen_write_name_dword("TOM2", (msr.hi << 12) | msr.lo >> 20);
+       acpigen_patch_len(lens - 1);
+       return (unsigned long) (acpigen_get_current());
+}
 
 unsigned long acpi_fill_mcfg(unsigned long current)
 {
@@ -109,6 +129,7 @@ unsigned long write_acpi_tables(unsigned long start)
        acpi_facs_t *facs;
        acpi_header_t *dsdt;
        acpi_header_t *ssdt;
+       acpi_header_t *ssdt2;
 
        get_bus_conf(); /* it will get sblk, pci1234, hcdn, and sbdn */
 
@@ -130,99 +151,97 @@ unsigned long write_acpi_tables(unsigned long start)
        acpi_write_rsdp(rsdp, rsdt, NULL);
        acpi_write_rsdt(rsdt);
 
+       /* DSDT */
+       current  = ( current + 0x07) & -0x08;
+       printk(BIOS_DEBUG, "ACPI:  * DSDT at %lx\n", current);
+       dsdt = (acpi_header_t *)current;
+       memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
+       current += dsdt->length;
+       memcpy(dsdt, &AmlCode, dsdt->length);
+       printk(BIOS_DEBUG, "ACPI:  * DSDT @ %p Length %x\n",dsdt,dsdt->length);
+
+       /* FACS */ // it needs 64 bit alignment
+       current  = ( current + 0x07) & -0x08;
+       printk(BIOS_DEBUG, "ACPI:  * FACS at %lx\n", current);
+       facs = (acpi_facs_t *) current;
+       current += sizeof(acpi_facs_t);
+       acpi_create_facs(facs);
+
+       /* FADT */
+       current  = ( current + 0x07) & -0x08;
+       printk(BIOS_DEBUG, "ACPI:  * FADT at %lx\n", current);
+       fadt = (acpi_fadt_t *) current;
+       current += sizeof(acpi_fadt_t);
+
+       acpi_create_fadt(fadt, facs, dsdt);
+       acpi_add_table(rsdp, fadt);
+
        /*
-       * We explicitly add these tables later on:
-       */
-       current   = ( current + 0x07) & -0x08;
-       printk(BIOS_DEBUG, "ACPI:    * HPET at %lx\n", current);
+        * We explicitly add these tables later on:
+        */
+       current  = ( current + 0x07) & -0x08;
+       printk(BIOS_DEBUG, "ACPI:  * HPET at %lx\n", current);
        hpet = (acpi_hpet_t *) current;
        current += sizeof(acpi_hpet_t);
        acpi_create_hpet(hpet);
        acpi_add_table(rsdp, hpet);
 
        /* If we want to use HPET Timers Linux wants an MADT */
-       current   = ( current + 0x07) & -0x08;
-       printk(BIOS_DEBUG, "ACPI:    * MADT at %lx\n",current);
+       current  = ( current + 0x07) & -0x08;
+       printk(BIOS_DEBUG, "ACPI:  * MADT at %lx\n",current);
        madt = (acpi_madt_t *) current;
        acpi_create_madt(madt);
        current += madt->header.length;
        acpi_add_table(rsdp, madt);
 
        /* SRAT */
-       current   = ( current + 0x07) & -0x08;
-       printk(BIOS_DEBUG, "ACPI:    * SRAT at %lx\n", current);
+       current  = ( current + 0x07) & -0x08;
+       printk(BIOS_DEBUG, "ACPI:  * SRAT at %lx\n", current);
        srat = (acpi_srat_t *) agesawrapper_getlateinitptr (PICK_SRAT);
        if (srat != NULL) {
-       memcpy(current, srat, srat->header.length);
-       srat = (acpi_srat_t *) current;
-       //acpi_create_srat(srat);
-       current += srat->header.length;
-       acpi_add_table(rsdp, srat);
+               memcpy((void *)current, srat, srat->header.length);
+               srat = (acpi_srat_t *) current;
+               current += srat->header.length;
+               acpi_add_table(rsdp, srat);
+       }
+       else {
+               printk(BIOS_DEBUG, "  AGESA SRAT table NULL. Skipping.\n");
        }
 
        /* SLIT */
-       current   = ( current + 0x07) & -0x08;
-       printk(BIOS_DEBUG, "ACPI:   * SLIT at %lx\n", current);
+       current  = ( current + 0x07) & -0x08;
+       printk(BIOS_DEBUG, "ACPI:  * SLIT at %lx\n", current);
        slit = (acpi_slit_t *) agesawrapper_getlateinitptr (PICK_SLIT);
        if (slit != NULL) {
-       memcpy(current, slit, slit->header.length);
-       slit = (acpi_slit_t *) current;
-       //acpi_create_slit(slit);
-       current += slit->header.length;
-       acpi_add_table(rsdp, slit);
+               memcpy((void *)current, slit, slit->header.length);
+               slit = (acpi_slit_t *) current;
+               current += slit->header.length;
+               acpi_add_table(rsdp, slit);
+       }
+       else {
+               printk(BIOS_DEBUG, "  AGESA SLIT table NULL. Skipping.\n");
        }
 
        /* SSDT */
-       current   = ( current + 0x0f) & -0x10;
-       printk(BIOS_DEBUG, "ACPI:    * SSDT at %lx\n", current);
+       current  = ( current + 0x0f) & -0x10;
+       printk(BIOS_DEBUG, "ACPI:  * AGESA SSDT Pstate at %lx\n", current);
        ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
        if (ssdt != NULL) {
-       memcpy(current, ssdt, ssdt->length);
-       ssdt = (acpi_header_t *) current;
-       current += ssdt->length;
+               memcpy((void *)current, ssdt, ssdt->length);
+               ssdt = (acpi_header_t *) current;
+               current += ssdt->length;
        }
        else {
-       ssdt = (acpi_header_t *) current;
-       memcpy(ssdt, &AmlCode_ssdt, sizeof(acpi_header_t));
-       current += ssdt->length;
-       memcpy(ssdt, &AmlCode_ssdt, ssdt->length);
-
-       char *position = ssdt;
-       if (memcmp (position + 50, "TOM1", 4) == 0)
-       *(u32 *) (position + 55) = __readmsr (0xc001001a);
-
-       /* recalculate checksum */
-       ssdt->checksum = 0;
-       ssdt->checksum = acpi_checksum((unsigned char *)ssdt,ssdt->length);
+               printk(BIOS_DEBUG, "  AGESA SSDT table NULL. Skipping.\n");
        }
        acpi_add_table(rsdp,ssdt);
 
-       printk(BIOS_DEBUG, "ACPI:    * SSDT for PState at %lx\n", current);
-
-       /* DSDT */
-       current   = ( current + 0x07) & -0x08;
-       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);
-       printk(BIOS_DEBUG, "ACPI:    * DSDT @ %p Length %x\n",dsdt,dsdt->length);
-
-       /* FACS */ // it needs 64 bit alignment
-       current   = ( current + 0x07) & -0x08;
-       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);
-       acpi_create_facs(facs);
-
-       /* FDAT */
-       current   = ( current + 0x07) & -0x08;
-       printk(BIOS_DEBUG, "ACPI:    * FADT at %lx\n", current);
-       fadt = (acpi_fadt_t *) current;
-       current += sizeof(acpi_fadt_t);
-
-       acpi_create_fadt(fadt, facs, dsdt);
-       acpi_add_table(rsdp, fadt);
+       current  = ( current + 0x0f) & -0x10;
+       printk(BIOS_DEBUG, "ACPI:  * coreboot TOM SSDT2 at %lx\n", current);
+       ssdt2 = (acpi_header_t *) current;
+       acpi_create_ssdt_generator(ssdt2, ACPI_TABLE_CREATOR);
+       current += ssdt2->length;
+       acpi_add_table(rsdp,ssdt2);
 
 #if DUMP_ACPI_TABLES == 1
        printk(BIOS_DEBUG, "rsdp\n");
@@ -243,6 +262,9 @@ unsigned long write_acpi_tables(unsigned long start)
        printk(BIOS_DEBUG, "ssdt\n");
        dump_mem(ssdt, ((void *)ssdt) + ssdt->length);
 
+       printk(BIOS_DEBUG, "ssdt2\n");
+       dump_mem(ssdt2, ((void *)ssdt2) + ssdt2->length);
+
        printk(BIOS_DEBUG, "fadt\n");
        dump_mem(fadt, ((void *)fadt) + fadt->header.length);
 #endif