]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdePkg BaseLib NASM Thunk16: Use bits 16 for 16-bit code
authorJordan Justen <jordan.l.justen@intel.com>
Mon, 1 Sep 2014 17:23:51 +0000 (17:23 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 1 Sep 2014 17:23:51 +0000 (17:23 +0000)
By using 'bits 16', we can write code for 16-bit use the actual
assembly syntax rather than 'DB' and sometimes writing code with
seemingly incorrect operands because we know it will run correctly
when the processor is running in 16-bit mode.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16023 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Library/BaseLib/Ia32/Thunk16.nasm
MdePkg/Library/BaseLib/X64/Thunk16.nasm

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