AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Lib / IA32 / amdlib32.asm
1 ;/**
2 ; * @file
3 ; *
4 ; * Agesa library 32bit
5 ; *
6 ; * Contains AMD AGESA Library
7 ; *
8 ; * @xrefitem bom "File Content Label" "Release Content"
9 ; * @e project:      AGESA
10 ; * @e sub-project:  Lib
11 ; * @e \$Revision: 17071 $   @e \$Date: 2009-07-30 10:13:11 -0700 (Thu, 30 Jul 2009) $
12 ; */
13 ;*****************************************************************************
14 ;
15 ; Copyright (C) 2012 Advanced Micro Devices, Inc.
16 ; All rights reserved.
17 ;
18 ; Redistribution and use in source and binary forms, with or without
19 ; modification, are permitted provided that the following conditions are met:
20 ;     * Redistributions of source code must retain the above copyright
21 ;       notice, this list of conditions and the following disclaimer.
22 ;     * Redistributions in binary form must reproduce the above copyright
23 ;       notice, this list of conditions and the following disclaimer in the
24 ;       documentation and/or other materials provided with the distribution.
25 ;     * Neither the name of Advanced Micro Devices, Inc. nor the names of
26 ;       its contributors may be used to endorse or promote products derived
27 ;       from this software without specific prior written permission.
28 ;
29 ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30 ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 ; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
33 ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ;
40 ;*****************************************************************************
41
42 .586p
43 .xmm
44 .model  flat
45 ASSUME FS:NOTHING
46 .code
47
48 ;/*---------------------------------------------------------------------------------------*/
49 ;/**
50 ; *  Write IO byte
51 ; *
52 ; *  @param[in]   Address IO port address
53 ; *  @param[in]   Data    IO port Value
54 ; */
55
56 public  WriteIo8
57 WriteIo8        PROC NEAR C USES DX AX Address:WORD, Data:Byte
58         mov     dx, Address
59         mov     al, Data
60         out     dx, al
61         ret
62 WriteIo8        ENDP
63
64 ;/*---------------------------------------------------------------------------------------*/
65 ;/**
66 ; *  Write IO word
67 ; *
68 ; *  @param[in]   Address IO port address
69 ; *  @param[in]   Data    IO port Value
70 ; */
71 public WriteIo16
72 WriteIo16       PROC NEAR C USES DX AX Address:WORD, Data:WORD
73         mov     dx, Address
74         mov     ax, Data
75         out     dx, ax
76         ret
77 WriteIo16       ENDP
78
79 ;/*---------------------------------------------------------------------------------------*/
80 ;/**
81 ; *  Write IO dword
82 ; *
83 ; *  @param[in]   Address IO port address
84 ; *  @param[in]   Data    IO port Value
85 ; */
86
87 public WriteIo32
88 WriteIo32       PROC NEAR C USES DX EAX Address:WORD, Data:DWORD
89         mov     dx, Address
90         mov     eax, Data
91         out     dx, eax
92         ret
93 WriteIo32       ENDP
94
95 ;/*---------------------------------------------------------------------------------------*/
96 ;/**
97 ; *  Read IO byte
98 ; *
99 ; *  @param[in] - IO port address
100 ; *  @retval      IO port Value
101 ; */
102 public ReadIo8
103 ReadIo8 PROC NEAR C USES DX Address:WORD
104         mov     dx, Address
105         in      al, dx
106         ret
107 ReadIo8 ENDP
108
109 ;/*---------------------------------------------------------------------------------------*/
110 ;/**
111 ; *  Read IO word
112 ; *
113 ; *  @param[in]   Address IO port address
114 ; *  @retval      IO port Value
115 ; */
116 public ReadIo16
117 ReadIo16        PROC NEAR C USES DX Address:WORD
118         mov     dx, Address
119         in      ax, dx
120         ret
121 ReadIo16        ENDP
122
123 ;/*---------------------------------------------------------------------------------------*/
124 ;/**
125 ; *  Read IO dword
126 ; *
127 ; *  @param[in]   Address  IO port address
128 ; *  @retval      IO port Value
129 ; */
130 public ReadIo32
131 ReadIo32        PROC NEAR C USES DX Address:WORD
132         mov     dx, Address
133         in      eax, dx
134         ret
135 ReadIo32        ENDP
136
137
138 ;/*---------------------------------------------------------------------------------------*/
139 ;/**
140 ; *  Read MSR
141 ; *
142 ; *  @param[in]  Address  MSR Address
143 ; *  @param[in]  Data     Pointer to data
144 ; *  @param[in]  ConfigPtr (Optional)
145 ; */
146 public LibAmdMsrRead
147 LibAmdMsrRead  PROC NEAR C USES ECX ESI EDX Address:DWORD, Value:PTR, ConfigPtr:PTR
148         mov     esi, ConfigPtr        ;Dummy read to avoid compilation warning
149         mov     ecx, Address
150         rdmsr
151         mov     esi, Value
152         mov     [esi],   eax
153         mov     [esi+4], edx
154         ret
155 LibAmdMsrRead  ENDP
156
157 ;/*---------------------------------------------------------------------------------------*/
158 ;/**
159 ; *  Write MSR
160 ; *
161 ; *  @param[in]  Address    MSR Address
162 ; *  @param[in]  Data       Pointer to data
163 ; *  @param[in]  ConfigPtr  (Optional)
164 ; */
165 public LibAmdMsrWrite
166 LibAmdMsrWrite                PROC NEAR C USES ECX ESI EDX Address:DWORD, Data:PTR, ConfigPtr:PTR
167         mov     esi, ConfigPtr         ;Dummy read to avoid compilation warning
168         mov     ecx, Address
169         mov     esi, Data
170         mov     eax, [esi]
171         mov     edx, [esi+4]
172         wrmsr
173         ret
174 LibAmdMsrWrite                ENDP
175
176 ;/*---------------------------------------------------------------------------------------*/
177 ;/**
178 ; *  Read CPUID
179 ; *
180 ; *  @param[in]  Func   CPUID function
181 ; *  @param[in]  DATA   Pointer to CPUID_DATA to save cpuid data
182 ; *  @param[in]  ConfigPtr (Optional)
183 ; */
184 public LibAmdCpuidRead
185 LibAmdCpuidRead       PROC NEAR C  Func:DWORD, DATA:PTR, ConfigPtr:PTR
186         pushad
187         mov     esi, ConfigPtr           ;Dummy read to avoid compilation warning
188         mov     eax, Func
189         cpuid
190         mov     esi, DATA
191         mov     [esi],   eax
192         mov     [esi+4], ebx
193         mov     [esi+8], ecx
194         mov     [esi+12],edx
195         popad
196         ret
197 LibAmdCpuidRead              ENDP
198
199 ;/*---------------------------------------------------------------------------------------*/
200 ;/**
201 ; *  Read TSC
202 ; *
203 ; *
204 ; *
205 ; */
206
207 public ReadTSC
208 ReadTSC  PROC    NEAR C
209         rdtsc
210         ret
211 ReadTSC  ENDP
212
213
214 ;/*---------------------------------------------------------------------------------------*/
215 ;/**
216 ; *  Set FS_BASE
217 ; *
218 ; *
219 ; *
220 ; * @param[in]  esi - Low Dword of physical address
221 ; * @param[in]  edi - High Dword of physical address
222 ; */
223 SetFsBase  PROC NEAR PUBLIC USES EAX EBX ECX EDX EDI
224
225         mov     eax, ecx
226         mov     ecx, 0C0010015h ; HWCR
227         rdmsr
228         mov     ebx, eax
229         bts     eax, 17         ; HWCR.Wrap32Dis
230         wrmsr
231         xchg    edx, edi
232         mov     eax, esi
233         mov     esi, ebx
234
235         mov     ecx, 0C0000100h ; FS_BASE
236         wrmsr
237         ret
238
239 SetFsBase  ENDP
240
241
242 ;/*---------------------------------------------------------------------------------------*/
243 ;/**
244 ; *  Restore MSR0C001_0015
245 ; *
246 ; * @param[in]  esi - Low Dword
247 ; * @param[in]  edi - High Dword
248 ; */
249 RestoreHwcr PROC NEAR PUBLIC USES EAX ECX EDX
250
251         mov     ecx, 0C0010015h
252         mov     eax, esi
253         mov     edx, edi
254         wrmsr
255         ret
256
257 RestoreHwcr ENDP
258
259
260 ;/*---------------------------------------------------------------------------------------*/
261 ;/**
262 ; *  Read memory/MMIO byte
263 ; *
264 ; * @param[in]  Address - Memory Address
265 ; * @retval     Memory byte at given address
266 ; */
267 Read64Mem8  PROC NEAR C PUBLIC USES EBX EDI ESI Address:QWORD
268
269         mov     esi, DWORD PTR Address[0]
270         mov     edi, DWORD PTR Address[4]
271         test    edi, edi
272         jz      AccesBelow4G
273
274         push    fs
275         call    SetFsBase
276         xor     ebx, ebx
277         mov     al, fs:[ebx]
278         call    RestoreHwcr
279         pop     fs
280         jmp     Done
281 AccesBelow4G:
282         mov     al, ds:[esi]
283 Done:
284         ret
285
286 Read64Mem8  ENDP
287
288
289 ;/*---------------------------------------------------------------------------------------*/
290 ;/**
291 ; *  Read memory/MMIO word
292 ; *
293 ; * @param[in]  Address - Memory Address
294 ; * @retval     Memory word at given address
295 ; */
296 Read64Mem16  PROC NEAR C PUBLIC USES EBX EDI ESI Address:QWORD
297
298         mov     esi, DWORD PTR Address[0]
299         mov     edi, DWORD PTR Address[4]
300         test    edi, edi
301         jz      AccesBelow4G
302
303         push    fs
304         call    SetFsBase
305         xor     ebx, ebx
306         mov     ax, fs:[ebx]
307         call    RestoreHwcr
308         pop     fs
309         jmp     Done
310 AccesBelow4G:
311         mov     ax, ds:[esi]
312 Done:
313
314         ret
315
316 Read64Mem16  ENDP
317
318 ;/*---------------------------------------------------------------------------------------*/
319 ;/**
320 ; *  Read memory/MMIO dword
321 ; *
322 ; * @param[in]  Address - Memory Address
323 ; * @retval     Memory dword at given address
324 ; */
325 Read64Mem32  PROC NEAR C PUBLIC USES EBX EDI ESI Address:QWORD
326
327         mov     esi, DWORD PTR Address[0]
328         mov     edi, DWORD PTR Address[4]
329         test    edi, edi
330         jz      AccesBelow4G
331
332         push    fs
333         call    SetFsBase
334         xor     ebx, ebx
335         mov     eax, fs:[ebx]
336         call    RestoreHwcr
337         pop     fs
338         jmp     Done
339 AccesBelow4G:
340         mov     eax, ds:[esi]
341 Done:
342         ret
343
344 Read64Mem32  ENDP
345
346
347 ;/*---------------------------------------------------------------------------------------*/
348 ;/**
349 ; *  Write memory/MMIO byte
350 ; *
351 ; * @param[in]  Address - Memory Address
352 ; * @param[in]  Value   - Value to write
353 ; */
354
355 Write64Mem8  PROC NEAR C PUBLIC USES EBX EDI ESI Address:QWORD, Data:BYTE
356
357         mov     esi, DWORD PTR Address[0]
358         mov     edi, DWORD PTR Address[4]
359         test    edi, edi
360         jz      AccesBelow4G
361
362         push    fs
363         call    SetFsBase
364         xor     ebx, ebx
365         mov     al, Data
366         mov     fs:[ebx], al
367         call    RestoreHwcr
368         pop     fs
369         jmp     Done
370 AccesBelow4G:
371         mov     al, Data
372         mov     ds:[esi], al
373 Done:
374
375         ret
376
377 Write64Mem8  ENDP
378
379 ;/*---------------------------------------------------------------------------------------*/
380 ;/**
381 ; *  Write memory/MMIO word
382 ; *
383 ; * @param[in]  Address - Memory Address
384 ; * @param[in]  Value   - Value to write
385 ; */
386 Write64Mem16  PROC NEAR C PUBLIC USES EBX EDI ESI Address:QWORD, Data:WORD
387
388         mov     esi, DWORD PTR Address[0]
389         mov     edi, DWORD PTR Address[4]
390         test    edi, edi
391         jz      AccesBelow4G
392
393         push    fs
394         call    SetFsBase
395         xor     ebx, ebx
396         mov     ax, Data
397         mov     fs:[ebx], ax
398         call    RestoreHwcr
399         pop     fs
400         jmp     Done
401 AccesBelow4G:
402         mov     ax, Data
403         mov     ds:[esi], ax
404 Done:
405         ret
406
407 Write64Mem16  ENDP
408
409 ;/*---------------------------------------------------------------------------------------*/
410 ;/**
411 ; *  Write memory/MMIO dword
412 ; *
413 ; * @param[in]  Address - Memory Address
414 ; * @param[in]  Value   - Value to write
415 ; */
416 Write64Mem32  PROC NEAR C PUBLIC USES EBX EDI ESI Address:QWORD, Data:DWORD
417
418         mov     esi, DWORD PTR Address[0]
419         mov     edi, DWORD PTR Address[4]
420         test    edi, edi
421         jz      AccesBelow4G
422
423         push    fs
424         call    SetFsBase
425         xor     ebx, ebx
426         mov     eax, Data
427         mov     fs:[ebx], eax
428         call    RestoreHwcr
429         pop     fs
430         jmp     Done
431 AccesBelow4G:
432         mov     eax, Data
433         mov     ds:[esi], eax
434
435 Done:
436
437         ret
438
439 Write64Mem32  ENDP
440
441 ;/*---------------------------------------------------------------------------------------*/
442 ;/**
443 ; *  Read various CPU registers
444 ; *
445 ; * @param[in]  Reg     Register ID (0/4 - CR0/CR4, 10h/11h/12h/13h/17h - DR0/DR1/DR2/DR3/DR7)
446 ; * @param[in]  Value   Value to write
447 ; */
448
449 LibAmdReadCpuReg PROC NEAR C Reg:BYTE, Value:NEAR PTR DWORD
450     pushad
451     push ds
452
453     .if(Reg == 00h)
454         mov eax, cr0
455     .elseif(Reg == 04h)
456         mov eax, cr4
457     .elseif(Reg == 10h)
458         mov eax, dr0
459     .elseif(Reg == 11h)
460         mov eax, dr1
461     .elseif(Reg == 12h)
462         mov eax, dr2
463     .elseif(Reg == 13h)
464         mov eax, dr3
465     .elseif(Reg == 17h)
466         mov eax, dr7
467     .else
468         xor eax,eax
469     .endif
470
471     mov edi, Value
472     mov [edi], eax
473
474     pop ds
475     popad
476     ret
477 LibAmdReadCpuReg ENDP
478
479
480
481 ;/*---------------------------------------------------------------------------------------*/
482 ;/**
483 ; *  Write various CPU registers
484 ; *
485 ; * @param[in]  Reg     Register ID (0/4 - CR0/CR4, 10h/11h/12h/13h/17h - DR0/DR1/DR2/DR3/DR7)
486 ; * @param[in]  Value   Value to write
487 ; */
488
489 LibAmdWriteCpuReg PROC NEAR C Reg:BYTE, Value:DWORD
490     mov eax, Value
491
492     .if(Reg == 00h)
493         mov cr0, eax
494     .elseif(Reg == 4)
495         mov cr4, eax
496     .elseif(Reg == 10h)
497         mov dr0, eax
498     .elseif(Reg == 11h)
499         mov dr1, eax
500     .elseif(Reg == 12h)
501         mov dr2, eax
502     .elseif(Reg == 13h)
503         mov dr3, eax
504     .elseif(Reg == 17h)
505         mov dr7, eax
506     .endif
507     ret
508 LibAmdWriteCpuReg ENDP
509
510 ;/*---------------------------------------------------------------------------------------*/
511 ;/**
512 ; *  Write back invalidate caches using wbinvd.
513 ; *
514 ; *
515 ; *
516 ; */
517
518 PUBLIC LibAmdWriteBackInvalidateCache
519 LibAmdWriteBackInvalidateCache PROC NEAR C
520     wbinvd
521     ret
522 LibAmdWriteBackInvalidateCache ENDP
523
524 ;/*---------------------------------------------------------------------------------------*/
525 ;/**
526 ; *  Stop CPU
527 ; *
528 ; *
529 ; *
530 ; */
531
532 PUBLIC StopHere
533 StopHere PROC NEAR C
534 @@:
535     jmp short @b
536 StopHere ENDP
537
538 ;/*---------------------------------------------------------------------------------------*/
539 ;/**
540 ; *  Enter debugger on SimNow
541 ; *
542 ; *
543 ; *
544 ; */
545 PUBLIC LibAmdSimNowEnterDebugger
546 LibAmdSimNowEnterDebugger PROC NEAR C
547     pushad
548     mov     eax, 0BACCD00Bh         ; Backdoor in SimNow
549     mov     ebx, 2                  ; Select breakpoint feature
550     cpuid
551 @@:
552     jmp short @b
553     popad
554     ret
555 LibAmdSimNowEnterDebugger ENDP
556
557 ;/*---------------------------------------------------------------------------------------*/
558 ;/**
559 ; *  IDS IO port write
560 ; *
561 ; * @param[in]  Address     IO Port Address
562 ; * @param[in]  Value       Value to write
563 ; * @param[in]  Flag        IDS flags
564 ; *
565 ; */
566
567 PUBLIC IdsOutPort
568 IdsOutPort PROC NEAR C Address:DWORD, Value:DWORD ,Flag:DWORD
569     push edx
570     push eax
571     push ebx
572     mov edx, Address
573     mov eax, Value
574     mov ebx, Flag
575     out dx, eax
576     pop ebx
577     pop eax
578     pop edx
579     ret
580 IdsOutPort  ENDP
581
582 ;/*---------------------------------------------------------------------------------------*/
583 ;/**
584 ; *  Force breakpoint on HDT
585 ; *
586 ; *
587 ; */
588 PUBLIC LibAmdHDTBreakPoint
589 LibAmdHDTBreakPoint PROC NEAR C
590
591     pushad
592
593     mov ecx, 0C001100Ah             ;bit 0 = HDT redirect
594     mov edi, 09C5A203Ah             ;Password
595     RDMSR                           ;
596     or al, 1                        ;
597     WRMSR                           ;
598     mov al, 0B2h                    ;Marker = B2
599     db 0F1h                         ;ICEBP
600
601     popad
602     ret
603
604 LibAmdHDTBreakPoint ENDP
605
606 ;/*---------------------------------------------------------------------------------------*/
607 ;/**
608 ; *  Find the most right hand side non-zero bit with .
609 ; *
610 ; * @param[in]  Value       Value
611 ; */
612 PUBLIC LibAmdBitScanForward
613 LibAmdBitScanForward PROC NEAR C Value:DWORD
614     mov eax, Value
615     bsf eax, Value
616     .if (Zero?)
617       mov al,32
618     .endif
619     ret
620 LibAmdBitScanForward  ENDP
621
622 ;/*---------------------------------------------------------------------------------------*/
623 ;/**
624 ; *  Find the most left hand side non-zero bit.
625 ; *
626 ; * @param[in]  Value       Value
627 ; */
628 PUBLIC LibAmdBitScanReverse
629 LibAmdBitScanReverse PROC NEAR C Value:DWORD
630     mov eax, Value
631     bsr eax, Value
632     .if (Zero?)
633       mov al,0FFh
634     .endif
635     ret
636 LibAmdBitScanReverse  ENDP
637
638 ;/*---------------------------------------------------------------------------------------*/
639 ;/**
640 ; *  Flush specified number of cache line
641 ; *
642 ; *  @param[in]  Address      Physical address to be flushed
643 ; *  @param[in]  Count        number of cachelines to be flushed
644 ; */
645 PUBLIC LibAmdCLFlush
646 LibAmdCLFlush  PROC NEAR C Address:QWORD, Count:BYTE
647     pushad
648     mov ecx, 0C0010015h ; HWCR
649     rdmsr
650     mov esi, eax
651     mov edi, edx
652     bts eax, 17         ; HWCR.Wrap32Dis
653     wrmsr
654     xor eax, eax
655     mov edx, DWORD PTR Address[4]
656     mov ecx, 0C0000100h ; FS_BASE
657     wrmsr
658     mov eax, DWORD PTR Address[0]
659     movzx ecx, Count
660     @@:
661     mfence
662     clflush fs:[eax]
663     mfence
664     add eax,64
665     loop @B
666     call RestoreHwcr
667     popad
668     ret
669 LibAmdCLFlush  ENDP
670
671 END