From f543c7b6d3e485dd59555de04e2649b19953187c Mon Sep 17 00:00:00 2001 From: zbao Date: Fri, 13 Apr 2012 13:42:46 +0800 Subject: [PATCH] S3 code in the mainboard. Persimmon is the demo board. Tested by Linux and Windows 7. Change-Id: I5ded942b51e63ebeb08ace0b202b4ed239b0c14c Signed-off-by: Zheng Bao Signed-off-by: zbao Reviewed-on: http://review.coreboot.org/624 Tested-by: build bot (Jenkins) Reviewed-by: Marc Jones --- src/mainboard/amd/persimmon/BiosCallOuts.c | 40 ++--- src/mainboard/amd/persimmon/BiosCallOuts.h | 4 +- src/mainboard/amd/persimmon/Kconfig | 1 + src/mainboard/amd/persimmon/PlatformGnbPcie.c | 2 +- .../amd/persimmon/PlatformGnbPcieComplex.h | 1 + src/mainboard/amd/persimmon/agesawrapper.c | 160 +++++++++++++++++- src/mainboard/amd/persimmon/agesawrapper.h | 5 + src/mainboard/amd/persimmon/buildOpts.c | 6 +- src/mainboard/amd/persimmon/get_bus_conf.c | 23 ++- src/mainboard/amd/persimmon/mainboard.c | 16 +- src/mainboard/amd/persimmon/romstage.c | 88 ++++++++-- 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 //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 +#include +#include #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. */ - status = agesawrapper_amdinitlate(); - if(status) { - printk(BIOS_DEBUG, "agesawrapper_amdinitlate failed: %x \n", status); +#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) + 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 #include #include -#include #include -//#include +#include +#include #include "chip.h" +#include "BiosCallOuts.h" +#include +#include 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 #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"); +#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(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"); + 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);