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>
Reviewed-on: http://review.coreboot.org/624
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marcj303@gmail.com>
This commit is contained in:
zbao 2012-04-13 13:42:46 +08:00 committed by Marc Jones
parent f72237346d
commit f543c7b6d3
11 changed files with 296 additions and 50 deletions

View File

@ -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 */
@ -242,11 +244,11 @@ 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;
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
*/
@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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
@ -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,

View File

@ -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

View File

@ -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

View File

@ -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) {
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,6 +136,7 @@ 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 */
bus_isa = 10;
apicid_base = CONFIG_MAX_CPUS;

View File

@ -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,

View File

@ -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,6 +107,9 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
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 ();
@ -106,7 +118,7 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
else
printk(BIOS_DEBUG, "passed.\n");
post_code(0x41);
post_code(0x42);
printk(BIOS_DEBUG, "agesawrapper_amdinitenv ");
val = agesawrapper_amdinitenv ();
if (val)
@ -114,12 +126,56 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
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);