Clean up AMD Fam14 SSDT
[coreboot.git] / src / mainboard / amd / persimmon / acpi_tables.c
index 637a304cefcd6df6125b152c1c52119401b45fd8..47e35af86f3e5e0001ab66b4266128c3812318d0 100644 (file)
@@ -9,12 +9,12 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,  MA 02110-1301 USA
  */
 
 #include <console/console.h>
@@ -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 */
 
@@ -130,23 +153,23 @@ 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
+       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);
+       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
+       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);
+       printk(BIOS_DEBUG, "ACPI:  * FADT at %lx\n", current);
        fadt = (acpi_fadt_t *) current;
        current += sizeof(acpi_fadt_t);
 
@@ -157,7 +180,7 @@ unsigned long write_acpi_tables(unsigned long start)
         * We explicitly add these tables later on:
         */
        current  = ( current + 0x07) & -0x08;
-       printk(BIOS_DEBUG, "ACPI:       * HPET at %lx\n", current);
+       printk(BIOS_DEBUG, "ACPI:  * HPET at %lx\n", current);
        hpet = (acpi_hpet_t *) current;
        current += sizeof(acpi_hpet_t);
        acpi_create_hpet(hpet);
@@ -165,7 +188,7 @@ unsigned long write_acpi_tables(unsigned long start)
 
        /* If we want to use HPET Timers Linux wants an MADT */
        current  = ( current + 0x07) & -0x08;
-       printk(BIOS_DEBUG, "ACPI:       * MADT at %lx\n",current);
+       printk(BIOS_DEBUG, "ACPI:  * MADT at %lx\n",current);
        madt = (acpi_madt_t *) current;
        acpi_create_madt(madt);
        current += madt->header.length;
@@ -173,31 +196,35 @@ unsigned long write_acpi_tables(unsigned long start)
 
        /* SRAT */
        current  = ( current + 0x07) & -0x08;
-       printk(BIOS_DEBUG, "ACPI:       * SRAT at %lx\n", current);
+       printk(BIOS_DEBUG, "ACPI:  * SRAT at %lx\n", current);
        srat = (acpi_srat_t *) agesawrapper_getlateinitptr (PICK_SRAT);
        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);
+               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);
+       printk(BIOS_DEBUG, "ACPI:  * SLIT at %lx\n", current);
        slit = (acpi_slit_t *) agesawrapper_getlateinitptr (PICK_SLIT);
        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);
+               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);
+       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