;------------------------------------------------------------------------------ | |
; | |
; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> | |
; Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR> | |
; | |
; SPDX-License-Identifier: BSD-2-Clause-Patent | |
; | |
;------------------------------------------------------------------------------ | |
DEFAULT REL | |
SECTION .text | |
;------------------------------------------------------------------------------ | |
; Check whether we need to unroll the String I/O in SEV guest | |
; | |
; Return // eax (1 - unroll, 0 - no unroll) | |
;------------------------------------------------------------------------------ | |
global ASM_PFX(SevNoRepIo) | |
ASM_PFX(SevNoRepIo): | |
; CPUID clobbers ebx, ecx and edx | |
push rbx | |
push rcx | |
push rdx | |
; Check if we are runing under hypervisor | |
; CPUID(1).ECX Bit 31 | |
mov eax, 1 | |
cpuid | |
bt ecx, 31 | |
jnc @UseRepIo | |
; Check if we have Memory encryption CPUID leaf | |
mov eax, 0x80000000 | |
cpuid | |
cmp eax, 0x8000001f | |
jl @UseRepIo | |
; Check for memory encryption feature: | |
; CPUID Fn8000_001F[EAX] - Bit 1 | |
; | |
mov eax, 0x8000001f | |
cpuid | |
bt eax, 1 | |
jnc @UseRepIo | |
; Check if memory encryption is enabled | |
; MSR_0xC0010131 - Bit 0 (SEV enabled) | |
; MSR_0xC0010131 - Bit 1 (SEV-ES enabled) | |
mov ecx, 0xc0010131 | |
rdmsr | |
; Check for (SevEsEnabled == 0 && SevEnabled == 1) | |
and eax, 3 | |
cmp eax, 1 | |
je @SevNoRepIo_Done | |
@UseRepIo: | |
xor eax, eax | |
@SevNoRepIo_Done: | |
pop rdx | |
pop rcx | |
pop rbx | |
ret | |
;------------------------------------------------------------------------------ | |
; VOID | |
; EFIAPI | |
; SevIoReadFifo8 ( | |
; IN UINTN Port, // rcx | |
; IN UINTN Size, // rdx | |
; OUT VOID *Buffer // r8 | |
; ); | |
;------------------------------------------------------------------------------ | |
global ASM_PFX(SevIoReadFifo8) | |
ASM_PFX(SevIoReadFifo8): | |
xchg rcx, rdx | |
xchg rdi, r8 ; rdi: buffer address; r8: save rdi | |
; Check if we need to unroll String I/O | |
call ASM_PFX(SevNoRepIo) | |
test eax, eax | |
jnz @IoReadFifo8_NoRep | |
cld | |
rep insb | |
jmp @IoReadFifo8_Done | |
@IoReadFifo8_NoRep: | |
jrcxz @IoReadFifo8_Done | |
@IoReadFifo8_Loop: | |
in al, dx | |
mov byte [rdi], al | |
inc rdi | |
loop @IoReadFifo8_Loop | |
@IoReadFifo8_Done: | |
mov rdi, r8 ; restore rdi | |
ret | |
;------------------------------------------------------------------------------ | |
; VOID | |
; EFIAPI | |
; SevIoReadFifo16 ( | |
; IN UINTN Port, // rcx | |
; IN UINTN Size, // rdx | |
; OUT VOID *Buffer // r8 | |
; ); | |
;------------------------------------------------------------------------------ | |
global ASM_PFX(SevIoReadFifo16) | |
ASM_PFX(SevIoReadFifo16): | |
xchg rcx, rdx | |
xchg rdi, r8 ; rdi: buffer address; r8: save rdi | |
; Check if we need to unroll String I/O | |
call ASM_PFX(SevNoRepIo) | |
test eax, eax | |
jnz @IoReadFifo16_NoRep | |
cld | |
rep insw | |
jmp @IoReadFifo16_Done | |
@IoReadFifo16_NoRep: | |
jrcxz @IoReadFifo16_Done | |
@IoReadFifo16_Loop: | |
in ax, dx | |
mov word [rdi], ax | |
add rdi, 2 | |
loop @IoReadFifo16_Loop | |
@IoReadFifo16_Done: | |
mov rdi, r8 ; restore rdi | |
ret | |
;------------------------------------------------------------------------------ | |
; VOID | |
; EFIAPI | |
; SevIoReadFifo32 ( | |
; IN UINTN Port, // rcx | |
; IN UINTN Size, // rdx | |
; OUT VOID *Buffer // r8 | |
; ); | |
;------------------------------------------------------------------------------ | |
global ASM_PFX(SevIoReadFifo32) | |
ASM_PFX(SevIoReadFifo32): | |
xchg rcx, rdx | |
xchg rdi, r8 ; rdi: buffer address; r8: save rdi | |
; Check if we need to unroll String I/O | |
call ASM_PFX(SevNoRepIo) | |
test eax, eax | |
jnz @IoReadFifo32_NoRep | |
cld | |
rep insd | |
jmp @IoReadFifo32_Done | |
@IoReadFifo32_NoRep: | |
jrcxz @IoReadFifo32_Done | |
@IoReadFifo32_Loop: | |
in eax, dx | |
mov dword [rdi], eax | |
add rdi, 4 | |
loop @IoReadFifo32_Loop | |
@IoReadFifo32_Done: | |
mov rdi, r8 ; restore rdi | |
ret | |
;------------------------------------------------------------------------------ | |
; VOID | |
; EFIAPI | |
; IoWriteFifo8 ( | |
; IN UINTN Port, // rcx | |
; IN UINTN Size, // rdx | |
; IN VOID *Buffer // r8 | |
; ); | |
;------------------------------------------------------------------------------ | |
global ASM_PFX(SevIoWriteFifo8) | |
ASM_PFX(SevIoWriteFifo8): | |
xchg rcx, rdx | |
xchg rsi, r8 ; rsi: buffer address; r8: save rsi | |
; Check if we need to unroll String I/O | |
call ASM_PFX(SevNoRepIo) | |
test eax, eax | |
jnz @IoWriteFifo8_NoRep | |
cld | |
rep outsb | |
jmp @IoWriteFifo8_Done | |
@IoWriteFifo8_NoRep: | |
jrcxz @IoWriteFifo8_Done | |
@IoWriteFifo8_Loop: | |
mov al, byte [rsi] | |
out dx, al | |
inc rsi | |
loop @IoWriteFifo8_Loop | |
@IoWriteFifo8_Done: | |
mov rsi, r8 ; restore rsi | |
ret | |
;------------------------------------------------------------------------------ | |
; VOID | |
; EFIAPI | |
; SevIoWriteFifo16 ( | |
; IN UINTN Port, // rcx | |
; IN UINTN Size, // rdx | |
; IN VOID *Buffer // r8 | |
; ); | |
;------------------------------------------------------------------------------ | |
global ASM_PFX(SevIoWriteFifo16) | |
ASM_PFX(SevIoWriteFifo16): | |
xchg rcx, rdx | |
xchg rsi, r8 ; rsi: buffer address; r8: save rsi | |
; Check if we need to unroll String I/O | |
call ASM_PFX(SevNoRepIo) | |
test eax, eax | |
jnz @IoWriteFifo16_NoRep | |
cld | |
rep outsw | |
jmp @IoWriteFifo16_Done | |
@IoWriteFifo16_NoRep: | |
jrcxz @IoWriteFifo16_Done | |
@IoWriteFifo16_Loop: | |
mov ax, word [rsi] | |
out dx, ax | |
add rsi, 2 | |
loop @IoWriteFifo16_Loop | |
@IoWriteFifo16_Done: | |
mov rsi, r8 ; restore rsi | |
ret | |
;------------------------------------------------------------------------------ | |
; VOID | |
; EFIAPI | |
; SevIoWriteFifo32 ( | |
; IN UINTN Port, // rcx | |
; IN UINTN Size, // rdx | |
; IN VOID *Buffer // r8 | |
; ); | |
;------------------------------------------------------------------------------ | |
global ASM_PFX(SevIoWriteFifo32) | |
ASM_PFX(SevIoWriteFifo32): | |
xchg rcx, rdx | |
xchg rsi, r8 ; rsi: buffer address; r8: save rsi | |
; Check if we need to unroll String I/O | |
call ASM_PFX(SevNoRepIo) | |
test eax, eax | |
jnz @IoWriteFifo32_NoRep | |
cld | |
rep outsd | |
jmp @IoWriteFifo32_Done | |
@IoWriteFifo32_NoRep: | |
jrcxz @IoWriteFifo32_Done | |
@IoWriteFifo32_Loop: | |
mov eax, dword [rsi] | |
out dx, eax | |
add rsi, 4 | |
loop @IoWriteFifo32_Loop | |
@IoWriteFifo32_Done: | |
mov rsi, r8 ; restore rsi | |
ret | |