Clean up AMD Fam14 SSDT
[coreboot.git] / src / mainboard / amd / persimmon / acpi_tables.c
index 99a6e887a62f0b3201512298ef822be9ed95354d..47e35af86f3e5e0001ab66b4266128c3812318d0 100644 (file)
@@ -48,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)
 {
@@ -107,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 */
 
@@ -131,7 +154,7 @@ unsigned long write_acpi_tables(unsigned long start)
        /* DSDT */
        current  = ( current + 0x07) & -0x08;
        printk(BIOS_DEBUG, "ACPI:  * DSDT at %lx\n", current);
-       dsdt = (acpi_header_t *)current; // it will used by fadt
+       dsdt = (acpi_header_t *)current;
        memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
        current += dsdt->length;
        memcpy(dsdt, &AmlCode, dsdt->length);
@@ -140,11 +163,11 @@ unsigned long write_acpi_tables(unsigned long start)
        /* 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
+       facs = (acpi_facs_t *) current;
        current += sizeof(acpi_facs_t);
        acpi_create_facs(facs);
 
-       /* FDAT */
+       /* FADT */
        current  = ( current + 0x07) & -0x08;
        printk(BIOS_DEBUG, "ACPI:  * FADT at %lx\n", current);
        fadt = (acpi_fadt_t *) current;
@@ -178,10 +201,12 @@ unsigned long write_acpi_tables(unsigned long start)
        if (srat != NULL) {
                memcpy((void *)current, srat, srat->header.length);
                srat = (acpi_srat_t *) current;
-               //acpi_create_srat(srat);
                current += srat->header.length;
                acpi_add_table(rsdp, srat);
        }
+       else {
+               printk(BIOS_DEBUG, "  AGESA SRAT table NULL. Skipping.\n");
+       }
 
        /* SLIT */
        current  = ( current + 0x07) & -0x08;
@@ -190,14 +215,16 @@ unsigned long write_acpi_tables(unsigned long start)
        if (slit != NULL) {
                memcpy((void *)current, slit, slit->header.length);
                slit = (acpi_slit_t *) current;
-               //acpi_create_slit(slit);
                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);
+       printk(BIOS_DEBUG, "ACPI:  * AGESA SSDT Pstate at %lx\n", current);
        ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
        if (ssdt != NULL) {
                memcpy((void *)current, ssdt, ssdt->length);
@@ -205,17 +232,16 @@ unsigned long write_acpi_tables(unsigned long start)
                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);
-                /* 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);
+       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");
@@ -236,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