1. Added comments to ASM files

2. Fixed a bug in 64-bit AsmDisablePaging64(), which may cause a #GP exception.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2206 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
bxing 2007-01-10 06:57:04 +00:00
parent 741fb36417
commit a9a812a0ed
45 changed files with 184 additions and 77 deletions

View File

@ -33,7 +33,7 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
CpuFlushTlb PROC CpuFlushTlb PROC
mov eax, cr3 mov eax, cr3
mov cr3, eax mov cr3, eax ; moving to CR3 flushes TLB
ret ret
CpuFlushTlb ENDP CpuFlushTlb ENDP

View File

@ -33,18 +33,18 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalMathDivRemU64x32 PROC InternalMathDivRemU64x32 PROC
mov ecx, [esp + 12] mov ecx, [esp + 12] ; ecx <- divisor
mov eax, [esp + 8] mov eax, [esp + 8] ; eax <- dividend[32..63]
xor edx, edx xor edx, edx
div ecx div ecx ; eax <- quotient[32..63], edx <- remainder
push eax push eax
mov eax, [esp + 8] mov eax, [esp + 8] ; eax <- dividend[0..31]
div ecx div ecx ; eax <- quotient[0..31]
mov ecx, [esp + 20] mov ecx, [esp + 20] ; ecx <- Remainder
jecxz @F ; abandon remainder if Remainder == NULL jecxz @F ; abandon remainder if Remainder == NULL
mov [ecx], edx mov [ecx], edx
@@: @@:
pop edx pop edx ; edx <- quotient[32..63]
ret ret
InternalMathDivRemU64x32 ENDP InternalMathDivRemU64x32 ENDP

View File

@ -36,13 +36,13 @@ EXTERN InternalMathDivRemU64x32:PROC
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalMathDivRemU64x64 PROC InternalMathDivRemU64x64 PROC
mov ecx, [esp + 16] mov ecx, [esp + 16] ; ecx <- divisor[32..63]
test ecx, ecx test ecx, ecx
jnz _@DivRemU64x64 ; call _@DivRemU64x64 if Divisor > 2^32 jnz _@DivRemU64x64 ; call _@DivRemU64x64 if Divisor > 2^32
mov ecx, [esp + 20] mov ecx, [esp + 20]
jecxz @F jecxz @F
and dword ptr [ecx + 4], 0 and dword ptr [ecx + 4], 0 ; zero high dword of remainder
mov [esp + 16], ecx mov [esp + 16], ecx ; set up stack frame to match DivRemU64x32
@@: @@:
jmp InternalMathDivRemU64x32 jmp InternalMathDivRemU64x32
InternalMathDivRemU64x64 ENDP InternalMathDivRemU64x64 ENDP
@ -61,11 +61,11 @@ _@DivRemU64x64 PROC USES ebx esi edi
jnz @B jnz @B
div ebx div ebx
mov ebx, eax ; ebx <- quotient mov ebx, eax ; ebx <- quotient
mov ecx, [esp + 28] mov ecx, [esp + 28] ; ecx <- high dword of divisor
mul dword ptr [esp + 24] mul dword ptr [esp + 24] ; edx:eax <- quotient * divisor[0..31]
imul ecx, ebx imul ecx, ebx ; ecx <- quotient * divisor[32..63]
add edx, ecx add edx, ecx ; edx <- (quotient * divisor)[32..63]
mov ecx, dword ptr [esp + 32] mov ecx, dword ptr [esp + 32] ; ecx <- addr for Remainder
jc @TooLarge ; product > 2^64 jc @TooLarge ; product > 2^64
cmp edi, edx ; compare high 32 bits cmp edi, edx ; compare high 32 bits
ja @Correct ja @Correct
@ -76,7 +76,7 @@ _@DivRemU64x64 PROC USES ebx esi edi
dec ebx ; adjust quotient by -1 dec ebx ; adjust quotient by -1
jecxz @Return ; return if Remainder == NULL jecxz @Return ; return if Remainder == NULL
sub eax, dword ptr [esp + 24] sub eax, dword ptr [esp + 24]
sbb edx, dword ptr [esp + 28] sbb edx, dword ptr [esp + 28] ; edx:eax <- (quotient - 1) * divisor
@Correct: @Correct:
jecxz @Return jecxz @Return
sub esi, eax sub esi, eax
@ -85,7 +85,7 @@ _@DivRemU64x64 PROC USES ebx esi edi
mov [ecx + 4], edi mov [ecx + 4], edi
@Return: @Return:
mov eax, ebx ; eax <- quotient mov eax, ebx ; eax <- quotient
xor edx, edx xor edx, edx ; quotient is 32 bits long
ret ret
_@DivRemU64x64 ENDP _@DivRemU64x64 ENDP

View File

@ -40,14 +40,14 @@ InternalX86EnablePaging32 PROC
mov ecx, [esp + 8] mov ecx, [esp + 8]
mov edx, [esp + 12] mov edx, [esp + 12]
pushfd pushfd
pop edi pop edi ; save flags in edi
cli cli
mov eax, cr0 mov eax, cr0
bts eax, 31 bts eax, 31
mov esp, [esp + 16] mov esp, [esp + 16]
mov cr0, eax mov cr0, eax
push edi push edi
popfd popfd ; restore flags
push edx push edx
push ecx push ecx
call ebx call ebx

View File

@ -47,11 +47,11 @@ InternalX86EnablePaging64 PROC
or ah, 1 ; set LME or ah, 1 ; set LME
wrmsr wrmsr
mov eax, cr0 mov eax, cr0
bts eax, 31 bts eax, 31 ; set PG
mov cr0, eax ; enable paging mov cr0, eax ; enable paging
retf retf ; topmost 2 dwords hold the address
@@: ; long mode starts here @@: ; long mode starts here
DB 67h, 48h DB 67h, 48h ; 32-bit address size, 64-bit operand size
mov ebx, [esp] ; mov rbx, [esp] mov ebx, [esp] ; mov rbx, [esp]
DB 67h, 48h DB 67h, 48h
mov ecx, [esp + 8] ; mov rcx, [esp + 8] mov ecx, [esp + 8] ; mov rcx, [esp + 8]
@ -62,7 +62,7 @@ InternalX86EnablePaging64 PROC
DB 48h DB 48h
add esp, -20h ; add rsp, -20h add esp, -20h ; add rsp, -20h
call ebx ; call rbx call ebx ; call rbx
jmp $ hlt ; no one should get here
InternalX86EnablePaging64 ENDP InternalX86EnablePaging64 ENDP
END END

View File

@ -34,7 +34,7 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalX86FxRestore PROC InternalX86FxRestore PROC
mov eax, [esp + 4] mov eax, [esp + 4] ; Buffer must be 16-byte aligned
fxrstor [eax] fxrstor [eax]
ret ret
InternalX86FxRestore ENDP InternalX86FxRestore ENDP

View File

@ -34,7 +34,7 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalX86FxSave PROC InternalX86FxSave PROC
mov eax, [esp + 4] mov eax, [esp + 4] ; Buffer must be 16-byte aligned
fxsave [eax] fxsave [eax]
ret ret
InternalX86FxSave ENDP InternalX86FxSave ENDP

View File

@ -40,7 +40,7 @@ InternalLongJump PROC
mov edi, [edx + 8] mov edi, [edx + 8]
mov ebp, [edx + 12] mov ebp, [edx + 12]
mov esp, [edx + 16] mov esp, [edx + 16]
jmp dword ptr [edx + 20] jmp dword ptr [edx + 20] ; restore "eip"
InternalLongJump ENDP InternalLongJump ENDP
END END

View File

@ -32,15 +32,15 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalMathMultU64x64 PROC USES ebx InternalMathMultU64x64 PROC USES ebx
mov ebx, [esp + 8] mov ebx, [esp + 8] ; ebx <- M1[0..31]
mov edx, [esp + 16] mov edx, [esp + 16] ; edx <- M2[0..31]
mov ecx, ebx mov ecx, ebx
mov eax, edx mov eax, edx
imul ebx, [esp + 20] imul ebx, [esp + 20] ; ebx <- M1[0..31] * M2[32..63]
imul edx, [esp + 12] imul edx, [esp + 12] ; edx <- M1[32..63] * M2[0..31]
add ebx, edx add ebx, edx ; carries are abandoned
mul ecx mul ecx ; edx:eax <- M1[0..31] * M2[0..31]
add edx, ebx add edx, ebx ; carries are abandoned
ret ret
InternalMathMultU64x64 ENDP InternalMathMultU64x64 ENDP

View File

@ -40,7 +40,7 @@ InternalMathRRotU64 PROC USES ebx
rol ebx, cl rol ebx, cl
shrd edx, ebx, cl shrd edx, ebx, cl
test cl, 32 ; Count >= 32? test cl, 32 ; Count >= 32?
cmovnz ecx, eax cmovnz ecx, eax ; switch eax & edx if Count >= 32
cmovnz eax, edx cmovnz eax, edx
cmovnz edx, ecx cmovnz edx, ecx
ret ret

View File

@ -32,10 +32,10 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalMathRShiftU64 PROC InternalMathRShiftU64 PROC
mov cl, [esp + 12] mov cl, [esp + 12] ; cl <- Count
xor edx, edx xor edx, edx
mov eax, [esp + 8] mov eax, [esp + 8]
test cl, 32 test cl, 32 ; Count >= 32?
cmovz edx, eax cmovz edx, eax
cmovz eax, [esp + 4] cmovz eax, [esp + 4]
shrd eax, edx, cl shrd eax, edx, cl

View File

@ -33,6 +33,13 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadDr4 PROC AsmReadDr4 PROC
;
; DR4 is alias to DR6 only if DE (in CR4) is cleared. Otherwise, reading
; this register will cause a #UD exception.
;
; MS assembler doesn't support this instruction since no one would use it
; under normal circustances. Here opcode is used.
;
DB 0fh, 21h, 0e0h DB 0fh, 21h, 0e0h
ret ret
AsmReadDr4 ENDP AsmReadDr4 ENDP

View File

@ -33,6 +33,13 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadDr5 PROC AsmReadDr5 PROC
;
; DR5 is alias to DR7 only if DE (in CR4) is cleared. Otherwise, reading
; this register will cause a #UD exception.
;
; MS assembler doesn't support this instruction since no one would use it
; under normal circustances. Here opcode is used.
;
DB 0fh, 21h, 0e8h DB 0fh, 21h, 0e8h
ret ret
AsmReadDr5 ENDP AsmReadDr5 ENDP

View File

@ -34,16 +34,16 @@ InternalAssertJumpBuffer PROTO C
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
SetJump PROC SetJump PROC
push [esp + 4] push [esp + 4]
call InternalAssertJumpBuffer call InternalAssertJumpBuffer ; To validate JumpBuffer
pop ecx
pop ecx pop ecx
pop ecx ; ecx <- return address
mov edx, [esp] mov edx, [esp]
mov [edx], ebx mov [edx], ebx
mov [edx + 4], esi mov [edx + 4], esi
mov [edx + 8], edi mov [edx + 8], edi
mov [edx + 12], ebp mov [edx + 12], ebp
mov [edx + 16], esp mov [edx + 16], esp
mov [edx + 20], ecx mov [edx + 20], ecx ; eip value to restore in LongJump
xor eax, eax xor eax, eax
jmp ecx jmp ecx
SetJump ENDP SetJump ENDP

View File

@ -33,8 +33,8 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalMathSwapBytes64 PROC InternalMathSwapBytes64 PROC
mov eax, [esp + 8] mov eax, [esp + 8] ; eax <- upper 32 bits
mov edx, [esp + 4] mov edx, [esp + 4] ; edx <- lower 32 bits
bswap eax bswap eax
bswap edx bswap edx
ret ret

View File

@ -75,6 +75,11 @@ SavedGdt LABEL FWORD
; by user code. It will be shadowed to somewhere in memory below 1MB. ; by user code. It will be shadowed to somewhere in memory below 1MB.
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
_BackFromUserCode PROC _BackFromUserCode PROC
;
; The order of saved registers on the stack matches the order they appears
; in IA32_REGS structure. This facilitates wrapper function to extract them
; into that structure.
;
push ss push ss
push cs push cs
DB 66h DB 66h
@ -104,6 +109,11 @@ _ThunkAttr DD ?
mov eax, ss mov eax, ss
DB 67h DB 67h
lea bp, [esp + sizeof (IA32_REGS)] lea bp, [esp + sizeof (IA32_REGS)]
;
; esi's in the following 2 instructions are indeed bp in 16-bit code. Fact
; is "esi" in 32-bit addressing mode has the same encoding of "bp" in 16-
; bit addressing mode.
;
mov word ptr (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._ESP, bp mov word ptr (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._ESP, bp
mov ebx, (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._EIP mov ebx, (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._EIP
shl ax, 4 ; shl eax, 4 shl ax, 4 ; shl eax, 4
@ -167,7 +177,7 @@ _ToUserCode PROC
pop fs pop fs
pop gs pop gs
popf ; popfd popf ; popfd
DB 66h DB 66h ; Use 32-bit addressing for "retf" below
retf ; transfer control to user code retf ; transfer control to user code
_ToUserCode ENDP _ToUserCode ENDP
@ -197,7 +207,7 @@ GdtEnd LABEL QWORD
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalAsmThunk16 PROC USES ebp ebx esi edi ds es fs gs InternalAsmThunk16 PROC USES ebp ebx esi edi ds es fs gs
mov esi, [esp + 36] ; esi <- RegSet mov esi, [esp + 36] ; esi <- RegSet, the 1st parameter
movzx edx, (IA32_REGS ptr [esi])._SS movzx edx, (IA32_REGS ptr [esi])._SS
mov edi, (IA32_REGS ptr [esi])._ESP mov edi, (IA32_REGS ptr [esi])._ESP
add edi, - (sizeof (IA32_REGS) + 4) ; reserve stack space add edi, - (sizeof (IA32_REGS) + 4) ; reserve stack space
@ -227,11 +237,11 @@ InternalAsmThunk16 PROC USES ebp ebx esi edi ds es fs gs
push 10h push 10h
pop ecx ; ecx <- selector for data segments pop ecx ; ecx <- selector for data segments
lgdt fword ptr [edx + (_16Gdtr - SavedCr0)] lgdt fword ptr [edx + (_16Gdtr - SavedCr0)]
pushfd pushfd ; Save df/if indeed
call fword ptr [edx + (_EntryPoint - SavedCr0)] call fword ptr [edx + (_EntryPoint - SavedCr0)]
popfd popfd
lidt fword ptr [esp + 36] ; restore protected mode IDTR lidt fword ptr [esp + 36] ; restore protected mode IDTR
lea eax, [ebp - sizeof (IA32_REGS)] lea eax, [ebp - sizeof (IA32_REGS)] ; eax <- the address of IA32_REGS
ret ret
InternalAsmThunk16 ENDP InternalAsmThunk16 ENDP

View File

@ -34,6 +34,13 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteDr4 PROC AsmWriteDr4 PROC
mov eax, [esp + 4] mov eax, [esp + 4]
;
; DR4 is alias to DR6 only if DE (in CR4) is cleared. Otherwise, writing to
; this register will cause a #UD exception.
;
; MS assembler doesn't support this instruction since no one would use it
; under normal circustances. Here opcode is used.
;
DB 0fh, 23h, 0e0h DB 0fh, 23h, 0e0h
ret ret
AsmWriteDr4 ENDP AsmWriteDr4 ENDP

View File

@ -34,6 +34,13 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteDr5 PROC AsmWriteDr5 PROC
mov eax, [esp + 4] mov eax, [esp + 4]
;
; DR5 is alias to DR7 only if DE (in CR4) is cleared. Otherwise, writing to
; this register will cause a #UD exception.
;
; MS assembler doesn't support this instruction since no one would use it
; under normal circustances. Here opcode is used.
;
DB 0fh, 23h, 0e8h DB 0fh, 23h, 0e8h
ret ret
AsmWriteDr5 ENDP AsmWriteDr5 ENDP

View File

@ -36,15 +36,14 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalX86DisablePaging64 PROC InternalX86DisablePaging64 PROC
cli cli
shl rcx, 32 shl rcx, 32 ; rcx[32..47] <- Cs
lea eax, @F lea eax, @F
mov ecx, eax
push rcx
mov ebx, edx
mov esi, r8d mov esi, r8d
or rcx, rax ; rcx[0..47] <- Cs:@F
mov edi, r9d mov edi, r9d
mov eax, [rsp + 28h] mov eax, [rsp + 28h] ; eax <- New Stack
retf push rcx
retf ; switch to compatibility mode
@@: @@:
mov esp, eax ; set up new stack mov esp, eax ; set up new stack
mov rax, cr0 mov rax, cr0
@ -57,10 +56,10 @@ InternalX86DisablePaging64 PROC
mov rax, cr4 mov rax, cr4
and al, NOT (1 SHL 5) ; clear PAE and al, NOT (1 SHL 5) ; clear PAE
mov cr4, rax mov cr4, rax
push rdi push rdi ; push Context2
push rsi push rsi ; push Context1
call rbx call rdx ; transfer control to EntryPoint
jmp $ hlt ; no one should get here
InternalX86DisablePaging64 ENDP InternalX86DisablePaging64 ENDP
END END

View File

@ -36,7 +36,7 @@
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalX86EnablePaging64 PROC InternalX86EnablePaging64 PROC
cli cli
pop rax pop rax ; skip the return address
call @Base call @Base
@Base: @Base:
add dword ptr [rsp], @F - @Base ; offset for far retf, seg is the 1st arg add dword ptr [rsp], @F - @Base ; offset for far retf, seg is the 1st arg
@ -58,7 +58,7 @@ InternalX86EnablePaging64 PROC
mov rsp, [esp + 18h] mov rsp, [esp + 18h]
add rsp, -20h add rsp, -20h
call rbx call rbx
jmp $ ; halt processor if EntryPoint() returned hlt ; halt processor if EntryPoint() returned
InternalX86EnablePaging64 ENDP InternalX86EnablePaging64 ENDP
END END

View File

@ -39,7 +39,7 @@ InternalLongJump PROC
mov r13, [rcx + 30h] mov r13, [rcx + 30h]
mov r14, [rcx + 38h] mov r14, [rcx + 38h]
mov r15, [rcx + 40h] mov r15, [rcx + 40h]
mov rax, rdx mov rax, rdx ; set return value
jmp qword ptr [rcx + 48h] jmp qword ptr [rcx + 48h]
InternalLongJump ENDP InternalLongJump ENDP

View File

@ -36,7 +36,7 @@ AsmMonitor PROC
mov eax, ecx mov eax, ecx
mov ecx, edx mov ecx, edx
mov edx, r8d mov edx, r8d
DB 0fh, 1, 0c8h DB 0fh, 1, 0c8h ; monitor
ret ret
AsmMonitor ENDP AsmMonitor ENDP

View File

@ -34,7 +34,7 @@
AsmMwait PROC AsmMwait PROC
mov eax, ecx mov eax, ecx
mov ecx, edx mov ecx, edx
DB 0fh, 1, 0c9h DB 0fh, 1, 0c9h ; mwait
ret ret
AsmMwait ENDP AsmMwait ENDP

View File

@ -31,6 +31,10 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadDr4 PROC AsmReadDr4 PROC
;
; There's no obvious reason to access this register, since it's aliased to
; DR7 when DE=0 or an exception generated when DE=1
;
DB 0fh, 21h, 0e0h DB 0fh, 21h, 0e0h
ret ret
AsmReadDr4 ENDP AsmReadDr4 ENDP

View File

@ -31,6 +31,10 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadDr5 PROC AsmReadDr5 PROC
;
; There's no obvious reason to access this register, since it's aliased to
; DR7 when DE=0 or an exception generated when DE=1
;
DB 0fh, 21h, 0e8h DB 0fh, 21h, 0e8h
ret ret
AsmReadDr5 ENDP AsmReadDr5 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadMm0 PROC AsmReadMm0 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 7eh, 0c0h DB 48h, 0fh, 7eh, 0c0h
ret ret
AsmReadMm0 ENDP AsmReadMm0 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadMm1 PROC AsmReadMm1 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 7eh, 0c8h DB 48h, 0fh, 7eh, 0c8h
ret ret
AsmReadMm1 ENDP AsmReadMm1 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadMm2 PROC AsmReadMm2 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 7eh, 0d0h DB 48h, 0fh, 7eh, 0d0h
ret ret
AsmReadMm2 ENDP AsmReadMm2 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadMm3 PROC AsmReadMm3 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 7eh, 0d8h DB 48h, 0fh, 7eh, 0d8h
ret ret
AsmReadMm3 ENDP AsmReadMm3 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadMm4 PROC AsmReadMm4 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 7eh, 0e0h DB 48h, 0fh, 7eh, 0e0h
ret ret
AsmReadMm4 ENDP AsmReadMm4 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadMm5 PROC AsmReadMm5 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 7eh, 0e8h DB 48h, 0fh, 7eh, 0e8h
ret ret
AsmReadMm5 ENDP AsmReadMm5 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadMm6 PROC AsmReadMm6 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 7eh, 0f0h DB 48h, 0fh, 7eh, 0f0h
ret ret
AsmReadMm6 ENDP AsmReadMm6 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmReadMm7 PROC AsmReadMm7 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 7eh, 0f8h DB 48h, 0fh, 7eh, 0f8h
ret ret
AsmReadMm7 ENDP AsmReadMm7 ENDP

View File

@ -66,6 +66,14 @@ SavedGdt LABEL FWORD
; by user code. It will be shadowed to somewhere in memory below 1MB. ; by user code. It will be shadowed to somewhere in memory below 1MB.
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
_BackFromUserCode PROC _BackFromUserCode PROC
;
; The order of saved registers on the stack matches the order they appears
; in IA32_REGS structure. This facilitates wrapper function to extract them
; into that structure.
;
; Some instructions for manipulation of segment registers have to be written
; in opcode since 64-bit MASM prevents accesses to those registers.
;
DB 16h ; push ss DB 16h ; push ss
DB 0eh ; push cs DB 0eh ; push cs
DB 66h DB 66h
@ -115,7 +123,7 @@ SavedCr4 DD ?
; ;
; rdi in the instruction below is indeed bx in 16-bit code ; rdi in the instruction below is indeed bx in 16-bit code
; ;
DB 66h, 2eh DB 66h, 2eh ; 2eh is "cs:" segment override
lgdt fword ptr [rdi + (SavedGdt - @Base)] lgdt fword ptr [rdi + (SavedGdt - @Base)]
DB 66h DB 66h
mov ecx, 0c0000080h mov ecx, 0c0000080h
@ -129,9 +137,8 @@ SavedCr0 DD ?
@64Eip DD ? @64Eip DD ?
SavedCs DW ? SavedCs DW ?
@64BitCode: @64BitCode:
DB 48h, 0b8h ; mov rax, imm64 mov rsp, r8 ; restore stack
SavedRip DQ ? ret
jmp rax ; return to caller
_BackFromUserCode ENDP _BackFromUserCode ENDP
_EntryPoint DD _ToUserCode - m16Start _EntryPoint DD _ToUserCode - m16Start
@ -160,14 +167,14 @@ _ToUserCode PROC
mov cr4, rbp mov cr4, rbp
mov ss, esi ; set up 16-bit stack segment mov ss, esi ; set up 16-bit stack segment
mov sp, bx ; set up 16-bit stack pointer mov sp, bx ; set up 16-bit stack pointer
DB 66h DB 66h ; make the following call 32-bit
call @Base ; push eip call @Base ; push eip
@Base: @Base:
pop bp ; ebp <- address of @Base pop bp ; ebp <- address of @Base
push [esp + sizeof (IA32_REGS) + 2] push [esp + sizeof (IA32_REGS) + 2]
lea eax, [rsi + (@RealMode - @Base)] lea eax, [rsi + (@RealMode - @Base)] ; rsi is "bp" in 16-bit code
push rax push rax
retf retf ; execution begins at next instruction
@RealMode: @RealMode:
DB 66h, 2eh ; CS and operand size override DB 66h, 2eh ; CS and operand size override
lidt fword ptr [rsi + (_16Idtr - @Base)] lidt fword ptr [rsi + (_16Idtr - @Base)]
@ -178,7 +185,7 @@ _ToUserCode PROC
pop gs pop gs
popf ; popfd popf ; popfd
lea sp, [esp + 4] ; skip high order 32 bits of EFlags lea sp, [esp + 4] ; skip high order 32 bits of EFlags
DB 66h DB 66h ; make the following retf 32-bit
retf ; transfer control to user code retf ; transfer control to user code
_ToUserCode ENDP _ToUserCode ENDP
@ -220,8 +227,8 @@ GDT_SIZE = $ - _NullSeg
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
InternalAsmThunk16 PROC USES rbp rbx rsi rdi InternalAsmThunk16 PROC USES rbp rbx rsi rdi
mov r10d, ds mov r10d, ds ; r9 ~ r11 are not accessible in 16-bit
mov r11d, es mov r11d, es ; so use them for saving seg registers
mov r9d, ss mov r9d, ss
push fs push fs
push gs push gs
@ -238,8 +245,8 @@ InternalAsmThunk16 PROC USES rbp rbx rsi rdi
lea ecx, [rdx + (SavedCr4 - m16Start)] lea ecx, [rdx + (SavedCr4 - m16Start)]
mov eax, edx ; eax <- transition code address mov eax, edx ; eax <- transition code address
and edx, 0fh and edx, 0fh
shl eax, 12 shl eax, 12 ; segment address in high order 16 bits
lea ax, [rdx + (_BackFromUserCode - m16Start)] lea ax, [rdx + (_BackFromUserCode - m16Start)] ; offset address
stosd ; [edi] <- return address of user code stosd ; [edi] <- return address of user code
sgdt fword ptr [rcx + (SavedGdt - SavedCr4)] sgdt fword ptr [rcx + (SavedGdt - SavedCr4)]
sidt fword ptr [rsp + 38h] ; save IDT stack in argument space sidt fword ptr [rsp + 38h] ; save IDT stack in argument space
@ -257,13 +264,12 @@ InternalAsmThunk16 PROC USES rbp rbx rsi rdi
pushfq pushfq
lea edx, [rdx + DATA16 - DATA32] lea edx, [rdx + DATA16 - DATA32]
lea r8, @RetFromRealMode lea r8, @RetFromRealMode
mov [rcx + (SavedRip - SavedCr4)], r8 push r8
mov r8d, cs mov r8d, cs
mov [rcx + (SavedCs - SavedCr4)], r8w mov [rcx + (SavedCs - SavedCr4)], r8w
mov r8, rsp mov r8, rsp
jmp fword ptr [rcx + (_EntryPoint - SavedCr4)] jmp fword ptr [rcx + (_EntryPoint - SavedCr4)]
@RetFromRealMode: @RetFromRealMode:
mov rsp, r8
popfq popfq
lidt fword ptr [rsp + 38h] ; restore protected mode IDTR lidt fword ptr [rsp + 38h] ; restore protected mode IDTR
lea eax, [rbp - sizeof (IA32_REGS)] lea eax, [rbp - sizeof (IA32_REGS)]

View File

@ -31,6 +31,10 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteDr4 PROC AsmWriteDr4 PROC
;
; There's no obvious reason to access this register, since it's aliased to
; DR6 when DE=0 or an exception generated when DE=1
;
DB 0fh, 23h, 0e1h DB 0fh, 23h, 0e1h
mov rax, rcx mov rax, rcx
ret ret

View File

@ -31,6 +31,10 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteDr5 PROC AsmWriteDr5 PROC
;
; There's no obvious reason to access this register, since it's aliased to
; DR7 when DE=0 or an exception generated when DE=1
;
DB 0fh, 23h, 0e9h DB 0fh, 23h, 0e9h
mov rax, rcx mov rax, rcx
ret ret

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMm0 PROC AsmWriteMm0 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 6eh, 0c1h DB 48h, 0fh, 6eh, 0c1h
ret ret
AsmWriteMm0 ENDP AsmWriteMm0 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMm1 PROC AsmWriteMm1 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 6eh, 0c9h DB 48h, 0fh, 6eh, 0c9h
ret ret
AsmWriteMm1 ENDP AsmWriteMm1 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMm2 PROC AsmWriteMm2 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 6eh, 0d1h DB 48h, 0fh, 6eh, 0d1h
ret ret
AsmWriteMm2 ENDP AsmWriteMm2 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMm3 PROC AsmWriteMm3 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 6eh, 0d9h DB 48h, 0fh, 6eh, 0d9h
ret ret
AsmWriteMm3 ENDP AsmWriteMm3 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMm4 PROC AsmWriteMm4 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 6eh, 0e1h DB 48h, 0fh, 6eh, 0e1h
ret ret
AsmWriteMm4 ENDP AsmWriteMm4 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMm5 PROC AsmWriteMm5 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 6eh, 0e9h DB 48h, 0fh, 6eh, 0e9h
ret ret
AsmWriteMm5 ENDP AsmWriteMm5 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMm6 PROC AsmWriteMm6 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 6eh, 0f1h DB 48h, 0fh, 6eh, 0f1h
ret ret
AsmWriteMm6 ENDP AsmWriteMm6 ENDP

View File

@ -31,6 +31,9 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMm7 PROC AsmWriteMm7 PROC
;
; 64-bit MASM doesn't support MMX instructions, so use opcode here
;
DB 48h, 0fh, 6eh, 0f9h DB 48h, 0fh, 6eh, 0f9h
ret ret
AsmWriteMm7 ENDP AsmWriteMm7 ENDP

View File

@ -32,8 +32,8 @@
; ); ; );
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
AsmWriteMsr64 PROC AsmWriteMsr64 PROC
mov rax, rdx mov rax, rdx ; meanwhile, rax <- return value
shr rdx, 20h shr rdx, 20h ; edx:eax contains the value to write
wrmsr wrmsr
ret ret
AsmWriteMsr64 ENDP AsmWriteMsr64 ENDP