summaryrefslogtreecommitdiff
path: root/src/mainboard/amd/south_station
diff options
context:
space:
mode:
authorzbao <fishbaozi@gmail.com>2012-04-13 13:57:14 +0800
committerPeter Stuge <peter@stuge.se>2012-04-16 04:56:05 +0200
commitcaf494c83170e97b192e2174bc461482699a3712 (patch)
tree2efa5ce9d290d80f7c16d4a89fc1bcb3139337fe /src/mainboard/amd/south_station
parent90655c83d03f51105ab561928224a1b50cebe829 (diff)
ACPI HEST table.
HEST feature starts from ACPI 4.0. HEST is one of four kinds of tables of ACPI Platform Error Interfaces (APEI). In Windows world, APEI is called Windows Hardware Error Architecture (WHEA). APEI consists of four separate tables: 1. Error Record Serialization Table (ERST) 2. BOOT Error Record Table (BERT) 3. Hardware Error Source Table (HEST) 4. Error Injection Table (EINJ) All these 4 tables have the same header as FADT, MADT, etc. They are pointed by RSDP. For the HEST, it contains the error source. The types of them are defined as type description 1. Machine Check Exception (MCE) 2. Corrected Machine Check (CMC) 3. NMI Error 6. PCI Express Root Port AER 7. PCI Express Device AER 8. PCI Express Bridge AER 9. Generic Hardware Error Source Error source types 3, 4, and 5 are reserved for legacy reasons and must not be used. Currently AMD board only provide part of "Machine Check Exception (MCE)" & Corrected Machine Check (CMC)". we need to provide the header of each error source. Other types of Error Sources is in TODO list. Only persimmon is tested. Linux can add HEST feature. The dmesg says, ACPI: HEST 0000000066fe5010 00198 (v03 CORE COREBOOT 00000000 CORE 00000000) ...... HEST: Table parsing has been initialized. No more message is got. Windows can boot with this patch. Havent found a way to test it. Change-Id: I447e7f57b8e8f0433a145a43d0710910afabf00f Signed-off-by: Zheng Bao <zheng.bao@amd.com> Signed-off-by: zbao <fishbaozi@gmail.com> Reviewed-on: http://review.coreboot.org/888 Reviewed-by: Peter Stuge <peter@stuge.se> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/mainboard/amd/south_station')
-rw-r--r--src/mainboard/amd/south_station/acpi_tables.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/src/mainboard/amd/south_station/acpi_tables.c b/src/mainboard/amd/south_station/acpi_tables.c
index 2e6e50fd4f..8d32614651 100644
--- a/src/mainboard/amd/south_station/acpi_tables.c
+++ b/src/mainboard/amd/south_station/acpi_tables.c
@@ -104,6 +104,24 @@ unsigned long acpi_fill_madt(unsigned long current)
return current;
}
+unsigned long acpi_fill_hest(acpi_hest_t *hest)
+{
+ void *addr, *current;
+
+ /* Skip the HEST header. */
+ current = (void *)(hest + 1);
+
+ addr = agesawrapper_getlateinitptr(PICK_WHEA_MCE);
+ if (addr != NULL)
+ current += acpi_create_hest_error_source(hest, current, 0, (void *)((u32)addr + 2), *(UINT16 *)addr - 2);
+
+ addr = agesawrapper_getlateinitptr(PICK_WHEA_CMC);
+ if (addr != NULL)
+ current += acpi_create_hest_error_source(hest, current, 1, (void *)((u32)addr + 2), *(UINT16 *)addr - 2);
+
+ return (unsigned long)current;
+}
+
unsigned long acpi_fill_slit(unsigned long current)
{
// Not implemented
@@ -131,6 +149,7 @@ unsigned long write_acpi_tables(unsigned long start)
acpi_header_t *ssdt;
acpi_header_t *ssdt2;
acpi_header_t *alib;
+ acpi_hest_t *hest;
get_bus_conf(); /* it will get sblk, pci1234, hcdn, and sbdn */
@@ -153,7 +172,7 @@ unsigned long write_acpi_tables(unsigned long start)
acpi_write_rsdt(rsdt);
/* DSDT */
- current = ( current + 0x07) & -0x08;
+ 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));
@@ -162,14 +181,14 @@ unsigned long write_acpi_tables(unsigned long start)
printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n",dsdt,dsdt->length);
/* FACS */ // it needs 64 bit alignment
- current = ( current + 0x07) & -0x08;
+ 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;
+ current = (current + 0x07) & -0x08;
printk(BIOS_DEBUG, "ACPI: * FADT at %lx\n", current);
fadt = (acpi_fadt_t *) current;
current += sizeof(acpi_fadt_t);
@@ -180,7 +199,7 @@ unsigned long write_acpi_tables(unsigned long start)
/*
* We explicitly add these tables later on:
*/
- current = ( current + 0x07) & -0x08;
+ current = (current + 0x07) & -0x08;
printk(BIOS_DEBUG, "ACPI: * HPET at %lx\n", current);
hpet = (acpi_hpet_t *) current;
current += sizeof(acpi_hpet_t);
@@ -188,15 +207,22 @@ unsigned long write_acpi_tables(unsigned long start)
acpi_add_table(rsdp, hpet);
/* If we want to use HPET Timers Linux wants an MADT */
- current = ( current + 0x07) & -0x08;
+ 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);
+ /* HEST */
+ current = (current + 0x07) & -0x08;
+ hest = (acpi_hest_t *)current;
+ acpi_write_hest((void *)current);
+ acpi_add_table(rsdp, (void *)current);
+ current += ((acpi_header_t *)current)->length;
+
/* SRAT */
- current = ( current + 0x07) & -0x08;
+ current = (current + 0x07) & -0x08;
printk(BIOS_DEBUG, "ACPI: * SRAT at %lx\n", current);
srat = (acpi_srat_t *) agesawrapper_getlateinitptr (PICK_SRAT);
if (srat != NULL) {
@@ -210,7 +236,7 @@ unsigned long write_acpi_tables(unsigned long start)
}
/* SLIT */
- current = ( current + 0x07) & -0x08;
+ current = (current + 0x07) & -0x08;
printk(BIOS_DEBUG, "ACPI: * SLIT at %lx\n", current);
slit = (acpi_slit_t *) agesawrapper_getlateinitptr (PICK_SLIT);
if (slit != NULL) {
@@ -224,7 +250,7 @@ unsigned long write_acpi_tables(unsigned long start)
}
/* SSDT */
- current = ( current + 0x0f) & -0x10;
+ current = (current + 0x0f) & -0x10;
printk(BIOS_DEBUG, "ACPI: * AGESA ALIB SSDT at %lx\n", current);
alib = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_ALIB);
if (alib != NULL) {
@@ -238,7 +264,7 @@ unsigned long write_acpi_tables(unsigned long start)
}
#if 0 // The DSDT needs additional work for the AGESA SSDT Pstate table
- current = ( current + 0x0f) & -0x10;
+ 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) {
@@ -252,7 +278,7 @@ unsigned long write_acpi_tables(unsigned long start)
acpi_add_table(rsdp,ssdt);
#endif
- current = ( current + 0x0f) & -0x10;
+ 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);
@@ -283,6 +309,9 @@ unsigned long write_acpi_tables(unsigned long start)
printk(BIOS_DEBUG, "fadt\n");
dump_mem(fadt, ((void *)fadt) + fadt->header.length);
+
+ printk(BIOS_DEBUG, "hest\n");
+ dump_mem(hest, ((void *)hest) + hest->header.length);
#endif
printk(BIOS_INFO, "ACPI: done.\n");