blob: f8cdcf145b83ce07f8a164961666bd70f39ad71c [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * AMD AGESA Basic Level Public APIs
6 *
7 * Contains basic Level Initialization routines.
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: Interface
12 * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
13 *
14 */
15/*****************************************************************************
16 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080017 * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc.
18 * All rights reserved.
zbao7d94cf92012-07-02 14:19:14 +080019 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080020 * 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.
zbao7d94cf92012-07-02 14:19:14 +080030 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080031 * 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.
zbao7d94cf92012-07-02 14:19:14 +080041 ******************************************************************************
42 */
43
44
45/*----------------------------------------------------------------------------------------
46 * M O D U L E S U S E D
47 *----------------------------------------------------------------------------------------
48 */
49#include "AGESA.h"
50#include "amdlib.h"
51#include "Ids.h"
52#include "mm.h"
53#include "mn.h"
54#include "S3.h"
55#include "mfs3.h"
56#include "CommonInits.h"
57#include "AmdFch.h"
58#include "GnbInterface.h"
59#include "Filecode.h"
60#include "heapManager.h"
61#include "CreateStruct.h"
62CODE_GROUP (G3_DXE)
63RDATA_GROUP (G3_DXE)
64
65#define FILECODE PROC_COMMON_AMDS3SAVE_FILECODE
66
67extern BLDOPT_FCH_FUNCTION BldoptFchFunction;
68
69/*----------------------------------------------------------------------------------------
70 * D E F I N I T I O N S A N D M A C R O S
71 *----------------------------------------------------------------------------------------
72 */
73
74
75/*----------------------------------------------------------------------------------------
76 * T Y P E D E F S A N D S T R U C T U R E S
77 *----------------------------------------------------------------------------------------
78 */
79CONST UINT32 ROMDATA S3LateHeapTable[] =
80{
81 EVENT_LOG_BUFFER_HANDLE,
82 SOCKET_DIE_MAP_HANDLE,
83 NODE_ID_MAP_HANDLE,
84 LOCAL_AP_MAIL_BOX_CACHE_HANDLE,
85 IDS_CONTROL_HANDLE,
86 AMD_S3_SCRIPT_SAVE_TABLE_HANDLE,
87 AMD_PCIE_COMPLEX_DATA_HANDLE
88};
89
90#define S3LATE_TABLE_SIZE (sizeof (S3LateHeapTable) / sizeof (UINT32)) //(sizeof (S3LateHeapTable) / sizeof (S3LATE_HEAP_ELEMENT))
91
92
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 *----------------------------------------------------------------------------------------
96 */
97AGESA_STATUS
98AmdS3SavePlatformConfigInit (
99 IN OUT PLATFORM_CONFIGURATION *PlatformConfig,
100 IN OUT AMD_CONFIG_PARAMS *StdHeader
101 );
102
103/*----------------------------------------------------------------------------------------
104 * E X P O R T E D F U N C T I O N S
105 *----------------------------------------------------------------------------------------
106 */
107extern BUILD_OPT_CFG UserOptions;
108
109/*---------------------------------------------------------------------------------------*/
110/**
111 * Main entry point for the AMD_S3_SAVE function.
112 *
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.
115 *
116 * @param[in,out] AmdS3SaveParams Required input parameters for the AMD_S3_SAVE
117 * entry point.
118 *
119 * @return Aggregated status across all internal AMD S3 save calls invoked.
120 *
121 */
122AGESA_STATUS
123AmdS3Save (
124 IN OUT AMD_S3SAVE_PARAMS *AmdS3SaveParams
125 )
126{
127 UINTN i;
128 UINT32 EarlyBufferSize;
129 UINT32 LateBufferSize;
130 UINT32 LateContextSize;
131 UINT32 HeapSize;
132 UINT8 *BufferPointer;
133 UINT8 HeapStatus;
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 AGESA_STATUS AgesaStatus;
142 VOID *HeapPtrs[S3LATE_TABLE_SIZE];
143 UINT32 HeapSizes[S3LATE_TABLE_SIZE];
144 UINT32 HeapBuffersPresent;
145 HEAP_MANAGER *HeapPtr;
146 VOID *MemDataPointer;
147
148 AGESA_TESTPOINT (TpIfAmdS3SaveEntry, &AmdS3SaveParams->StdHeader);
149
150 ASSERT (AmdS3SaveParams != NULL);
151
152 HeapBuffersPresent = 0;
153 EarlyBufferSize = 0;
154 LateBufferSize = 0;
155 LateContextSize = 0;
156 HeapSize = 0;
157 NonMemoryRelatedDeviceList = NULL;
158 MemoryRelatedDeviceList = NULL;
159 ReturnStatus = AGESA_SUCCESS;
160 MemDataPointer = NULL;
161
162 IDS_SKIP_HOOK (IDS_BEFORE_S3_SAVE, AmdS3SaveParams, &(AmdS3SaveParams->StdHeader)) {
163 AgesaStatus = GnbInitAtS3Save (AmdS3SaveParams);
164 if (AgesaStatus > ReturnStatus) {
165 ReturnStatus = AgesaStatus;
166 }
167
168 LocateHeap.BufferHandle = AMD_MEM_S3_SAVE_HANDLE;
169 if (HeapLocateBuffer (&LocateHeap, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) {
170 // Memory data has been saved and stored in the heap.
171 // Just copy data from heap.
172 // First 4 bytes in the heap store the size of the saved memory data.
173 EarlyBufferSize = *(UINT32 *) LocateHeap.BufferPtr;
174 MemDataPointer = LocateHeap.BufferPtr + 4;
175 } else {
176 // Get memory device list
177 MemFS3GetDeviceList (&MemoryRelatedDeviceList, &AmdS3SaveParams->StdHeader);
178 if (MemoryRelatedDeviceList != NULL) {
179 // Determine size needed
180 EarlyBufferSize = GetWorstCaseContextSize (MemoryRelatedDeviceList, INIT_RESUME, &AmdS3SaveParams->StdHeader);
181 }
182 }
183
184 if (UserOptions.CfgS3LateRestore) {
185 for (i = 0; i < S3LATE_TABLE_SIZE; i++) {
186 LocateHeap.BufferHandle = S3LateHeapTable[i];
187 if (HeapLocateBuffer (&LocateHeap, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) {
188 HeapBuffersPresent++;
189 HeapSize += LocateHeap.BufferSize;
190 HeapPtrs[i] = LocateHeap.BufferPtr;
191 HeapSizes[i] = LocateHeap.BufferSize;
192 } else {
193 HeapPtrs[i] = NULL;
194 HeapSizes[i] = 0;
195 }
196 }
197
198 // Determine heap data size requirements
199 if (HeapBuffersPresent != 0) {
200 HeapSize += ((sizeof (HEAP_MANAGER)) + (HeapBuffersPresent * ((sizeof (BUFFER_NODE)) + (NUM_OF_SENTINEL * SIZE_OF_SENTINEL) + 0xF))); // reserve 0xF per buffer node for 16 byte alignment
201 }
202
203 // Get non memory device list
204 GetNonMemoryRelatedDeviceList (&NonMemoryRelatedDeviceList, &AmdS3SaveParams->StdHeader);
205
206 if (NonMemoryRelatedDeviceList != NULL) {
207 // Determine size needed
208 LateContextSize = GetWorstCaseContextSize (NonMemoryRelatedDeviceList, S3_LATE_RESTORE, &AmdS3SaveParams->StdHeader);
209 }
210 LateBufferSize = HeapSize + LateContextSize;
211 if (LateBufferSize != 0) {
212 LateBufferSize += sizeof (S3_VOLATILE_STORAGE_HEADER);
213 }
214 }
215
216 if ((EarlyBufferSize != 0) || (LateBufferSize != 0)) {
217 //
218 // Allocate a buffer
219 //
220 AllocParams.RequestedBufferSize = EarlyBufferSize + LateBufferSize;
221 AllocParams.BufferHandle = AMD_S3_INFO_BUFFER_HANDLE;
222 AllocParams.Persist = 0;
223 AGESA_TESTPOINT (TpIfBeforeAllocateS3SaveBuffer, &AmdS3SaveParams->StdHeader);
224 if (HeapAllocateBuffer (&AllocParams, &AmdS3SaveParams->StdHeader) != AGESA_SUCCESS) {
225 if (AGESA_ERROR > ReturnStatus) {
226 ReturnStatus = AGESA_ERROR;
227 }
228 }
229 AGESA_TESTPOINT (TpIfAfterAllocateS3SaveBuffer, &AmdS3SaveParams->StdHeader);
230
231 if (EarlyBufferSize != 0) {
232 AmdS3SaveParams->S3DataBlock.NvStorage = AllocParams.BufferPtr;
233 if (MemDataPointer != NULL) {
234 LibAmdMemCopy (AmdS3SaveParams->S3DataBlock.NvStorage,
235 MemDataPointer,
236 EarlyBufferSize,
237 &AmdS3SaveParams->StdHeader);
238 } else {
239 SaveDeviceListContext (MemoryRelatedDeviceList,
240 AmdS3SaveParams->S3DataBlock.NvStorage,
241 INIT_RESUME,
242 &EarlyBufferSize,
243 &AmdS3SaveParams->StdHeader);
244 }
245 AmdS3SaveParams->S3DataBlock.NvStorageSize = EarlyBufferSize;
246 }
247
248 if (LateBufferSize != 0) {
249 BufferPointer = AllocParams.BufferPtr;
250 AmdS3SaveParams->S3DataBlock.VolatileStorage = &(BufferPointer[EarlyBufferSize]);
251
252 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapOffset = 0;
253 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapSize = HeapSize;
254 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataOffset = 0;
255 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataSize = LateContextSize;
256
257 if (HeapSize != 0) {
258 // Transfer heap contents
259 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->HeapOffset = sizeof (S3_VOLATILE_STORAGE_HEADER);
260 HeapPtr = (HEAP_MANAGER *) &BufferPointer[EarlyBufferSize + sizeof (S3_VOLATILE_STORAGE_HEADER)];
261 HeapPtr->UsedSize = sizeof (HEAP_MANAGER);
262 HeapPtr->Signature = HEAP_SIGNATURE_VALID;
263 HeapPtr->FirstActiveBufferOffset = AMD_HEAP_INVALID_HEAP_OFFSET;
264 HeapPtr->FirstFreeSpaceOffset = sizeof (HEAP_MANAGER);
265 FreeSpaceNode = (BUFFER_NODE *) ((UINT8 *) HeapPtr + sizeof (HEAP_MANAGER));
266 FreeSpaceNode->BufferSize = HeapSize - sizeof (HEAP_MANAGER) - sizeof (BUFFER_NODE);
267 FreeSpaceNode->OffsetOfNextNode = AMD_HEAP_INVALID_HEAP_OFFSET;
268
269 HeapStatus = AmdS3SaveParams->StdHeader.HeapStatus;
270 AmdS3SaveParams->StdHeader.HeapStatus = HEAP_S3_RESUME;
271 AmdS3SaveParams->StdHeader.HeapBasePtr = (UINT64) (UINTN) HeapPtr;
272
273 for (i = 0; i < S3LATE_TABLE_SIZE; i++) {
274 if (HeapPtrs[i] != NULL) {
275 HeapParams.RequestedBufferSize = HeapSizes[i]; // S3LateHeapTable[i].BufferLength;
276 HeapParams.BufferHandle = S3LateHeapTable[i];
277 HeapParams.Persist = HEAP_S3_RESUME;
278 if (HeapAllocateBuffer (&HeapParams, &AmdS3SaveParams->StdHeader) == AGESA_SUCCESS) {
279 LibAmdMemCopy ((VOID *) HeapParams.BufferPtr, HeapPtrs[i], HeapSizes[i], &AmdS3SaveParams->StdHeader);
280 }
281 }
282 }
283
284 AmdS3SaveParams->StdHeader.HeapStatus = HeapStatus;
285 }
286
287
288 if (LateContextSize != 0) {
289
290 ((S3_VOLATILE_STORAGE_HEADER *) AmdS3SaveParams->S3DataBlock.VolatileStorage)->RegisterDataOffset = HeapSize + sizeof (S3_VOLATILE_STORAGE_HEADER);
291
292 SaveDeviceListContext (NonMemoryRelatedDeviceList,
293 &(BufferPointer[EarlyBufferSize + HeapSize + sizeof (S3_VOLATILE_STORAGE_HEADER)]),
294 S3_LATE_RESTORE,
295 &LateContextSize,
296 &AmdS3SaveParams->StdHeader);
297 }
298
299 AmdS3SaveParams->S3DataBlock.VolatileStorageSize = HeapSize + LateContextSize + sizeof (S3_VOLATILE_STORAGE_HEADER);
300 }
301 }
302 }
303
304 AgesaStatus = BldoptFchFunction.InitLate (AmdS3SaveParams);
305 if (AgesaStatus > ReturnStatus) {
306 ReturnStatus = AgesaStatus;
307 }
308 IDS_OPTION_HOOK (IDS_AFTER_S3_SAVE, AmdS3SaveParams, &AmdS3SaveParams->StdHeader);
309 AGESA_TESTPOINT (TpIfAmdS3SaveExit, &AmdS3SaveParams->StdHeader);
310 return ReturnStatus;
311}
312
313/*---------------------------------------------------------------------------------------*/
314/**
315 * Constructor for the AMD_S3_SAVE function.
316 *
317 * This routine is responsible for setting default values for the
318 * input parameters needed by the AMD_S3_SAVE entry point.
319 *
320 * @param[in] StdHeader The standard header.
321 * @param[in,out] S3SaveParams Required input parameters for the AMD_S3_SAVE
322 * entry point.
323 *
324 * @retval AGESA_SUCCESS Always Succeeds.
325 *
326 */
327AGESA_STATUS
328AmdS3SaveInitializer (
329 IN OUT AMD_CONFIG_PARAMS *StdHeader,
330 IN OUT AMD_S3SAVE_PARAMS *S3SaveParams
331 )
332{
333 ASSERT (StdHeader != NULL);
334 ASSERT (S3SaveParams != NULL);
335
336 S3SaveParams->StdHeader = *StdHeader;
337
338 AmdS3ParamsInitializer (&S3SaveParams->S3DataBlock);
339
340 AmdS3SavePlatformConfigInit (&S3SaveParams->PlatformConfig, &S3SaveParams->StdHeader);
341 BldoptFchFunction.InitLateConstructor (S3SaveParams);
342
343 return AGESA_SUCCESS;
344}
345
346/*---------------------------------------------------------------------------------------*/
347/**
348 * Destructor for the AMD_S3_SAVE function.
349 *
350 * This routine is responsible for deallocation of heap space allocated during
351 * AMD_S3_SAVE entry point.
352 *
353 * @param[in] StdHeader The standard header.
354 * @param[in,out] S3SaveParams Required input parameters for the AMD_INIT_RESUME
355 * entry point.
356 *
357 * @retval AGESA_STATUS
358 *
359 */
360AGESA_STATUS
361AmdS3SaveDestructor (
362 IN AMD_CONFIG_PARAMS *StdHeader,
363 IN OUT AMD_S3SAVE_PARAMS *S3SaveParams
364 )
365{
366 AGESA_STATUS ReturnStatus;
367 AGESA_STATUS RetVal;
368 LOCATE_HEAP_PTR LocateHeap;
369
370 ASSERT (S3SaveParams != NULL);
371
372 ReturnStatus = AGESA_SUCCESS;
373
374 // Deallocate heap space allocated during memory S3 save
375 LocateHeap.BufferHandle = AMD_MEM_S3_SAVE_HANDLE;
376 if (HeapLocateBuffer (&LocateHeap, StdHeader) == AGESA_SUCCESS) {
377 RetVal = HeapDeallocateBuffer (AMD_MEM_S3_SAVE_HANDLE, StdHeader);
378 } else {
379 RetVal = MemS3Deallocate (&S3SaveParams->StdHeader);
380 }
381 if (RetVal > ReturnStatus) {
382 ReturnStatus = RetVal;
383 }
384
385 RetVal = HeapDeallocateBuffer (AMD_S3_NB_INFO_BUFFER_HANDLE, StdHeader);
386 if (RetVal > ReturnStatus) {
387 ReturnStatus = RetVal;
388 }
389
390 RetVal = HeapDeallocateBuffer (AMD_S3_INFO_BUFFER_HANDLE, StdHeader);
391 if (RetVal > ReturnStatus) {
392 ReturnStatus = RetVal;
393 }
394
395 return ReturnStatus;
396}
397
398/*------------------------------------------------------------------------------------*/
399/**
400 * Initialize AmdS3Save stage platform profile and user option input.
401 *
402 * @param[in,out] PlatformConfig Platform profile/build option config structure
403 * @param[in,out] StdHeader AMD standard header config param
404 *
405 * @retval AGESA_SUCCESS Always Succeeds.
406 *
407 */
408AGESA_STATUS
409AmdS3SavePlatformConfigInit (
410 IN OUT PLATFORM_CONFIGURATION *PlatformConfig,
411 IN OUT AMD_CONFIG_PARAMS *StdHeader
412 )
413{
414 CommonPlatformConfigInit (PlatformConfig, StdHeader);
415
416 return AGESA_SUCCESS;
417}