AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Lib / x64 / amdlib64.asm
1 ;/**
2 ; * @file
3 ; *
4 ; * Agesa library 64bit
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 .code
43 ;/*++
44
45 ;/*---------------------------------------------------------------------------------------*/
46 ;/**
47 ; *  Write IO byte
48 ; *
49 ; *  @param[in]   CX    IO port address
50 ; *  @param[in]   DL    IO port Value
51 ; */
52
53 PUBLIC  WriteIo8
54 WriteIo8        PROC
55         mov     al, dl
56         mov     dx, cx
57         out     dx, al
58         ret
59 WriteIo8        ENDP
60
61 ;/*---------------------------------------------------------------------------------------*/
62 ;/**
63 ; *  Write IO word
64 ; *
65 ; *  @param[in]   CX      IO port address
66 ; *  @param[in]   DX      IO port Value
67 ; */
68 PUBLIC  WriteIo16
69 WriteIo16       PROC
70         mov     ax, dx
71         mov     dx, cx
72         out     dx, ax
73         ret
74 WriteIo16       ENDP
75
76 ;/*---------------------------------------------------------------------------------------*/
77 ;/**
78 ; *  Write IO dword
79 ; *
80 ; *  @param[in]   CX      IO port address
81 ; *  @param[in]   EDX     IO port Value
82 ; */
83
84 PUBLIC WriteIo32
85 WriteIo32       PROC
86         mov     eax, edx
87         mov     dx, cx
88         out     dx, eax
89         ret
90 WriteIo32       ENDP
91
92 ;/*---------------------------------------------------------------------------------------*/
93 ;/**
94 ; *  Read IO byte
95 ; *
96 ; *  @param[in] CX  IO port address
97 ; *  @retval    AL  IO port Value
98 ; */
99 PUBLIC ReadIo8
100 ReadIo8 PROC
101         mov     dx, cx
102         in      al, dx
103         ret
104 ReadIo8 ENDP
105
106 ;/*---------------------------------------------------------------------------------------*/
107 ;/**
108 ; *  Read IO word
109 ; *
110 ; *  @param[in]   CX  IO port address
111 ; *  @retval      AX  IO port Value
112 ; */
113 PUBLIC ReadIo16
114 ReadIo16        PROC
115         mov     dx, cx
116         in      ax, dx
117         ret
118 ReadIo16        ENDP
119
120 ;/*---------------------------------------------------------------------------------------*/
121 ;/**
122 ; *  Read IO dword
123 ; *
124 ; *  @param[in]   CX  IO port address
125 ; *  @retval      EAX IO port Value
126 ; */
127 PUBLIC ReadIo32
128 ReadIo32        PROC
129         mov     dx, cx
130         in      eax, dx
131         ret
132 ReadIo32        ENDP
133
134
135 ;/*---------------------------------------------------------------------------------------*/
136 ;/**
137 ; *  Read MSR
138 ; *
139 ; *  @param[in]  RCX      MSR Address
140 ; *  @param[in]  RDX      Pointer to data
141 ; *  @param[in]  R8D      ConfigPtr (Optional)
142 ; */
143 PUBLIC LibAmdMsrRead
144 LibAmdMsrRead  PROC
145     push rsi
146     mov     rsi, rdx
147     rdmsr
148     mov     [rsi], eax
149     mov     [rsi+4], edx
150     pop rsi
151     ret
152 LibAmdMsrRead  ENDP
153
154 ;/*---------------------------------------------------------------------------------------*/
155 ;/**
156 ; *  Write MSR
157 ; *
158 ; *  @param[in]  RCX        MSR Address
159 ; *  @param[in]  RDX        Pointer to data
160 ; *  @param[in]  R8D        ConfigPtr  (Optional)
161 ; */
162 PUBLIC LibAmdMsrWrite
163 LibAmdMsrWrite                PROC
164     push rsi
165     mov rsi, rdx
166     mov eax, [rsi]
167     and rax, 0ffffffffh
168     mov edx, [rsi+4]
169     and rdx, 0ffffffffh
170     wrmsr
171     pop rsi
172     ret
173 LibAmdMsrWrite                ENDP
174
175 ;/*---------------------------------------------------------------------------------------*/
176 ;/**
177 ; *  Read CPUID
178 ; *
179 ; *  @param[in]  RCX    CPUID function
180 ; *  @param[in]  RDX    Pointer to CPUID_DATA to save cpuid data
181 ; *  @param[in]  R8D    ConfigPtr (Optional)
182 ; */
183 PUBLIC LibAmdCpuidRead
184 LibAmdCpuidRead       PROC
185
186     push rbx
187     push rsi
188     mov  rsi, rdx
189     mov  rax, rcx
190     cpuid
191     mov [rsi],   eax
192     mov [rsi+4], ebx
193     mov [rsi+8], ecx
194     mov [rsi+12],edx
195     pop rsi
196     pop rbx
197     ret
198
199 LibAmdCpuidRead              ENDP
200
201 ;/*---------------------------------------------------------------------------------------*/
202 ;/**
203 ; *  Read TSC
204 ; *
205 ; *
206 ; * @retval     RAX Time stamp counter value
207 ; */
208
209 PUBLIC ReadTSC
210 ReadTSC  PROC
211     rdtsc
212     and  rax, 0ffffffffh
213     shl  rdx, 32
214     or   rax, rdx
215     ret
216 ReadTSC  ENDP
217
218
219 ;/*---------------------------------------------------------------------------------------*/
220 ;/**
221 ; *  Read memory/MMIO byte
222 ; *
223 ; * @param[in]  RCX - Memory Address
224 ; * @retval     Memory byte at given address
225 ; */
226 PUBLIC  Read64Mem8
227 Read64Mem8  PROC
228
229      xor  rax, rax
230      mov  al, [rcx]
231      ret
232
233 Read64Mem8  ENDP
234
235 ;/*---------------------------------------------------------------------------------------*/
236 ;/**
237 ; *  Read memory/MMIO word
238 ; *
239 ; * @param[in]  RCX - Memory Address
240 ; * @retval     Memory word at given address
241 ; */
242 PUBLIC  Read64Mem16
243 Read64Mem16  PROC
244
245         xor     rax, rax
246         mov     ax, [rcx]
247         ret
248
249 Read64Mem16  ENDP
250
251 ;/*---------------------------------------------------------------------------------------*/
252 ;/**
253 ; *  Read memory/MMIO dword
254 ; *
255 ; * @param[in]  RCX - Memory Address
256 ; * @retval     Memory dword at given address
257 ; */
258 PUBLIC  Read64Mem32
259 Read64Mem32  PROC
260
261         xor     rax, rax
262         mov     eax, [rcx]
263         ret
264
265 Read64Mem32  ENDP
266
267
268 ;/*---------------------------------------------------------------------------------------*/
269 ;/**
270 ; *  Write memory/MMIO byte
271 ; *
272 ; * @param[in]  RCX   Memory Address
273 ; * @param[in]  DL    Value to write
274 ; */
275
276 PUBLIC  Write64Mem8
277 Write64Mem8  PROC
278
279         xor     rax, rax
280         mov     rax, rdx
281         mov     [rcx], al
282         ret
283
284 Write64Mem8  ENDP
285
286 ;/*---------------------------------------------------------------------------------------*/
287 ;/**
288 ; *  Write memory/MMIO word
289 ; *
290 ; * @param[in]  RCX   Memory Address
291 ; * @param[in]  DX    Value to write
292 ; */
293 PUBLIC  Write64Mem16
294 Write64Mem16  PROC
295
296         xor     rax, rax
297         mov     rax, rdx
298         mov     [rcx], ax
299         ret
300
301 Write64Mem16  ENDP
302
303 ;/*---------------------------------------------------------------------------------------*/
304 ;/**
305 ; *  Write memory/MMIO dword
306 ; *
307 ; * @param[in]  RCX   Memory Address
308 ; * @param[in]  EDX   Value to write
309 ; */
310 PUBLIC  Write64Mem32
311 Write64Mem32  PROC
312
313         xor     rax, rax
314         mov     rax, rdx
315         mov     [rcx], eax
316         ret
317
318 Write64Mem32  ENDP
319
320 ;/*---------------------------------------------------------------------------------------*/
321 ;/**
322 ; *  Read various CPU registers
323 ; *
324 ; * @param[in]  CL     Register ID (0/4 - CR0/CR4, 10h/11h/12h/13h/17h - DR0/DR1/DR2/DR3/DR7)
325 ; * @param[in]  RDX    Pointer to value
326 ; */
327
328 PUBLIC  LibAmdReadCpuReg
329 LibAmdReadCpuReg PROC
330
331         push    rax
332         xor     rax, rax
333 Reg00h:
334         cmp     cl, 00h
335         jne     Reg04h
336         mov     rax, cr0
337         jmp     RegRead
338 Reg04h:
339         cmp     cl, 04h
340         jne     Reg10h
341         mov     rax, cr4
342         jmp     RegRead
343 Reg10h:
344         cmp     cl, 10h
345         jne     Reg11h
346         mov     rax, dr0
347         jmp     RegRead
348 Reg11h:
349         cmp     cl, 11h
350         jne     Reg12h
351         mov     rax, dr1
352         jmp     RegRead
353 Reg12h:
354         cmp     cl, 12h
355         jne     Reg13h
356         mov     rax, dr2
357         jmp     RegRead
358 Reg13h:
359         cmp     cl, 13h
360         jne     Reg17h
361         mov     rax, dr3
362         jmp     RegRead
363 Reg17h:
364         cmp     cl, 17h
365         jne     RegRead
366         mov     rax, dr7
367 RegRead:
368         mov     [rdx], eax
369         pop     rax
370         ret
371 LibAmdReadCpuReg ENDP
372
373
374
375 ;/*---------------------------------------------------------------------------------------*/
376 ;/**
377 ; *  Write various CPU registers
378 ; *
379 ; * @param[in]  CL    Register ID (0/4 - CR0/CR4, 10h/11h/12h/13h/17h - DR0/DR1/DR2/DR3/DR7)
380 ; * @param[in]  RDX   Value to write
381 ; */
382
383 PUBLIC  LibAmdWriteCpuReg
384 LibAmdWriteCpuReg PROC
385
386         push    rax
387 Reg00h:
388         cmp     cl, 00h
389         jne     Reg04h
390         mov     rax, cr0
391         mov     eax, edx
392         mov     cr0, rax
393         jmp     Done
394 Reg04h:
395         cmp     cl, 04h
396         jne     Reg10h
397         mov     rax, cr4
398         mov     eax, edx
399         mov     cr4, rax
400         jmp     Done
401 Reg10h:
402         cmp     cl, 10h
403         jne     Reg11h
404         mov     rax, dr0
405         mov     eax, edx
406         mov     dr0, rax
407         jmp     Done
408 Reg11h:
409         cmp     cl, 11h
410         jne     Reg12h
411         mov     rax, dr1
412         mov     eax, edx
413         mov     dr1, rax
414         jmp     Done
415 Reg12h:
416         cmp     cl, 12h
417         jne     Reg13h
418         mov     rax, dr2
419         mov     eax, edx
420         mov     dr2, rax
421         jmp     Done
422 Reg13h:
423         cmp     cl, 13h
424         jne     Reg17h
425         mov     rax, dr3
426         mov     eax, edx
427         mov     dr3, rax
428         jmp     Done
429 Reg17h:
430         cmp     cl, 17h
431         jne     Done
432         mov     rax, dr7
433         mov     eax, edx
434         mov     dr7, rax
435 Done:
436         pop     rax
437         ret
438 LibAmdWriteCpuReg ENDP
439
440 ;/*---------------------------------------------------------------------------------------*/
441 ;/**
442 ; *  Write back invalidate caches using wbinvd.
443 ; *
444 ; *
445 ; *
446 ; */
447
448 PUBLIC LibAmdWriteBackInvalidateCache
449 LibAmdWriteBackInvalidateCache PROC
450     wbinvd
451     ret
452 LibAmdWriteBackInvalidateCache ENDP
453
454 ;/*---------------------------------------------------------------------------------------*/
455 ;/**
456 ; *  Stop CPU
457 ; *
458 ; *
459 ; *
460 ; */
461
462 PUBLIC StopHere
463 StopHere PROC
464 @@:
465     jmp short @b
466 StopHere ENDP
467
468 ;/*---------------------------------------------------------------------------------------*/
469 ;/**
470 ; *  Enter debugger on SimNow
471 ; *
472 ; *
473 ; *
474 ; */
475 PUBLIC LibAmdSimNowEnterDebugger
476 LibAmdSimNowEnterDebugger PROC
477     pushfq
478     mov     rax, 0BACCD00Bh         ; Backdoor in SimNow
479     mov     rbx, 2                  ; Select breakpoint feature
480     cpuid
481 @@:
482     jmp short @b
483     popfq
484     ret
485 LibAmdSimNowEnterDebugger ENDP
486
487 ;/*---------------------------------------------------------------------------------------*/
488 ;/**
489 ; *  IDS IO port write
490 ; *
491 ; * @param[in]  ECX     IO Port Address
492 ; * @param[in]  EDX     Value to write
493 ; * @param[in]  R8D     IDS flags
494 ; *
495 ; */
496
497 PUBLIC IdsOutPort
498 IdsOutPort PROC
499     push rbx
500     push rax
501
502     mov ebx, r8d
503     mov eax, edx
504     mov edx, ecx
505     out dx, eax
506
507     pop rax
508     pop rbx
509     ret
510 IdsOutPort  ENDP
511
512 ;/*---------------------------------------------------------------------------------------*/
513 ;/**
514 ; *  Force breakpoint on HDT
515 ; *
516 ; *
517 ; */
518 PUBLIC LibAmdHDTBreakPoint
519 LibAmdHDTBreakPoint PROC
520
521     push rbx
522
523     mov rcx, 0C001100Ah             ;bit 0 = HDT redirect
524     mov rdi, 09C5A203Ah             ;Password
525     rdmsr
526     and rax, 0ffffffffh
527     or rax, 1
528
529     wrmsr
530
531     mov rax, 0B2h                  ;Marker = B2
532     db 0F1h                        ;ICEBP
533
534     pop rbx
535     ret
536
537 LibAmdHDTBreakPoint ENDP
538
539 ;/*---------------------------------------------------------------------------------------*/
540 ;/**
541 ; *  Find the most right hand side non-zero bit with
542 ; *
543 ; * @param[in]  ECX       Value
544 ; */
545 PUBLIC LibAmdBitScanForward
546 LibAmdBitScanForward PROC
547     bsf eax, ecx
548     jnz nonZeroSource
549     mov al,32
550 nonZeroSource:
551     ret
552 LibAmdBitScanForward  ENDP
553
554 ;/*---------------------------------------------------------------------------------------*/
555 ;/**
556 ; *  Find the most left hand side non-zero bit.
557 ; *
558 ; * @param[in]  ECX       Value
559 ; */
560 PUBLIC LibAmdBitScanReverse
561 LibAmdBitScanReverse PROC
562     bsr eax, ecx
563     jnz nonZeroSource
564     mov al,0FFh
565 nonZeroSource:
566     ret
567 LibAmdBitScanReverse  ENDP
568
569 ;/*---------------------------------------------------------------------------------------*/
570 ;/**
571 ; *  Flush specified number of cache line
572 ; *
573 ; *  @param[in]  RCX      Physical address to be flushed
574 ; *  @param[in]  DL       number of cachelines to be flushed
575 ; */
576 PUBLIC LibAmdCLFlush
577 LibAmdCLFlush  PROC
578     push rax
579     mov rax, rcx
580     movzx rcx, dl
581     @@:
582     mfence
583     clflush [rax]
584     mfence
585     add rax,64
586     loop @B
587     pop rax
588     ret
589 LibAmdCLFlush  ENDP
590
591 END