Zheng Bao (zheng.bao@amd.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/624
-gerrit
commit 58b649df7457e8e4eddeef5d9202042eb8c3744a Author: zbao fishbaozi@gmail.com Date: Tue Feb 14 18:57:25 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 zheng.bao@amd.com Signed-off-by: zbao fishbaozi@gmail.com --- src/mainboard/amd/persimmon/BiosCallOuts.c | 75 +++++---- 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 | 18 ++- src/mainboard/amd/persimmon/mainboard.c | 15 ++- src/mainboard/amd/persimmon/romstage.c | 90 ++++++++-- 11 files changed, 327 insertions(+), 63 deletions(-)
diff --git a/src/mainboard/amd/persimmon/BiosCallOuts.c b/src/mainboard/amd/persimmon/BiosCallOuts.c index c8379ff..df00c7c 100644 --- a/src/mainboard/amd/persimmon/BiosCallOuts.c +++ b/src/mainboard/amd/persimmon/BiosCallOuts.c @@ -81,6 +81,10 @@ AGESA_STATUS GetBiosCallout (UINT32 Func, UINT32 Data, VOID *ConfigPtr) AGESA_STATUS CalloutStatus; UINTN CallOutCount = sizeof (BiosCallouts) / sizeof (BiosCallouts [0]);
+ /* + * printk(BIOS_SPEW,"%s function: %x\n", __func__, (u32) Func); + */ + CalloutStatus = AGESA_UNSUPPORTED;
for (i = 0; i < CallOutCount; i++) { @@ -95,28 +99,30 @@ AGESA_STATUS GetBiosCallout (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
AGESA_STATUS BiosAllocateBuffer (UINT32 Func, UINT32 Data, VOID *ConfigPtr) { - UINT32 AvailableHeapSize; - UINT8 *BiosHeapBaseAddr; - UINT32 CurrNodeOffset; - UINT32 PrevNodeOffset; - UINT32 FreedNodeOffset; - UINT32 BestFitNodeOffset; - UINT32 BestFitPrevNodeOffset; - UINT32 NextFreeOffset; - BIOS_BUFFER_NODE *CurrNodePtr; - BIOS_BUFFER_NODE *FreedNodePtr; - BIOS_BUFFER_NODE *BestFitNodePtr; - BIOS_BUFFER_NODE *BestFitPrevNodePtr; - BIOS_BUFFER_NODE *NextFreePtr; - BIOS_HEAP_MANAGER *BiosHeapBasePtr; + UINT32 AvailableHeapSize; + UINT8 *BiosHeapBaseAddr; + UINT32 CurrNodeOffset; + UINT32 PrevNodeOffset; + UINT32 FreedNodeOffset; + UINT32 BestFitNodeOffset; + UINT32 BestFitPrevNodeOffset; + UINT32 NextFreeOffset; + BIOS_BUFFER_NODE *CurrNodePtr; + BIOS_BUFFER_NODE *FreedNodePtr; + BIOS_BUFFER_NODE *BestFitNodePtr; + BIOS_BUFFER_NODE *BestFitPrevNodePtr; + BIOS_BUFFER_NODE *NextFreePtr; + BIOS_HEAP_MANAGER *BiosHeapBasePtr; AGESA_BUFFER_PARAMS *AllocParams;
AllocParams = ((AGESA_BUFFER_PARAMS *) 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 */ @@ -224,32 +230,33 @@ 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); PrevNodeOffset = AllocNodeOffset;
- while (AllocNodePtr->BufferHandle != AllocParams->BufferHandle) { + while (AllocNodePtr->BufferHandle != AllocParams->BufferHandle) { if (AllocNodePtr->NextNodeOffset == 0) { return AGESA_BOUNDS_CHK; } @@ -348,8 +355,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 e01e101..01ea3a8 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..0b79e5f 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 //FALSE +#define AGESA_ENTRY_INIT_GENERAL_SERVICES TRUE //FALSE
#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..fef7d60 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++) { diff --git a/src/mainboard/amd/persimmon/mainboard.c b/src/mainboard/amd/persimmon/mainboard.c index 3b181a1..23eea86 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; diff --git a/src/mainboard/amd/persimmon/romstage.c b/src/mainboard/amd/persimmon/romstage.c index dfb1aca..52756ff 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"); + + 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(); + + printk(BIOS_DEBUG, "agesawrapper_amds3laterestore "); + val = agesawrapper_amds3laterestore (); + if (val) + printk(BIOS_DEBUG, "error level: %x \n", val); + else + printk(BIOS_DEBUG, "passed.\n"); + + /* + * Copy the system memory that is in the ramstage area to the + * reserved area. + */ + if (resume_backup_memory) + memcopy_fast(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);