AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Proc / Mem / Main / mu.asm
1 ;*****************************************************************************
2 ; AMD Generic Encapsulated Software Architecture
3 ;
4 ;  $Workfile:: mu.asm   $ $Revision:: 443#$  $Date: 2010-12-22 02:16:51 -0700 (Wed, 22 Dec 2010) $
5 ; Description: Main memory controller system configuration for AGESA
6 ;
7 ;
8 ;*****************************************************************************
9 ;
10 ; Copyright (C) 2012 Advanced Micro Devices, Inc.
11 ; All rights reserved.
12 ;
13 ; Redistribution and use in source and binary forms, with or without
14 ; modification, are permitted provided that the following conditions are met:
15 ;     * Redistributions of source code must retain the above copyright
16 ;       notice, this list of conditions and the following disclaimer.
17 ;     * Redistributions in binary form must reproduce the above copyright
18 ;       notice, this list of conditions and the following disclaimer in the
19 ;       documentation and/or other materials provided with the distribution.
20 ;     * Neither the name of Advanced Micro Devices, Inc. nor the names of
21 ;       its contributors may be used to endorse or promote products derived
22 ;       from this software without specific prior written permission.
23 ;
24 ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 ; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
28 ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 ;
35 ;*****************************************************************************
36 ;============================================================================
37
38
39     .XLIST
40     .LIST
41
42     .686p
43     .MODEL FLAT
44     .CODE
45     ASSUME FS: NOTHING
46
47 ; Define the calling convention used for the C library modules
48 ;@attention - This should be in a central include file
49 CALLCONV    EQU     NEAR C
50
51
52 ;===============================================================================
53 ;memUOutPort:
54 ;
55 ; Do a 32 Bit IO Out operation using edx.
56 ; NOTE: This function will be obsolete in the future.
57 ;
58 ;             In: Port  - port number
59 ;                 Value - value to be written
60 ;
61 ;            Out:
62 ;
63 ; All registers preserved.
64 ;===============================================================================
65 MemUOutPort PROC CALLCONV PUBLIC Port:DWORD, Value:DWORD
66     pushad
67     mov edx,Port
68     mov eax,Value
69     out dx,al
70     popad
71     ret
72 MemUOutPort ENDP
73
74
75 ;----------------------------------------------------------------------------
76 ; _SFENCE();
77 ;
78 _SFENCE macro
79     db  0Fh,0AEh,0F8h
80     endm
81
82 ;----------------------------------------------------------------------------
83 ; _MFENCE();
84 ;
85 _MFENCE macro
86     db  0Fh,0AEh,0F0h
87     endm
88
89 ;----------------------------------------------------------------------------
90 ; _EXECFENCE();
91 ;
92 _EXECFENCE macro
93     out 0EDh,al             ;prevent speculative execution of following instructions
94     endm
95
96 ;===============================================================================
97 ;MemUWriteCachelines:
98 ;   Write a test pattern to DRAM
99 ;
100 ;             In: Pattern   - pointer to the write pattern
101 ;                 Address   - Physical address to be read
102 ;                 ClCount   - number of cachelines to be read
103 ;            Out:
104 ;
105 ;All registers preserved.
106 ;===============================================================================
107 MemUWriteCachelines PROC CALLCONV PUBLIC Address:DWORD, Pattern:NEAR PTR DWORD, ClCount:WORD
108         pushad
109         push ds
110
111         mov eax,Address
112         push ss
113         pop ds
114         xor edx,edx
115         mov edx, DWORD PTR Pattern
116         mov esi,edx
117         mov edx,16
118         _EXECFENCE
119         xor ecx, ecx
120         mov cx,ClCount
121         shl ecx,2
122         @@:
123         db 66h, 0Fh,6Fh,06           ;MOVDQA xmm0,[esi]
124         db 64h, 66h, 0Fh,0E7h,00      ;MOVNTDQ fs:[eax],xmm0  (xmm0 is 128 bits)
125         add eax,edx
126         add esi,edx
127         loop @B
128
129         pop ds
130         popad
131         ret
132 MemUWriteCachelines ENDP
133
134 ;===============================================================================
135 ;MemUReadCachelines:
136 ;
137 ; Read a pattern of 72 bit times (per DQ), to test dram functionality.  The
138 ;pattern is a stress pattern which exercises both ISI and crosstalk.  The number
139 ;of cache lines to fill is dependent on DCT width mode and burstlength.
140 ;
141 ;             In: Buffer    - pointer to a buffer where read data will be stored
142 ;                 Address   - Physical address to be read
143 ;                 ClCount   - number of cachelines to be read
144 ;            Out:
145 ;
146 ;All registers preserved.
147 ;===============================================================================
148 MemUReadCachelines PROC CALLCONV PUBLIC Buffer:NEAR PTR DWORD, Address:DWORD, ClCount:WORD
149 LOCAL Count:BYTE
150         pushad
151         ; First, issue continuous dummy reads to fill up the cache
152         mov eax,Address
153         .if (ClCount > 18)
154             mov cx,ClCount
155             shr cx,4
156             mov Count,cl
157             .while (Count != 0)
158                 push eax
159                 mov edi,eax
160                 add edi,128                     ;bias value (to account for signed displacement)
161                                                 ;clflush opcode=0F AE /7
162                 mov esi,edi
163                 mov ebx,esi
164                 mov ecx,esi
165                 mov edx,esi
166                 add edi,4*64                    ;TestAddr+4 cache lines
167                 add ebx,8*64                    ;TestAddr+8 cache lines
168                 add ecx,12*64                   ;TestAddr+12 cache lines
169                 add edx,16*64                   ;TestAddr+16 cache lines
170                 sub edx,128
171                 _EXECFENCE
172                 mov eax,fs:[esi-128]            ;TestAddr
173                 _MFENCE
174                 mov eax,fs:[esi-64]             ;TestAddr+1 cache line
175                 _MFENCE
176                 mov eax,fs:[esi]                ;TestAddr+2 cache lines
177                 _MFENCE
178                 mov eax,fs:[esi+64]             ;TestAddr+3 cache lines
179                 _MFENCE
180                 mov eax,fs:[edi-128]            ;TestAddr+4 cache lines
181                 _MFENCE
182                 mov eax,fs:[edi-64]             ;TestAddr+5 cache lines
183                 _MFENCE
184                 mov eax,fs:[edi]                ;TestAddr+6 cache lines
185                 _MFENCE
186                 mov eax,fs:[edi+64]             ;TestAddr+7 cache lines
187                 _MFENCE
188                 mov eax,fs:[ebx-128]            ;TestAddr+8 cache lines
189                 _MFENCE
190                 mov eax,fs:[ebx-64]             ;TestAddr+9 cache lines
191                 _MFENCE
192                 mov eax,fs:[ebx]                ;TestAddr+10 cache lines
193                 _MFENCE
194                 mov eax,fs:[ebx+64]             ;TestAddr+11 cache lines
195                 _MFENCE
196                 mov eax,fs:[ecx-128]            ;TestAddr+12 cache lines
197                 _MFENCE
198                 mov eax,fs:[ecx-64]             ;TestAddr+13 cache lines
199                 _MFENCE
200                 mov eax,fs:[ecx]                ;TestAddr+14 cache lines
201                 _MFENCE
202                 mov eax,fs:[ecx+64]             ;TestAddr+15 cache lines
203                 _MFENCE
204                 pop eax
205                 add eax,(16*64)                 ;Next 16CL
206                 dec Count
207             .endw
208         .else
209             mov edi,eax
210             add edi,128                     ;bias value (to account for signed displacement)
211                                             ;clflush opcode=0F AE /7
212             mov esi,edi
213             mov ebx,esi
214             mov ecx,esi
215             mov edx,esi
216             add edi,4*64                    ;TestAddr+4 cache lines
217             add ebx,8*64                    ;TestAddr+8 cache lines
218             add ecx,12*64                   ;TestAddr+12 cache lines
219             add edx,16*64                   ;TestAddr+16 cache lines
220             sub edx,128
221             .if(ClCount == 1)
222                 _MFENCE
223                 mov eax,fs:[esi-128]            ;TestAddr
224                 _MFENCE
225             .elseif(ClCount == 3)
226                 _EXECFENCE
227                 mov eax,fs:[esi-128]            ;TestAddr
228                 _MFENCE
229                 mov eax,fs:[esi-64]             ;TestAddr+1 cache line
230                 _MFENCE
231                 mov eax,fs:[esi]                ;TestAddr+2 cache lines
232                 _MFENCE
233             .elseif(ClCount == 6)
234                 _EXECFENCE
235                 mov eax,fs:[esi-128]            ;TestAddr
236                 _MFENCE
237                 mov eax,fs:[esi-64]             ;TestAddr+1 cache line
238                 _MFENCE
239                 mov eax,fs:[esi]                ;TestAddr+2 cache lines
240                 _MFENCE
241                 mov eax,fs:[esi+64]             ;TestAddr+3 cache lines
242                 _MFENCE
243                 mov eax,fs:[edi-128]            ;TestAddr+4 cache lines
244                 _MFENCE
245                 mov eax,fs:[edi-64]             ;TestAddr+5 cache lines
246                 _MFENCE
247             .elseif(ClCount == 9)
248                 _EXECFENCE
249                 mov eax,fs:[esi-128]            ;TestAddr
250                 _MFENCE
251                 mov eax,fs:[esi-64]             ;TestAddr+1 cache line
252                 _MFENCE
253                 mov eax,fs:[esi]                ;TestAddr+2 cache lines
254                 _MFENCE
255                 mov eax,fs:[esi+64]             ;TestAddr+3 cache lines
256                 _MFENCE
257                 mov eax,fs:[edi-128]            ;TestAddr+4 cache lines
258                 _MFENCE
259                 mov eax,fs:[edi-64]             ;TestAddr+5 cache lines
260                 _MFENCE
261                 mov eax,fs:[edi]                ;TestAddr+6 cache lines
262                 _MFENCE
263                 mov eax,fs:[edi+64]             ;TestAddr+7 cache lines
264                 _MFENCE
265                 mov eax,fs:[ebx-128]            ;TestAddr+8 cache lines
266                 _MFENCE
267             .elseif(ClCount == 18)
268                 _EXECFENCE
269                 mov eax,fs:[esi-128]            ;TestAddr
270                 _MFENCE
271                 mov eax,fs:[esi-64]             ;TestAddr+1 cache line
272                 _MFENCE
273                 mov eax,fs:[esi]                ;TestAddr+2 cache lines
274                 _MFENCE
275                 mov eax,fs:[esi+64]             ;TestAddr+3 cache lines
276                 _MFENCE
277                 mov eax,fs:[edi-128]            ;TestAddr+4 cache lines
278                 _MFENCE
279                 mov eax,fs:[edi-64]             ;TestAddr+5 cache lines
280                 _MFENCE
281                 mov eax,fs:[edi]                ;TestAddr+6 cache lines
282                 _MFENCE
283                 mov eax,fs:[edi+64]             ;TestAddr+7 cache lines
284                 _MFENCE
285                 mov eax,fs:[ebx-128]            ;TestAddr+8 cache lines
286                 _MFENCE
287                 mov eax,fs:[ebx-64]             ;TestAddr+9 cache lines
288                 _MFENCE
289                 mov eax,fs:[ebx]                ;TestAddr+10 cache lines
290                 _MFENCE
291                 mov eax,fs:[ebx+64]             ;TestAddr+11 cache lines
292                 _MFENCE
293                 mov eax,fs:[ecx-128]            ;TestAddr+12 cache lines
294                 _MFENCE
295                 mov eax,fs:[ecx-64]             ;TestAddr+13 cache lines
296                 _MFENCE
297                 mov eax,fs:[ecx]                ;TestAddr+14 cache lines
298                 _MFENCE
299                 mov eax,fs:[ecx+64]             ;TestAddr+15 cache lines
300                 _MFENCE
301                 mov eax,fs:[edx]                ;TestAddr+16 cache lines
302                 _MFENCE
303                 mov eax,fs:[edx+64]             ;TestAddr+17 cache lines
304                 _MFENCE
305             .endif
306         .endif
307         _MFENCE
308
309         ; Then, copy data to buffer
310         mov esi,Address
311         xor edx,edx
312         mov edx,DWORD PTR Buffer
313         mov edi,edx
314         xor ecx, ecx
315         mov cx,ClCount
316         shl ecx,6
317         @@:
318         mov al,fs:[esi]
319         mov ss:[edi],al
320         inc esi
321         inc edi
322         loop @B
323
324         popad
325         ret
326 MemUReadCachelines ENDP
327
328 ;===============================================================================
329 ;MemUDummyCLRead:
330 ;
331 ;   Perform a single cache line read from a given physical address.
332 ;
333 ;             In: Address   - Physical address to be read
334 ;                 ClCount   - number of cachelines to be read
335 ;            Out:
336 ;
337 ;All registers preserved.
338 ;===============================================================================
339 MemUDummyCLRead PROC CALLCONV PUBLIC Address:DWORD
340     _SFENCE
341     pushad
342     mov eax,Address
343     mov dl,fs:[eax]
344     popad
345     ret
346 MemUDummyCLRead ENDP
347
348 ;===============================================================================
349 ;MemUFlushPattern:
350 ;
351 ; Flush a pattern of 72 bit times (per DQ) from cache.  This procedure is used
352 ;to ensure cache miss on the next read training.
353 ;
354 ;             In: Address   - Physical address to be flushed
355 ;                 ClCount   - number of cachelines to be flushed
356 ;            Out:
357 ;
358 ;All registers preserved.
359 ;===============================================================================
360 MemUFlushPattern PROC CALLCONV PUBLIC Address:DWORD, ClCount:WORD
361         pushad
362         mov edi,Address
363         movzx ecx,ClCount
364         @@:
365         _MFENCE                     ; Force strong ordering of clflush
366         db  64h,0Fh,0AEh,3Fh        ; MemUClFlush fs:[edi]
367         _MFENCE
368         add edi,64
369         loop @B
370         popad
371         ret
372 MemUFlushPattern ENDP
373
374
375 ;===============================================================================
376 ;MemUGetWrLvNblErr:
377 ;   Read ClCount number of cachelines then return the bitmap that indicates
378 ;   the write leveling result of each byte lane.
379 ;
380 ;   IN:     ErrBitmap - pointer to a DWORD that will be assigned with WL result
381 ;           Address   - Physical address to be sampled
382 ;           ClCount   - number of cachelines to be read
383 ;
384 ;   OUT:    ErrBitmap - WL result
385 ;
386 ;All registers preserved
387 ;===============================================================================
388 MemUGetWrLvNblErr PROC CALLCONV PUBLIC ErrBitmap:NEAR PTR DWORD, Address:DWORD, ClCount:WORD
389 LOCAL ZeroCount[32]:WORD
390
391         pushad
392         mov esi,Address
393         _EXECFENCE
394     ;Cache fill
395         movzx ecx,ClCount
396         @@:
397         mov eax,fs:[esi]
398         add esi,64
399         loop @B
400         _MFENCE
401
402     ; Then, count the number of 0's
403         ;push es
404         ;push ss
405         ;pop es
406         lea edi,ZeroCount
407         mov cx,SIZEOF ZeroCount
408         mov al,0
409         rep stosb
410         ;pop es
411
412         mov esi,Address
413         lea edi,ZeroCount
414         mov cx,ClCount
415         shl cx,6
416         .while(cx > 0)
417             mov al,fs:[esi]
418             test al,00Fh        ;check lower nibble
419             .if(ZERO?)
420                 inc WORD PTR [edi]
421             .endif
422             add edi,2
423             test al,0F0h        ;check upper nibble
424             .if(ZERO?)
425                 inc WORD PTR [edi]
426             .endif
427             add edi,2
428             inc esi
429             dec cx
430             test cx,07h
431             .if(ZERO?)
432                 sub edi,(16*2)
433                 sub cx,8
434                 add esi,8
435             .endif
436         .endw
437
438     ; Then, average and compress data to error bits
439         lea esi,ZeroCount
440         mov dx,ClCount
441         shl dx,1
442         xor eax,eax
443         xor ecx,ecx
444         mov cl,0
445         .while(cl<16)
446             .if(WORD PTR [esi] < dx)
447                 bts eax,ecx
448             .endif
449             add esi,2
450             inc cl
451         .endw
452         xor edx,edx
453         mov dx,WORD PTR ErrBitmap
454         mov [edx], ax
455
456         popad
457         ret
458 MemUGetWrLvNblErr ENDP
459
460 ;===============================================================================
461 ;AlignPointerTo16Byte:
462 ;   Modifies BufferPtr to be 16 byte aligned
463 ;
464 ;             In: BufferPtrPtr - Pointer to buffer pointer
465 ;            Out: BufferPtrPtr - Pointer to buffer pointer that has been 16 byte aligned
466 ;
467 ;All registers preserved.
468 ;===============================================================================
469 AlignPointerTo16Byte PROC CALLCONV PUBLIC BufferPtrPtr:NEAR PTR DWORD
470         push edx
471         push eax
472         mov edx, BufferPtrPtr
473         mov eax, [edx]
474         add eax, 16
475         and ax, 0FFF0h
476         mov [edx], eax
477         pop eax
478         pop edx
479         ret
480 AlignPointerTo16Byte ENDP
481
482 ;===============================================================================
483 ;MemUMFenceInstr:
484 ;   Serialize instruction
485 ;
486 ;             In:
487 ;            Out:
488 ;
489 ;All registers preserved.
490 ;===============================================================================
491 MemUMFenceInstr PROC CALLCONV PUBLIC
492         _MFENCE
493         ret
494 MemUMFenceInstr ENDP
495
496     END
497