summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/amd/persimmon/BiosCallOuts.c40
-rw-r--r--src/mainboard/amd/persimmon/BiosCallOuts.h4
-rw-r--r--src/mainboard/amd/persimmon/Kconfig1
-rw-r--r--src/mainboard/amd/persimmon/PlatformGnbPcie.c2
-rw-r--r--src/mainboard/amd/persimmon/PlatformGnbPcieComplex.h1
-rw-r--r--src/mainboard/amd/persimmon/agesawrapper.c160
-rw-r--r--src/mainboard/amd/persimmon/agesawrapper.h5
-rw-r--r--src/mainboard/amd/persimmon/buildOpts.c6
-rw-r--r--src/mainboard/amd/persimmon/get_bus_conf.c21
-rw-r--r--src/mainboard/amd/persimmon/mainboard.c16
-rw-r--r--src/mainboard/amd/persimmon/romstage.c90
11 files changed, 296 insertions, 50 deletions
diff --git a/src/mainboard/amd/persimmon/BiosCallOuts.c b/src/mainboard/amd/persimmon/BiosCallOuts.c
index 7323832eee..52eb9dd698 100644
--- a/src/mainboard/amd/persimmon/BiosCallOuts.c
+++ b/src/mainboard/amd/persimmon/BiosCallOuts.c
@@ -119,8 +119,10 @@ AGESA_STATUS BiosAllocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
AllocParams->BufferPointer = NULL;
AvailableHeapSize = BIOS_HEAP_SIZE - sizeof (BIOS_HEAP_MANAGER);
- BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
- BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
+ BiosHeapBaseAddr = (UINT8 *) GetHeapBase(&(AllocParams->StdHeader));
+ BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BiosHeapBaseAddr;
+
+ printk(BIOS_SPEW, "%s BiosHeapBaseAddr: %x\n", __func__, (u32) BiosHeapBaseAddr);
if (BiosHeapBasePtr->StartOfAllocatedNodes == 0) {
/* First allocation */
@@ -229,26 +231,26 @@ AGESA_STATUS BiosAllocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
AGESA_STATUS BiosDeallocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
{
- UINT8 *BiosHeapBaseAddr;
- UINT32 AllocNodeOffset;
- UINT32 PrevNodeOffset;
- UINT32 NextNodeOffset;
- UINT32 FreedNodeOffset;
- UINT32 EndNodeOffset;
- BIOS_BUFFER_NODE *AllocNodePtr;
- BIOS_BUFFER_NODE *PrevNodePtr;
- BIOS_BUFFER_NODE *FreedNodePtr;
- BIOS_BUFFER_NODE *NextNodePtr;
- BIOS_HEAP_MANAGER *BiosHeapBasePtr;
+ UINT8 *BiosHeapBaseAddr;
+ UINT32 AllocNodeOffset;
+ UINT32 PrevNodeOffset;
+ UINT32 NextNodeOffset;
+ UINT32 FreedNodeOffset;
+ UINT32 EndNodeOffset;
+ BIOS_BUFFER_NODE *AllocNodePtr;
+ BIOS_BUFFER_NODE *PrevNodePtr;
+ BIOS_BUFFER_NODE *FreedNodePtr;
+ BIOS_BUFFER_NODE *NextNodePtr;
+ BIOS_HEAP_MANAGER *BiosHeapBasePtr;
AGESA_BUFFER_PARAMS *AllocParams;
- BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
- BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
-
AllocParams = (AGESA_BUFFER_PARAMS *) ConfigPtr;
+ BiosHeapBaseAddr = (UINT8 *) GetHeapBase(&(AllocParams->StdHeader));
+ BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BiosHeapBaseAddr;
+
/* Find target node to deallocate in list of allocated nodes.
- Return AGESA_BOUNDS_CHK if the BufferHandle is not found
+ Return AGESA_BOUNDS_CHK if the BufferHandle is not found
*/
AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
@@ -355,8 +357,8 @@ AGESA_STATUS BiosLocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
AllocParams = (AGESA_BUFFER_PARAMS *) ConfigPtr;
- BiosHeapBaseAddr = (UINT8 *) BIOS_HEAP_START_ADDRESS;
- BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BIOS_HEAP_START_ADDRESS;
+ BiosHeapBaseAddr = (UINT8 *) GetHeapBase(&(AllocParams->StdHeader));
+ BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BiosHeapBaseAddr;
AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + AllocNodeOffset);
diff --git a/src/mainboard/amd/persimmon/BiosCallOuts.h b/src/mainboard/amd/persimmon/BiosCallOuts.h
index d9e44978c0..071c73c3c6 100644
--- a/src/mainboard/amd/persimmon/BiosCallOuts.h
+++ b/src/mainboard/amd/persimmon/BiosCallOuts.h
@@ -23,8 +23,8 @@
#include "Porting.h"
#include "AGESA.h"
-#define BIOS_HEAP_START_ADDRESS 0x00010000
-#define BIOS_HEAP_SIZE 0x20000 /* 64MB */
+#define BIOS_HEAP_SIZE 0x20000
+#define BSP_STACK_BASE_ADDR 0x30000
typedef struct _BIOS_HEAP_MANAGER {
//UINT32 AvailableSize;
diff --git a/src/mainboard/amd/persimmon/Kconfig b/src/mainboard/amd/persimmon/Kconfig
index 9212e20bd1..27e27a5c0e 100644
--- a/src/mainboard/amd/persimmon/Kconfig
+++ b/src/mainboard/amd/persimmon/Kconfig
@@ -33,6 +33,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
select HAVE_PIRQ_TABLE
select HAVE_MP_TABLE
select HAVE_MAINBOARD_RESOURCES
+ select HAVE_ACPI_RESUME
select HAVE_HARD_RESET
select SB_HT_CHAIN_UNITID_OFFSET_ONLY
select LIFT_BSP_APIC_ID
diff --git a/src/mainboard/amd/persimmon/PlatformGnbPcie.c b/src/mainboard/amd/persimmon/PlatformGnbPcie.c
index 5e37f51205..bdfcb66e0e 100644
--- a/src/mainboard/amd/persimmon/PlatformGnbPcie.c
+++ b/src/mainboard/amd/persimmon/PlatformGnbPcie.c
@@ -23,6 +23,7 @@
#include "heapManager.h"
#include "PlatformGnbPcieComplex.h"
#include "Filecode.h"
+#include "BiosCallOuts.h"
#define FILECODE PROC_RECOVERY_MEM_NB_ON_MRNON_FILECODE
@@ -165,4 +166,3 @@ PCIe_COMPLEX_DESCRIPTOR Brazos = {
InitEarly->GnbConfig.PcieComplexList = BrazosPcieComplexListPtr;
InitEarly->GnbConfig.PsppPolicy = 0;
}
-
diff --git a/src/mainboard/amd/persimmon/PlatformGnbPcieComplex.h b/src/mainboard/amd/persimmon/PlatformGnbPcieComplex.h
index b50cb1a371..a49be624eb 100644
--- a/src/mainboard/amd/persimmon/PlatformGnbPcieComplex.h
+++ b/src/mainboard/amd/persimmon/PlatformGnbPcieComplex.h
@@ -23,6 +23,7 @@
#include "Porting.h"
#include "AGESA.h"
#include "amdlib.h"
+#include <cpu/amd/agesa/s3_resume.h>
//GNB GPP Port4
#define GNB_GPP_PORT4_PORT_PRESENT 1 //0:Disable 1:Enable
diff --git a/src/mainboard/amd/persimmon/agesawrapper.c b/src/mainboard/amd/persimmon/agesawrapper.c
index 6e9997fd07..6bba7ca15a 100644
--- a/src/mainboard/amd/persimmon/agesawrapper.c
+++ b/src/mainboard/amd/persimmon/agesawrapper.c
@@ -33,10 +33,13 @@
#include "cpuLateInit.h"
#include "Dispatcher.h"
#include "cpuCacheInit.h"
+#include "heapManager.h"
#include "amdlib.h"
#include "PlatformGnbPcieComplex.h"
#include "Filecode.h"
#include <arch/io.h>
+#include <cpu/amd/agesa/s3_resume.h>
+#include <cbmem.h>
#define FILECODE UNASSIGNED_FILE_FILECODE
@@ -209,7 +212,7 @@ agesawrapper_amdinitreset (
if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
AmdReleaseStruct (&AmdParamStruct);
return (UINT32)status;
- }
+}
UINT32
agesawrapper_amdinitearly (
@@ -243,6 +246,17 @@ agesawrapper_amdinitearly (
return (UINT32)status;
}
+UINT32 GetHeapBase(
+ AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 high_heap;
+
+ high_heap = (UINT32)cbmem_find(CBMEM_ID_RESUME_SCRATCH) + (CONFIG_HIGH_SCRATCH_MEMORY_SIZE - BIOS_HEAP_SIZE); /* base + high_stack_size */
+
+ return high_heap;
+}
+
UINT32
agesawrapper_amdinitpost (
VOID
@@ -272,7 +286,7 @@ agesawrapper_amdinitpost (
AmdReleaseStruct (&AmdParamStruct);
/* Initialize heap space */
- BiosManagerPtr = (BIOS_HEAP_MANAGER *)BIOS_HEAP_START_ADDRESS;
+ BiosManagerPtr = (BIOS_HEAP_MANAGER *)GetHeapBase(&AmdParamStruct.StdHeader);
HeadPtr = (UINT32 *) ((UINT8 *) BiosManagerPtr + sizeof (BIOS_HEAP_MANAGER));
for (i = 0; i < ((BIOS_HEAP_SIZE/4) - (sizeof (BIOS_HEAP_MANAGER)/4)); i++) {
@@ -496,6 +510,148 @@ agesawrapper_amdinitlate (
return (UINT32)Status;
}
+#if CONFIG_HAVE_ACPI_RESUME == 1
+UINT32
+agesawrapper_amdinitresume (
+ VOID
+ )
+{
+ AGESA_STATUS status;
+ AMD_INTERFACE_PARAMS AmdParamStruct;
+ AMD_RESUME_PARAMS *AmdResumeParamsPtr;
+ S3_DATA_TYPE S3DataType;
+
+ LibAmdMemFill (&AmdParamStruct,
+ 0,
+ sizeof (AMD_INTERFACE_PARAMS),
+ &(AmdParamStruct.StdHeader));
+
+ AmdParamStruct.AgesaFunctionName = AMD_INIT_RESUME;
+ AmdParamStruct.AllocationMethod = PreMemHeap;
+ AmdParamStruct.StdHeader.AltImageBasePtr = 0;
+ AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
+ AmdParamStruct.StdHeader.Func = 0;
+ AmdParamStruct.StdHeader.ImageBasePtr = 0;
+ AmdCreateStruct (&AmdParamStruct);
+
+ AmdResumeParamsPtr = (AMD_RESUME_PARAMS *)AmdParamStruct.NewStructPtr;
+
+ AmdResumeParamsPtr->S3DataBlock.NvStorageSize = 0;
+ AmdResumeParamsPtr->S3DataBlock.VolatileStorageSize = 0;
+ S3DataType = S3DataTypeNonVolatile;
+
+ OemAgesaGetS3Info (S3DataType,
+ (u32 *) &AmdResumeParamsPtr->S3DataBlock.NvStorageSize,
+ (void **) &AmdResumeParamsPtr->S3DataBlock.NvStorage);
+
+ status = AmdInitResume ((AMD_RESUME_PARAMS *)AmdParamStruct.NewStructPtr);
+
+ if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
+ AmdReleaseStruct (&AmdParamStruct);
+
+ return (UINT32)status;
+}
+
+UINT32
+agesawrapper_amds3laterestore (
+ VOID
+ )
+{
+ AGESA_STATUS Status;
+ AMD_INTERFACE_PARAMS AmdInterfaceParams;
+ AMD_S3LATE_PARAMS AmdS3LateParams;
+ AMD_S3LATE_PARAMS *AmdS3LateParamsPtr;
+ S3_DATA_TYPE S3DataType;
+
+ LibAmdMemFill (&AmdS3LateParams,
+ 0,
+ sizeof (AMD_S3LATE_PARAMS),
+ &(AmdS3LateParams.StdHeader));
+ AmdInterfaceParams.StdHeader.ImageBasePtr = 0;
+ AmdInterfaceParams.AllocationMethod = ByHost;
+ AmdInterfaceParams.AgesaFunctionName = AMD_S3LATE_RESTORE;
+ AmdInterfaceParams.NewStructPtr = &AmdS3LateParams;
+ AmdInterfaceParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
+ AmdS3LateParamsPtr = &AmdS3LateParams;
+ AmdInterfaceParams.NewStructSize = sizeof (AMD_S3LATE_PARAMS);
+
+ AmdCreateStruct (&AmdInterfaceParams);
+
+ AmdS3LateParamsPtr->S3DataBlock.VolatileStorageSize = 0;
+ S3DataType = S3DataTypeVolatile;
+
+ OemAgesaGetS3Info (S3DataType,
+ (u32 *) &AmdS3LateParamsPtr->S3DataBlock.VolatileStorageSize,
+ (void **) &AmdS3LateParamsPtr->S3DataBlock.VolatileStorage);
+
+ Status = AmdS3LateRestore (AmdS3LateParamsPtr);
+ if (Status != AGESA_SUCCESS) {
+ agesawrapper_amdreadeventlog();
+ ASSERT(Status == AGESA_SUCCESS);
+ }
+
+ return (UINT32)Status;
+}
+
+#ifndef __PRE_RAM__
+UINT32
+agesawrapper_amdS3Save (
+ VOID
+ )
+{
+ AGESA_STATUS Status;
+ AMD_S3SAVE_PARAMS *AmdS3SaveParamsPtr;
+ AMD_INTERFACE_PARAMS AmdInterfaceParams;
+ S3_DATA_TYPE S3DataType;
+
+ LibAmdMemFill (&AmdInterfaceParams,
+ 0,
+ sizeof (AMD_INTERFACE_PARAMS),
+ &(AmdInterfaceParams.StdHeader));
+
+ AmdInterfaceParams.StdHeader.ImageBasePtr = 0;
+ AmdInterfaceParams.StdHeader.HeapStatus = HEAP_SYSTEM_MEM;
+ AmdInterfaceParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
+ AmdInterfaceParams.AllocationMethod = PostMemDram;
+ AmdInterfaceParams.AgesaFunctionName = AMD_S3_SAVE;
+ AmdInterfaceParams.StdHeader.AltImageBasePtr = 0;
+ AmdInterfaceParams.StdHeader.Func = 0;
+ AmdCreateStruct(&AmdInterfaceParams);
+
+ AmdS3SaveParamsPtr = (AMD_S3SAVE_PARAMS *)AmdInterfaceParams.NewStructPtr;
+ AmdS3SaveParamsPtr->StdHeader = AmdInterfaceParams.StdHeader;
+
+ Status = AmdS3Save (AmdS3SaveParamsPtr);
+ if (Status != AGESA_SUCCESS) {
+ agesawrapper_amdreadeventlog();
+ ASSERT(Status == AGESA_SUCCESS);
+ }
+
+ S3DataType = S3DataTypeNonVolatile;
+
+ Status = OemAgesaSaveS3Info (
+ S3DataType,
+ AmdS3SaveParamsPtr->S3DataBlock.NvStorageSize,
+ AmdS3SaveParamsPtr->S3DataBlock.NvStorage);
+
+ if (AmdS3SaveParamsPtr->S3DataBlock.VolatileStorageSize != 0) {
+ S3DataType = S3DataTypeVolatile;
+
+ Status = OemAgesaSaveS3Info (
+ S3DataType,
+ AmdS3SaveParamsPtr->S3DataBlock.VolatileStorageSize,
+ AmdS3SaveParamsPtr->S3DataBlock.VolatileStorage
+ );
+ }
+
+ OemAgesaSaveMtrr();
+ AmdReleaseStruct (&AmdInterfaceParams);
+
+ return (UINT32)Status;
+}
+#endif /* #ifndef __PRE_RAM__ */
+#endif /* CONFIG_HAVE_ACPI_RESUME */
+
UINT32
agesawrapper_amdlaterunaptask (
UINT32 Func,
diff --git a/src/mainboard/amd/persimmon/agesawrapper.h b/src/mainboard/amd/persimmon/agesawrapper.h
index 7bed570e8c..7babd58a5e 100644
--- a/src/mainboard/amd/persimmon/agesawrapper.h
+++ b/src/mainboard/amd/persimmon/agesawrapper.h
@@ -84,7 +84,12 @@ UINT32 agesawrapper_amdreadeventlog (void);
UINT32 agesawrapper_amdinitcpuio (void);
UINT32 agesawrapper_amdinitmmio (void);
+UINT32 agesawrapper_amdinitresume (void);
+UINT32 agesawrapper_amdS3Save (void);
+UINT32 agesawrapper_amds3laterestore (void);
UINT32 agesawrapper_amdlaterunaptask (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
void *agesawrapper_getlateinitptr (int pick);
+UINT32 GetHeapBase(AMD_CONFIG_PARAMS *StdHeader);
+
#endif
diff --git a/src/mainboard/amd/persimmon/buildOpts.c b/src/mainboard/amd/persimmon/buildOpts.c
index 3e5b14e2c2..389e1d49af 100644
--- a/src/mainboard/amd/persimmon/buildOpts.c
+++ b/src/mainboard/amd/persimmon/buildOpts.c
@@ -120,8 +120,8 @@
#define AGESA_ENTRY_INIT_LATE TRUE
#define AGESA_ENTRY_INIT_S3SAVE TRUE
#define AGESA_ENTRY_INIT_RESUME TRUE
-#define AGESA_ENTRY_INIT_LATE_RESTORE FALSE
-#define AGESA_ENTRY_INIT_GENERAL_SERVICES FALSE
+#define AGESA_ENTRY_INIT_LATE_RESTORE TRUE
+#define AGESA_ENTRY_INIT_GENERAL_SERVICES TRUE
#define BLDCFG_PCI_MMIO_BASE CONFIG_MMCONF_BASE_ADDRESS
#define BLDCFG_PCI_MMIO_SIZE CONFIG_MMCONF_BUS_NUMBER
@@ -169,7 +169,7 @@
//#define BLDCFG_USE_HT_ASSIST TRUE
//#define BLDCFG_USE_ATM_MODE TRUE
//#define BLDCFG_PLATFORM_CONTROL_FLOW_MODE Nfcm
-#define BLDCFG_S3_LATE_RESTORE FALSE
+#define BLDCFG_S3_LATE_RESTORE TRUE
//#define BLDCFG_USE_32_BYTE_REFRESH FALSE
//#define BLDCFG_USE_VARIABLE_MCT_ISOC_PRIORITY FALSE
//#define BLDCFG_PLATFORM_POWER_POLICY_MODE Performance
diff --git a/src/mainboard/amd/persimmon/get_bus_conf.c b/src/mainboard/amd/persimmon/get_bus_conf.c
index 0142762c0a..4c094aecae 100644
--- a/src/mainboard/amd/persimmon/get_bus_conf.c
+++ b/src/mainboard/amd/persimmon/get_bus_conf.c
@@ -51,6 +51,9 @@ u32 sbdn_sb800;
static u32 get_bus_conf_done = 0;
+#if CONFIG_HAVE_ACPI_RESUME == 1
+extern u8 acpi_slp_type;
+#endif
void get_bus_conf(void)
{
@@ -80,11 +83,20 @@ void get_bus_conf(void)
* of each of the write functions called prior to the ACPI write functions, so this
* becomes the best place for this call.
*/
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ if (acpi_slp_type != 3) {
+ status = agesawrapper_amdinitlate();
+ if(status)
+ printk(BIOS_DEBUG, "agesawrapper_amdinitlate failed: %x \n", status);
+ status = agesawrapper_amdS3Save();
+ if(status)
+ printk(BIOS_DEBUG, "agesawrapper_amds3save failed: %x \n", status);
+ }
+#else
status = agesawrapper_amdinitlate();
- if(status) {
+ if(status)
printk(BIOS_DEBUG, "agesawrapper_amdinitlate failed: %x \n", status);
- }
-
+#endif
sbdn_sb800 = 0;
for (i = 0; i < 3; i++) {
@@ -124,7 +136,8 @@ void get_bus_conf(void)
for (j = bus_sb800[2]; j < bus_isa; j++)
bus_type[j] = 1;
- /* I/O APICs: APIC ID Version State Address */
+
+ /* I/O APICs: APIC ID Version State Address */
bus_isa = 10;
apicid_base = CONFIG_MAX_CPUS;
apicid_sb800 = apicid_base;
diff --git a/src/mainboard/amd/persimmon/mainboard.c b/src/mainboard/amd/persimmon/mainboard.c
index 3b181a12bf..9a8428e25b 100644
--- a/src/mainboard/amd/persimmon/mainboard.c
+++ b/src/mainboard/amd/persimmon/mainboard.c
@@ -23,10 +23,13 @@
#include <arch/io.h>
#include <boot/tables.h>
#include <cpu/x86/msr.h>
-#include <cpu/amd/mtrr.h>
#include <device/pci_def.h>
-//#include <southbridge/amd/sb800/sb800.h>
+#include <southbridge/amd/sb800/sb800.h>
+#include <arch/acpi.h>
#include "chip.h"
+#include "BiosCallOuts.h"
+#include <cpu/amd/agesa/s3_resume.h>
+#include <cpu/amd/mtrr.h>
void set_pcie_reset(void);
void set_pcie_dereset(void);
@@ -56,6 +59,14 @@ static void persimmon_enable(device_t dev)
{
printk(BIOS_INFO, "Mainboard " CONFIG_MAINBOARD_PART_NUMBER " Enable.\n");
+/*
+ * The mainboard is the first place that we get control in ramstage. Check
+ * for S3 resume and call the approriate AGESA/CIMx resume functions.
+ */
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ acpi_slp_type = acpi_get_sleep_type();
+#endif
+
#if (CONFIG_GFXUMA == 1)
msr_t msr, msr2;
uint32_t sys_mem;
@@ -110,6 +121,7 @@ int add_mainboard_resources(struct lb_memory *mem)
#endif
return 0;
}
+
struct chip_operations mainboard_ops = {
CHIP_NAME(CONFIG_MAINBOARD_VENDOR " " CONFIG_MAINBOARD_PART_NUMBER " Mainboard")
.enable_dev = persimmon_enable,
diff --git a/src/mainboard/amd/persimmon/romstage.c b/src/mainboard/amd/persimmon/romstage.c
index dfb1aca729..f1d1b2a0d6 100644
--- a/src/mainboard/amd/persimmon/romstage.c
+++ b/src/mainboard/amd/persimmon/romstage.c
@@ -35,9 +35,14 @@
#include "cpu/x86/lapic/boot_cpu.c"
#include "pc80/i8254.c"
#include "pc80/i8259.c"
+#include <cpu/x86/cache.h>
#include "sb_cimx.h"
#include "SBPLATFORM.h"
+#include "cbmem.h"
+#include "cpu/amd/mtrr.h"
+#include "cpu/amd/agesa/s3_resume.h"
+void disable_cache_as_ram(void); /* cache_as_ram.inc */
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx);
#define SERIAL_DEV PNP_DEV(0x4e, F81865F_SP1)
@@ -46,6 +51,10 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
{
u32 val;
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ void *resume_backup_memory;
+#endif
+
/*
* All cores: allow caching of flash chip code and data
* (there are no cache-as-ram reliability concerns with family 14h)
@@ -98,28 +107,75 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
else
printk(BIOS_DEBUG, "passed.\n");
- post_code(0x40);
- printk(BIOS_DEBUG, "agesawrapper_amdinitpost ");
- val = agesawrapper_amdinitpost ();
- if (val)
- printk(BIOS_DEBUG, "error level: %x \n", val);
- else
- printk(BIOS_DEBUG, "passed.\n");
-
- post_code(0x41);
- printk(BIOS_DEBUG, "agesawrapper_amdinitenv ");
- val = agesawrapper_amdinitenv ();
- if (val)
- printk(BIOS_DEBUG, "error level: %x \n", val);
- else
- printk(BIOS_DEBUG, "passed.\n");
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ if (!acpi_is_wakeup_early()) { /* Check for S3 resume */
+#endif
+ post_code(0x40);
+ printk(BIOS_DEBUG, "agesawrapper_amdinitpost ");
+ val = agesawrapper_amdinitpost ();
+ if (val)
+ printk(BIOS_DEBUG, "error level: %x \n", val);
+ else
+ printk(BIOS_DEBUG, "passed.\n");
+
+ post_code(0x42);
+ printk(BIOS_DEBUG, "agesawrapper_amdinitenv ");
+ val = agesawrapper_amdinitenv ();
+ if (val)
+ printk(BIOS_DEBUG, "error level: %x \n", val);
+ else
+ printk(BIOS_DEBUG, "passed.\n");
+
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ } else { /* S3 detect */
+ printk(BIOS_INFO, "S3 detected\n");
+
+ post_code(0x60);
+ printk(BIOS_DEBUG, "agesawrapper_amdinitresume ");
+ val = agesawrapper_amdinitresume();
+ if (val)
+ printk(BIOS_DEBUG, "error level: %x \n", val);
+ else
+ printk(BIOS_DEBUG, "passed.\n");
+
+ printk(BIOS_DEBUG, "agesawrapper_amds3laterestore ");
+ val = agesawrapper_amds3laterestore ();
+ if (val)
+ printk(BIOS_DEBUG, "error level: %x \n", val);
+ else
+ printk(BIOS_DEBUG, "passed.\n");
+
+ post_code(0x61);
+ printk(BIOS_DEBUG, "Find resume memory location\n");
+ resume_backup_memory = backup_resume();
+
+ post_code(0x62);
+ printk(BIOS_DEBUG, "Move CAR stack.\n");
+ move_stack_high_mem();
+ printk(BIOS_DEBUG, "stack moved to: 0x%x\n", (u32) (resume_backup_memory + HIGH_MEMORY_SAVE));
+
+ post_code(0x63);
+ disable_cache_as_ram();
+ printk(BIOS_DEBUG, "CAR disabled.\n");
+ set_resume_cache();
+
+ /*
+ * Copy the system memory that is in the ramstage area to the
+ * reserved area.
+ */
+ if (resume_backup_memory)
+ memcpy(resume_backup_memory, (void *)(CONFIG_RAMBASE), HIGH_MEMORY_SAVE);
+
+ printk(BIOS_DEBUG, "System memory saved. OK to load ramstage.\n");
+ }
+#endif
/* Initialize i8259 pic */
- post_code(0x41);
+ post_code(0x43);
setup_i8259 ();
/* Initialize i8254 timers */
- post_code(0x42);
+ post_code(0x44);
setup_i8254 ();
post_code(0x50);