AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Common / AmdInitPost.c
1 /* $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: 56279 $   @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
13  *
14  */
15 /*****************************************************************************
16  *
17  * Copyright (C) 2012 Advanced Micro Devices, Inc.
18  * All rights reserved.
19  *
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.
30  *
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.
41  *
42  ******************************************************************************
43  */
44
45
46 /*----------------------------------------------------------------------------------------
47  *                             M O D U L E S    U S E D
48  *----------------------------------------------------------------------------------------
49  */
50 #include "AGESA.h"
51 #include "amdlib.h"
52 #include "mm.h"
53 #include "Ids.h"
54 #include "cpuRegisters.h"
55 #include "cpuServices.h"
56 #include "cpuPostInit.h"
57 #include "AdvancedApi.h"
58 #include "heapManager.h"
59 #include "CommonInits.h"
60 #include "cpuServices.h"
61 #include "GnbInterface.h"
62 #include "Filecode.h"
63 #include "CreateStruct.h"
64 CODE_GROUP (G1_PEICC)
65 RDATA_GROUP (G2_PEI)
66
67 #define FILECODE PROC_COMMON_AMDINITPOST_FILECODE
68 /*----------------------------------------------------------------------------------------
69  *                   D E F I N I T I O N S    A N D    M A C R O S
70  *----------------------------------------------------------------------------------------
71  */
72
73
74 /*----------------------------------------------------------------------------------------
75  *                  T Y P E D E F S     A N D     S T R U C T U R E S
76  *----------------------------------------------------------------------------------------
77  */
78
79
80 /*----------------------------------------------------------------------------------------
81  *           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
82  *----------------------------------------------------------------------------------------
83  */
84 AGESA_STATUS
85 AmdPostPlatformConfigInit (
86   IN OUT   PLATFORM_CONFIGURATION    *PlatformConfig,
87   IN OUT   AMD_CONFIG_PARAMS         *StdHeader
88   );
89
90
91 /*----------------------------------------------------------------------------------------
92  *                          E X P O R T E D    F U N C T I O N S
93  *----------------------------------------------------------------------------------------
94  */
95
96 extern BUILD_OPT_CFG UserOptions;
97
98 /*------------------------------------------------------------------------------------*/
99 /**
100  * Initialize AmdInitPost stage platform profile and user option input.
101  *
102  * @param[in,out]   PlatformConfig   Platform profile/build option config structure
103  * @param[in,out]   StdHeader        AMD standard header config param
104  *
105  * @retval      AGESA_SUCCESS     Always Succeeds.
106  *
107  */
108 AGESA_STATUS
109 AmdPostPlatformConfigInit (
110   IN OUT   PLATFORM_CONFIGURATION    *PlatformConfig,
111   IN OUT   AMD_CONFIG_PARAMS         *StdHeader
112   )
113 {
114   CommonPlatformConfigInit (PlatformConfig, StdHeader);
115
116   return AGESA_SUCCESS;
117 }
118
119 /*
120  *---------------------------------------------------------------------------------------
121  *
122  *  AmdInitPostInitializer
123  *
124  *  Initializer routine that will be invoked by the wrapper
125  *  to initialize the input structure for the AmdInitPost
126  *
127  *  @param[in, out]    IN OUT   AMD_POST_PARAMS *PostParamsPtr
128  *
129  *  @retval         AGESA_STATUS
130  *
131  *---------------------------------------------------------------------------------------
132  */
133 AGESA_STATUS
134 AmdInitPostInitializer (
135   IN       AMD_CONFIG_PARAMS *StdHeader,
136   IN OUT   AMD_POST_PARAMS   *PostParamsPtr
137   )
138 {
139   AGESA_STATUS  AgesaStatus;
140   ALLOCATE_HEAP_PARAMS AllocHeapParams;
141
142   ASSERT (StdHeader != NULL);
143   ASSERT (PostParamsPtr != NULL);
144
145   PostParamsPtr->StdHeader = *StdHeader;
146
147   AllocHeapParams.RequestedBufferSize = sizeof (MEM_DATA_STRUCT);
148   AllocHeapParams.BufferHandle = AMD_MEM_DATA_HANDLE;
149   AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
150   AgesaStatus = HeapAllocateBuffer (&AllocHeapParams, &PostParamsPtr->StdHeader);
151
152   if (AgesaStatus == AGESA_SUCCESS) {
153     PostParamsPtr->MemConfig.MemData = (MEM_DATA_STRUCT *) AllocHeapParams.BufferPtr;
154     PostParamsPtr->MemConfig.MemData->ParameterListPtr = &(PostParamsPtr->MemConfig);
155     PostParamsPtr->MemConfig.MemData->StdHeader = PostParamsPtr->StdHeader;
156     AmdPostPlatformConfigInit (&PostParamsPtr->PlatformConfig, &PostParamsPtr->StdHeader);
157     AmdMemInitDataStructDef (PostParamsPtr->MemConfig.MemData, &PostParamsPtr->PlatformConfig);
158   }
159   return AgesaStatus;
160 }
161
162 /*
163  *---------------------------------------------------------------------------------------
164  *
165  *  AmdInitPostDestructor
166  *
167  *  Destruct routine that provide a chance if something need to be done
168  *  before the end of AmdInitPost.
169  *
170  *  @param[in]    StdHeader       The standard header.
171  *  @param[in]    PostParamsPtr   AMD init post param.
172  *
173  *  @retval         AGESA_STATUS
174  *
175  *---------------------------------------------------------------------------------------
176  */
177 AGESA_STATUS
178 AmdInitPostDestructor (
179   IN   AMD_CONFIG_PARAMS *StdHeader,
180   IN   AMD_POST_PARAMS   *PostParamsPtr
181   )
182 {
183
184   ASSERT (PostParamsPtr != NULL);
185
186   PostParamsPtr->StdHeader = *StdHeader;
187   PostParamsPtr->MemConfig.MemData->StdHeader = *StdHeader;
188
189   //
190   // AmdMemAuto completed. Here, release heap space which is used for memory init.
191   //
192   MemAmdFinalize (PostParamsPtr->MemConfig.MemData);
193   HeapDeallocateBuffer (AMD_MEM_DATA_HANDLE, StdHeader);
194
195   //
196   // AmdCpuPost completed.
197   //
198   if (PostParamsPtr->MemConfig.SysLimit != 0) {
199     // WBINVD can only be executed when memory is available
200     FinalizeAtPost (StdHeader);
201   }
202
203   return AGESA_SUCCESS;
204 }
205
206 /*---------------------------------------------------------------------------------------*/
207 /**
208  * Main entry point for the AMD_INIT_POST function.
209  *
210  * This entry point is responsible for initializing all system memory,
211  * gathering important data out of the pre-memory cache storage into a
212  * temporary holding buffer in main memory. After that APs will be
213  * shutdown in preparation for the host environment to take control.
214  * Note: pre-memory stack will be disabled also.
215  *
216  * @param[in,out] PostParams     Required input parameters for the AMD_INIT_POST
217  *                                  entry point.
218  *
219  * @return        Aggregated status across all internal AMD POST calls invoked.
220  *
221  */
222 AGESA_STATUS
223 AmdInitPost (
224   IN OUT   AMD_POST_PARAMS *PostParams
225   )
226 {
227   AGESA_STATUS  AgesaStatus;
228   AGESA_STATUS  AmdInitPostStatus;
229   WARM_RESET_REQUEST Request;
230   UINT8 PrevRequestBit;
231   UINT8 PrevStateBits;
232
233   AGESA_TESTPOINT (TpIfAmdInitPostEntry, &PostParams->StdHeader);
234   IDS_HDT_CONSOLE (MAIN_FLOW, "AmdInitPost: Start\n\n");
235   IDS_PERF_TIME_MEASURE (&PostParams->StdHeader);
236
237   ASSERT (PostParams != NULL);
238   AmdInitPostStatus = AGESA_SUCCESS;
239   PrevRequestBit = FALSE;
240   PrevStateBits = WR_STATE_COLD;
241
242   IDS_OPTION_HOOK (IDS_INIT_POST_BEFORE, PostParams, &PostParams->StdHeader);
243
244   // If a previously requested warm reset cannot be triggered in the
245   // current stage, store the previous state of request and reset the
246   // request struct to the current post stage
247   GetWarmResetFlag (&PostParams->StdHeader, &Request);
248   if (Request.RequestBit == TRUE) {
249     if (Request.StateBits >= Request.PostStage) {
250       PrevRequestBit = Request.RequestBit;
251       PrevStateBits = Request.StateBits;
252       Request.RequestBit = FALSE;
253       Request.StateBits = Request.PostStage - 1;
254       SetWarmResetFlag (&PostParams->StdHeader, &Request);
255     }
256   }
257
258   AgesaStatus = GnbInitAtPost (PostParams);
259   if (AgesaStatus > AmdInitPostStatus) {
260     AmdInitPostStatus = AgesaStatus;
261   }
262
263   IDS_HDT_CONSOLE (MAIN_FLOW, "AmdMemAuto: Start\n");
264   AgesaStatus = AmdMemAuto (PostParams->MemConfig.MemData);
265   IDS_HDT_CONSOLE (MAIN_FLOW, "AmdMemAuto: End\n");
266   if (AgesaStatus > AmdInitPostStatus) {
267     AmdInitPostStatus = AgesaStatus;
268   }
269
270   if (AgesaStatus != AGESA_FATAL) {
271
272     // Check BIST status
273     AgesaStatus = CheckBistStatus (&PostParams->StdHeader);
274     if (AgesaStatus > AmdInitPostStatus) {
275       AmdInitPostStatus = AgesaStatus;
276     }
277
278     //
279     // P-State data gathered, then, Relinquish APs
280     //
281     IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuPost: Start\n");
282     AgesaStatus = AmdCpuPost (&PostParams->StdHeader, &PostParams->PlatformConfig);
283     IDS_HDT_CONSOLE (MAIN_FLOW, "AmdCpuPost: End\n");
284     if (AgesaStatus > AmdInitPostStatus) {
285       AmdInitPostStatus = AgesaStatus;
286     }
287
288     // Warm Reset
289     GetWarmResetFlag (&PostParams->StdHeader, &Request);
290     // If a warm reset is requested in the current post stage, trigger the
291     // warm reset and ignore the previous request
292     if (Request.RequestBit == TRUE) {
293       if (Request.StateBits < Request.PostStage) {
294         AgesaDoReset (WARM_RESET_WHENEVER, &PostParams->StdHeader);
295       }
296     } else {
297       // Otherwise, if there's a previous request, restore it
298       // so that the subsequent post stage can trigger the warm reset
299       if (PrevRequestBit == TRUE) {
300         Request.RequestBit = PrevRequestBit;
301         Request.StateBits = PrevStateBits;
302         SetWarmResetFlag (&PostParams->StdHeader, &Request);
303       }
304     }
305
306     AgesaStatus = GnbInitAtPostAfterDram (PostParams);
307     if (AgesaStatus > AmdInitPostStatus) {
308       AmdInitPostStatus = AgesaStatus;
309     }
310
311     IDS_OPTION_HOOK (IDS_INIT_POST_AFTER, PostParams, &PostParams->StdHeader);
312
313     IDS_PERF_TIME_MEASURE (&PostParams->StdHeader);
314     AGESA_TESTPOINT (TpIfAmdInitPostExit, &PostParams->StdHeader);
315     IDS_HDT_CONSOLE (MAIN_FLOW, "\nAmdInitPost: End\n\n");
316     IDS_HDT_CONSOLE (MAIN_FLOW, "Heap transfer Start ...\n\n");
317
318     //For Heap will be relocate to new address in next stage, flush out  debug print buffer if needed
319     IDS_HDT_CONSOLE_FLUSH_BUFFER (&PostParams->StdHeader);
320
321     // WARNING: IDT will be moved from local cache to temp memory, so restore IDTR for BSP here
322     IDS_EXCEPTION_TRAP (IDS_IDT_RESTORE_IDTR_FOR_BSC, NULL, &PostParams->StdHeader);
323     // Copies BSP heap content to RAM, and it should be at the end of AmdInitPost
324     AgesaStatus = CopyHeapToTempRamAtPost (&(PostParams->StdHeader));
325     if (AgesaStatus > AmdInitPostStatus) {
326       AmdInitPostStatus = AgesaStatus;
327     }
328     PostParams->StdHeader.HeapStatus = HEAP_TEMP_MEM;
329   }
330   // Check for Cache As Ram Corruption
331   IDS_CAR_CORRUPTION_CHECK (&PostParams->StdHeader);
332
333   // At the end of AmdInitPost, set StateBits to POST to allow any warm reset that occurs outside
334   // of AGESA to be recognized by IsWarmReset()
335   GetWarmResetFlag (&PostParams->StdHeader, &Request);
336   Request.StateBits = Request.PostStage;
337   SetWarmResetFlag (&PostParams->StdHeader, &Request);
338
339   return  AmdInitPostStatus;
340 }
341