Home | History | Annotate | Download | only in Ia32
      1 ;*****************************************************************************
      2 ;*
      3 ;*   Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
      4 ;*   This program and the accompanying materials                          
      5 ;*   are licensed and made available under the terms and conditions of the BSD License         
      6 ;*   which accompanies this distribution.  The full text of the license may be found at        
      7 ;*   http://opensource.org/licenses/bsd-license.php                                            
      8 ;*                                                                                             
      9 ;*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
     10 ;*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
     11 ;*   
     12 ;*   Module Name:
     13 ;*
     14 ;*    Thunk.asm
     15 ;*  
     16 ;*   Abstract:
     17 ;*  
     18 ;*    Real mode thunk
     19 ;*  
     20 ;*****************************************************************************
     21 
     22     .686p
     23 
     24 EXTERNDEF   C   mCode16Size:DWORD
     25 
     26 CONST   SEGMENT FLAT    "DATA"  READONLY
     27 
     28 mCode16Size     DD      _TEXT16SIZE
     29 
     30 CONST   ENDS
     31 
     32 _DATA   SEGMENT FLAT    "DATA"
     33 
     34 NullSegSel      DQ      0
     35 _16BitCsSel     LABEL   QWORD
     36                 DW      -1
     37                 DW      0
     38                 DB      0
     39                 DB      9bh
     40                 DB      8fh             ; 16-bit segment
     41                 DB      0
     42 _16BitSsSel     LABEL   QWORD
     43                 DW      -1
     44                 DW      0
     45                 DB      0
     46                 DB      93h
     47                 DB      8fh            ; 16-bit segment
     48                 DB      0
     49 
     50 _16Gdtr         LABEL   FWORD
     51                 DW      $ - offset NullSegSel - 1
     52                 DD      offset NullSegSel
     53 
     54 _DATA   ENDS
     55 
     56 _TEXT   SEGMENT FLAT    "CODE"  PARA
     57 
     58 STACK_PARAM_SIZE  EQU  16
     59 
     60 IA32_REGS   STRUC   4t
     61 _EDI        DD      ?
     62 _ESI        DD      ?
     63 _EBP        DD      ?
     64 _ESP        DD      ?
     65 _EBX        DD      ?
     66 _EDX        DD      ?
     67 _ECX        DD      ?
     68 _EAX        DD      ?
     69 _DS         DW      ?
     70 _ES         DW      ?
     71 _FS         DW      ?
     72 _GS         DW      ?
     73 _EFLAGS     DD      ?
     74 _EIP        DD      ?
     75 _CS         DW      ?
     76 _SS         DW      ?
     77 IA32_REGS   ENDS
     78 
     79 _STK16      STRUC   1t
     80 RetEip      DD      ?
     81 RetCs       DW      ?
     82 ThunkFlags  DW      ?
     83 SavedEsp    DD      ?
     84 SavedSs     DW      ?
     85 SavedGdtr   FWORD   ?
     86 SavedCr0    DD      ?
     87 SavedCr4    DD      ?
     88 _STK16      ENDS
     89 
     90     ASSUME  ds:_DATA
     91 
     92 __Thunk16   PROC    USES    ebp ebx esi edi ds  es  fs  gs
     93     ASSUME  esi:PTR IA32_REGS
     94     mov     esi, [esp + 36]
     95     movzx   edx, [esi]._SS
     96     mov     edi, [esi]._ESP
     97     add     edi, - sizeof (_STK16) - sizeof (IA32_REGS)
     98     push    edi                         ; save stack offset
     99     imul    eax, edx, 16                ; eax <- edx*16
    100     add     edi, eax                    ; edi <- linear address of 16-bit stack
    101     push    sizeof (IA32_REGS) / 4
    102     pop     ecx
    103     rep     movsd                       ; copy context to 16-bit stack
    104 
    105     ; copy eflags to stack frame
    106     mov     eax, [esi - sizeof(IA32_REGS)]._EFLAGS
    107     mov     [edi - sizeof(IA32_REGS) - STACK_PARAM_SIZE - 4], eax
    108 
    109     pop     ebx                         ; ebx <- 16-bit stack offset
    110     mov     eax, offset @F              ; return offset
    111     stosd
    112     mov     eax, cs                     ; return segment
    113     stosw
    114     mov     eax, [esp + 40]             ; THUNK flags
    115     stosw
    116     mov     eax, esp
    117     stosd                               ; save esp
    118     mov     eax, ss                     ; save ss
    119     stosw
    120     sgdt    fword ptr [edi]             ; save GDTR
    121     sidt    fword ptr [esp + 36]        ; save IDTR
    122     mov     esi, cr0
    123     mov     [edi + 6], esi              ; save CR0
    124     and     esi, NOT 80000001h          ; esi <- CR0 to set
    125     mov     eax, cr4
    126     mov     [edi + 10], eax             ; save CR4
    127     and     al, NOT 30h                 ; clear PAE & PSE
    128     mov     edi, edx                    ; edi <- 16-bit stack segment
    129     mov     edx, [esp + 44]
    130     shl     edx, 16
    131     push    edx
    132     pop     edx
    133     mov     dx, _16BitSsSel - NullSegSel
    134     lgdt    _16Gdtr                     ; load 16-bit GDTR
    135     DB      0eah
    136     DD      offset @16Bit
    137     DW      _16BitCsSel - NullSegSel    ; jmp far 8:@16Bit
    138 @16Bit:
    139     mov     ss, dx
    140     mov     cr0, esi                    ; disable protected mode
    141     mov     cr4, eax                    ; disable PAE & PSE
    142     db      67h, 0FFh, 06Ch, 024h, 0FCh ; jmp     dword ptr [esp-4]
    143 @@:
    144     xor     eax, eax
    145     mov     ax, ss
    146     shl     eax, 4
    147     add     eax, esp                    ; eax <- address of 16-bit stack
    148     lss     esp, fword ptr (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedEsp
    149     lidt    fword ptr [esp + 36]        ; restore IDTR
    150     ret
    151 __Thunk16   ENDP
    152 
    153 _TEXT   ENDS
    154 
    155 _TEXT16 SEGMENT USE16   "CODE"  PARA
    156 
    157 _Code16Addr PROC    C
    158 _Code16Addr ENDP
    159 
    160 RealMode    PROC
    161     mov     ss, di                      ; set up stack
    162     mov     esp, ebx
    163     lidt    fword ptr cs:[_16Idtr - _Code16Addr]
    164     popad
    165     pop     ds
    166     pop     es
    167     pop     fs
    168     pop     gs
    169     sub     esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4
    170     popfd
    171     test    (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
    172     jz      @F
    173     pushf                               ; push Flags when it's INT#
    174 @@:
    175     push    cs
    176 ;    push    @FarCallRet - _Code16Addr
    177     DB      68h                         ; push /iw
    178     DW      @FarCallRet - _Code16Addr
    179     jz      @F
    180     jmp     fword ptr [esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
    181 @@:
    182     jmp     fword ptr [esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
    183 @FarCallRet:
    184     add     esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4
    185     pushfd
    186     push    gs
    187     push    fs
    188     push    es
    189     push    ds
    190     pushad
    191     cli
    192     DB      66h
    193     lgdt    (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr
    194     mov     eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr4
    195     mov     cr4, eax
    196     mov     eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr0
    197     mov     cr0, eax                    ; restore CR0
    198     jmp     fword ptr (_STK16 ptr [esp + sizeof (IA32_REGS)]).RetEip
    199 RealMode    ENDP
    200 
    201 _16Idtr     FWORD   (1 SHL 10) - 1
    202 
    203 _TEXT16END:
    204 
    205 _TEXT16SIZE = _TEXT16END - _Code16Addr
    206 
    207 _TEXT16 ENDS
    208 
    209     END
    210