| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * Copyright (C) 2013 Advanced Micro Devices, Inc. | ||
| * Copyright (C) 2013 Sage Electronic Engineering, LLC | ||
| * | ||
| * 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 | ||
| */ | ||
|
|
||
| /* DefinitionBlock Statement */ | ||
| DefinitionBlock ( | ||
| "DSDT.AML", /* Output filename */ | ||
| "DSDT", /* Signature */ | ||
| 0x02, /* DSDT Revision, needs to be 2 for 64bit */ | ||
| "AMD ", /* OEMID */ | ||
| "COREBOOT", /* TABLE ID */ | ||
| 0x00010001 /* OEM Revision */ | ||
| ) | ||
| { /* Start of ASL file */ | ||
| /* #include <arch/x86/acpi/debug.asl> */ /* Include global debug methods if needed */ | ||
|
|
||
| /* Globals for the platform */ | ||
| #include "acpi/mainboard.asl" | ||
|
|
||
| /* Describe the USB Overcurrent pins */ | ||
| #include "acpi/usb_oc.asl" | ||
|
|
||
| /* PCI IRQ mapping for the Southbridge */ | ||
| #include <southbridge/amd/pi/hudson/acpi/pcie.asl> | ||
|
|
||
| /* Describe the processor tree (\_PR) */ | ||
| #include <cpu/amd/pi/00730F01/acpi/cpu.asl> | ||
|
|
||
| /* Contains the supported sleep states for this chipset */ | ||
| #include <southbridge/amd/pi/hudson/acpi/sleepstates.asl> | ||
|
|
||
| /* Contains the Sleep methods (WAK, PTS, GTS, etc.) */ | ||
| #include "acpi/sleep.asl" | ||
|
|
||
| /* System Bus */ | ||
| Scope(\_SB) { /* Start \_SB scope */ | ||
| /* global utility methods expected within the \_SB scope */ | ||
| #include <arch/x86/acpi/globutil.asl> | ||
|
|
||
| /* Describe IRQ Routing mapping for this platform (within the \_SB scope) */ | ||
| #include "acpi/routing.asl" | ||
|
|
||
| Device(PWRB) { | ||
| Name(_HID, EISAID("PNP0C0C")) | ||
| Name(_UID, 0xAA) | ||
| Name(_PRW, Package () {3, 0x04}) | ||
| Name(_STA, 0x0B) | ||
| } | ||
|
|
||
| Device(PCI0) { | ||
| /* Describe the AMD Northbridge */ | ||
| #include <northbridge/amd/pi/00730F01/acpi/northbridge.asl> | ||
|
|
||
| /* Describe the AMD Fusion Controller Hub Southbridge */ | ||
| #include <southbridge/amd/pi/hudson/acpi/fch.asl> | ||
| } | ||
|
|
||
| /* Describe PCI INT[A-H] for the Southbridge */ | ||
| #include "acpi/pci_int.asl" | ||
|
|
||
|
|
||
|
|
||
|
|
||
| } /* End \_SB scope */ | ||
|
|
||
| /* Describe SMBUS for the Southbridge */ | ||
| #include <southbridge/amd/pi/hudson/acpi/smbus.asl> | ||
|
|
||
| /* Define the General Purpose Events for the platform */ | ||
| #include "acpi/gpe.asl" | ||
|
|
||
| /* Define the Thermal zones and methods for the platform */ | ||
| #include "acpi/thermal.asl" | ||
|
|
||
| /* Define the System Indicators for the platform */ | ||
| #include "acpi/si.asl" | ||
| } | ||
| /* End of ASL file */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| /* | ||
| * 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 <console/console.h> | ||
| #include <device/pci.h> | ||
| #include <string.h> | ||
| #include <stdint.h> | ||
| #include <arch/pirq_routing.h> | ||
| #include <cpu/amd/amdfam16.h> | ||
|
|
||
| static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn, | ||
| u8 link0, u16 bitmap0, u8 link1, u16 bitmap1, | ||
| u8 link2, u16 bitmap2, u8 link3, u16 bitmap3, | ||
| u8 slot, u8 rfu) | ||
| { | ||
| pirq_info->bus = bus; | ||
| pirq_info->devfn = devfn; | ||
| pirq_info->irq[0].link = link0; | ||
| pirq_info->irq[0].bitmap = bitmap0; | ||
| pirq_info->irq[1].link = link1; | ||
| pirq_info->irq[1].bitmap = bitmap1; | ||
| pirq_info->irq[2].link = link2; | ||
| pirq_info->irq[2].bitmap = bitmap2; | ||
| pirq_info->irq[3].link = link3; | ||
| pirq_info->irq[3].bitmap = bitmap3; | ||
| pirq_info->slot = slot; | ||
| pirq_info->rfu = rfu; | ||
| } | ||
|
|
||
| #define IRQ_BITMAP 0xdee8 //0xdef8 Removed IRQ 4, this is used for serial | ||
|
|
||
| unsigned long write_pirq_routing_table(unsigned long addr) | ||
| { | ||
| struct irq_routing_table *pirq; | ||
| struct irq_info *pirq_info; | ||
| u32 slot_num; | ||
| u8 *v; | ||
|
|
||
| u8 sum = 0; | ||
| int i; | ||
|
|
||
| /* Align the table to be 16 byte aligned. */ | ||
| addr += 15; | ||
| addr &= ~15; | ||
|
|
||
| /* This table must be between 0xf0000 & 0x100000 */ | ||
| printk(BIOS_INFO, "Writing IRQ routing tables to 0x%lx...", addr); | ||
|
|
||
| pirq = (void *)(addr); | ||
| v = (u8 *) (addr); | ||
|
|
||
| pirq->signature = PIRQ_SIGNATURE; | ||
| pirq->version = PIRQ_VERSION; | ||
|
|
||
| pirq->rtr_bus = 0; | ||
| pirq->rtr_devfn = PCI_DEVFN(0x14, 4); | ||
|
|
||
| pirq->exclusive_irqs = 0; | ||
|
|
||
| pirq->rtr_vendor = 0x1002; | ||
| pirq->rtr_device = 0x4384; | ||
|
|
||
| pirq->miniport_data = 0; | ||
|
|
||
| memset(pirq->rfu, 0, sizeof(pirq->rfu)); | ||
|
|
||
| pirq_info = (void *)(&pirq->checksum + 1); | ||
| slot_num = 0; | ||
|
|
||
| /* pci bridge */ | ||
| write_pirq_info(pirq_info, 0, PCI_DEVFN(0x14, 4), | ||
| 0x1, IRQ_BITMAP, 0x2, IRQ_BITMAP, 0x3, IRQ_BITMAP, 0x4, IRQ_BITMAP, 0, | ||
| 0); | ||
| pirq_info++; | ||
|
|
||
| slot_num++; | ||
|
|
||
| pirq->size = 32 + 16 * slot_num; | ||
|
|
||
| for (i = 0; i < pirq->size; i++) | ||
| sum += v[i]; | ||
|
|
||
| sum = pirq->checksum - sum; | ||
|
|
||
| if (sum != pirq->checksum) { | ||
| pirq->checksum = sum; | ||
| } | ||
|
|
||
| printk(BIOS_INFO, "write_pirq_routing_table done.\n"); | ||
|
|
||
| return (unsigned long)pirq_info; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,231 @@ | ||
| /* | ||
| * 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 <console/console.h> | ||
| #include <device/device.h> | ||
| #include <device/pci.h> | ||
| #include <arch/io.h> | ||
| #include <device/pci_def.h> | ||
| #include <arch/acpi.h> | ||
| #include <northbridge/amd/pi/BiosCallOuts.h> | ||
| #include <cpu/amd/pi/s3_resume.h> | ||
| #include <northbridge/amd/pi/agesawrapper.h> | ||
| #include <cpu/x86/msr.h> | ||
| #include <cpu/amd/mtrr.h> | ||
| #if CONFIG_USE_OPTION_TABLE | ||
| #include <pc80/mc146818rtc.h> | ||
| #endif //CONFIG_USE_OPTION_TABLE | ||
| #if CONFIG_HAVE_OPTION_TABLE | ||
| #include "option_table.h" | ||
| #endif //CONFIG_HAVE_OPTION_TABLE | ||
| #include <eltanhudson.h> | ||
| #include <timestamp.h> | ||
| #include <fchgpio.h> | ||
| #include "apu5.h" | ||
| #include <superio/nuvoton/nct5104d/nct5104d.h> | ||
| #include <northbridge/amd/pi/00730F01/eltannorthbridge.h> | ||
| #if CONFIG_USE_CBMEM_FILE_OVERRIDE | ||
| #include <boot/cbmemfile.h> | ||
| #endif //CONFIG_USE_CBMEM_FILE_OVERRIDE | ||
| #include <spd_cache.h> | ||
| #include <smbios.h> | ||
| #include <string.h> | ||
| #include <cpu/amd/amdfam16.h> | ||
| #include <cpuRegisters.h> | ||
| #include <build.h> | ||
| #include "bios_knobs.h" | ||
|
|
||
| /********************************************** | ||
| * enable the dedicated function in mainboard. | ||
| **********************************************/ | ||
|
|
||
| static void mainboard_enable(device_t dev) | ||
| { | ||
| struct device *sio_dev; | ||
|
|
||
| bool scon = check_console(); | ||
| setup_bsp_ramtop(); | ||
| u32 total_mem = bsp_topmem() / (1024 * 1024); | ||
| if (bsp_topmem2() > 0) | ||
| total_mem += (bsp_topmem2() / (1024 * 1024)) - 4 * 1024; | ||
| if (scon) { | ||
| printk(BIOS_ALERT, CONFIG_MAINBOARD_PART_NUMBER "\n"); | ||
| printk(BIOS_ALERT, "coreboot build %s\n", COREBOOT_YYYYMMDD_DATE); | ||
| printk(BIOS_ALERT, "BIOS version %s\n", COREBOOT_ORIGIN_GIT_TAG); | ||
| printk(BIOS_ALERT, "%d MB", total_mem); | ||
| } | ||
|
|
||
| u8 spd_buffer[SPD_SIZE]; | ||
| int index = 0; | ||
|
|
||
| /* One SPD file contains all 4 options, determine which index to read here, then call into the standard routines*/ | ||
|
|
||
| if ( ReadFchGpio(APU5_SPD_STRAP0_GPIO) ) index |= BIT0; | ||
| if ( ReadFchGpio(APU5_SPD_STRAP1_GPIO) ) index |= BIT1; | ||
|
|
||
| printk(BIOS_SPEW, "Reading SPD index %d to get ECC info \n", index); | ||
| if (read_spd_from_cbfs(spd_buffer, index) < 0) | ||
| spd_buffer[3]=3; // Indicate no ECC | ||
|
|
||
| if (scon) { | ||
| if ( spd_buffer[3] == 8 ) printk(BIOS_ALERT, " ECC"); | ||
| printk(BIOS_ALERT, " DRAM\n\n"); | ||
| } | ||
|
|
||
| // | ||
| // Enable the RTC output | ||
| // | ||
| pm_write16 ( PM_RTC_CONTROL, pm_read16( PM_RTC_CONTROL ) | (1 << 11)); | ||
|
|
||
| // | ||
| // Enable power on from WAKE# | ||
| // | ||
| pm_write16 ( PM_S_STATE_CONTROL, pm_read16( PM_S_STATE_CONTROL ) | (1 << 14)); | ||
|
|
||
| if (acpi_is_wakeup_s3()) | ||
| agesawrapper_fchs3earlyrestore(); | ||
|
|
||
| // | ||
| // SIO CONFIG, enable and disable UARTC and UARTD depending on the configuration | ||
| // | ||
| if (check_uartc()) { | ||
| printk(BIOS_INFO, "UARTC enabled\n"); | ||
|
|
||
| sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_SP3); | ||
| if ( sio_dev ) sio_dev->enabled = 1; | ||
| sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_GPIO0); | ||
| if ( sio_dev ) sio_dev->enabled = 0; | ||
| } else { | ||
| printk(BIOS_INFO, "UARTC disabled\n"); | ||
|
|
||
| sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_SP3); | ||
| if ( sio_dev ) sio_dev->enabled = 0; | ||
| sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_GPIO0); | ||
| if ( sio_dev ) sio_dev->enabled = 1; | ||
| } | ||
|
|
||
| if (check_uartd()) { | ||
| printk(BIOS_INFO, "UARTD enabled\n"); | ||
|
|
||
| sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_SP4); | ||
| if ( sio_dev ) sio_dev->enabled = 1; | ||
| sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_GPIO1); | ||
| if ( sio_dev ) sio_dev->enabled = 0; | ||
| } else { | ||
| printk(BIOS_INFO, "UARTD disabled\n"); | ||
|
|
||
| sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_SP4); | ||
| if ( sio_dev ) sio_dev->enabled = 0; | ||
| sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_GPIO1); | ||
| if ( sio_dev ) sio_dev->enabled = 1; | ||
| } | ||
| } | ||
|
|
||
| static void mainboard_final(void *chip_info) { | ||
|
|
||
| printk(BIOS_INFO, "Mainboard " CONFIG_MAINBOARD_PART_NUMBER "final\n"); | ||
|
|
||
| /* Disabling LPCCLK0 which is unused according to the schematic doesn't work. The system is stuck if we do this | ||
| * So we don't do this. | ||
| */ | ||
|
|
||
| #if CONFIG_DUMP_GPIO_CONFIGURATION | ||
| DumpGpioConfiguration( ); | ||
| #endif //CONFIG_DUMP_GPIO_CONFIGURATION | ||
|
|
||
| #if CONFIG_DUMP_CLOCK_CONFIGURATION | ||
| DumpClockConfiguration( ); | ||
| #endif //CONFIG_DUMP_GPIO_CONFIGURATION | ||
|
|
||
| #if CONFIG_DUMP_LINK_CONFIGURATION | ||
| DumpLinkConfiguration( ); | ||
| #endif //CONFIG_DUMP_LINK_CONFIGURATION | ||
|
|
||
| // | ||
| // Turn off LED 2 and 3 | ||
| // | ||
| printk(BIOS_INFO, "Turn off LED 2 and 3\n"); | ||
| WriteFchGpio( APU5_LED2_L_GPIO, 1); | ||
| WriteFchGpio( APU5_LED3_L_GPIO, 1); | ||
|
|
||
| printk(BIOS_INFO, "USB PORT ROUTING = 0x%08x\n", *((u8 *)(ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF ))); | ||
| if ( *((u8 *)(ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF )) & (1<<7) ) { | ||
|
|
||
| printk(BIOS_INFO, "USB PORT ROUTING = XHCI PORTS ENABLED\n"); | ||
| } else { | ||
|
|
||
| printk(BIOS_INFO, "USB PORT ROUTING = EHCI PORTS ENABLED\n"); | ||
| } | ||
| } | ||
|
|
||
| struct chip_operations mainboard_ops = { | ||
| .enable_dev = mainboard_enable, | ||
| .final = mainboard_final, | ||
| }; | ||
|
|
||
| const char *smbios_mainboard_serial_number(void) | ||
| { | ||
| static char serial[10]; | ||
| msr_t msr; | ||
| u32 mac_addr = 0; | ||
| device_t nic_dev; | ||
|
|
||
| // Allows the IO configuration space access method, IOCF8 and IOCFC, to be | ||
| // used to generate extended configuration cycles | ||
| msr = rdmsr(NB_CFG_MSR); | ||
| msr.hi |= (ENABLE_CF8_EXT_CFG); | ||
| wrmsr(NB_CFG_MSR, msr); | ||
|
|
||
| nic_dev = dev_find_slot(1, PCI_DEVFN(0, 0)); | ||
|
|
||
| if ((serial[0] != 0) || !nic_dev) | ||
| return serial; | ||
|
|
||
| // Read 4 bytes starting from 0x144 offset | ||
| mac_addr = pci_read_config32(nic_dev, 0x144); | ||
| // MSB here is always 0xff | ||
| // Discard it so only bottom 3b of mac address are left | ||
| mac_addr &= 0x00ffffff; | ||
|
|
||
| // Set bit EnableCf8ExtCfg back to 0 | ||
| msr.hi &= ~(ENABLE_CF8_EXT_CFG); | ||
| wrmsr(NB_CFG_MSR, msr); | ||
|
|
||
| // Calculate serial value | ||
| mac_addr /= 4; | ||
| mac_addr -= 64; | ||
|
|
||
| snprintf(serial, sizeof(serial), "%d", mac_addr); | ||
|
|
||
| return serial; | ||
| } | ||
|
|
||
| const char *smbios_mainboard_sku(void) | ||
| { | ||
| static char sku[5]; | ||
| if (sku[0] != 0) | ||
| return sku; | ||
|
|
||
| if (!ReadFchGpio(APU5_SPD_STRAP0_GPIO)) | ||
| snprintf(sku, sizeof(sku), "2 GB"); | ||
| else | ||
| snprintf(sku, sizeof(sku), "4 GB"); | ||
| return sku; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,202 @@ | ||
| /* | ||
| * 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 <console/console.h> | ||
| #include <arch/smp/mpspec.h> | ||
| #include <device/pci.h> | ||
| #include <arch/io.h> | ||
| #include <arch/ioapic.h> | ||
| #include <string.h> | ||
| #include <stdint.h> | ||
| #include <cpu/amd/amdfam15.h> | ||
| #include <arch/cpu.h> | ||
| #include <cpu/x86/lapic.h> | ||
| //#include <southbridge/amd/agesa/hudson/hudson.h> /* pm_ioread() */ | ||
| #include <southbridge/amd/pi/hudson/hudson.h> /* pm_ioread() */ | ||
| #include <southbridge/amd/pi/hudson/amd_pci_int_defs.h> // IRQ routing info | ||
|
|
||
|
|
||
| u8 picr_data[FCH_INT_TABLE_SIZE] = { | ||
| 0x03,0x03,0x05,0x07,0x0B,0x0A,0x1F,0x1F, /* 00 - 07 : INTA - INTF and 2 reserved dont map 4*/ | ||
| 0xFA,0xF1,0x00,0x00,0x1F,0x1F,0x1F,0x1F, /* 08 - 0F */ | ||
| 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F, /* 10 - 17 */ | ||
| 0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 18 - 1F */ | ||
| 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00, /* 20 - 27 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 28 - 2F */ | ||
| 0x05,0x1F,0x05,0x1F,0x04,0x1F,0x1F,0x1F, /* 30 - 37 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 38 - 3F */ | ||
| 0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00, /* 40 - 47 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48 - 4F */ | ||
| // 0x03,0x04,0x05,0x07,0x00,0x00,0x00,0x00, /* 50 - 57 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 50 - 57 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 58 - 5F */ | ||
| 0x00,0x00,0x1F /* 60 - 62 */ | ||
| }; | ||
| u8 intr_data[FCH_INT_TABLE_SIZE] = { | ||
| 0x10,0x10,0x12,0x13,0x14,0x15,0x1F,0x1F, /* 00 - 07 : INTA - INTF and 2 reserved dont map 4*/ | ||
| 0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F, /* 08 - 0F */ | ||
| 0x09,0x1F,0x1F,0x1F,0x1F,0x1f,0x1F,0x10, /* 10 - 17 */ | ||
| 0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 18 - 1F */ | ||
| 0x05,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,0x00, /* 20 - 27 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 28 - 2F */ | ||
| 0x12,0x1f,0x12,0x1F,0x12,0x1F,0x1F,0x00, /* 30 - 37 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 38 - 3F */ | ||
| 0x1f,0x13,0x00,0x00,0x00,0x00,0x00,0x00, /* 40 - 47 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48 - 4F */ | ||
| // 0x10,0x11,0x12,0x13,0x00,0x00,0x00,0x00, /* 50 - 57 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 50 - 57 */ | ||
| 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 58 - 5F */ | ||
| 0x00,0x00,0x1F /* 60 - 62 */ | ||
| }; | ||
|
|
||
| static void smp_add_mpc_entry(struct mp_config_table *mc, unsigned length) | ||
| { | ||
| mc->mpc_length += length; | ||
| mc->mpc_entry_count++; | ||
| } | ||
|
|
||
| static void my_smp_write_bus(struct mp_config_table *mc, | ||
| unsigned char id, const char *bustype) | ||
| { | ||
| struct mpc_config_bus *mpc; | ||
| mpc = smp_next_mpc_entry(mc); | ||
| memset(mpc, '\0', sizeof(*mpc)); | ||
| mpc->mpc_type = MP_BUS; | ||
| mpc->mpc_busid = id; | ||
| memcpy(mpc->mpc_bustype, bustype, sizeof(mpc->mpc_bustype)); | ||
| smp_add_mpc_entry(mc, sizeof(*mpc)); | ||
| } | ||
|
|
||
| static void *smp_write_config_table(void *v) | ||
| { | ||
| struct mp_config_table *mc; | ||
| int bus_isa; | ||
| u8 byte; | ||
|
|
||
| /* | ||
| * By the time this function gets called, the IOAPIC registers | ||
| * have been written so they can be read to get the correct | ||
| * APIC ID and Version | ||
| */ | ||
| u8 ioapic_id = (io_apic_read(VIO_APIC_VADDR, 0x00) >> 24); | ||
| u8 ioapic_ver = (io_apic_read(VIO_APIC_VADDR, 0x01) & 0xFF); | ||
|
|
||
| mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); | ||
|
|
||
| mptable_init(mc, LOCAL_APIC_ADDR); | ||
| memcpy(mc->mpc_oem, "AMD ", 8); | ||
|
|
||
| smp_write_processors(mc); | ||
|
|
||
| //mptable_write_buses(mc, NULL, &bus_isa); | ||
| my_smp_write_bus(mc, 0, "PCI "); | ||
| my_smp_write_bus(mc, 1, "PCI "); | ||
| bus_isa = 0x02; | ||
| my_smp_write_bus(mc, bus_isa, "ISA "); | ||
|
|
||
| /* I/O APICs: APIC ID Version State Address */ | ||
| smp_write_ioapic(mc, ioapic_id, ioapic_ver, VIO_APIC_VADDR); | ||
|
|
||
| smp_write_ioapic(mc, ioapic_id+1, 0x21, (void *)0xFEC20000); | ||
| /* PIC IRQ routine */ | ||
| for (byte = 0x0; byte < sizeof(picr_data); byte ++) { | ||
| outb(byte, 0xC00); | ||
| outb(picr_data[byte], 0xC01); | ||
| } | ||
|
|
||
| /* APIC IRQ routine */ | ||
| for (byte = 0x0; byte < sizeof(intr_data); byte ++) { | ||
| outb(byte | 0x80, 0xC00); | ||
| outb(intr_data[byte], 0xC01); | ||
| } | ||
| /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ | ||
| #define IO_LOCAL_INT(type, intr, apicid, pin) \ | ||
| smp_write_lintsrc(mc, (type), MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, bus_isa, (intr), (apicid), (pin)); | ||
| mptable_add_isa_interrupts(mc, bus_isa, ioapic_id, 0); | ||
|
|
||
| /* PCI interrupts are level triggered, and are | ||
| * associated with a specific bus/device/function tuple. | ||
| */ | ||
| #define PCI_INT(bus, dev, int_sign, pin) \ | ||
| smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, (bus), (((dev)<<2)|(int_sign)), ioapic_id, (pin)) | ||
|
|
||
| /* Internal VGA */ | ||
| PCI_INT(0x0, 0x01, 0x0, intr_data[PIRQ_B]); | ||
| PCI_INT(0x0, 0x01, 0x1, intr_data[PIRQ_C]); | ||
|
|
||
| /* SMBUS */ | ||
| PCI_INT(0x0, 0x14, 0x0, 0x10); | ||
|
|
||
| /* HD Audio */ | ||
| // PCI_INT(0x0, 0x14, 0x0, intr_data[PIRQ_HDA]); | ||
|
|
||
| /* SD card */ | ||
| PCI_INT(0x0, 0x14, 0x1, intr_data[PIRQ_SD]); | ||
|
|
||
| /* USB */ | ||
| PCI_INT(0x0, 0x12, 0x0, intr_data[PIRQ_EHCI1]); | ||
| PCI_INT(0x0, 0x13, 0x0, intr_data[PIRQ_EHCI2]); | ||
| PCI_INT(0x0, 0x16, 0x0, intr_data[PIRQ_EHCI3]); | ||
|
|
||
| /* sata */ | ||
| PCI_INT(0x0, 0x11, 0x0, intr_data[PIRQ_SATA]); | ||
|
|
||
| /* on board NIC & Slot PCIE. */ | ||
|
|
||
|
|
||
| /* PCIe Lan*/ | ||
| // PCI_INT(0x0, 0x06, 0x0, 0x13); // No integrated LAN | ||
|
|
||
| // /* FCH PCIe PortA */ | ||
| // PCI_INT(0x0, 0x15, 0x0, 0x10); | ||
| // /* FCH PCIe PortB */ | ||
| // PCI_INT(0x0, 0x15, 0x1, 0x11); | ||
| // /* FCH PCIe PortC */ | ||
| // PCI_INT(0x0, 0x15, 0x2, 0x12); | ||
| // /* FCH PCIe PortD */ | ||
| // PCI_INT(0x0, 0x15, 0x3, 0x13); | ||
|
|
||
| /* GPP0 */ | ||
| PCI_INT(0x0, 0x2, 0x0, 0x10); // Network 3 | ||
| /* GPP1 */ | ||
| PCI_INT(0x0, 0x2, 0x1, 0x11); // Network 2 | ||
| /* GPP2 */ | ||
| PCI_INT(0x0, 0x2, 0x2, 0x12); // Network 1 | ||
| /* GPP3 */ | ||
| PCI_INT(0x0, 0x2, 0x3, 0x13); // mPCI | ||
| /* GPP4 */ | ||
| PCI_INT(0x0, 0x2, 0x4, 0x14); // mPCI | ||
|
|
||
|
|
||
|
|
||
| /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ | ||
| IO_LOCAL_INT(mp_ExtINT, 0, MP_APIC_ALL, 0x0); | ||
| IO_LOCAL_INT(mp_NMI, 0, MP_APIC_ALL, 0x1); | ||
| /* There is no extension information... */ | ||
|
|
||
| /* Compute the checksums */ | ||
| return mptable_finalize(mc); | ||
| } | ||
|
|
||
| unsigned long write_smp_table(unsigned long addr) | ||
| { | ||
| void *v; | ||
| v = smp_write_floating_table(addr, 0); | ||
| return (unsigned long)smp_write_config_table(v); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,262 @@ | ||
| /* | ||
| * 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 <stdint.h> | ||
| #include <string.h> | ||
| #include <device/pci_def.h> | ||
| #include <device/pci_ids.h> | ||
| #include <arch/acpi.h> | ||
| #include <arch/io.h> | ||
| #include <arch/stages.h> | ||
| #include <device/pnp_def.h> | ||
| #include <arch/cpu.h> | ||
| #include <cpu/x86/lapic.h> | ||
| #include <console/console.h> | ||
| #include <console/loglevel.h> | ||
| #include <cpu/amd/car.h> | ||
| #include <agesawrapper.h> | ||
| #include <northbridge/amd/pi/agesawrapper_call.h> | ||
| #include <cpu/x86/bist.h> | ||
| #include <cpu/x86/lapic.h> | ||
| #include <hudson.h> | ||
| #include <cpu/amd/pi/s3_resume.h> | ||
| #include <fchgpio.h> | ||
| #include "apu5.h" | ||
| #include <northbridge/amd/pi/00730F01/eltannorthbridge.h> | ||
| #include <eltanhudson.h> | ||
| #include <build.h> | ||
| #include "bios_knobs.h" | ||
|
|
||
| // | ||
| // GPIO Init Table | ||
| // | ||
| // GPIO_DEFINITION (gpio, function, outputenable, output, pullup, pulldown) | ||
| static const GPIO_CONTROL gGpioInitTable[] = { | ||
| GPIO_DEFINITION (APU5_SPD_STRAP0_GPIO, APU5_SPD_STRAP0_FUNC, 0, 0, 0, 0), | ||
| GPIO_DEFINITION (APU5_SPD_STRAP1_GPIO, APU5_SPD_STRAP1_FUNC, 0, 0, 0, 0), | ||
| GPIO_DEFINITION (APU5_SIM1RST_L_GPIO, APU5_SIM1RST_L_FUNC, 1, 1, 0, 0), | ||
| GPIO_DEFINITION (APU5_SIM2RST_L_GPIO, APU5_SIM2RST_L_FUNC, 1, 1, 0, 0), | ||
| GPIO_DEFINITION (APU5_LED1_L_GPIO, APU5_LED1_L_FUNC, 1, 0, 0, 0), // Turn on the LEDs by default | ||
| GPIO_DEFINITION (APU5_LED2_L_GPIO, APU5_LED2_L_FUNC, 1, 0, 0, 0), | ||
| GPIO_DEFINITION (APU5_LED3_L_GPIO, APU5_LED3_L_FUNC, 1, 0, 0, 0), | ||
| GPIO_DEFINITION (APU5_SIM3RST_L_GPIO, APU5_SIM3RST_L_FUNC, 1, 1, 0, 0), | ||
| GPIO_DEFINITION (APU5_SIMSWAP1_GPIO, APU5_SIMSWAP1_FUNC, 1, 1, 0, 0), | ||
| // SPKR doesn't require init, left at default | ||
| GPIO_DEFINITION (APU5_PROCHOT_GPIO, APU5_PROCHOT_FUNC, 0, 0, 0, 0), | ||
| GPIO_DEFINITION (APU5_SIMSWAP2_GPIO, APU5_SIMSWAP2_FUNC, 1, 1, 0, 0), | ||
| GPIO_DEFINITION (APU5_SIMSWAP3_GPIO, APU5_SIMSWAP3_FUNC, 1, 1, 0, 0), | ||
| {0xFF, 0xFF, 0xFF} // Terminator | ||
| }; | ||
|
|
||
|
|
||
| void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) | ||
| { | ||
| u32 val; | ||
| #if CONFIG_SVI2_SLOW_SPEED | ||
| device_t d18f3_dev = PCI_DEV(0, 0x18, 3); | ||
| #endif //CONFIG_SVI2_SLOW_SPEED | ||
| #if CONFIG_SVI_WAIT_COMP_DIS | ||
| device_t d18f5_dev = PCI_DEV(0, 0x18, 5); | ||
| #endif //CONFIG_SVI_WAIT_COMP_DIS | ||
|
|
||
| /* | ||
| * In Hudson RRG, PMIOxD2[5:4] is "Drive strength control for | ||
| * LpcClk[1:0]". This following register setting has been | ||
| * replicated in every reference design since Parmer, so it is | ||
| * believed to be required even though it is not documented in | ||
| * the SoC BKDGs. Without this setting, there is no serial | ||
| * output. | ||
| */ | ||
| outb(0xD2, 0xcd6); | ||
| outb(0x00, 0xcd7); | ||
|
|
||
| AGESAWRAPPER_PRE_CONSOLE(amdinitmmio); | ||
|
|
||
| if (!cpu_init_detectedx && boot_cpu()) { | ||
|
|
||
| u32 data, *memptr; | ||
| bool mpcie2_clk; | ||
|
|
||
| hudson_lpc_port80(); | ||
| // | ||
| // Configure the GPIO's | ||
| // | ||
| HandleFchGpioTbl ( (GPIO_CONTROL *) &gGpioInitTable[0] ); | ||
|
|
||
| hudson_clk_output_48Mhz(); | ||
|
|
||
| post_code(0x31); | ||
| console_init(); | ||
|
|
||
| printk(BIOS_INFO, "14-25-48Mhz Clock settings\n"); | ||
|
|
||
| memptr = (u32 *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG28 ); | ||
| data = *memptr; | ||
| printk(BIOS_INFO, "FCH_MISC_REG28 is 0x%08x \n", data); | ||
|
|
||
| memptr = (u32 *)(ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40 ); | ||
| data = *memptr; | ||
| printk(BIOS_INFO, "FCH_MISC_REG40 is 0x%08x \n", data); | ||
|
|
||
| // | ||
| // Configure clock request | ||
| // | ||
| data = *((u32 *)(ACPI_MMIO_BASE + MISC_BASE+FCH_MISC_REG00)); | ||
|
|
||
| data &= 0xFFFF0000; | ||
| data |= (0 + 1) << (0 * 4); // CLKREQ 0 to CLK0 | ||
| data |= (1 + 1) << (1 * 4); // CLKREQ 1 to CLK1 | ||
| // data |= (2 + 1) << (2 * 4); // do not enable CLK2, disable PE2 | ||
| // make CLK3 to ignore CLKREQ# input | ||
| // force it to be always on | ||
| data |= ( 0xf ) << (3 * 4); // CLKREQ 3 to CLK3 | ||
|
|
||
| *((u32 *)(ACPI_MMIO_BASE + MISC_BASE+FCH_MISC_REG00)) = data; | ||
|
|
||
| data = *((u32 *)(ACPI_MMIO_BASE + MISC_BASE+FCH_MISC_REG04)); | ||
|
|
||
| data &= 0xFFFFFF0F; | ||
|
|
||
| mpcie2_clk = check_mpcie2_clk(); | ||
| if (mpcie2_clk) { | ||
| // make GFXCLK to ignore CLKREQ# input | ||
| // force it to be always on | ||
| data |= 0xF << (1 * 4); // CLKREQ GFX to GFXCLK | ||
| } | ||
| else { | ||
| data |= 0xA << (1 * 4); // CLKREQ GFX to GFXCLK | ||
| } | ||
|
|
||
| *((u32 *)(ACPI_MMIO_BASE + MISC_BASE+FCH_MISC_REG04)) = data; | ||
|
|
||
| // // | ||
| // // Configure clock strength | ||
| // // | ||
| // data = *((u32 *)(ACPI_MMIO_BASE + MISC_BASE+FCH_MISC_REG24)); | ||
| // | ||
| // data &= ~( (3 << 18) | (3 << 6) | (3 << 4) | (3 << 2) | (3 << 0) ); | ||
| // data |= 3 << 18; // GFX CLOCK | ||
| // data |= 3 << (0 * 2); // CLK0 | ||
| // data |= 3 << (1 * 2); // CLK1 | ||
| // data |= 3 << (2 * 2); // CLK2 | ||
| // data |= 3 << (3 * 2); // CLK3 | ||
| // | ||
| // *((u32 *)(ACPI_MMIO_BASE + MISC_BASE+FCH_MISC_REG24)) = data; | ||
| } | ||
|
|
||
| /* Halt if there was a built in self test failure */ | ||
| post_code(0x34); | ||
| report_bist_failure(bist); | ||
|
|
||
| /* Load MPB */ | ||
| val = cpuid_eax(1); | ||
| printk(BIOS_DEBUG, "BSP Family_Model: %08x \n", val); | ||
| printk(BIOS_DEBUG, "cpu_init_detectedx = %08lx \n", cpu_init_detectedx); | ||
|
|
||
| /* | ||
| * This refers to LpcClkDrvSth settling time. Without this setting, processor | ||
| * initialization is slow or incorrect, so this wait has been replicated from | ||
| * earlier development boards. | ||
| */ | ||
| { int i; for(i = 0; i < 200000; i++) inb(0xCD6); } | ||
|
|
||
| post_code(0x37); | ||
| AGESAWRAPPER(amdinitreset); | ||
|
|
||
| /* TODO There is no debug output between the return from amdinitreset and amdinitearly */ | ||
|
|
||
| post_code(0x38); | ||
| printk(BIOS_DEBUG, "Got past avalon_early_setup\n"); | ||
|
|
||
| post_code(0x39); | ||
| AGESAWRAPPER(amdinitearly); | ||
|
|
||
| /* | ||
| // Moved here to prevent double signon message | ||
| // amdinitreset AGESA code might issue a reset when the hardware is in a wrong state. | ||
| */ | ||
|
|
||
| printk(BIOS_ERR, CONFIG_MAINBOARD_PART_NUMBER "\n"); | ||
| printk(BIOS_ERR, "coreboot build " COREBOOT_YYYYMMDD_DATE "\n"); | ||
|
|
||
| #if CONFIG_SVI2_SLOW_SPEED | ||
| /* Force SVI2 to slow speed for APU5 */ | ||
| val = pci_read_config32( d18f3_dev, 0xA0); | ||
| if ( val & (1 << 14 ) ) { | ||
|
|
||
| printk(BIOS_DEBUG, "SVI2 FREQUENCY 20 Mhz changing to 3.4\n"); | ||
| val &= ~(1 << 14 ); | ||
| pci_write_config32(d18f3_dev, 0xA0, val ); | ||
|
|
||
| } else { | ||
|
|
||
| printk(BIOS_DEBUG, "SVI2 FREQUENCY 3.4 Mhz\n"); | ||
| } | ||
| #endif //CONFIG_SVI2_SLOW_SPEED | ||
|
|
||
| #if CONFIG_SVI_WAIT_COMP_DIS | ||
| /* Disable SVI2 controller to wait for command completion */ | ||
| val = pci_read_config32( d18f5_dev, 0x12C); | ||
| if ( val & (1 << 30 ) ) { | ||
|
|
||
| printk(BIOS_DEBUG, "SVI2 Wait completion disabled\n"); | ||
|
|
||
| } else { | ||
|
|
||
| printk(BIOS_DEBUG, "Disabling SVI2 Wait completion\n"); | ||
| val |= (1 << 30 ); | ||
| pci_write_config32(d18f5_dev, 0x12C, val ); | ||
| } | ||
|
|
||
| #endif //CONFIG_SVI_WAIT_COMP_DIS | ||
|
|
||
| int s3resume = acpi_is_wakeup_s3(); | ||
| if (!s3resume) { | ||
| post_code(0x40); | ||
| AGESAWRAPPER(amdinitpost); | ||
|
|
||
| //PspMboxBiosCmdDramInfo(); | ||
| post_code(0x41); | ||
| AGESAWRAPPER(amdinitenv); | ||
| /* | ||
| If code hangs here, please check cahaltasm.S | ||
| */ | ||
| disable_cache_as_ram(); | ||
|
|
||
| } else { /* S3 detect */ | ||
|
|
||
| printk(BIOS_INFO, "S3 detected\n"); | ||
|
|
||
| post_code(0x60); | ||
| AGESAWRAPPER(amdinitresume); | ||
|
|
||
| AGESAWRAPPER(amds3laterestore); | ||
|
|
||
| post_code(0x61); | ||
| prepare_for_resume(); | ||
| } | ||
|
|
||
| outb(0xEA, 0xCD6); | ||
| outb(0x1, 0xcd7); | ||
|
|
||
| post_code(0x50); | ||
| copy_and_run(); | ||
|
|
||
| post_code(0x54); /* Should never see this post code. */ | ||
| } |