diff --git a/MdePkg/Library/BaseLib/Ia32/Thunk16.nasm b/MdePkg/Library/BaseLib/Ia32/Thunk16.nasm index c00e3ab078..a1093e0107 100644 --- a/MdePkg/Library/BaseLib/Ia32/Thunk16.nasm +++ b/MdePkg/Library/BaseLib/Ia32/Thunk16.nasm @@ -82,23 +82,24 @@ _BackFromUserCode: ; in IA32_REGS structure. This facilitates wrapper function to extract them ; into that structure. ; +BITS 16 push ss push cs - DB 66h - call .Base ; push eip +o32 call dword .Base ; push eip .Base: - pushfw ; pushfd actually + pushfd cli ; disable interrupts push gs push fs push es push ds - pushaw ; pushad actually + pushad DB 66h, 0bah ; mov edx, imm32 .ThunkAttr: dd 0 test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 jz .1 - mov eax, 15cd2401h ; mov ax, 2401h & int 15h + mov ax, 2401h + int 15h cli ; disable interrupts jnc .2 .1: @@ -108,24 +109,17 @@ _BackFromUserCode: or al, 2 out 92h, al ; deactivate A20M# .2: - xor ax, ax ; xor eax, eax - mov eax, ss ; mov ax, ss - DB 67h - lea bp, [esp + IA32_REGS.size] - ; - ; 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 [esi - IA32_REGS.size + IA32_REGS._ESP], bp - mov ebx, [esi - IA32_REGS.size + IA32_REGS._EIP] - shl ax, 4 ; shl eax, 4 - add bp, ax ; add ebp, eax + xor eax, eax + mov ax, ss + lea ebp, [esp + IA32_REGS.size] + mov [bp - IA32_REGS.size + IA32_REGS._ESP], ebp + mov bx, [bp - IA32_REGS.size + IA32_REGS._EIP] + shl eax, 4 ; shl eax, 4 + add ebp, eax ; add ebp, eax DB 66h, 0b8h ; mov eax, imm32 .SavedCr4: DD 0 mov cr4, eax - DB 66h - lgdt [cs:edi + (SavedGdt - .Base)] +o32 lgdt [cs:bx + (SavedGdt - .Base)] DB 66h, 0b8h ; mov eax, imm32 .SavedCr0: DD 0 mov cr0, eax @@ -134,8 +128,7 @@ _BackFromUserCode: mov ss, eax DB 66h, 0bch ; mov esp, imm32 .SavedEsp DD 0 - DB 66h - retf ; return to protected mode +o32 retf ; return to protected mode _EntryPoint: DD _ToUserCode - ASM_PFX(m16Start) @@ -153,45 +146,34 @@ _16GdtrBase: ; It will be shadowed to somewhere in memory below 1MB. ;------------------------------------------------------------------------------ _ToUserCode: - mov edx, ss - mov ss, ecx ; set new segment selectors - mov ds, ecx - mov es, ecx - mov fs, ecx - mov gs, ecx +BITS 16 + mov dx, ss + mov ss, cx ; set new segment selectors + mov ds, cx + mov es, cx + mov fs, cx + mov gs, cx mov cr0, eax ; real mode starts at next instruction ; which (per SDM) *must* be a far JMP. DB 0eah .RealAddr: DW 0, 0 mov cr4, ebp - mov ss, esi ; set up 16-bit stack segment - xchg sp, bx ; set up 16-bit stack pointer + mov ss, si ; set up 16-bit stack segment + xchg esp, ebx ; set up 16-bit stack pointer + mov bp, [esp + IA32_REGS.size] + mov [cs:bp + (_BackFromUserCode.SavedSs - _BackFromUserCode)], dx + mov [cs:bp + (_BackFromUserCode.SavedEsp - _BackFromUserCode)], ebx + lidt [cs:bp + (_16Idtr - _BackFromUserCode)] -; mov bp, [esp + sizeof(IA32_REGS) - DB 67h - mov ebp, [esp + IA32_REGS.size] ; BackFromUserCode address from stack - -; mov cs:[bp + (_BackFromUserCode.SavedSs - _BackFromUserCode)], dx - mov [cs:esi + (_BackFromUserCode.SavedSs - _BackFromUserCode)], edx - -; mov cs:[bp + (_BackFromUserCode.SavedEsp - _BackFromUserCode)], ebx - DB 2eh, 66h, 89h, 9eh - DW _BackFromUserCode.SavedEsp - _BackFromUserCode - -; lidt cs:[bp + (_16Idtr - _BackFromUserCode)] - DB 2eh, 66h, 0fh, 01h, 9eh - DW _16Idtr - _BackFromUserCode - - popaw ; popad actually + popad pop ds pop es pop fs pop gs - popfw ; popfd + popfd - DB 66h ; Use 32-bit addressing for "retf" below - retf ; transfer control to user code +o32 retf ; transfer control to user code ALIGN 16 _NullSegDesc DQ 0 @@ -221,6 +203,7 @@ GdtEnd: ;------------------------------------------------------------------------------ global ASM_PFX(InternalAsmThunk16) ASM_PFX(InternalAsmThunk16): +BITS 32 push ebp push ebx push esi diff --git a/MdePkg/Library/BaseLib/X64/Thunk16.nasm b/MdePkg/Library/BaseLib/X64/Thunk16.nasm index cabe9d94d1..5fa705998e 100644 --- a/MdePkg/Library/BaseLib/X64/Thunk16.nasm +++ b/MdePkg/Library/BaseLib/X64/Thunk16.nasm @@ -80,28 +80,25 @@ _BackFromUserCode: ; 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 0eh ; push cs - DB 66h - call .Base ; push eip +BITS 16 + push ss + push cs +o32 call dword .Base ; push eip .Base: - DB 66h - push 0 ; reserved high order 32 bits of EFlags - pushfw ; pushfd actually + push dword 0 ; reserved high order 32 bits of EFlags + pushfd cli ; disable interrupts push gs push fs - DB 6 ; push es - DB 1eh ; push ds - DB 66h, 60h ; pushad + push es + push ds + pushad DB 66h, 0bah ; mov edx, imm32 -.ThunkAttr: dd 0 +.ThunkAttr: dd 0 test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 jz .1 - mov eax, 15cd2401h ; mov ax, 2401h & int 15h + mov ax, 2401h + int 15h cli ; disable interrupts jnc .2 .1: @@ -111,43 +108,34 @@ _BackFromUserCode: or al, 2 out 92h, al ; deactivate A20M# .2: - xor ax, ax ; xor eax, eax - mov eax, ss ; mov ax, ss - lea bp, [esp + IA32_REGS.size] - ; - ; rsi in the following 2 instructions is indeed bp in 16-bit code - ; - mov [rsi - IA32_REGS.size + IA32_REGS._ESP], bp - DB 66h - mov ebx, [rsi - IA32_REGS.size + IA32_REGS._EIP] - shl ax, 4 ; shl eax, 4 - add bp, ax ; add ebp, eax - mov ax, cs - shl ax, 4 - lea ax, [eax + ebx + (.64BitCode - .Base)] - DB 66h, 2eh, 89h, 87h ; mov cs:[bx + (.64Eip - .Base)], eax - DW .64Eip - .Base + xor eax, eax + mov ax, ss + lea ebp, [esp + IA32_REGS.size] + mov [bp - IA32_REGS.size + IA32_REGS._ESP], ebp + mov ebx, [bp - IA32_REGS.size + IA32_REGS._EIP] + shl eax, 4 ; shl eax, 4 + add ebp, eax ; add ebp, eax + mov eax, cs + shl eax, 4 + lea eax, [eax + ebx + (.64BitCode - .Base)] + mov [cs:bx + (.64Eip - .Base)], eax DB 66h, 0b8h ; mov eax, imm32 .SavedCr4: DD 0 - mov cr4, rax - ; - ; rdi in the instruction below is indeed bx in 16-bit code - ; - DB 66h, 2eh ; 2eh is "cs:" segment override - lgdt [rdi + (SavedGdt - .Base)] - DB 66h + mov cr4, eax +o32 lgdt [cs:bx + (SavedGdt - .Base)] mov ecx, 0c0000080h rdmsr or ah, 1 wrmsr DB 66h, 0b8h ; mov eax, imm32 .SavedCr0: DD 0 - mov cr0, rax + mov cr0, eax DB 66h, 0eah ; jmp far cs:.64Bit .64Eip: DD 0 .SavedCs: DW 0 .64BitCode: - db 090h +BITS 64 + nop db 048h, 0bch ; mov rsp, imm64 .SavedSp: DQ 0 ; restore stack nop @@ -169,40 +157,40 @@ _16Idtr: ; It will be shadowed to somewhere in memory below 1MB. ;------------------------------------------------------------------------------ _ToUserCode: - mov ss, edx ; set new segment selectors - mov ds, edx - mov es, edx - mov fs, edx - mov gs, edx - DB 66h +BITS 16 + mov ss, dx ; set new segment selectors + mov ds, dx + mov es, dx + mov fs, dx + mov gs, dx mov ecx, 0c0000080h - mov cr0, rax ; real mode starts at next instruction + mov cr0, eax ; real mode starts at next instruction rdmsr and ah, ~1 wrmsr - mov cr4, rbp - mov ss, esi ; set up 16-bit stack segment - mov sp, bx ; set up 16-bit stack pointer - DB 66h ; make the following call 32-bit - call .Base ; push eip + mov cr4, ebp + mov ss, si ; set up 16-bit stack segment + mov esp, ebx ; set up 16-bit stack pointer + call dword .Base ; push eip .Base: - pop bp ; ebp <- address of .Base - push qword [esp + IA32_REGS.size + 2] - lea eax, [rsi + (.RealMode - .Base)] ; rsi is "bp" in 16-bit code - push rax + pop ebp ; ebp <- address of .Base + push word [dword esp + IA32_REGS.size + 2] + lea ax, [bp + (.RealMode - .Base)] + push ax retf ; execution begins at next instruction .RealMode: - DB 66h, 2eh ; CS and operand size override - lidt [rsi + (_16Idtr - .Base)] - DB 66h, 61h ; popad - DB 1fh ; pop ds - DB 07h ; pop es + +o32 lidt [cs:bp + (_16Idtr - .Base)] + + popad + pop ds + pop es pop fs pop gs - popfw ; popfd - lea sp, [esp + 4] ; skip high order 32 bits of EFlags - DB 66h ; make the following retf 32-bit - retf ; transfer control to user code + popfd + lea esp, [esp + 4] ; skip high order 32 bits of EFlags + +o32 retf ; transfer control to user code ALIGN 8 @@ -245,6 +233,7 @@ GDT_SIZE equ $ - _NullSeg ;------------------------------------------------------------------------------ global ASM_PFX(InternalAsmThunk16) ASM_PFX(InternalAsmThunk16): +BITS 64 push rbp push rbx push rsi @@ -300,7 +289,7 @@ ASM_PFX(InternalAsmThunk16): mov [rcx], ebp ; save CR4 in _BackFromUserCode.SavedCr4 and ebp, ~30h ; clear PAE, PSE bits mov esi, r8d ; esi <- 16-bit stack segment - DB 6ah, DATA32 ; push DATA32 + push DATA32 pop rdx ; rdx <- 32-bit data segment selector lgdt [rcx + (_16Gdtr - _BackFromUserCode.SavedCr4)] mov ss, edx