Zheng Bao ([email protected]) just uploaded a new patch set to gerrit, which 
you can find at http://review.coreboot.org/624

-gerrit

commit 1e2892a899e2f83f7f4068168c77d6fb3e98e10c
Author: zbao <[email protected]>
Date:   Tue Mar 27 19:00:41 2012 +0800

    S3 code in the mainboard.
    
    Persimmon is the demo board. Tested by Linux and Windows 7.
    
    Change-Id: I5ded942b51e63ebeb08ace0b202b4ed239b0c14c
    Signed-off-by: Zheng Bao <[email protected]>
    Signed-off-by: zbao <[email protected]>
---
 src/mainboard/amd/persimmon/BiosCallOuts.c         |   17 +-
 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         |  173 +++++++++++++++++++-
 src/mainboard/amd/persimmon/agesawrapper.h         |    5 +
 src/mainboard/amd/persimmon/buildOpts.c            |    6 +-
 src/mainboard/amd/persimmon/get_bus_conf.c         |   21 ++-
 src/mainboard/amd/persimmon/mainboard.c            |   16 ++-
 src/mainboard/amd/persimmon/romstage.c             |   90 ++++++++--
 11 files changed, 299 insertions(+), 37 deletions(-)

diff --git a/src/mainboard/amd/persimmon/BiosCallOuts.c 
b/src/mainboard/amd/persimmon/BiosCallOuts.c
index c8379ff..98f9e3e 100644
--- a/src/mainboard/amd/persimmon/BiosCallOuts.c
+++ b/src/mainboard/amd/persimmon/BiosCallOuts.c
@@ -115,8 +115,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 */
@@ -237,9 +239,6 @@ AGESA_STATUS BiosDeallocateBuffer (UINT32 Func, UINT32 
Data, VOID *ConfigPtr)
        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;
 
        /* Find target node to deallocate in list of allocated nodes.
@@ -247,6 +246,10 @@ AGESA_STATUS BiosDeallocateBuffer (UINT32 Func, UINT32 
Data, VOID *ConfigPtr)
        */
        AllocNodeOffset = BiosHeapBasePtr->StartOfAllocatedNodes;
        AllocNodePtr = (BIOS_BUFFER_NODE *) (BiosHeapBaseAddr + 
AllocNodeOffset);
+       BiosHeapBaseAddr = (UINT8 *) GetHeapBase(&(AllocParams->StdHeader));
+       BiosHeapBasePtr = (BIOS_HEAP_MANAGER *) BiosHeapBaseAddr;
+
+
        PrevNodeOffset = AllocNodeOffset;
 
        while (AllocNodePtr->BufferHandle !=    AllocParams->BufferHandle) {
@@ -348,8 +351,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 d9e4497..071c73c 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 9212e20..27e27a5 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 5e37f51..bdfcb66 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 b50cb1a..a49be62 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 6e9997f..53ca04c 100644
--- a/src/mainboard/amd/persimmon/agesawrapper.c
+++ b/src/mainboard/amd/persimmon/agesawrapper.c
@@ -33,10 +33,12 @@
 #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>
 
 #define FILECODE UNASSIGNED_FILE_FILECODE
 
@@ -243,6 +245,35 @@ agesawrapper_amdinitearly (
        return (UINT32)status;
 }
 
+
+UINT32 GetHeapBase(
+       AMD_CONFIG_PARAMS *StdHeader
+       )
+{
+       UINT64                  MsrReg;
+       UINT32                  sys_mem, uma_base, uma_size;
+
+       /* TOP_MEM: the top of DRAM below 4G */
+       LibAmdMsrRead(TOP_MEM, &MsrReg, StdHeader);
+
+       /* refer to UMA Size Consideration in Family14h BKDG. */
+       sys_mem = (UINT32)(MsrReg & 0xFFFFFFFFUL) + 0x1000000; // Ignore 16MB 
allocated for C6 when finding UMA size, refer MemNGetUmaSizeON()
+       if ((MsrReg & 0x0000000F00000000) || (sys_mem >= 0x80000000)) {
+               uma_size = 0x18000000;  /* >= 2G memory, 384M recommended UMA */
+       }
+       else {
+         if (sys_mem >= 0x40000000) {
+                 uma_size = 0x10000000;        /* >= 1G memory, 256M 
recommended UMA */
+         }
+         else {
+                 uma_size = 0x4000000; /* <1G memory, 64M recommended UMA */
+         }
+       }
+
+       uma_base =  (UINT32)(MsrReg & 0xFFFFFFFFUL) - uma_size ;        /* 
TOP_MEM1 */
+       return uma_base  - BIOS_HEAP_SIZE;
+}
+
 UINT32
 agesawrapper_amdinitpost (
        VOID
@@ -272,7 +303,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 +527,146 @@ 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;
+}
+
+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
+
 UINT32
 agesawrapper_amdlaterunaptask (
        UINT32 Func,
diff --git a/src/mainboard/amd/persimmon/agesawrapper.h 
b/src/mainboard/amd/persimmon/agesawrapper.h
index 7bed570..7babd58 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 3e5b14e..389e1d4 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 0142762..4c094ae 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 3b181a1..9a8428e 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 dfb1aca..f52b447 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(resume_backup_memory + HIGH_MEMORY_SAVE);
+               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);

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to