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:
@@ -33,7 +33,7 @@
|
||||
;------------------------------------------------------------------------------
|
||||
CpuFlushTlb PROC
|
||||
mov eax, cr3
|
||||
mov cr3, eax
|
||||
mov cr3, eax ; moving to CR3 flushes TLB
|
||||
ret
|
||||
CpuFlushTlb ENDP
|
||||
|
||||
|
@@ -33,18 +33,18 @@
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
InternalMathDivRemU64x32 PROC
|
||||
mov ecx, [esp + 12]
|
||||
mov eax, [esp + 8]
|
||||
mov ecx, [esp + 12] ; ecx <- divisor
|
||||
mov eax, [esp + 8] ; eax <- dividend[32..63]
|
||||
xor edx, edx
|
||||
div ecx
|
||||
div ecx ; eax <- quotient[32..63], edx <- remainder
|
||||
push eax
|
||||
mov eax, [esp + 8]
|
||||
div ecx
|
||||
mov ecx, [esp + 20]
|
||||
mov eax, [esp + 8] ; eax <- dividend[0..31]
|
||||
div ecx ; eax <- quotient[0..31]
|
||||
mov ecx, [esp + 20] ; ecx <- Remainder
|
||||
jecxz @F ; abandon remainder if Remainder == NULL
|
||||
mov [ecx], edx
|
||||
@@:
|
||||
pop edx
|
||||
pop edx ; edx <- quotient[32..63]
|
||||
ret
|
||||
InternalMathDivRemU64x32 ENDP
|
||||
|
||||
|
@@ -36,13 +36,13 @@ EXTERN InternalMathDivRemU64x32:PROC
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
InternalMathDivRemU64x64 PROC
|
||||
mov ecx, [esp + 16]
|
||||
mov ecx, [esp + 16] ; ecx <- divisor[32..63]
|
||||
test ecx, ecx
|
||||
jnz _@DivRemU64x64 ; call _@DivRemU64x64 if Divisor > 2^32
|
||||
mov ecx, [esp + 20]
|
||||
jecxz @F
|
||||
and dword ptr [ecx + 4], 0
|
||||
mov [esp + 16], ecx
|
||||
and dword ptr [ecx + 4], 0 ; zero high dword of remainder
|
||||
mov [esp + 16], ecx ; set up stack frame to match DivRemU64x32
|
||||
@@:
|
||||
jmp InternalMathDivRemU64x32
|
||||
InternalMathDivRemU64x64 ENDP
|
||||
@@ -61,11 +61,11 @@ _@DivRemU64x64 PROC USES ebx esi edi
|
||||
jnz @B
|
||||
div ebx
|
||||
mov ebx, eax ; ebx <- quotient
|
||||
mov ecx, [esp + 28]
|
||||
mul dword ptr [esp + 24]
|
||||
imul ecx, ebx
|
||||
add edx, ecx
|
||||
mov ecx, dword ptr [esp + 32]
|
||||
mov ecx, [esp + 28] ; ecx <- high dword of divisor
|
||||
mul dword ptr [esp + 24] ; edx:eax <- quotient * divisor[0..31]
|
||||
imul ecx, ebx ; ecx <- quotient * divisor[32..63]
|
||||
add edx, ecx ; edx <- (quotient * divisor)[32..63]
|
||||
mov ecx, dword ptr [esp + 32] ; ecx <- addr for Remainder
|
||||
jc @TooLarge ; product > 2^64
|
||||
cmp edi, edx ; compare high 32 bits
|
||||
ja @Correct
|
||||
@@ -76,7 +76,7 @@ _@DivRemU64x64 PROC USES ebx esi edi
|
||||
dec ebx ; adjust quotient by -1
|
||||
jecxz @Return ; return if Remainder == NULL
|
||||
sub eax, dword ptr [esp + 24]
|
||||
sbb edx, dword ptr [esp + 28]
|
||||
sbb edx, dword ptr [esp + 28] ; edx:eax <- (quotient - 1) * divisor
|
||||
@Correct:
|
||||
jecxz @Return
|
||||
sub esi, eax
|
||||
@@ -85,7 +85,7 @@ _@DivRemU64x64 PROC USES ebx esi edi
|
||||
mov [ecx + 4], edi
|
||||
@Return:
|
||||
mov eax, ebx ; eax <- quotient
|
||||
xor edx, edx
|
||||
xor edx, edx ; quotient is 32 bits long
|
||||
ret
|
||||
_@DivRemU64x64 ENDP
|
||||
|
||||
|
@@ -40,14 +40,14 @@ InternalX86EnablePaging32 PROC
|
||||
mov ecx, [esp + 8]
|
||||
mov edx, [esp + 12]
|
||||
pushfd
|
||||
pop edi
|
||||
pop edi ; save flags in edi
|
||||
cli
|
||||
mov eax, cr0
|
||||
bts eax, 31
|
||||
mov esp, [esp + 16]
|
||||
mov cr0, eax
|
||||
push edi
|
||||
popfd
|
||||
popfd ; restore flags
|
||||
push edx
|
||||
push ecx
|
||||
call ebx
|
||||
|
@@ -47,11 +47,11 @@ InternalX86EnablePaging64 PROC
|
||||
or ah, 1 ; set LME
|
||||
wrmsr
|
||||
mov eax, cr0
|
||||
bts eax, 31
|
||||
bts eax, 31 ; set PG
|
||||
mov cr0, eax ; enable paging
|
||||
retf
|
||||
retf ; topmost 2 dwords hold the address
|
||||
@@: ; long mode starts here
|
||||
DB 67h, 48h
|
||||
DB 67h, 48h ; 32-bit address size, 64-bit operand size
|
||||
mov ebx, [esp] ; mov rbx, [esp]
|
||||
DB 67h, 48h
|
||||
mov ecx, [esp + 8] ; mov rcx, [esp + 8]
|
||||
@@ -62,7 +62,7 @@ InternalX86EnablePaging64 PROC
|
||||
DB 48h
|
||||
add esp, -20h ; add rsp, -20h
|
||||
call ebx ; call rbx
|
||||
jmp $
|
||||
hlt ; no one should get here
|
||||
InternalX86EnablePaging64 ENDP
|
||||
|
||||
END
|
||||
|
@@ -34,7 +34,7 @@
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
InternalX86FxRestore PROC
|
||||
mov eax, [esp + 4]
|
||||
mov eax, [esp + 4] ; Buffer must be 16-byte aligned
|
||||
fxrstor [eax]
|
||||
ret
|
||||
InternalX86FxRestore ENDP
|
||||
|
@@ -34,7 +34,7 @@
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
InternalX86FxSave PROC
|
||||
mov eax, [esp + 4]
|
||||
mov eax, [esp + 4] ; Buffer must be 16-byte aligned
|
||||
fxsave [eax]
|
||||
ret
|
||||
InternalX86FxSave ENDP
|
||||
|
@@ -40,7 +40,7 @@ InternalLongJump PROC
|
||||
mov edi, [edx + 8]
|
||||
mov ebp, [edx + 12]
|
||||
mov esp, [edx + 16]
|
||||
jmp dword ptr [edx + 20]
|
||||
jmp dword ptr [edx + 20] ; restore "eip"
|
||||
InternalLongJump ENDP
|
||||
|
||||
END
|
||||
|
@@ -32,15 +32,15 @@
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
InternalMathMultU64x64 PROC USES ebx
|
||||
mov ebx, [esp + 8]
|
||||
mov edx, [esp + 16]
|
||||
mov ebx, [esp + 8] ; ebx <- M1[0..31]
|
||||
mov edx, [esp + 16] ; edx <- M2[0..31]
|
||||
mov ecx, ebx
|
||||
mov eax, edx
|
||||
imul ebx, [esp + 20]
|
||||
imul edx, [esp + 12]
|
||||
add ebx, edx
|
||||
mul ecx
|
||||
add edx, ebx
|
||||
imul ebx, [esp + 20] ; ebx <- M1[0..31] * M2[32..63]
|
||||
imul edx, [esp + 12] ; edx <- M1[32..63] * M2[0..31]
|
||||
add ebx, edx ; carries are abandoned
|
||||
mul ecx ; edx:eax <- M1[0..31] * M2[0..31]
|
||||
add edx, ebx ; carries are abandoned
|
||||
ret
|
||||
InternalMathMultU64x64 ENDP
|
||||
|
||||
|
@@ -40,7 +40,7 @@ InternalMathRRotU64 PROC USES ebx
|
||||
rol ebx, cl
|
||||
shrd edx, ebx, cl
|
||||
test cl, 32 ; Count >= 32?
|
||||
cmovnz ecx, eax
|
||||
cmovnz ecx, eax ; switch eax & edx if Count >= 32
|
||||
cmovnz eax, edx
|
||||
cmovnz edx, ecx
|
||||
ret
|
||||
|
@@ -32,10 +32,10 @@
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
InternalMathRShiftU64 PROC
|
||||
mov cl, [esp + 12]
|
||||
mov cl, [esp + 12] ; cl <- Count
|
||||
xor edx, edx
|
||||
mov eax, [esp + 8]
|
||||
test cl, 32
|
||||
test cl, 32 ; Count >= 32?
|
||||
cmovz edx, eax
|
||||
cmovz eax, [esp + 4]
|
||||
shrd eax, edx, cl
|
||||
|
@@ -33,6 +33,13 @@
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
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
|
||||
ret
|
||||
AsmReadDr4 ENDP
|
||||
|
@@ -33,6 +33,13 @@
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
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
|
||||
ret
|
||||
AsmReadDr5 ENDP
|
||||
|
@@ -34,16 +34,16 @@ InternalAssertJumpBuffer PROTO C
|
||||
;------------------------------------------------------------------------------
|
||||
SetJump PROC
|
||||
push [esp + 4]
|
||||
call InternalAssertJumpBuffer
|
||||
pop ecx
|
||||
call InternalAssertJumpBuffer ; To validate JumpBuffer
|
||||
pop ecx
|
||||
pop ecx ; ecx <- return address
|
||||
mov edx, [esp]
|
||||
mov [edx], ebx
|
||||
mov [edx + 4], esi
|
||||
mov [edx + 8], edi
|
||||
mov [edx + 12], ebp
|
||||
mov [edx + 16], esp
|
||||
mov [edx + 20], ecx
|
||||
mov [edx + 20], ecx ; eip value to restore in LongJump
|
||||
xor eax, eax
|
||||
jmp ecx
|
||||
SetJump ENDP
|
||||
|
@@ -33,8 +33,8 @@
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
InternalMathSwapBytes64 PROC
|
||||
mov eax, [esp + 8]
|
||||
mov edx, [esp + 4]
|
||||
mov eax, [esp + 8] ; eax <- upper 32 bits
|
||||
mov edx, [esp + 4] ; edx <- lower 32 bits
|
||||
bswap eax
|
||||
bswap edx
|
||||
ret
|
||||
|
@@ -75,6 +75,11 @@ SavedGdt LABEL FWORD
|
||||
; by user code. It will be shadowed to somewhere in memory below 1MB.
|
||||
;------------------------------------------------------------------------------
|
||||
_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 cs
|
||||
DB 66h
|
||||
@@ -104,6 +109,11 @@ _ThunkAttr DD ?
|
||||
mov eax, ss
|
||||
DB 67h
|
||||
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 ebx, (IA32_REGS ptr [esi - sizeof (IA32_REGS)])._EIP
|
||||
shl ax, 4 ; shl eax, 4
|
||||
@@ -167,7 +177,7 @@ _ToUserCode PROC
|
||||
pop fs
|
||||
pop gs
|
||||
popf ; popfd
|
||||
DB 66h
|
||||
DB 66h ; Use 32-bit addressing for "retf" below
|
||||
retf ; transfer control to user code
|
||||
_ToUserCode ENDP
|
||||
|
||||
@@ -197,7 +207,7 @@ GdtEnd LABEL QWORD
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
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
|
||||
mov edi, (IA32_REGS ptr [esi])._ESP
|
||||
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
|
||||
pop ecx ; ecx <- selector for data segments
|
||||
lgdt fword ptr [edx + (_16Gdtr - SavedCr0)]
|
||||
pushfd
|
||||
pushfd ; Save df/if indeed
|
||||
call fword ptr [edx + (_EntryPoint - SavedCr0)]
|
||||
popfd
|
||||
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
|
||||
InternalAsmThunk16 ENDP
|
||||
|
||||
|
@@ -34,6 +34,13 @@
|
||||
;------------------------------------------------------------------------------
|
||||
AsmWriteDr4 PROC
|
||||
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
|
||||
ret
|
||||
AsmWriteDr4 ENDP
|
||||
|
@@ -34,6 +34,13 @@
|
||||
;------------------------------------------------------------------------------
|
||||
AsmWriteDr5 PROC
|
||||
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
|
||||
ret
|
||||
AsmWriteDr5 ENDP
|
||||
|
Reference in New Issue
Block a user