AMD Agesa macro expansion fix
[coreboot.git] / src / vendorcode / amd / agesa / f12 / Proc / CPU / cahalt.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * HyperTransport features and sequence implementation.
6  *
7  * Implements the external AmdHtInitialize entry point.
8  * Contains routines for directing the sequence of available features.
9  * Mostly, but not exclusively, AGESA_TESTPOINT invocations should be
10  * contained in this file, and not in the feature code.
11  *
12  * From a build option perspective, it may be that a few lines could be removed
13  * from compilation in this file for certain options.  It is considered that
14  * the code savings from this are too small to be of concern and this file
15  * should not have any explicit build option implementation.
16  *
17  * @xrefitem bom "File Content Label" "Release Content"
18  * @e project:      AGESA
19  * @e sub-project:  HyperTransport
20  * @e \$Revision: 35978 $   @e \$Date: 2010-08-07 02:18:50 +0800 (Sat, 07 Aug 2010) $
21  *
22  */
23 /*
24  *****************************************************************************
25  *
26  * Copyright (c) 2011, Advanced Micro Devices, Inc.
27  * All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions are met:
31  *     * Redistributions of source code must retain the above copyright
32  *       notice, this list of conditions and the following disclaimer.
33  *     * Redistributions in binary form must reproduce the above copyright
34  *       notice, this list of conditions and the following disclaimer in the
35  *       documentation and/or other materials provided with the distribution.
36  *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
37  *       its contributors may be used to endorse or promote products derived
38  *       from this software without specific prior written permission.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
44  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50  *
51  * ***************************************************************************
52  *
53  */
54
55 #include "AGESA.h"
56 #include "cpuRegisters.h"
57 #include "cpuApicUtilities.h"
58 #include "Filecode.h"
59
60  /*----------------------------------------------------------------------------------------
61  *                   D E F I N I T I O N S    A N D    M A C R O S
62  *----------------------------------------------------------------------------------------
63  */
64
65 /*----------------------------------------------------------------------------------------
66  *                  T Y P E D E F S     A N D     S T R U C T U  R E S
67  *----------------------------------------------------------------------------------------
68  */
69
70 // typedef unsigned int   uintptr_t;
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
77 VOID
78 ExecuteFinalHltInstruction (
79   IN       UINT32 SharedCore,
80   IN       AP_MTRR_SETTINGS  *ApMtrrSettingsList,
81   IN       AMD_CONFIG_PARAMS *StdHeader
82   );
83
84 VOID
85 NmiHandler (
86   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
87   );
88
89 VOID
90 ExecuteHltInstruction (
91   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
92   );
93
94 VOID
95 ExecuteWbinvdInstruction (
96   IN       AMD_CONFIG_PARAMS *StdHeader
97   );
98
99  /*----------------------------------------------------------------------------------------
100  *                          E X P O R T E D    F U N C T I O N S
101  *----------------------------------------------------------------------------------------
102  */
103
104
105 //----------------------------------------------------------------------------
106
107 STATIC
108 VOID
109 PrimaryCoreFunctions (AP_MTRR_SETTINGS  *ApMtrrSettingsList)
110    {
111    UINT64 data;
112    UINT32 msrno;
113    // Configure the MTRRs on the AP so
114    // when it runs remote code it will execute
115    // out of RAM instead of ROM.
116    // Disable MTRRs and turn on modification enable bit
117
118    data = __readmsr (0xC0010010);         // MTRR_SYS_CFG
119    data &= ~(1 << 18);                    // MtrrFixDramEn
120    data &= ~(1 << 20);                    // MtrrVarDramEn
121    data |= (1 << 19);                     // MtrrFixDramModEn
122    data |= (1 << 17);                     // SysUcLockEn
123
124
125    __writemsr (0xC0010010, data);
126
127    // Set 7FFFh-00000h and 9FFFFh-80000h as WB DRAM
128    __writemsr (0x250, 0x1E1E1E1E1E1E1E1Eull); // AMD_MTRR_FIX64k_00000
129    __writemsr (0x258, 0x1E1E1E1E1E1E1E1Eull); // AMD_MTRR_FIX16k_80000
130
131    // Set BFFFFh-A0000h, DFFFFh-C0000h as Uncacheable Memory-mapped IO
132    __writemsr (0x259, 0);                 // AMD_AP_MTRR_FIX16k_A0000
133    __writemsr (0x268, 0);                 // AMD_MTRR_FIX4k_C0000
134    __writemsr (0x269, 0);                 // AMD_MTRR_FIX4k_C8000
135    __writemsr (0x26A, 0);                 // AMD_MTRR_FIX4k_D0000
136    __writemsr (0x26B, 0);                 // AMD_MTRR_FIX4k_D8000
137
138    // Set FFFFFh-E0000h as Uncacheable Memory
139    for (msrno = 0x26C; msrno <= 0x26F; msrno++)
140       __writemsr (msrno, 0x1818181818181818ull);
141
142    // If IBV provided settings for Fixed-Sized MTRRs,
143    // overwrite the default settings.
144    if ((uintptr_t) ApMtrrSettingsList != 0 && (uintptr_t) ApMtrrSettingsList != 0xFFFFFFFF)
145       {
146       int index;
147       for (index = 0; ApMtrrSettingsList [index].MsrAddr != CPU_LIST_TERMINAL; index++)
148          __writemsr (ApMtrrSettingsList [index].MsrAddr, ApMtrrSettingsList [index].MsrData);
149       }
150
151    // restore variable MTTR6 and MTTR7 to default states
152    for (msrno = 0x20F; msrno <= 0x20C; msrno--)  // decrement so that the pair is disable before the base is cleared
153       __writemsr (msrno, 0);
154
155    // Enable fixed-range and variable-range MTRRs
156    // Set Fixed-Range Enable (FE) and MTRR Enable (E) bits
157    __writemsr (0x2FF, __readmsr (0x2FF) | 0xC00);
158
159    // Enable Top-of-Memory setting
160    // Enable use of RdMem/WrMem bits attributes
161    data = __readmsr (0xC0010010);         // MTRR_SYS_CFG
162    data |= (1 << 18);                     // MtrrFixDramEn
163    data |= (1 << 20);                     // MtrrVarDramEn
164    data &= ~(1 << 19);                    // MtrrFixDramModEn
165    __writemsr (0xC0010010, data);
166    }
167
168 //----------------------------------------------------------------------------
169
170 VOID
171 ExecuteFinalHltInstruction (
172   IN       UINT32 SharedCore,
173   IN       AP_MTRR_SETTINGS  *ApMtrrSettingsList,
174   IN       AMD_CONFIG_PARAMS *StdHeader
175   )
176 {
177    int abcdRegs [4];
178    UINT32 cr0val;
179    UINT64 data;
180
181    cr0val = __readcr0 ();
182    if (SharedCore & 2)
183       {
184       // set CombineCr0Cd and enable cache in CR0
185       __writemsr (MSR_CU_CFG3, __readmsr (MSR_CU_CFG3) | 1ULL << 49);
186       __writecr0 (cr0val & ~0x60000000);
187       }
188    else
189       __writecr0 (cr0val | 0x60000000);
190
191    if (SharedCore & 1) PrimaryCoreFunctions (ApMtrrSettingsList);
192
193    // Make sure not to touch any Shared MSR from this point on
194
195    // Restore settings that were temporarily overridden for the cache as ram phase
196    data = __readmsr (0xC0011022);      // MSR_DC_CFG
197    data &= ~(1 << 4);                  // DC_DIS_SPEC_TLB_RLD
198    data &= ~(1 << 8);                  // DIS_CLR_WBTOL2_SMC_HIT
199    data &= ~(1 << 13);                 // DIS_HW_PF
200    __writemsr (0xC0011022, data);
201
202    data = __readmsr (0xC0011021);      // MSR_IC_CFG - C001_1021
203    data &= ~(1 << 9);                  // IC_DIS_SPEC_TLB_RLD
204    __writemsr (0xC0011021, data);
205
206    // AMD_DISABLE_STACK_FAMILY_HOOK
207    __cpuid (abcdRegs, 1);
208    if ((abcdRegs [0] >> 20) == 1) //-----family 10h (Hydra) only-----
209       {
210       data = __readmsr (0xC0011022);
211       data &= ~(1 << 4);
212       data &= ~(1 << 8);
213       data &= ~(1 << 13);
214       __writemsr (0xC0011022, data);
215
216       data = __readmsr (0xC0011021);
217       data &= ~(1 << 14);
218       data &= ~(1 << 9);
219       __writemsr (0xC0011021, data);
220
221       data = __readmsr (0xC001102A);
222       data &= ~(1 << 15);
223       data &= ~(1ull << 35);
224       __writemsr (0xC001102A, data);
225       }
226    else if ((abcdRegs [0] >> 20) == 6) //-----family 15h (Orochi) only-----
227       {
228       data = __readmsr (0xC0011020);
229       data &= ~(1 << 28);
230       __writemsr (0xC0011020, data);
231
232       data = __readmsr (0xC0011021);
233       data &= ~(1 << 9);
234       __writemsr (0xC0011021, data);
235
236       data = __readmsr (0xC0011022);
237       data &= ~(1 << 4);
238       data &= ~(1l << 13);
239       __writemsr (0xC0011022, data);
240       }
241
242    for (;;)
243      {
244      _disable ();
245      __halt ();
246      }
247   }
248
249 //----------------------------------------------------------------------------
250
251 /// Structure needed to load the IDTR using the lidt instruction
252
253 VOID
254 SetIdtr (
255   IN     IDT_BASE_LIMIT *IdtInfo,
256   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
257   )
258 {
259    __lidt (IdtInfo);
260 }
261
262 //----------------------------------------------------------------------------
263
264 VOID
265 GetCsSelector (
266   IN     UINT16 *Selector,
267   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
268   )
269 {
270   static const UINT8 opcode [] = {0x8C, 0xC8, 0xC3}; // mov eax, cs; ret
271   *Selector = ((UINT16 (*)(void)) (size_t) opcode) ();
272 }
273
274 //----------------------------------------------------------------------------
275
276 VOID
277 NmiHandler (
278   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
279   )
280 {
281   static const UINT8 opcode [] = {0xCF};  // iret
282   ((void (*)(void)) (size_t) opcode) ();
283 }
284
285 //----------------------------------------------------------------------------
286
287 VOID
288 ExecuteHltInstruction (
289   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
290   )
291 {
292   _disable ();
293   __halt ();
294 }
295
296 //---------------------------------------------------------------------------
297
298 VOID
299 ExecuteWbinvdInstruction (
300   IN       AMD_CONFIG_PARAMS *StdHeader
301   )
302 {
303   __wbinvd ();
304 }
305
306 //----------------------------------------------------------------------------