5 * AMD AGESA Basic Level Public APIs
7 * Contains basic Level Initialization routines.
9 * @xrefitem bom "File Content Label" "Release Content"
11 * @e sub-project: Interface
12 * @e \$Revision: 55552 $ @e \$Date: 2011-06-22 09:31:58 -0600 (Wed, 22 Jun 2011) $
15 /*****************************************************************************
17 * Copyright (C) 2012 Advanced Micro Devices, Inc.
18 * All rights reserved.
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 * * Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * * Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ******************************************************************************
46 /*----------------------------------------------------------------------------------------
47 * M O D U L E S U S E D
48 *----------------------------------------------------------------------------------------
57 #include "CommonInits.h"
60 #include "heapManager.h"
61 #include "CreateStruct.h"
65 #define FILECODE PROC_COMMON_AMDS3SAVE_FILECODE
67 extern BLDOPT_FCH_FUNCTION BldoptFchFunction;
69 /*----------------------------------------------------------------------------------------
70 * D E F I N I T I O N S A N D M A C R O S
71 *----------------------------------------------------------------------------------------
75 /*----------------------------------------------------------------------------------------
76 * T Y P E D E F S A N D S T R U C T U R E S
77 *----------------------------------------------------------------------------------------
79 CONST UINT32 ROMDATA S3LateHeapTable[] =
81 EVENT_LOG_BUFFER_HANDLE,
82 SOCKET_DIE_MAP_HANDLE,
84 LOCAL_AP_MAIL_BOX_CACHE_HANDLE,
86 AMD_S3_SCRIPT_SAVE_TABLE_HANDLE,
87 AMD_PCIE_COMPLEX_DATA_HANDLE
90 #define S3LATE_TABLE_SIZE (sizeof (S3LateHeapTable) / sizeof (UINT32)) //(sizeof (S3LateHeapTable) / sizeof (S3LATE_HEAP_ELEMENT))
93 /*----------------------------------------------------------------------------------------
94 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
95 *----------------------------------------------------------------------------------------
98 AmdS3SavePlatformConfigInit (
99 IN OUT PLATFORM_CONFIGURATION *PlatformConfig,
100 IN OUT AMD_CONFIG_PARAMS *StdHeader
103 /*----------------------------------------------------------------------------------------
104 * E X P O R T E D F U N C T I O N S
105 *----------------------------------------------------------------------------------------
107 extern BUILD_OPT_CFG UserOptions;
109 /*---------------------------------------------------------------------------------------*/
111 * Main entry point for the AMD_S3_SAVE function.
113 * This entry point is responsible for saving silicon component registers to the
114 * SMM save area in preparation of entering system suspend-to-RAM mode.
116 * @param[in,out] AmdS3SaveParams Required input parameters for the AMD_S3_SAVE
119 * @return Aggregated status across all internal AMD S3 save calls invoked.
124 IN OUT AMD_S3SAVE_PARAMS *AmdS3SaveParams
128 UINT32 EarlyBufferSize;
129 UINT32 LateBufferSize;
130 UINT32 LateContextSize;
132 UINT8 *BufferPointer;
134 ALLOCATE_HEAP_PARAMS HeapParams;
135 LOCATE_HEAP_PTR LocateHeap;
136 BUFFER_NODE *FreeSpaceNode;
137 ALLOCATE_HEAP_PARAMS AllocParams;
138 DEVICE_BLOCK_HEADER *MemoryRelatedDeviceList;
139 DEVICE_BLOCK_HEADER *NonMemoryRelatedDeviceList;
140 AGESA_STATUS ReturnStatus;
141 VOID *HeapPtrs[S3LATE_TABLE_SIZE];
142 UINT32 HeapSizes[S3LATE_TABLE_SIZE];
143 UINT32 HeapBuffersPresent;
144 HEAP_MANAGER *HeapPtr;
146 AGESA_TESTPOINT (TpIfAmdS3SaveEntry, &AmdS3SaveParams->StdHeader);
148 ASSERT (AmdS3SaveParams != NULL);
150 HeapBuffersPresent = 0;
155 NonMemoryRelatedDeviceList = NULL;
156 MemoryRelatedDeviceList = NULL;
157 ReturnStatus = AGESA_SUCCESS;
159 IDS_SKIP_HOOK (IDS_BEFORE_S3_SAVE, AmdS3SaveParams, &(AmdS3SaveParams->StdHeader)) {
161 // Get memory device list
162 MemFS3GetDeviceList (&MemoryRelatedDeviceList, &AmdS3SaveParams->StdHeader);
163 if (MemoryRelatedDeviceList != NULL) {
164 // Determine size needed
165 EarlyBufferSize = GetWorstCaseContextSize (MemoryRelatedDeviceList, INIT_RESUME, &AmdS3SaveParams->StdHeader);
168 if (UserOptions.CfgS3LateRestore) {
169 for (i = 0; i < S3LATE_TABLE_SIZE; i++) {
170 LocateHeap.BufferHandle = S3LateHeapTable[i];
171 if (HeapLocateBuffer (&LocateHeap, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) {
172 HeapBuffersPresent++;
173 HeapSize += LocateHeap.BufferSize;
174 HeapPtrs[i] = LocateHeap.BufferPtr;
175 HeapSizes[i] = LocateHeap.BufferSize;
182 // Determine heap data size requirements
183 if (HeapBuffersPresent != 0) {
184 HeapSize += ((sizeof (HEAP_MANAGER)) + (HeapBuffersPresent * ((sizeof (BUFFER_NODE)) + (NUM_OF_SENTINEL * SIZE_OF_SENTINEL) + 0xF))); // reserve 0xF per buffer node for 16 byte alignment
187 // Get non memory device list
188 GetNonMemoryRelatedDeviceList (&NonMemoryRelatedDeviceList, &AmdS3SaveParams->StdHeader);
190 if (NonMemoryRelatedDeviceList != NULL) {
191 // Determine size needed
192 LateContextSize = GetWorstCaseContextSize (NonMemoryRelatedDeviceList, S3_LATE_RESTORE, &AmdS3SaveParams->StdHeader);
194 LateBufferSize = HeapSize + LateContextSize;
195 if (LateBufferSize != 0) {
196 LateBufferSize += sizeof (S3_VOLATILE_STORAGE_HEADER);
200 if ((EarlyBufferSize != 0) || (LateBufferSize != 0)) {
204 AllocParams.RequestedBufferSize = EarlyBufferSize + LateBufferSize;
205 AllocParams.BufferHandle = AMD_S3_INFO_BUFFER_HANDLE;
206 AllocParams.Persist = 0;
208 AGESA_TESTPOINT (TpIfBeforeAllocateS3SaveBuffer, &AmdS3SaveParams->StdHeader);
209 if (HeapAllocateBuffer (&AllocParams, &AmdS3SaveParams->StdHeader) != AGESA_SUCCESS) {
210 if (AGESA_ERROR > ReturnStatus) {
211 ReturnStatus = AGESA_ERROR;
214 AGESA_TESTPOINT (TpIfAfterAllocateS3SaveBuffer, &AmdS3SaveParams->StdHeader);
216 if (EarlyBufferSize != 0) {
217 AmdS3SaveParams->S3DataBlock.NvStorage = AllocParams.BufferPtr;
218 SaveDeviceListContext (MemoryRelatedDeviceList,
219 AmdS3SaveParams->S3DataBlock.NvStorage,
222 &AmdS3SaveParams->StdHeader);
224 AmdS3SaveParams->S3DataBlock.NvStorageSize = EarlyBufferSize;
227 if (LateBufferSize != 0) {
228 BufferPointer = AllocParams.BufferPtr;
229 AmdS3SaveParams->S3DataBlock.VolatileStorage = &(BufferPointer[EarlyBufferSize]);
231 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapOffset = 0;
232 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapSize = HeapSize;
233 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataOffset = 0;
234 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataSize = LateContextSize;
237 // Transfer heap contents
238 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapOffset = sizeof (S3_VOLATILE_STORAGE_HEADER);
239 HeapPtr = (HEAP_MANAGER *) &BufferPointer[EarlyBufferSize + sizeof (S3_VOLATILE_STORAGE_HEADER)];
240 HeapPtr->UsedSize = sizeof (HEAP_MANAGER);
241 HeapPtr->Signature = HEAP_SIGNATURE_VALID;
242 HeapPtr->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
243 HeapPtr->FirstFreeSpaceOffset = sizeof (HEAP_MANAGER);
244 FreeSpaceNode = (BUFFER_NODE *) ((UINT8 *) HeapPtr + sizeof (HEAP_MANAGER));
245 FreeSpaceNode->BufferSize = HeapSize - sizeof (HEAP_MANAGER) - sizeof (BUFFER_NODE);
246 FreeSpaceNode->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;
248 HeapStatus = AmdS3SaveParams->StdHeader.HeapStatus;
249 AmdS3SaveParams->StdHeader.HeapStatus = HEAP_S3_RESUME;
250 AmdS3SaveParams->StdHeader.HeapBasePtr = (UINT64) HeapPtr;
252 for (i = 0; i < S3LATE_TABLE_SIZE; i++) {
253 if (HeapPtrs[i] != NULL) {
254 HeapParams.RequestedBufferSize = HeapSizes[i]; // S3LateHeapTable[i].BufferLength;
255 HeapParams.BufferHandle = S3LateHeapTable[i];
256 HeapParams.Persist = HEAP_S3_RESUME;
257 if (HeapAllocateBuffer (&HeapParams, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) {
258 LibAmdMemCopy ((VOID *) HeapParams.BufferPtr, HeapPtrs[i], HeapSizes[i], &AmdS3SaveParams->StdHeader);
263 AmdS3SaveParams->StdHeader.HeapStatus = HeapStatus;
267 if (LateContextSize != 0) {
269 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataOffset = HeapSize + sizeof (S3_VOLATILE_STORAGE_HEADER);
271 SaveDeviceListContext (NonMemoryRelatedDeviceList,
272 &(BufferPointer[EarlyBufferSize + HeapSize + sizeof (S3_VOLATILE_STORAGE_HEADER)]),
275 &AmdS3SaveParams->StdHeader);
278 AmdS3SaveParams->S3DataBlock.VolatileStorageSize = HeapSize + LateContextSize + sizeof (S3_VOLATILE_STORAGE_HEADER);
283 ReturnStatus = BldoptFchFunction.InitLate (AmdS3SaveParams);
285 IDS_OPTION_HOOK (IDS_AFTER_S3_SAVE, AmdS3SaveParams, &AmdS3SaveParams->StdHeader);
286 AGESA_TESTPOINT (TpIfAmdS3SaveExit, &AmdS3SaveParams->StdHeader);
290 /*---------------------------------------------------------------------------------------*/
292 * Constructor for the AMD_S3_SAVE function.
294 * This routine is responsible for setting default values for the
295 * input parameters needed by the AMD_S3_SAVE entry point.
297 * @param[in] StdHeader The standard header.
298 * @param[in,out] S3SaveParams Required input parameters for the AMD_S3_SAVE
301 * @retval AGESA_SUCCESS Always Succeeds.
305 AmdS3SaveInitializer (
306 IN OUT AMD_CONFIG_PARAMS *StdHeader,
307 IN OUT AMD_S3SAVE_PARAMS *S3SaveParams
310 ASSERT (StdHeader != NULL);
311 ASSERT (S3SaveParams != NULL);
313 S3SaveParams->StdHeader = *StdHeader;
315 AmdS3ParamsInitializer (&S3SaveParams->S3DataBlock);
317 AmdS3SavePlatformConfigInit (&S3SaveParams->PlatformConfig, &S3SaveParams->StdHeader);
318 BldoptFchFunction.InitLateConstructor (S3SaveParams);
320 return AGESA_SUCCESS;
323 /*---------------------------------------------------------------------------------------*/
325 * Destructor for the AMD_S3_SAVE function.
327 * This routine is responsible for deallocation of heap space allocated during
328 * AMD_S3_SAVE entry point.
330 * @param[in] StdHeader The standard header.
331 * @param[in,out] S3SaveParams Required input parameters for the AMD_INIT_RESUME
334 * @retval AGESA_STATUS
338 AmdS3SaveDestructor (
339 IN AMD_CONFIG_PARAMS *StdHeader,
340 IN OUT AMD_S3SAVE_PARAMS *S3SaveParams
343 AGESA_STATUS ReturnStatus;
346 ASSERT (S3SaveParams != NULL);
348 ReturnStatus = AGESA_SUCCESS;
350 // Deallocate heap space allocated during memory S3 save
351 RetVal = MemS3Deallocate (&S3SaveParams->StdHeader);
352 if (RetVal > ReturnStatus) {
353 ReturnStatus = RetVal;
356 RetVal = HeapDeallocateBuffer (AMD_S3_NB_INFO_BUFFER_HANDLE, StdHeader);
357 if (RetVal > ReturnStatus) {
358 ReturnStatus = RetVal;
361 RetVal = HeapDeallocateBuffer (AMD_S3_INFO_BUFFER_HANDLE, StdHeader);
362 if (RetVal > ReturnStatus) {
363 ReturnStatus = RetVal;
369 /*------------------------------------------------------------------------------------*/
371 * Initialize AmdS3Save stage platform profile and user option input.
373 * @param[in,out] PlatformConfig Platform profile/build option config structure
374 * @param[in,out] StdHeader AMD standard header config param
376 * @retval AGESA_SUCCESS Always Succeeds.
380 AmdS3SavePlatformConfigInit (
381 IN OUT PLATFORM_CONFIGURATION *PlatformConfig,
382 IN OUT AMD_CONFIG_PARAMS *StdHeader
385 CommonPlatformConfigInit (PlatformConfig, StdHeader);
387 return AGESA_SUCCESS;