[coreboot] New patch to review for coreboot: 16d4da3 S3 code in the mainboard. Persimmon is a demo board.
Zheng Bao (zheng.bao@amd.com)
gerrit at coreboot.org
Mon Feb 13 11:09:03 CET 2012
Zheng Bao (zheng.bao at amd.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/624
-gerrit
commit 16d4da3acc42e53e7bef775c5c4e754a1fd43c5d
Author: zbao <zheng.bao at amd.com>
Date: Mon Feb 13 17:34:34 2012 +0800
S3 code in the mainboard.
Persimmon is a demo board.
Change-Id: I5ded942b51e63ebeb08ace0b202b4ed239b0c14c
Signed-off-by: Zheng Bao <zheng.bao at amd.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 | 1 +
.../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(+), 62 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..2f69e01 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
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..cc20c36 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(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);
More information about the coreboot
mailing list