AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Mem / Main / mu.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) 2012 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 /*----------------------------------------------------------------------------------------
56  *                             M O D U L E S    U S E D
57  *----------------------------------------------------------------------------------------
58  */
59
60 #include "AGESA.h"
61 #include "amdlib.h"
62 #include "mu.h"
63 #include "Filecode.h"
64
65 /*----------------------------------------------------------------------------------------
66  *                   D E F I N I T I O N S    A N D    M A C R O S
67  *----------------------------------------------------------------------------------------
68  */
69
70 /*----------------------------------------------------------------------------------------
71  *                  T Y P E D E F S     A N D     S T R U C T U  R E S
72  *----------------------------------------------------------------------------------------
73  */
74
75 /*----------------------------------------------------------------------------------------
76  *           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
77  *----------------------------------------------------------------------------------------
78  */
79
80 /*
81 VOID
82 MemUWriteCachelines (
83   IN       UINT32 Address,
84   IN       UINT8 Pattern[],
85   IN       UINT16 ClCount
86   );
87
88 VOID
89 MemUReadCachelines (
90   IN       UINT8 Buffer[],
91   IN       UINT32 Address,
92   IN       UINT16 ClCount
93   );
94
95 VOID
96 MemUDummyCLRead (
97   IN       UINT32 Address
98   );
99
100 VOID
101 MemUMFenceInstr (
102   VOID
103   );
104
105 VOID
106 MemUFlushPattern (
107   IN       UINT32 Address,
108   IN       UINT16 ClCount
109   );
110
111 VOID
112 AlignPointerTo16Byte (
113   IN OUT   UINT8 **BufferPtrPtr
114   );
115 */
116
117 /*----------------------------------------------------------------------------------------
118  *                          E X P O R T E D    F U N C T I O N S
119  *----------------------------------------------------------------------------------------
120  */
121
122 /*---------------------------------------------------------------------------------------
123  *                          L O C A L    F U N C T I O N S
124  *---------------------------------------------------------------------------------------
125  */
126
127
128
129 //----------------------------------------------------------------------------
130
131 VOID
132 MemUWriteCachelines (
133   IN       UINT32 Address,
134   IN       UINT8 Pattern[],
135   IN       UINT16 ClCount
136   )
137 {
138   UINTN Index;
139   CHAR8 *Position;
140   __m128i *Src = (void *) Pattern;
141   __m128i *Dest = (void *) (size_t)Address;
142
143   Position = (void *) Pattern;
144
145   // ssd - important: without this, the src data may get evicted from cache
146   _mm_mfence ();
147
148   for (Index = 0; Index < ClCount * 4; Index++){
149     _mm_stream_si128_fs (Dest, Src);
150     Src++;
151     Dest++;
152   }
153
154   // ssd - might not be required, but no measurable boot time impact
155   _mm_mfence ();
156 }
157
158
159 //----------------------------------------------------------------------------
160 // MemUReadCachelines:
161 //
162 // Read a pattern of 72 bit times (per DQ), to test dram functionality.  The
163 // pattern is a stress pattern which exercises both ISI and crosstalk.  The number
164 // of cache lines to fill is dependent on DCT width mode and burstlength.
165 //
166 //             In: Buffer    - pointer to a buffer where read data will be stored
167 //                 Address   - Physical address to be read
168 //                 ClCount   - number of cachelines to be read
169
170 VOID
171 MemUReadCachelines (
172   IN       UINT8 Buffer[],
173   IN       UINT32 Address,
174   IN       UINT16 ClCount
175   )
176 {
177   UINTN Index;
178   UINT32 *Dest;
179
180   for (Index = 0; Index < ClCount * 16; Index++) {
181     Dest = (void *) &Buffer [Index * 4];
182     *Dest = __readfsdword (Address + Index * 4);
183     _mm_mfence ();
184   }
185 }
186
187 //----------------------------------------------------------------------------
188 // MemUDummyCLRead:
189 //
190 //    Perform a single cache line read from a given physical address.
191 //
192 //              In: Address   - Physical address to be read
193 //                  ClCount   - number of cachelines to be read
194
195 //FUNC_ATTRIBUTE (noinline)
196 VOID
197 MemUDummyCLRead (
198   IN       UINT32 Address
199   )
200 {
201   _mm_sfence ();
202   __readfsbyte (Address);
203 }
204
205 //----------------------------------------------------------------------------
206
207 VOID
208 MemUMFenceInstr (
209   VOID
210   )
211 {
212   _mm_mfence ();
213 }
214
215 //----------------------------------------------------------------------------
216 // MemUFlushPattern:
217 //
218 //  Flush a pattern of 72 bit times (per DQ) from cache.  This procedure is used
219 //  to ensure cache miss on the next read training.
220 //
221 //              In: Address   - Physical address to be flushed
222 //                  ClCount   - number of cachelines to be flushed
223 //FUNC_ATTRIBUTE(noinline)
224 VOID
225 MemUFlushPattern (
226   IN       UINT32 Address,
227   IN       UINT16 ClCount
228   )
229 {
230   UINTN Index;
231
232   // ssd - theory: a tlb flush is needed to avoid problems with clflush
233   __writemsr (0x20F, __readmsr (0x20F));
234
235   for (Index = 0; Index < ClCount; Index++) {
236     // mfence prevents speculative execution of the clflush
237     _mm_mfence ();
238     _mm_clflush_fs ((void *) (size_t) (Address + Index * 64));
239   }
240 }
241
242 //----------------------------------------------------------------------------
243
244 //FUNC_ATTRIBUTE(noinline)
245 VOID
246 AlignPointerTo16Byte (
247   IN OUT   UINT8 **BufferPtrPtr
248   )
249 {
250   size_t Address = (size_t) *BufferPtrPtr;
251   Address += 15;
252   Address -= Address % 16;
253   *BufferPtrPtr = (void *) Address;
254 }
255
256 //----------------------------------------------------------------------------