summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzbao <fishbaozi@gmail.com>2012-04-13 13:42:15 +0800
committerMarc Jones <marcj303@gmail.com>2012-04-16 18:22:47 +0200
commitf72237346d9a0894b4675f0b6915da6fdcccd31e (patch)
tree3ccf4333bd94f38a68f3b76d3f161d27072316b5
parentcaf494c83170e97b192e2174bc461482699a3712 (diff)
S3 code in coreboot public folder.
1. Move the Stack to high memory. 2. Restore the MTRR before Coreboot jump to the wakeup vector. Change-Id: I9872e02fcd7eed98e7f630aa29ece810ac32d55a Signed-off-by: Zheng Bao <zheng.bao@amd.com> Signed-off-by: zbao <fishbaozi@gmail.com> Reviewed-on: http://review.coreboot.org/623 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones <marcj303@gmail.com>
-rw-r--r--src/Kconfig4
-rw-r--r--src/arch/x86/boot/tables.c1
-rw-r--r--src/cpu/amd/agesa/Makefile.inc2
-rwxr-xr-xsrc/cpu/amd/agesa/cache_as_ram.inc7
-rw-r--r--src/cpu/amd/agesa/family14/Kconfig5
-rw-r--r--src/cpu/amd/agesa/family14/model_14_init.c125
-rw-r--r--src/cpu/amd/agesa/s3_resume.c326
-rw-r--r--src/cpu/amd/agesa/s3_resume.h42
-rw-r--r--src/include/cbmem.h10
-rw-r--r--src/lib/cbmem.c1
-rw-r--r--src/northbridge/amd/agesa/Kconfig4
-rw-r--r--src/northbridge/amd/agesa/family14/northbridge.c77
12 files changed, 529 insertions, 75 deletions
diff --git a/src/Kconfig b/src/Kconfig
index b0261d9068..149568a7f3 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -222,6 +222,10 @@ config HAVE_INIT_TIMER
default n if UDELAY_IO
default y
+config HIGH_SCRATCH_MEMORY_SIZE
+ hex
+ default 0x0
+
config HAVE_MAINBOARD_RESOURCES
bool
default n
diff --git a/src/arch/x86/boot/tables.c b/src/arch/x86/boot/tables.c
index b7dc4fe8cc..70f3117cb5 100644
--- a/src/arch/x86/boot/tables.c
+++ b/src/arch/x86/boot/tables.c
@@ -237,6 +237,7 @@ struct lb_memory *write_tables(void)
* the result right now. If it fails, ACPI resume will be disabled.
*/
cbmem_add(CBMEM_ID_RESUME, HIGH_MEMORY_SAVE);
+ cbmem_add(CBMEM_ID_RESUME_SCRATCH, CONFIG_HIGH_SCRATCH_MEMORY_SIZE);
#endif
#if CONFIG_MULTIBOOT
diff --git a/src/cpu/amd/agesa/Makefile.inc b/src/cpu/amd/agesa/Makefile.inc
index fb536ddc53..696173daae 100644
--- a/src/cpu/amd/agesa/Makefile.inc
+++ b/src/cpu/amd/agesa/Makefile.inc
@@ -21,5 +21,7 @@ subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY12) += family12
subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY14) += family14
subdirs-$(CONFIG_CPU_AMD_AGESA_FAMILY15) += family15
+romstage-$(CONFIG_HAVE_ACPI_RESUME) += s3_resume.c
+ramstage-$(CONFIG_HAVE_ACPI_RESUME) += s3_resume.c
ramstage-y += apic_timer.c
cpu_incs += $(src)/cpu/amd/agesa/cache_as_ram.inc
diff --git a/src/cpu/amd/agesa/cache_as_ram.inc b/src/cpu/amd/agesa/cache_as_ram.inc
index f328db405e..2124bf3be8 100755
--- a/src/cpu/amd/agesa/cache_as_ram.inc
+++ b/src/cpu/amd/agesa/cache_as_ram.inc
@@ -86,6 +86,13 @@ disable_cache_as_ram:
/* Save return stack */
movd %esp, %xmm0
+ /* Disable cache */
+ movl %cr0, %eax
+ orl $(1 << 30), %eax
+ movl %eax, %cr0
+
+ invd
+
AMD_DISABLE_STACK
/* Restore the return stack */
diff --git a/src/cpu/amd/agesa/family14/Kconfig b/src/cpu/amd/agesa/family14/Kconfig
index 702270c1cc..6713660ff8 100644
--- a/src/cpu/amd/agesa/family14/Kconfig
+++ b/src/cpu/amd/agesa/family14/Kconfig
@@ -67,3 +67,8 @@ config HAVE_INIT_TIMER
default y
depends on CPU_AMD_AGESA_FAMILY14
+config HIGH_SCRATCH_MEMORY_SIZE
+ hex
+ # Assume the maximum size of stack as (0xA0000 - 0x30000 + 0x1000)
+ default 0x71000
+ depends on CPU_AMD_AGESA_FAMILY14
diff --git a/src/cpu/amd/agesa/family14/model_14_init.c b/src/cpu/amd/agesa/family14/model_14_init.c
index 577da1ba0d..d90695af4a 100644
--- a/src/cpu/amd/agesa/family14/model_14_init.c
+++ b/src/cpu/amd/agesa/family14/model_14_init.c
@@ -32,6 +32,8 @@
#include <cpu/x86/cache.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/amdfam14.h>
+#include <arch/acpi.h>
+#include <cpu/amd/agesa/s3_resume.h>
#define MCI_STATUS 0x401
@@ -57,69 +59,84 @@ void wrmsr_amd(u32 index, msr_t msr)
static void model_14_init(device_t dev)
{
- printk(BIOS_DEBUG, "Model 14 Init.\n");
-
- u8 i;
- msr_t msr;
- int msrno;
+ u32 i;
+ msr_t msr;
#if CONFIG_LOGICAL_CPUS == 1
- u32 siblings;
+ u32 siblings;
+#endif
+ printk(BIOS_DEBUG, "Model 14 Init.\n");
+
+ disable_cache ();
+ /*
+ * AGESA sets the MTRRs main MTRRs. The shadow area needs to be set
+ * by coreboot. The amd_setup_mtrrs should work, but needs debug on fam14.
+ * TODO:
+ * amd_setup_mtrrs();
+ */
+
+ /* Enable access to AMD RdDram and WrDram extension bits */
+ msr = rdmsr(SYSCFG_MSR);
+ msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
+ msr.lo &= ~SYSCFG_MSR_MtrrFixDramEn;
+ wrmsr(SYSCFG_MSR, msr);
+
+ /* Set shadow WB, RdMEM, WrMEM */
+ msr.lo = msr.hi = 0;
+ wrmsr (0x259, msr);
+ msr.hi = msr.lo = 0x1e1e1e1e;
+ wrmsr(0x250, msr);
+ wrmsr(0x258, msr);
+ for (i = 0x268; i <= 0x26f; i++)
+ wrmsr(i, msr);
+
+ msr = rdmsr(SYSCFG_MSR);
+ msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
+ msr.lo |= SYSCFG_MSR_MtrrFixDramEn;
+ wrmsr(SYSCFG_MSR, msr);
+
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ if (acpi_slp_type == 3)
+ restore_mtrr();
#endif
- disable_cache ();
- /* Enable access to AMD RdDram and WrDram extension bits */
- msr = rdmsr(SYSCFG_MSR);
- msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
- wrmsr(SYSCFG_MSR, msr);
-
- // BSP: make a0000-bffff UC, c0000-fffff WB, same as OntarioApMtrrSettingsList for APs
- msr.lo = msr.hi = 0;
- wrmsr (0x259, msr);
- msr.lo = msr.hi = 0x1e1e1e1e;
- for (msrno = 0x268; msrno <= 0x26f; msrno++)
- wrmsr (msrno, msr);
-
- /* disable access to AMD RdDram and WrDram extension bits */
- msr = rdmsr(SYSCFG_MSR);
- msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
- wrmsr(SYSCFG_MSR, msr);
- enable_cache ();
-
- /* zero the machine check error status registers */
- msr.lo = 0;
- msr.hi = 0;
- for (i = 0; i < 6; i++) {
- wrmsr(MCI_STATUS + (i * 4), msr);
- }
-
- /* Enable the local cpu apics */
- setup_lapic();
+ x86_mtrr_check();
+ x86_enable_cache();
+
+ /* zero the machine check error status registers */
+ msr.lo = 0;
+ msr.hi = 0;
+ for (i = 0; i < 6; i++) {
+ wrmsr(MCI_STATUS + (i * 4), msr);
+ }
+
+ /* Enable the local cpu apics */
+ setup_lapic();
#if CONFIG_LOGICAL_CPUS == 1
- siblings = cpuid_ecx(0x80000008) & 0xff;
-
- if (siblings > 0) {
- msr = rdmsr_amd(CPU_ID_FEATURES_MSR);
- msr.lo |= 1 << 28;
- wrmsr_amd(CPU_ID_FEATURES_MSR, msr);
-
- msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
- msr.hi |= 1 << (33 - 32);
- wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
- }
- printk(BIOS_DEBUG, "siblings = %02d, ", siblings);
+ siblings = cpuid_ecx(0x80000008) & 0xff;
+
+ if (siblings > 0) {
+ msr = rdmsr_amd(CPU_ID_FEATURES_MSR);
+ msr.lo |= 1 << 28;
+ wrmsr_amd(CPU_ID_FEATURES_MSR, msr);
+
+ msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
+ msr.hi |= 1 << (33 - 32);
+ wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
+ }
#endif
- /* DisableCf8ExtCfg */
- msr = rdmsr(NB_CFG_MSR);
- msr.hi &= ~(1 << (46 - 32));
- wrmsr(NB_CFG_MSR, msr);
+ /* DisableCf8ExtCfg */
+ msr = rdmsr(NB_CFG_MSR);
+ msr.hi &= ~(1 << (46 - 32));
+ wrmsr(NB_CFG_MSR, msr);
+ /* Write protect SMM space with SMMLOCK. */
+ msr = rdmsr(HWCR_MSR);
+ msr.lo |= (1 << 0);
+ wrmsr(HWCR_MSR, msr);
- /* Write protect SMM space with SMMLOCK. */
- msr = rdmsr(HWCR_MSR);
- msr.lo |= (1 << 0);
- wrmsr(HWCR_MSR, msr);
+ printk(BIOS_SPEW, "%s done.\n", __func__);
}
static struct device_operations cpu_dev_ops = {
diff --git a/src/cpu/amd/agesa/s3_resume.c b/src/cpu/amd/agesa/s3_resume.c
new file mode 100644
index 0000000000..16c959a570
--- /dev/null
+++ b/src/cpu/amd/agesa/s3_resume.c
@@ -0,0 +1,326 @@
+/*
+ * 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 "AGESA.h"
+#include "amdlib.h"
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/amd/mtrr.h>
+#include <cpu/x86/cache.h>
+#if CONFIG_WRITE_HIGH_TABLES
+#include <cbmem.h>
+#endif
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <arch/acpi.h>
+#include <string.h>
+#include "Porting.h"
+#include "BiosCallOuts.h"
+#include "s3_resume.h"
+#include "agesawrapper.h"
+
+#ifndef __PRE_RAM__
+#include "spi.h"
+#endif
+
+void restore_mtrr(void)
+{
+ u32 msr;
+ volatile UINT32 *msrPtr = (volatile UINT32 *)S3_DATA_MTRR_POS;
+ msr_t msr_data;
+
+ printk(BIOS_SPEW, "%s\n", __func__);
+
+ disable_cache();
+
+ /* Enable access to AMD RdDram and WrDram extension bits */
+ msr_data = rdmsr(SYS_CFG);
+ msr_data.lo |= SYSCFG_MSR_MtrrFixDramModEn;
+ wrmsr(SYS_CFG, msr_data);
+
+ /* Now restore the Fixed MTRRs */
+ msr_data.lo = *msrPtr;
+ msrPtr ++;
+ msr_data.hi = *msrPtr;
+ msrPtr ++;
+ wrmsr(0x250, msr_data);
+
+ msr_data.lo = *msrPtr;
+ msrPtr ++;
+ msr_data.hi = *msrPtr;
+ msrPtr ++;
+ wrmsr(0x258, msr_data);
+
+ msr_data.lo = *msrPtr;
+ msrPtr ++;
+ msr_data.hi = *msrPtr;
+ msrPtr ++;
+ wrmsr(0x259, msr_data);
+
+ for (msr = 0x268; msr <= 0x26F; msr++) {
+ msr_data.lo = *msrPtr;
+ msrPtr ++;
+ msr_data.hi = *msrPtr;
+ msrPtr ++;
+ wrmsr(msr, msr_data);
+ }
+
+ /* Disable access to AMD RdDram and WrDram extension bits */
+ msr_data = rdmsr(SYS_CFG);
+ msr_data.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
+ wrmsr(SYS_CFG, msr_data);
+
+ /* Restore the Variable MTRRs */
+ for (msr = 0x200; msr <= 0x20F; msr++) {
+ msr_data.lo = *msrPtr;
+ msrPtr ++;
+ msr_data.hi = *msrPtr;
+ msrPtr ++;
+ wrmsr(msr, msr_data);
+ }
+
+ /* Restore SYSCFG MTRR */
+ msr_data.lo = *msrPtr;
+ msrPtr ++;
+ msr_data.hi = *msrPtr;
+ msrPtr ++;
+ wrmsr(SYS_CFG, msr_data);
+}
+
+inline void *backup_resume(void)
+{
+ unsigned long high_ram_base;
+ void *resume_backup_memory;
+
+ /* Start address of high memory tables */
+ high_ram_base = (u32) get_cbmem_toc();
+
+ /*
+ * printk(BIOS_DEBUG, "CBMEM TOC is at: %x\n", (u32_t)high_ram_base);
+ * printk(BIOS_DEBUG, "CBMEM TOC 0-size:%x\n ",(u32_t)(high_ram_base + HIGH_MEMORY_SIZE + 4096));
+ */
+
+ cbmem_reinit((u64) high_ram_base);
+
+ resume_backup_memory = cbmem_find(CBMEM_ID_RESUME);
+ if (((u32) resume_backup_memory == 0)
+ || ((u32) resume_backup_memory == -1)) {
+ printk(BIOS_ERR, "Error: resume_backup_memory: %x\n",
+ (u32) resume_backup_memory);
+ for (;;) ;
+ }
+
+ return resume_backup_memory;
+}
+
+void move_stack_high_mem(void)
+{
+ void *high_stack;
+
+ high_stack = cbmem_find(CBMEM_ID_RESUME_SCRATCH);
+ memcpy(high_stack, (void *)BSP_STACK_BASE_ADDR,
+ (CONFIG_HIGH_SCRATCH_MEMORY_SIZE - BIOS_HEAP_SIZE));
+
+ __asm__
+ volatile ("add %0, %%esp; add %0, %%ebp; invd"::"g"
+ (high_stack - BSP_STACK_BASE_ADDR)
+ :);
+}
+
+void OemAgesaSaveMtrr(void)
+{
+#ifndef __PRE_RAM__
+ u32 spi_address;
+ msr_t msr_data;
+ device_t dev;
+ u32 nvram_pos = S3_DATA_MTRR_POS;
+ u32 i;
+
+ dev = dev_find_slot(0, PCI_DEVFN(0x14, 3));
+ spi_address = pci_read_config32(dev, 0xA0) & ~0x1F;
+
+ /* Enable access to AMD RdDram and WrDram extension bits */
+ msr_data = rdmsr(SYS_CFG);
+ msr_data.lo |= SYSCFG_MSR_MtrrFixDramModEn;
+ wrmsr(SYS_CFG, msr_data);
+
+ /* Fixed MTRRs */
+ msr_data = rdmsr(0x250);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.lo);
+ nvram_pos += 4;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.hi);
+ nvram_pos += 4;
+
+ msr_data = rdmsr(0x258);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.lo);
+ nvram_pos += 4;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.hi);
+ nvram_pos += 4;
+
+ msr_data = rdmsr(0x259);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.lo);
+ nvram_pos += 4;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.hi);
+ nvram_pos += 4;
+
+ for (i = 0x268; i < 0x270; i++) {
+ msr_data = rdmsr(i);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.lo);
+ nvram_pos += 4;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.hi);
+ nvram_pos += 4;
+ }
+
+ /* Disable access to AMD RdDram and WrDram extension bits */
+ msr_data = rdmsr(SYS_CFG);
+ msr_data.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
+ wrmsr(SYS_CFG, msr_data);
+
+ /* Variable MTRRs */
+ for (i = 0x200; i < 0x210; i++) {
+ msr_data = rdmsr(i);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.lo);
+ nvram_pos += 4;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.hi);
+ nvram_pos += 4;
+ }
+
+ /* SYS_CFG */
+ msr_data = rdmsr(0xC0010010);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.lo);
+ nvram_pos += 4;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.hi);
+ nvram_pos += 4;
+
+ /* TOM */
+ msr_data = rdmsr(0xC001001A);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.lo);
+ nvram_pos += 4;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.hi);
+ nvram_pos += 4;
+
+ /* TOM2 */
+ msr_data = rdmsr(0xC001001D);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.lo);
+ nvram_pos += 4;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos, msr_data.hi);
+ nvram_pos += 4;
+
+#endif
+}
+
+void OemAgesaGetS3Info(S3_DATA_TYPE S3DataType, u32 *DataSize, void **Data)
+{
+ AMD_CONFIG_PARAMS StdHeader;
+ if (S3DataType == S3DataTypeNonVolatile) {
+ *Data = (void *)S3_DATA_NONVOLATILE_POS;
+ *DataSize = *(UINTN *) (*Data);
+ *Data += 4;
+ } else {
+ *DataSize = *(UINTN *) S3_DATA_VOLATILE_POS;
+ *Data = (void *) GetHeapBase(&StdHeader);
+ memcpy((void *)(*Data), (void *)(S3_DATA_VOLATILE_POS + 4), *DataSize);
+ }
+}
+
+#ifndef __PRE_RAM__
+u32 OemAgesaSaveS3Info(S3_DATA_TYPE S3DataType, u32 DataSize, void *Data)
+{
+
+ u32 pos = S3_DATA_VOLATILE_POS;
+ u32 spi_address, data;
+ u32 nvram_pos;
+ device_t dev;
+
+ if (S3DataType == S3DataTypeNonVolatile) {
+ pos = S3_DATA_NONVOLATILE_POS;
+ } else { /* S3DataTypeVolatile */
+ pos = S3_DATA_VOLATILE_POS;
+ }
+
+ dev = dev_find_slot(0, PCI_DEVFN(0x14, 3));
+ spi_address = pci_read_config32(dev, 0xA0) & ~0x1F;
+
+ /* printk(BIOS_DEBUG, "spi_address=%x\n", spi_address); */
+ read_spi_id((u8 *) spi_address);
+ write_spi_status((u8 *)spi_address, 0);
+ if (S3DataType == S3DataTypeNonVolatile) {
+ sector_erase_spi((u8 *) spi_address, S3_DATA_NONVOLATILE_POS);
+ } else {
+ sector_erase_spi((u8 *) spi_address, S3_DATA_VOLATILE_POS);
+ sector_erase_spi((u8 *) spi_address,
+ S3_DATA_VOLATILE_POS + 0x1000);
+ sector_erase_spi((u8 *) spi_address,
+ S3_DATA_VOLATILE_POS + 0x2000);
+ sector_erase_spi((u8 *) spi_address,
+ S3_DATA_VOLATILE_POS + 0x3000);
+ }
+
+ nvram_pos = 0;
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos + pos, DataSize);
+
+ for (nvram_pos = 0; nvram_pos < DataSize; nvram_pos += 4) {
+ data = *(u32 *) (Data + nvram_pos);
+ dword_noneAAI_program((u8 *) spi_address, nvram_pos + pos + 4,
+ *(u32 *) (Data + nvram_pos));
+ }
+
+ return AGESA_SUCCESS;
+}
+#endif
+
+void set_resume_cache(void)
+{
+ msr_t msr;
+
+ /* disable fixed mtrr for now, it will be enabled by mtrr restore */
+ msr = rdmsr(SYSCFG_MSR);
+ msr.lo &= ~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrFixDramModEn);
+ wrmsr(SYSCFG_MSR, msr);
+
+ /* Enable caching for 0 - coreboot ram using variable mtrr */
+ msr.lo = 0 | MTRR_TYPE_WRBACK;
+ msr.hi = 0;
+ wrmsr(MTRRphysBase_MSR(0), msr);
+ msr.lo = ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid;
+ msr.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1;
+ wrmsr(MTRRphysMask_MSR(0), msr);
+
+ /* Set the default memory type and disable fixed and enable variable MTRRs */
+ msr.hi = 0;
+ msr.lo = (1 << 11);
+ wrmsr(MTRRdefType_MSR, msr);
+
+ enable_cache();
+}
+
+void s3_resume(void)
+{
+ int status;
+
+ printk(BIOS_DEBUG, "agesawrapper_amds3laterestore ");
+ status = agesawrapper_amds3laterestore();
+ if (status)
+ printk(BIOS_DEBUG, "error level: %x \n", (u32) status);
+ else
+ printk(BIOS_DEBUG, "passed.\n");
+}
diff --git a/src/cpu/amd/agesa/s3_resume.h b/src/cpu/amd/agesa/s3_resume.h
new file mode 100644
index 0000000000..22a72711bf
--- /dev/null
+++ b/src/cpu/amd/agesa/s3_resume.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 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
+ */
+
+#ifndef S3_RESUME_H
+#define S3_RESUME_H
+
+#define S3_DATA_NONVOLATILE_POS 0xFFFF4000
+#define S3_DATA_VOLATILE_POS 0xFFFF0000
+#define S3_DATA_MTRR_POS 0xFFFF3100
+
+typedef enum {
+ S3DataTypeNonVolatile=0, ///< NonVolatile Data Type
+ S3DataTypeVolatile ///< Volatile Data Type
+} S3_DATA_TYPE;
+
+void restore_mtrr(void);
+void s3_resume(void);
+inline void *backup_resume(void);
+void set_resume_cache(void);
+void move_stack_high_mem(void);
+
+u32 OemAgesaSaveS3Info (S3_DATA_TYPE S3DataType, u32 DataSize, void *Data);
+void OemAgesaGetS3Info (S3_DATA_TYPE S3DataType, u32 *DataSize, void **Data);
+void OemAgesaSaveMtrr (void);
+
+#endif
diff --git a/src/include/cbmem.h b/src/include/cbmem.h
index c55a7cac22..33e2de4f98 100644
--- a/src/include/cbmem.h
+++ b/src/include/cbmem.h
@@ -28,17 +28,18 @@
#endif
#if CONFIG_HAVE_ACPI_RESUME
-#define HIGH_MEMORY_SIZE ((CONFIG_RAMTOP - CONFIG_RAMBASE) + HIGH_MEMORY_DEF_SIZE)
-#define HIGH_MEMORY_SAVE ( HIGH_MEMORY_SIZE - HIGH_MEMORY_DEF_SIZE )
+#define HIGH_MEMORY_SAVE (CONFIG_RAMTOP - CONFIG_RAMBASE)
+#define HIGH_MEMORY_SIZE (HIGH_MEMORY_SAVE + CONFIG_HIGH_SCRATCH_MEMORY_SIZE + HIGH_MEMORY_DEF_SIZE)
/* Delegation of resume backup memory so we don't have to
* (slowly) handle backing up OS memory in romstage.c
*/
#define CBMEM_BOOT_MODE 0x610
#define CBMEM_RESUME_BACKUP 0x614
-#else
+
+#else /* CONFIG_HAVE_ACPI_RESUME */
#define HIGH_MEMORY_SIZE HIGH_MEMORY_DEF_SIZE
-#endif
+#endif /* CONFIG_HAVE_ACPI_RESUME */
#define CBMEM_ID_FREESPACE 0x46524545
#define CBMEM_ID_GDT 0x4c474454
@@ -47,6 +48,7 @@
#define CBMEM_ID_PIRQ 0x49525154
#define CBMEM_ID_MPTABLE 0x534d5054
#define CBMEM_ID_RESUME 0x5245534d
+#define CBMEM_ID_RESUME_SCRATCH 0x52455343
#define CBMEM_ID_SMBIOS 0x534d4254
#define CBMEM_ID_TIMESTAMP 0x54494d45
#define CBMEM_ID_MRCDATA 0x4d524344
diff --git a/src/lib/cbmem.c b/src/lib/cbmem.c
index b09b070d7a..e54e1c0592 100644
--- a/src/lib/cbmem.c
+++ b/src/lib/cbmem.c
@@ -254,6 +254,7 @@ void cbmem_list(void)
case CBMEM_ID_PIRQ: printk(BIOS_DEBUG, "IRQ TABLE "); break;
case CBMEM_ID_MPTABLE: printk(BIOS_DEBUG, "SMP TABLE "); break;
case CBMEM_ID_RESUME: printk(BIOS_DEBUG, "ACPI RESUME"); break;
+ case CBMEM_ID_RESUME_SCRATCH: printk(BIOS_DEBUG, "ACPISCRATCH"); break;
case CBMEM_ID_SMBIOS: printk(BIOS_DEBUG, "SMBIOS "); break;
case CBMEM_ID_TIMESTAMP: printk(BIOS_DEBUG, "TIME STAMP "); break;
case CBMEM_ID_CONSOLE: printk(BIOS_DEBUG, "CONSOLE "); break;
diff --git a/src/northbridge/amd/agesa/Kconfig b/src/northbridge/amd/agesa/Kconfig
index 2ee921bb3a..ebdda38cc5 100644
--- a/src/northbridge/amd/agesa/Kconfig
+++ b/src/northbridge/amd/agesa/Kconfig
@@ -27,6 +27,10 @@ config CONSOLE_VGA_MULTI
bool
default n
+config S3_VGA_ROM_RUN
+ bool
+ default n
+
source src/northbridge/amd/agesa/family10/Kconfig
source src/northbridge/amd/agesa/family12/Kconfig
source src/northbridge/amd/agesa/family14/Kconfig
diff --git a/src/northbridge/amd/agesa/family14/northbridge.c b/src/northbridge/amd/agesa/family14/northbridge.c
index 15efe12b8b..2647814389 100644
--- a/src/northbridge/amd/agesa/family14/northbridge.c
+++ b/src/northbridge/amd/agesa/family14/northbridge.c
@@ -745,20 +745,46 @@ static void domain_set_resources(device_t dev)
printk(BIOS_DEBUG, " adsr - leaving this lovely routine.\n");
}
-static void domain_enable_resources(device_t dev) {
+extern u8 acpi_slp_type;
+
+static void domain_enable_resources(device_t dev)
+{
u32 val;
#if CONFIG_AMD_SB_CIMX
+ #if CONFIG_HAVE_ACPI_RESUME
+ if (acpi_slp_type != 3) {
+ sb_After_Pci_Init();
+ sb_Mid_Post_Init();
+ } else {
+ sb_After_Pci_Restore_Init();
+ }
+ #else
sb_After_Pci_Init();
sb_Mid_Post_Init();
+ #endif
#endif
/* Must be called after PCI enumeration and resource allocation */
printk(BIOS_DEBUG, "\nFam14h - domain_enable_resources: AmdInitMid.\n");
- val = agesawrapper_amdinitmid();
- if (val) {
- printk(BIOS_DEBUG, "agesawrapper_amdinitmid failed: %x \n", val);
+
+#if CONFIG_HAVE_ACPI_RESUME
+ if (acpi_slp_type != 3) {
+ printk(BIOS_DEBUG, "agesawrapper_amdinitmid ");
+ val = agesawrapper_amdinitmid ();
+ if (val)
+ printk(BIOS_DEBUG, "error level: %x \n", val);
+ else
+ printk(BIOS_DEBUG, "passed.\n");
}
+#else
+ printk(BIOS_DEBUG, "agesawrapper_amdinitmid ");
+ val = agesawrapper_amdinitmid ();
+ if (val)
+ printk(BIOS_DEBUG, "error level: %x \n", val);
+ else
+ printk(BIOS_DEBUG, "passed.\n");
+#endif
printk(BIOS_DEBUG, " ader - leaving domain_enable_resources.\n");
}
@@ -788,24 +814,41 @@ static void cpu_bus_set_resources(device_t dev) {
pci_dev_set_resources(dev);
}
-static void cpu_bus_init(device_t dev) {
- struct device_path cpu_path;
+static u32 cpu_bus_scan(device_t dev, u32 max)
+{
device_t cpu;
- int apic_id;
+ struct device_path cpu_path;
+ int apic_id, cores_found;
- initialize_cpus(dev->link_list);
+ /* There is only one node for fam14, but there may be multiple cores. */
+ cpu = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+ if (!cpu)
+ printk(BIOS_ERR, "ERROR: %02x:%02x.0 not found", 0, 0x18);
- /* Build the AP cpu device path(s) */
- for (apic_id = 1; apic_id < CONFIG_MAX_CPUS; apic_id++) {
+ cores_found = (pci_read_config32(dev_find_slot(0,PCI_DEVFN(0x18,0x3)), 0xe8) >> 12) & 3;
+ printk(BIOS_DEBUG, " AP siblings=%d\n", cores_found);
+
+
+ for (apic_id = 0; apic_id <= cores_found; apic_id++) {
cpu_path.type = DEVICE_PATH_APIC;
cpu_path.apic.apic_id = apic_id;
- cpu = alloc_dev(dev->link_list, &cpu_path);
- if (!cpu)
- return;
- cpu->enabled = 1;
- cpu->path.apic.node_id = 0;
- cpu->path.apic.core_id = apic_id;
+ cpu = alloc_find_dev(dev->link_list, &cpu_path);
+ if (cpu) {
+ cpu->enabled = 1;
+ cpu->path.apic.node_id = 0;
+ cpu->path.apic.core_id = apic_id;
+ printk(BIOS_DEBUG, "CPU: %s %s\n",
+ dev_path(cpu), cpu->enabled?"enabled":"disabled");
+ } else {
+ cpu->enabled = 0;
+ }
}
+ return max;
+}
+
+static void cpu_bus_init(device_t dev)
+{
+ initialize_cpus(dev->link_list);
}
/* North Bridge Structures */
@@ -844,7 +887,7 @@ static struct device_operations cpu_bus_ops = {
.set_resources = cpu_bus_set_resources,
.enable_resources = NULL,
.init = cpu_bus_init,
- .scan_bus = NULL,
+ .scan_bus = cpu_bus_scan,
};
static void root_complex_enable_dev(struct device *dev) {