summaryrefslogtreecommitdiff
path: root/src/mainboard/amd/olivehillplus/acpi_tables.c
diff options
context:
space:
mode:
authorBruce Griffith <Bruce.Griffith@se-eng.com>2014-08-15 12:38:21 -0600
committerBruce Griffith <Bruce.Griffith@se-eng.com>2014-09-04 23:53:56 +0200
commit79f47cf8c0c54848ee13b727482ff8936a68e1f5 (patch)
tree1216e022d1eca8ca86eaea545e006f9397e99a3f /src/mainboard/amd/olivehillplus/acpi_tables.c
parent3c12cb03847d2db41809ae434530782a7dbef48b (diff)
downloadcoreboot-79f47cf8c0c54848ee13b727482ff8936a68e1f5.tar.xz
mainboard: Add AMD DB-FT3b (Olive Hill+) with Steppe Eagle SoC
Create a new mainboard based on the AMD DB-FT3 development board (Olive Hill) using an AMD Steppe Eagle processor. The actual DB-FT3 and DB-FT3b mainboards are identical except for the soldered-down SoC device. The new AMD DB-FT3b development board (Olive Hill+) features: * Mini-ITX form factor * 2x DisplayPort * 1x VGA * Integrated Realtek RTL8111-compatible Ethernet * 2x USB 3.0 ports * 2x USB 2.0 externally-accessible ports * 2x USB 2.0 internally-accessible ports (via headers) * micro LPC header * Integrated platform security processor * 2x Full-size DDR3 DIMM support (1 channel) * Realtek ALC272 HD audio * 2x SATA ports * 1x SD card slot * 1x PCIe (x4) slot * 1x mini-PCIe slot * 8-pin programming header Eliminate the extraneous headers included in PlatformGnbPcie. BiosCallOuts normally has a bunch of extraneous references to the mainboard name. Rather than correct the spelling of a bunch of instances, just get rid of them. For the most part, use the Olive Hill ACPI definitions since the DB-FT3b board ("Olive Hill+") and Olive Hill are the same board with different processors. Change some function prototypes for functions without parameters to void instead of AGESA's VOID. There are no parameters for these functions, so there is no real reason to use VOID. S3 and fan control are not supported. HD audio is not working. Change-Id: I794d7a8f4f948346cfe7cbd443c9aed5f70c99ed Signed-off-by: Bruce Griffith <Bruce.Griffith@se-eng.com> Reviewed-on: http://review.coreboot.org/6681 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Reviewed-by: Martin Roth <gaumless@gmail.com>
Diffstat (limited to 'src/mainboard/amd/olivehillplus/acpi_tables.c')
-rw-r--r--src/mainboard/amd/olivehillplus/acpi_tables.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/mainboard/amd/olivehillplus/acpi_tables.c b/src/mainboard/amd/olivehillplus/acpi_tables.c
new file mode 100644
index 0000000000..e066f15bd2
--- /dev/null
+++ b/src/mainboard/amd/olivehillplus/acpi_tables.c
@@ -0,0 +1,286 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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
+ * 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
+ */
+
+#include "agesawrapper.h"
+
+#include <console/console.h>
+#include <string.h>
+#include <arch/acpi.h>
+#include <arch/acpigen.h>
+#include <arch/ioapic.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/mtrr.h>
+#include <cpu/amd/amdfam16.h>
+
+extern const unsigned char AmlCode[];
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+ /* Just a dummy */
+ return current;
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+ /* create all subtables for processors */
+ 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);
+
+ /* TODO: Remove the hardcode */
+ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, CONFIG_MAX_CPUS+1,
+ 0xFEC20000, 24);
+
+ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+ current, 0, 0, 2, 0);
+ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+ current, 0, 9, 9, 0xF);
+ /* 0: mean bus 0--->ISA */
+ /* 0: PIC 0 */
+ /* 2: APIC 2 */
+ /* 5 mean: 0101 --> Edge-triggered, Active high */
+
+ /* create all subtables for processors */
+ current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, 0xff, 5, 1);
+ /* 1: LINT1 connect to NMI */
+
+ 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 */
+ return current;
+}
+
+unsigned long acpi_fill_srat(unsigned long current)
+{
+ /* No NUMA, no SRAT */
+ return current;
+}
+
+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 write_acpi_tables(unsigned long start)
+{
+ unsigned long current;
+ acpi_rsdp_t *rsdp;
+ acpi_rsdt_t *rsdt;
+ acpi_hpet_t *hpet;
+ acpi_madt_t *madt;
+ acpi_srat_t *srat;
+ acpi_slit_t *slit;
+ acpi_fadt_t *fadt;
+ acpi_facs_t *facs;
+ acpi_header_t *dsdt;
+ acpi_header_t *ssdt;
+ acpi_header_t *alib;
+ acpi_header_t *ivrs;
+ acpi_hest_t *hest;
+
+ /* Align ACPI tables to 16 bytes */
+ start = ALIGN(start, 16);
+ current = start;
+
+ printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", start);
+
+ /* We need at least an RSDP and an RSDT Table */
+ rsdp = (acpi_rsdp_t *) current;
+ current += sizeof(acpi_rsdp_t);
+ rsdt = (acpi_rsdt_t *) current;
+ current += sizeof(acpi_rsdt_t);
+
+ /* clear all table memory */
+ memset((void *)start, 0, current - start);
+
+ acpi_write_rsdp(rsdp, rsdt, NULL);
+ acpi_write_rsdt(rsdt);
+
+ /* DSDT */
+ current = ALIGN(current, 8);
+ 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 = ALIGN(current, 8);
+ 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);
+
+ /* FADT */
+ current = ALIGN(current, 8);
+ 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 = ALIGN(current, 8);
+ 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 = ALIGN(current, 8);
+ 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 = ALIGN(current, 8);
+ hest = (acpi_hest_t *)current;
+ acpi_write_hest((void *)current);
+ acpi_add_table(rsdp, (void *)current);
+ current += ((acpi_header_t *)current)->length;
+
+ current = ALIGN(current, 8);
+ printk(BIOS_DEBUG, "ACPI: * IVRS at %lx\n", current);
+ ivrs = agesawrapper_getlateinitptr(PICK_IVRS);
+ if (ivrs != NULL) {
+ memcpy((void *)current, ivrs, ivrs->length);
+ ivrs = (acpi_header_t *) current;
+ current += ivrs->length;
+ acpi_add_table(rsdp, ivrs);
+ } else {
+ printk(BIOS_DEBUG, " AGESA IVRS table NULL. Skipping.\n");
+ }
+
+ /* SRAT */
+ current = ALIGN(current, 8);
+ 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;
+ current += srat->header.length;
+ acpi_add_table(rsdp, srat);
+ } else {
+ printk(BIOS_DEBUG, " AGESA SRAT table NULL. Skipping.\n");
+ }
+
+ /* SLIT */
+ current = ALIGN(current, 8);
+ 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;
+ current += slit->header.length;
+ acpi_add_table(rsdp, slit);
+ } else {
+ printk(BIOS_DEBUG, " AGESA SLIT table NULL. Skipping.\n");
+ }
+
+ /* ALIB */
+ current = ALIGN(current, 16);
+ printk(BIOS_DEBUG, "ACPI: * AGESA ALIB SSDT at %lx\n", current);
+ alib = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_ALIB);
+ if (alib != NULL) {
+ memcpy((void *)current, alib, alib->length);
+ alib = (acpi_header_t *) current;
+ current += alib->length;
+ acpi_add_table(rsdp, (void *)alib);
+ }
+ else {
+ printk(BIOS_DEBUG, " AGESA ALIB SSDT table NULL. Skipping.\n");
+ }
+
+ /* this pstate ssdt may cause Blue Screen: Fixed: Keep this comment for a while. */
+ /* SSDT */
+ current = ALIGN(current, 16);
+ printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
+ ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
+ if (ssdt != NULL) {
+ memcpy((void *)current, ssdt, ssdt->length);
+ ssdt = (acpi_header_t *) current;
+ current += ssdt->length;
+ }
+ else {
+ printk(BIOS_DEBUG, " AGESA PState table NULL. Skipping.\n");
+ }
+ acpi_add_table(rsdp,ssdt);
+
+ printk(BIOS_DEBUG, "ACPI: * SSDT for PState at %lx\n", current);
+
+ printk(BIOS_DEBUG, "ACPI: * SSDT\n");
+ ssdt = (acpi_header_t *)current;
+
+ acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR);
+ current += ssdt->length;
+ acpi_add_table(rsdp, ssdt);
+
+ printk(BIOS_INFO, "ACPI: done.\n");
+ return current;
+}