Clean up AMD Fam14 SSDT
[coreboot.git] / src / mainboard / amd / union_station / acpi_tables.c
index ae058d6a786538826db0ab2880384562e1bc94c6..74df922b19b98a28ccb1787536a83840c2ef8885 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)
 {
@@ -62,13 +84,14 @@ unsigned long acpi_fill_madt(unsigned long current)
        current = acpi_create_madt_lapics(current);
 
        /* Write SB800 IOAPIC, only one */
-       current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, CONFIG_MAX_CPUS,
-                                                IO_APIC_ADDR, 0);
+       current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+                               CONFIG_MAX_CPUS, IO_APIC_ADDR, 0);
 
        current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
-                                               current, 0, 0, 2, 0);
+                       current, 0, 0, 2, 0);
        current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
-                                               current, 0, 9, 9, 0xF);
+                       current, 0, 9, 9, 0xF);
+
        /* 0: mean bus 0--->ISA */
        /* 0: PIC 0 */
        /* 2: APIC 2 */
@@ -106,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,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);
@@ -138,12 +162,12 @@ 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
+       printk(BIOS_DEBUG, "ACPI:  * FACS at %lx\n", current);
+       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;
@@ -177,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;
@@ -189,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);
@@ -204,21 +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);
-               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);
+       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");
@@ -239,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