| ;/** |
| ; * @file |
| ; * |
| ; * Agesa library 64bit |
| ; * |
| ; * Contains AMD AGESA Library |
| ; * |
| ; * @xrefitem bom "File Content Label" "Release Content" |
| ; * @e project: AGESA |
| ; * @e sub-project: Lib |
| ; * @e \$Revision: 17071 $ @e \$Date: 2009-07-30 10:13:11 -0700 (Thu, 30 Jul 2009) $ |
| ; */ |
| ;***************************************************************************** |
| ; |
| ; Copyright (c) 2011, Advanced Micro Devices, Inc. |
| ; All rights reserved. |
| ; |
| ; Redistribution and use in source and binary forms, with or without |
| ; modification, are permitted provided that the following conditions are met: |
| ; * Redistributions of source code must retain the above copyright |
| ; notice, this list of conditions and the following disclaimer. |
| ; * Redistributions in binary form must reproduce the above copyright |
| ; notice, this list of conditions and the following disclaimer in the |
| ; documentation and/or other materials provided with the distribution. |
| ; * Neither the name of Advanced Micro Devices, Inc. nor the names of |
| ; its contributors may be used to endorse or promote products derived |
| ; from this software without specific prior written permission. |
| ; |
| ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| ; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| ; DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY |
| ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| ; |
| ;***************************************************************************** |
| |
| .code |
| ;/*++ |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write IO byte |
| ; * |
| ; * @param[in] CX IO port address |
| ; * @param[in] DL IO port Value |
| ; */ |
| |
| PUBLIC WriteIo8 |
| WriteIo8 PROC |
| mov al, dl |
| mov dx, cx |
| out dx, al |
| ret |
| WriteIo8 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write IO word |
| ; * |
| ; * @param[in] CX IO port address |
| ; * @param[in] DX IO port Value |
| ; */ |
| PUBLIC WriteIo16 |
| WriteIo16 PROC |
| mov ax, dx |
| mov dx, cx |
| out dx, ax |
| ret |
| WriteIo16 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write IO dword |
| ; * |
| ; * @param[in] CX IO port address |
| ; * @param[in] EDX IO port Value |
| ; */ |
| |
| PUBLIC WriteIo32 |
| WriteIo32 PROC |
| mov eax, edx |
| mov dx, cx |
| out dx, eax |
| ret |
| WriteIo32 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read IO byte |
| ; * |
| ; * @param[in] CX IO port address |
| ; * @retval AL IO port Value |
| ; */ |
| PUBLIC ReadIo8 |
| ReadIo8 PROC |
| mov dx, cx |
| in al, dx |
| ret |
| ReadIo8 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read IO word |
| ; * |
| ; * @param[in] CX IO port address |
| ; * @retval AX IO port Value |
| ; */ |
| PUBLIC ReadIo16 |
| ReadIo16 PROC |
| mov dx, cx |
| in ax, dx |
| ret |
| ReadIo16 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read IO dword |
| ; * |
| ; * @param[in] CX IO port address |
| ; * @retval EAX IO port Value |
| ; */ |
| PUBLIC ReadIo32 |
| ReadIo32 PROC |
| mov dx, cx |
| in eax, dx |
| ret |
| ReadIo32 ENDP |
| |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read MSR |
| ; * |
| ; * @param[in] RCX MSR Address |
| ; * @param[in] RDX Pointer to data |
| ; * @param[in] R8D ConfigPtr (Optional) |
| ; */ |
| PUBLIC LibAmdMsrRead |
| LibAmdMsrRead PROC |
| push rsi |
| mov rsi, rdx |
| rdmsr |
| mov [rsi], eax |
| mov [rsi+4], edx |
| pop rsi |
| ret |
| LibAmdMsrRead ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write MSR |
| ; * |
| ; * @param[in] RCX MSR Address |
| ; * @param[in] RDX Pointer to data |
| ; * @param[in] R8D ConfigPtr (Optional) |
| ; */ |
| PUBLIC LibAmdMsrWrite |
| LibAmdMsrWrite PROC |
| push rsi |
| mov rsi, rdx |
| mov eax, [rsi] |
| and rax, 0ffffffffh |
| mov edx, [rsi+4] |
| and rdx, 0ffffffffh |
| wrmsr |
| pop rsi |
| ret |
| LibAmdMsrWrite ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read CPUID |
| ; * |
| ; * @param[in] RCX CPUID function |
| ; * @param[in] RDX Pointer to CPUID_DATA to save cpuid data |
| ; * @param[in] R8D ConfigPtr (Optional) |
| ; */ |
| PUBLIC LibAmdCpuidRead |
| LibAmdCpuidRead PROC |
| |
| push rbx |
| push rsi |
| mov rsi, rdx |
| mov rax, rcx |
| cpuid |
| mov [rsi], eax |
| mov [rsi+4], ebx |
| mov [rsi+8], ecx |
| mov [rsi+12],edx |
| pop rsi |
| pop rbx |
| ret |
| |
| LibAmdCpuidRead ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read TSC |
| ; * |
| ; * |
| ; * @retval RAX Time stamp counter value |
| ; */ |
| |
| PUBLIC ReadTSC |
| ReadTSC PROC |
| rdtsc |
| and rax, 0ffffffffh |
| shl rdx, 32 |
| or rax, rdx |
| ret |
| ReadTSC ENDP |
| |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read memory/MMIO byte |
| ; * |
| ; * @param[in] RCX - Memory Address |
| ; * @retval Memory byte at given address |
| ; */ |
| PUBLIC Read64Mem8 |
| Read64Mem8 PROC |
| |
| xor rax, rax |
| mov al, [rcx] |
| ret |
| |
| Read64Mem8 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read memory/MMIO word |
| ; * |
| ; * @param[in] RCX - Memory Address |
| ; * @retval Memory word at given address |
| ; */ |
| PUBLIC Read64Mem16 |
| Read64Mem16 PROC |
| |
| xor rax, rax |
| mov ax, [rcx] |
| ret |
| |
| Read64Mem16 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read memory/MMIO dword |
| ; * |
| ; * @param[in] RCX - Memory Address |
| ; * @retval Memory dword at given address |
| ; */ |
| PUBLIC Read64Mem32 |
| Read64Mem32 PROC |
| |
| xor rax, rax |
| mov eax, [rcx] |
| ret |
| |
| Read64Mem32 ENDP |
| |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write memory/MMIO byte |
| ; * |
| ; * @param[in] RCX Memory Address |
| ; * @param[in] DL Value to write |
| ; */ |
| |
| PUBLIC Write64Mem8 |
| Write64Mem8 PROC |
| |
| xor rax, rax |
| mov rax, rdx |
| mov [rcx], al |
| ret |
| |
| Write64Mem8 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write memory/MMIO word |
| ; * |
| ; * @param[in] RCX Memory Address |
| ; * @param[in] DX Value to write |
| ; */ |
| PUBLIC Write64Mem16 |
| Write64Mem16 PROC |
| |
| xor rax, rax |
| mov rax, rdx |
| mov [rcx], ax |
| ret |
| |
| Write64Mem16 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write memory/MMIO dword |
| ; * |
| ; * @param[in] RCX Memory Address |
| ; * @param[in] EDX Value to write |
| ; */ |
| PUBLIC Write64Mem32 |
| Write64Mem32 PROC |
| |
| xor rax, rax |
| mov rax, rdx |
| mov [rcx], eax |
| ret |
| |
| Write64Mem32 ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Read various CPU registers |
| ; * |
| ; * @param[in] CL Register ID (0/4 - CR0/CR4, 10h/11h/12h/13h/17h - DR0/DR1/DR2/DR3/DR7) |
| ; * @param[in] RDX Pointer to value |
| ; */ |
| |
| PUBLIC LibAmdReadCpuReg |
| LibAmdReadCpuReg PROC |
| |
| push rax |
| xor rax, rax |
| Reg00h: |
| cmp cl, 00h |
| jne Reg04h |
| mov rax, cr0 |
| jmp RegRead |
| Reg04h: |
| cmp cl, 04h |
| jne Reg10h |
| mov rax, cr4 |
| jmp RegRead |
| Reg10h: |
| cmp cl, 10h |
| jne Reg11h |
| mov rax, dr0 |
| jmp RegRead |
| Reg11h: |
| cmp cl, 11h |
| jne Reg12h |
| mov rax, dr1 |
| jmp RegRead |
| Reg12h: |
| cmp cl, 12h |
| jne Reg13h |
| mov rax, dr2 |
| jmp RegRead |
| Reg13h: |
| cmp cl, 13h |
| jne Reg17h |
| mov rax, dr3 |
| jmp RegRead |
| Reg17h: |
| cmp cl, 17h |
| jne RegRead |
| mov rax, dr7 |
| RegRead: |
| mov [rdx], eax |
| pop rax |
| ret |
| LibAmdReadCpuReg ENDP |
| |
| |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write various CPU registers |
| ; * |
| ; * @param[in] CL Register ID (0/4 - CR0/CR4, 10h/11h/12h/13h/17h - DR0/DR1/DR2/DR3/DR7) |
| ; * @param[in] RDX Value to write |
| ; */ |
| |
| PUBLIC LibAmdWriteCpuReg |
| LibAmdWriteCpuReg PROC |
| |
| push rax |
| Reg00h: |
| cmp cl, 00h |
| jne Reg04h |
| mov rax, cr0 |
| mov eax, edx |
| mov cr0, rax |
| jmp Done |
| Reg04h: |
| cmp cl, 04h |
| jne Reg10h |
| mov rax, cr4 |
| mov eax, edx |
| mov cr4, rax |
| jmp Done |
| Reg10h: |
| cmp cl, 10h |
| jne Reg11h |
| mov rax, dr0 |
| mov eax, edx |
| mov dr0, rax |
| jmp Done |
| Reg11h: |
| cmp cl, 11h |
| jne Reg12h |
| mov rax, dr1 |
| mov eax, edx |
| mov dr1, rax |
| jmp Done |
| Reg12h: |
| cmp cl, 12h |
| jne Reg13h |
| mov rax, dr2 |
| mov eax, edx |
| mov dr2, rax |
| jmp Done |
| Reg13h: |
| cmp cl, 13h |
| jne Reg17h |
| mov rax, dr3 |
| mov eax, edx |
| mov dr3, rax |
| jmp Done |
| Reg17h: |
| cmp cl, 17h |
| jne Done |
| mov rax, dr7 |
| mov eax, edx |
| mov dr7, rax |
| Done: |
| pop rax |
| ret |
| LibAmdWriteCpuReg ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Write back invalidate caches using wbinvd. |
| ; * |
| ; * |
| ; * |
| ; */ |
| |
| PUBLIC LibAmdWriteBackInvalidateCache |
| LibAmdWriteBackInvalidateCache PROC |
| wbinvd |
| ret |
| LibAmdWriteBackInvalidateCache ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Stop CPU |
| ; * |
| ; * |
| ; * |
| ; */ |
| |
| PUBLIC StopHere |
| StopHere PROC |
| @@: |
| jmp short @b |
| StopHere ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Enter debugger on SimNow |
| ; * |
| ; * |
| ; * |
| ; */ |
| PUBLIC LibAmdSimNowEnterDebugger |
| LibAmdSimNowEnterDebugger PROC |
| pushfq |
| mov rax, 0BACCD00Bh ; Backdoor in SimNow |
| mov rbx, 2 ; Select breakpoint feature |
| cpuid |
| @@: |
| jmp short @b |
| popfq |
| ret |
| LibAmdSimNowEnterDebugger ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * IDS IO port write |
| ; * |
| ; * @param[in] ECX IO Port Address |
| ; * @param[in] EDX Value to write |
| ; * @param[in] R8D IDS flags |
| ; * |
| ; */ |
| |
| PUBLIC IdsOutPort |
| IdsOutPort PROC |
| push rbx |
| push rax |
| |
| mov ebx, r8d |
| mov eax, edx |
| mov edx, ecx |
| out dx, eax |
| |
| pop rax |
| pop rbx |
| ret |
| IdsOutPort ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Force breakpoint on HDT |
| ; * |
| ; * |
| ; */ |
| PUBLIC LibAmdHDTBreakPoint |
| LibAmdHDTBreakPoint PROC |
| |
| push rbx |
| |
| mov rcx, 0C001100Ah ;bit 0 = HDT redirect |
| mov rdi, 09C5A203Ah ;Password |
| rdmsr |
| and rax, 0ffffffffh |
| or rax, 1 |
| |
| wrmsr |
| |
| mov rax, 0B2h ;Marker = B2 |
| db 0F1h ;ICEBP |
| |
| pop rbx |
| ret |
| |
| LibAmdHDTBreakPoint ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Find the most right hand side non-zero bit with |
| ; * |
| ; * @param[in] ECX Value |
| ; */ |
| PUBLIC LibAmdBitScanForward |
| LibAmdBitScanForward PROC |
| bsf eax, ecx |
| jnz nonZeroSource |
| mov al,32 |
| nonZeroSource: |
| ret |
| LibAmdBitScanForward ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Find the most left hand side non-zero bit. |
| ; * |
| ; * @param[in] ECX Value |
| ; */ |
| PUBLIC LibAmdBitScanReverse |
| LibAmdBitScanReverse PROC |
| bsr eax, ecx |
| jnz nonZeroSource |
| mov al,0FFh |
| nonZeroSource: |
| ret |
| LibAmdBitScanReverse ENDP |
| |
| ;/*---------------------------------------------------------------------------------------*/ |
| ;/** |
| ; * Flush specified number of cache line |
| ; * |
| ; * @param[in] RCX Physical address to be flushed |
| ; * @param[in] DL number of cachelines to be flushed |
| ; */ |
| PUBLIC LibAmdCLFlush |
| LibAmdCLFlush PROC |
| push rax |
| mov rax, rcx |
| movzx rcx, dl |
| @@: |
| mfence |
| clflush [rax] |
| mfence |
| add rax,64 |
| loop @B |
| pop rax |
| ret |
| LibAmdCLFlush ENDP |
| |
| END |