S3 code whitespaces changes.
[coreboot.git] / src / vendorcode / amd / agesa / f14 / 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 "Filecode.h"
58
59  /*----------------------------------------------------------------------------------------
60  *                   D E F I N I T I O N S    A N D    M A C R O S
61  *----------------------------------------------------------------------------------------
62  */
63
64 /*----------------------------------------------------------------------------------------
65  *                  T Y P E D E F S     A N D     S T R U C T U  R E S
66  *----------------------------------------------------------------------------------------
67  */
68
69 // typedef unsigned int   uintptr_t;
70
71 /*----------------------------------------------------------------------------------------
72  *           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
73  *----------------------------------------------------------------------------------------
74  */
75
76 VOID
77 SetIdtr (
78   IN     IDT_BASE_LIMIT *IdtInfo,
79   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
80   );
81
82 VOID
83 GetCsSelector (
84   IN     UINT16 *Selector,
85   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
86   );
87
88 VOID
89 NmiHandler (
90   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
91   );
92
93 VOID
94 ExecuteHltInstruction (
95   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
96   );
97
98 VOID
99 ExecuteWbinvdInstruction (
100   IN       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  */
107
108
109 //----------------------------------------------------------------------------
110
111 STATIC
112 VOID
113 PrimaryCoreFunctions (AP_MTRR_SETTINGS  *ApMtrrSettingsList)
114    {
115    UINT64 data;
116    UINT32 msrno;
117    // Configure the MTRRs on the AP so
118    // when it runs remote code it will execute
119    // out of RAM instead of ROM.
120    // Disable MTRRs and turn on modification enable bit
121
122    data = __readmsr (0xC0010010);         // MTRR_SYS_CFG
123    data &= ~(1 << 18);                    // MtrrFixDramEn
124    data &= ~(1 << 20);                    // MtrrVarDramEn
125    data |= (1 << 19);                     // MtrrFixDramModEn
126    data |= (1 << 17);                     // SysUcLockEn
127    
128
129    __writemsr (0xC0010010, data);
130
131    // Set 7FFFh-00000h and 9FFFFh-80000h as WB DRAM
132    __writemsr (0x250, 0x1E1E1E1E1E1E1E1E); // AMD_MTRR_FIX64k_00000
133    __writemsr (0x258, 0x1E1E1E1E1E1E1E1E); // AMD_MTRR_FIX16k_80000
134
135    // Set BFFFFh-A0000h, DFFFFh-C0000h as Uncacheable Memory-mapped IO
136    __writemsr (0x259, 0);                 // AMD_AP_MTRR_FIX16k_A0000
137    __writemsr (0x268, 0);                 // AMD_MTRR_FIX4k_C0000
138    __writemsr (0x269, 0);                 // AMD_MTRR_FIX4k_C8000
139    __writemsr (0x26A, 0);                 // AMD_MTRR_FIX4k_D0000
140    __writemsr (0x26B, 0);                 // AMD_MTRR_FIX4k_D8000
141
142    // Set FFFFFh-E0000h as Uncacheable Memory
143    for (msrno = 0x26C; msrno <= 0x26F; msrno++)
144       __writemsr (msrno, 0x1818181818181818);
145
146    // If IBV provided settings for Fixed-Sized MTRRs,
147    // overwrite the default settings.
148    if ((uintptr_t) ApMtrrSettingsList != 0 && (uintptr_t) ApMtrrSettingsList != 0xFFFFFFFF)
149       {
150       int index;
151       for (index = 0; ApMtrrSettingsList [index].MsrAddr != CPU_LIST_TERMINAL; index++)
152          __writemsr (ApMtrrSettingsList [index].MsrAddr, ApMtrrSettingsList [index].MsrData);
153       }
154
155    // restore variable MTTR6 and MTTR7 to default states
156    for (msrno = 0x20F; msrno <= 0x20C; msrno--)  // decrement so that the pair is disable before the base is cleared
157       __writemsr (msrno, 0);
158
159    // Enable fixed-range and variable-range MTRRs
160    // Set Fixed-Range Enable (FE) and MTRR Enable (E) bits
161    __writemsr (0x2FF, __readmsr (0x2FF) | 0xC00);
162
163    // Enable Top-of-Memory setting
164    // Enable use of RdMem/WrMem bits attributes
165    data = __readmsr (0xC0010010);         // MTRR_SYS_CFG
166    data |= (1 << 18);                     // MtrrFixDramEn
167    data |= (1 << 20);                     // MtrrVarDramEn
168    data &= ~(1 << 19);                    // MtrrFixDramModEn
169    __writemsr (0xC0010010, data);
170    }
171
172 //----------------------------------------------------------------------------
173
174 VOID
175 ExecuteFinalHltInstruction (
176   IN       UINT32 SharedCore,
177   IN       AP_MTRR_SETTINGS  *ApMtrrSettingsList,
178   IN       AMD_CONFIG_PARAMS *StdHeader
179   )
180 {
181    int abcdRegs [4];
182    UINT32 cr0val;
183    UINT64 data;
184
185    cr0val = __readcr0 ();
186    if (SharedCore & 2)
187       {
188       // set CombineCr0Cd and enable cache in CR0
189       __writemsr (MSR_CU_CFG3, __readmsr (MSR_CU_CFG3) | 1ULL << 49);
190       __writecr0 (cr0val & ~0x60000000);
191       }
192    else
193       __writecr0 (cr0val | 0x60000000);
194
195    if (SharedCore & 1) PrimaryCoreFunctions (ApMtrrSettingsList);
196
197    // Make sure not to touch any Shared MSR from this point on
198
199    // Restore settings that were temporarily overridden for the cache as ram phase
200    data = __readmsr (0xC0011022);      // MSR_DC_CFG
201    data &= ~(1 << 4);                  // DC_DIS_SPEC_TLB_RLD
202    data &= ~(1 << 8);                  // DIS_CLR_WBTOL2_SMC_HIT
203    data &= ~(1 << 13);                 // DIS_HW_PF
204    __writemsr (0xC0011022, data);
205
206    data = __readmsr (0xC0011021);      // MSR_IC_CFG - C001_1021
207    data &= ~(1 << 9);                  // IC_DIS_SPEC_TLB_RLD
208    __writemsr (0xC0011021, data);
209
210    // AMD_DISABLE_STACK_FAMILY_HOOK
211    __cpuid (abcdRegs, 1);
212    if ((abcdRegs [0] >> 20) == 1) //-----family 10h (Hydra) only-----
213       {
214       data = __readmsr (0xC0011022);
215       data &= ~(1 << 4);
216       data &= ~(1 << 8);
217       data &= ~(1 << 13);
218       __writemsr (0xC0011022, data);
219       
220       data = __readmsr (0xC0011021);
221       data &= ~(1 << 14);
222       data &= ~(1 << 9);
223       __writemsr (0xC0011021, data);
224       
225       data = __readmsr (0xC001102A);
226       data &= ~(1 << 15);
227       data &= ~(1ull << 35);
228       __writemsr (0xC001102A, data);
229       }
230    else if ((abcdRegs [0] >> 20) == 6) //-----family 15h (Orochi) only-----
231       {
232       data = __readmsr (0xC0011020);
233       data &= ~(1 << 28);
234       __writemsr (0xC0011020, data);
235       
236       data = __readmsr (0xC0011021);
237       data &= ~(1 << 9);
238       __writemsr (0xC0011021, data);
239       
240       data = __readmsr (0xC0011022);
241       data &= ~(1 << 4);
242       data &= ~(1l << 13);
243       __writemsr (0xC0011022, data);
244       }
245
246    for (;;)
247      {
248      _disable ();
249      __halt ();
250      }
251   }
252
253 //----------------------------------------------------------------------------
254
255 /// Structure needed to load the IDTR using the lidt instruction
256
257 VOID
258 SetIdtr (
259   IN     IDT_BASE_LIMIT *IdtInfo,
260   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
261   )
262 {
263    __lidt (IdtInfo);
264 }
265
266 //----------------------------------------------------------------------------
267
268 VOID
269 GetCsSelector (
270   IN     UINT16 *Selector,
271   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
272   )
273 {
274   static const UINT8 opcode [] = {0x8C, 0xC8, 0xC3}; // mov eax, cs; ret
275   *Selector = ((UINT16 (*)(void)) (size_t) opcode) ();
276 }
277
278 //----------------------------------------------------------------------------
279
280 VOID
281 NmiHandler (
282   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
283   )
284 {
285   static const UINT8 opcode [] = {0xCF};  // iret
286   ((void (*)(void)) (size_t) opcode) ();
287 }
288
289 //----------------------------------------------------------------------------
290
291 VOID
292 ExecuteHltInstruction (
293   IN OUT AMD_CONFIG_PARAMS *StdHeaderPtr
294   )
295 {
296   _disable ();
297   __halt ();
298 }
299
300 //---------------------------------------------------------------------------
301
302 VOID
303 ExecuteWbinvdInstruction (
304   IN       AMD_CONFIG_PARAMS *StdHeader
305   )
306 {
307   __wbinvd ();
308 }
309
310 //----------------------------------------------------------------------------