AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / CPU / cpuLateInit.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD CPU Late Init API
6  *
7  * Contains code for doing any late CPU initialization.
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:      AGESA
11  * @e sub-project:  CPU
12  * @e \$Revision: 51822 $   @e \$Date: 2011-04-27 18:58:43 -0600 (Wed, 27 Apr 2011) $
13  *
14  */
15 /*
16  ******************************************************************************
17  *
18  * Copyright (C) 2012 Advanced Micro Devices, Inc.
19  * All rights reserved.
20  *
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions are met:
23  *     * Redistributions of source code must retain the above copyright
24  *       notice, this list of conditions and the following disclaimer.
25  *     * Redistributions in binary form must reproduce the above copyright
26  *       notice, this list of conditions and the following disclaimer in the
27  *       documentation and/or other materials provided with the distribution.
28  *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
29  *       its contributors may be used to endorse or promote products derived
30  *       from this software without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35  * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 "Ids.h"
53 #include "cpuLateInit.h"
54 #include "cpuRegisters.h"
55 #include "GeneralServices.h"
56 #include "cpuServices.h"
57 #include "Filecode.h"
58 CODE_GROUP (G3_DXE)
59 RDATA_GROUP (G3_DXE)
60
61 #define FILECODE PROC_CPU_CPULATEINIT_FILECODE
62 /*----------------------------------------------------------------------------------------
63  *                   D E F I N I T I O N S    A N D    M A C R O S
64  *----------------------------------------------------------------------------------------
65  */
66
67 /*----------------------------------------------------------------------------------------
68  *                  T Y P E D E F S     A N D     S T R U C T U  R E S
69  *----------------------------------------------------------------------------------------
70  */
71
72 /*----------------------------------------------------------------------------------------
73  *           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
74  *----------------------------------------------------------------------------------------
75  */
76 VOID
77 DisableCf8ExtCfg (
78   IN       AMD_CONFIG_PARAMS   *StdHeader
79   );
80 /*----------------------------------------------------------------------------------------
81  *                          E X P O R T E D    F U N C T I O N S
82  *----------------------------------------------------------------------------------------
83  */
84
85
86 /*---------------------------------------------------------------------------------------*/
87 /**
88  * Performs CPU related initialization at the late entry point
89  *
90  * This function should be the last function run by the AGESA
91  * CPU module and prepares the processor for the operating system
92  * bootstrap load process.
93  *
94  * @param[in]  StdHeader         Config handle for library and services
95  * @param[in]  PlatformConfig    Contains the runtime modifiable feature input data.
96  *
97  * @retval     AGESA_SUCCESS
98  *
99  */
100 AGESA_STATUS
101 AmdCpuLate (
102   IN       AMD_CONFIG_PARAMS   *StdHeader,
103   IN       PLATFORM_CONFIGURATION *PlatformConfig
104   )
105 {
106   AP_EXE_PARAMS ApParams;
107
108   if ((PlatformConfig->PlatformProfile.AdvancedPerformanceProfile.HardwarePrefetchMode != HARDWARE_PREFETCHER_AUTO) ||
109       (PlatformConfig->PlatformProfile.AdvancedPerformanceProfile.SoftwarePrefetchMode != SOFTWARE_PREFETCHES_AUTO)) {
110     ApParams.StdHeader = *StdHeader;
111     ApParams.FunctionNumber = AP_LATE_TASK_CPU_LATE_INIT;
112     ApParams.RelatedDataBlock = (VOID *) PlatformConfig;
113     ApParams.RelatedBlockLength = sizeof (PLATFORM_CONFIGURATION);
114     RunLateApTaskOnAllAPs (&ApParams, StdHeader);
115     CpuLateInitApTask (&ApParams);
116   }
117   DisableCf8ExtCfg (StdHeader);
118   return (AGESA_SUCCESS);
119 }
120
121 /* -----------------------------------------------------------------------------*/
122 /**
123  *
124  *  CpuLateInitApTask
125  *
126  *  Description:
127  *    This is the last function run on all APs
128  *
129  *  Parameters:
130  *    @param[in] ApExeParams   Handle to config for library and services.
131  *
132  *    @retval         AGESA_STATUS
133  *
134  *  Processing:
135  *
136  */
137 AGESA_STATUS
138 CpuLateInitApTask (
139   IN       AP_EXE_PARAMS *ApExeParams
140   )
141 {
142   UINT64   LocalMsrRegister;
143   PLATFORM_CONFIGURATION *PlatformConfig;
144   BOOLEAN  CuCfg3Exist;
145
146   PlatformConfig = (PLATFORM_CONFIGURATION *) ApExeParams->RelatedDataBlock;
147   // The processor that has compute unit has CU_CFG3 MSR
148   switch (GetComputeUnitMapping (&(ApExeParams->StdHeader))) {
149   case AllCoresMapping:
150     CuCfg3Exist = FALSE;
151     break;
152   case EvenCoresMapping:
153     CuCfg3Exist = TRUE;
154     break;
155   default:
156     CuCfg3Exist = FALSE;
157   }
158
159   // DISABLE_HARDWARE_PREFETCH
160   if (PlatformConfig->PlatformProfile.AdvancedPerformanceProfile.HardwarePrefetchMode == DISABLE_HARDWARE_PREFETCH) {
161     // DC_CFG (MSR_C001_1022)
162     //  [13] = 1
163     //  [15] = 1
164     LibAmdMsrRead (MSR_DC_CFG, &LocalMsrRegister, &(ApExeParams->StdHeader));
165     LocalMsrRegister |= (BIT13 | BIT15);
166     LibAmdMsrWrite (MSR_DC_CFG, &LocalMsrRegister, &(ApExeParams->StdHeader));
167     // CU_CFG3 (MSR_C001_102B)
168     //  [3]  = 1
169     //  [16] = 1
170     //  [17] = 1
171     //  [18] = 1
172     if ((CuCfg3Exist) && (IsCorePairPrimary (FirstCoreIsComputeUnitPrimary, &(ApExeParams->StdHeader)))) {
173       LibAmdMsrRead (MSR_CU_CFG3, &LocalMsrRegister, &(ApExeParams->StdHeader));
174       LocalMsrRegister |= (BIT3 | BIT16 | BIT17 | BIT18);
175       LibAmdMsrWrite (MSR_CU_CFG3, &LocalMsrRegister, &(ApExeParams->StdHeader));
176     }
177   }
178
179   // DISABLE_L1_PREFETCHER
180   if ((PlatformConfig->PlatformProfile.AdvancedPerformanceProfile.HardwarePrefetchMode == DISABLE_L1_PREFETCHER) ||
181              (PlatformConfig->PlatformProfile.AdvancedPerformanceProfile.HardwarePrefetchMode == DISABLE_L1_PREFETCHER_AND_HW_PREFETCHER_TRAINING_ON_SOFTWARE_PREFETCHES )) {
182     // CU_CFG3 (MSR_C001_102B)
183     //  [3] = 1
184     if ((CuCfg3Exist) && (IsCorePairPrimary (FirstCoreIsComputeUnitPrimary, &(ApExeParams->StdHeader)))) {
185       LibAmdMsrRead (MSR_CU_CFG3, &LocalMsrRegister, &(ApExeParams->StdHeader));
186       LocalMsrRegister |= BIT3;
187       LibAmdMsrWrite (MSR_CU_CFG3, &LocalMsrRegister, &(ApExeParams->StdHeader));
188     }
189
190   }
191
192   // DISABLE_HW_PREFETCHER_TRAINING_ON_SOFTWARE_PREFETCHES
193   if ((PlatformConfig->PlatformProfile.AdvancedPerformanceProfile.HardwarePrefetchMode == DISABLE_HW_PREFETCHER_TRAINING_ON_SOFTWARE_PREFETCHES ) ||
194              (PlatformConfig->PlatformProfile.AdvancedPerformanceProfile.HardwarePrefetchMode == DISABLE_L1_PREFETCHER_AND_HW_PREFETCHER_TRAINING_ON_SOFTWARE_PREFETCHES )) {
195     // DC_CFG (MSR_C001_1022)
196     //  [15] = 1
197     LibAmdMsrRead (MSR_DC_CFG, &LocalMsrRegister, &(ApExeParams->StdHeader));
198     LocalMsrRegister |= BIT15;
199     LibAmdMsrWrite (MSR_DC_CFG, &LocalMsrRegister, &(ApExeParams->StdHeader));
200
201   }
202
203   // DISABLE_SOFTWARE_PREFETCHES
204   if (PlatformConfig->PlatformProfile.AdvancedPerformanceProfile.SoftwarePrefetchMode == DISABLE_SOFTWARE_PREFETCHES) {
205     // MSR_DE_CFG (MSR_C001_1029)
206     //  [7:2] = 0x3F
207     if (IsCorePairPrimary (FirstCoreIsComputeUnitPrimary, &(ApExeParams->StdHeader))) {
208       LibAmdMsrRead (MSR_DE_CFG, &LocalMsrRegister, &(ApExeParams->StdHeader));
209       LocalMsrRegister |= 0xFC;
210       LibAmdMsrWrite (MSR_DE_CFG, &LocalMsrRegister, &(ApExeParams->StdHeader));
211     }
212   }
213
214   return AGESA_SUCCESS;
215 }
216
217 /*---------------------------------------------------------------------------------------*/
218 /**
219  * Clear EnableCf8ExtCfg on all socket
220  *
221  * Clear F3x8C bit 14 EnableCf8ExtCfg
222  *
223  * @param[in]  StdHeader         Config handle for library and services
224  *
225  *
226  */
227 VOID
228 DisableCf8ExtCfg (
229   IN       AMD_CONFIG_PARAMS   *StdHeader
230   )
231 {
232   AGESA_STATUS  AgesaStatus;
233   PCI_ADDR PciAddress;
234   UINT32 Socket;
235   UINT32 Module;
236   UINT32 PciData;
237   UINT32 LegacyPciAccess;
238
239   ASSERT (IsBsp (StdHeader, &AgesaStatus));
240
241   for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
242     for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
243       if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) {
244         PciAddress.Address.Function = FUNC_3;
245         PciAddress.Address.Register = NB_CFG_HIGH_REG;
246         LegacyPciAccess = ((1 << 31) + (PciAddress.Address.Register & 0xFC) + (PciAddress.Address.Function << 8) + (PciAddress.Address.Device << 11) + (PciAddress.Address.Bus << 16) + ((PciAddress.Address.Register & 0xF00) << (24 - 8)));
247         // read from PCI register
248         LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
249         LibAmdIoRead (AccessWidth32, IOCFC, &PciData, StdHeader);
250         // Disable Cf8ExtCfg
251         PciData &= 0xFFFFBFFF;
252         // write to PCI register
253         LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
254         LibAmdIoWrite (AccessWidth32, IOCFC, &PciData, StdHeader);
255       }
256     }
257   }
258 }
259
260 /*---------------------------------------------------------------------------------------*/
261 /**
262  * Calculate an ACPI style checksum
263  *
264  * Computes the checksum and stores the value to the checksum
265  * field of the passed in ACPI table's header.
266  *
267  * @param[in]  Table             ACPI table to checksum
268  * @param[in]  StdHeader         Config handle for library and services
269  *
270  */
271 VOID
272 ChecksumAcpiTable (
273   IN OUT   ACPI_TABLE_HEADER *Table,
274   IN       AMD_CONFIG_PARAMS *StdHeader
275   )
276 {
277   UINT8  *BuffTempPtr;
278   UINT8  Checksum;
279   UINT32 BufferOffset;
280
281   Table->Checksum = 0;
282   Checksum = 0;
283   BuffTempPtr = (UINT8 *) Table;
284   for (BufferOffset = 0; BufferOffset < Table->TableLength; BufferOffset++) {
285     Checksum = Checksum - *(BuffTempPtr + BufferOffset);
286   }
287
288   Table->Checksum = Checksum;
289 }
290
291 /*---------------------------------------------------------------------------------------*/
292 /**
293  *
294  * Run code on every AP in the system.
295  *
296  * @param[in] ApParams       AP task pointer.
297  * @param[in] StdHeader      Handle to config for library and services
298  *
299  * @return    The most severe AGESA_STATUS returned by an AP.
300  *
301  */
302 AGESA_STATUS
303 RunLateApTaskOnAllAPs (
304   IN       AP_EXE_PARAMS     *ApParams,
305   IN       AMD_CONFIG_PARAMS *StdHeader
306   )
307 {
308   UINT32                  NumberOfSockets;
309   UINT32                  NumberOfCores;
310   UINT8                   Socket;
311   UINT8                   Core;
312   UINT8                   ApicId;
313   UINT32                  BscSocket;
314   UINT32                  Ignored;
315   UINT32                  BscCoreNum;
316   AGESA_STATUS            CalledStatus;
317   AGESA_STATUS            IgnoredStatus;
318   AGESA_STATUS            AgesaStatus;
319
320   ASSERT (IsBsp (StdHeader, &IgnoredStatus));
321
322   AgesaStatus = AGESA_SUCCESS;
323
324   IdentifyCore (StdHeader, &BscSocket, &Ignored, &BscCoreNum, &IgnoredStatus);
325   NumberOfSockets = GetPlatformNumberOfSockets ();
326
327   for (Socket = 0; Socket < NumberOfSockets; Socket++) {
328     if (GetActiveCoresInGivenSocket (Socket, &NumberOfCores, StdHeader)) {
329       for (Core = 0; Core < NumberOfCores; Core++) {
330         if ((Socket != BscSocket) || (Core != BscCoreNum)) {
331           GetApicId (StdHeader, Socket, Core, &ApicId, &IgnoredStatus);
332           AGESA_TESTPOINT (TpIfBeforeRunApFromAllAps, StdHeader);
333           CalledStatus = AgesaRunFcnOnAp ((UINTN) ApicId, ApParams);
334           AGESA_TESTPOINT (TpIfAfterRunApFromAllAps, StdHeader);
335           if (CalledStatus > AgesaStatus) {
336             AgesaStatus = CalledStatus;
337           }
338         }
339       }
340     }
341   }
342   return AgesaStatus;
343 }
344
345
346 /*---------------------------------------------------------------------------------------*/
347 /**
348  *
349  * Run code on core 0 of every socket in the system.
350  *
351  * @param[in] ApParams       AP task pointer.
352  * @param[in] StdHeader      Handle to config for library and services
353  *
354  * @return    The most severe AGESA_STATUS returned by an AP.
355  *
356  */
357 AGESA_STATUS
358 RunLateApTaskOnAllCore0s (
359   IN       AP_EXE_PARAMS     *ApParams,
360   IN       AMD_CONFIG_PARAMS *StdHeader
361   )
362 {
363   UINT32                  NumberOfSockets;
364   UINT8                   Socket;
365   UINT8                   ApicId;
366   UINT32                  BscSocket;
367   UINT32                  IgnoredModule;
368   UINT32                  IgnoredCore;
369   AGESA_STATUS            CalledStatus;
370   AGESA_STATUS            IgnoredStatus;
371   AGESA_STATUS            AgesaStatus;
372
373   ASSERT (IsBsp (StdHeader, &IgnoredStatus));
374
375   AgesaStatus = AGESA_SUCCESS;
376
377   IdentifyCore (StdHeader, &BscSocket, &IgnoredModule, &IgnoredCore, &IgnoredStatus);
378   NumberOfSockets = GetPlatformNumberOfSockets ();
379
380   for (Socket = 0; Socket < NumberOfSockets; Socket++) {
381     if (IsProcessorPresent (Socket, StdHeader)) {
382       if (Socket != BscSocket) {
383         GetApicId (StdHeader, Socket, 0, &ApicId, &IgnoredStatus);
384         AGESA_TESTPOINT (TpIfBeforeRunApFromAllCore0s, StdHeader);
385         CalledStatus = AgesaRunFcnOnAp ((UINTN) ApicId, ApParams);
386         AGESA_TESTPOINT (TpIfAfterRunApFromAllCore0s, StdHeader);
387         if (CalledStatus > AgesaStatus) {
388           AgesaStatus = CalledStatus;
389         }
390       }
391     }
392   }
393   return AgesaStatus;
394 }