Home | History | Annotate | Download | only in X64
      1 ;*****************************************************************************
      2 ;*
      3 ;*   Copyright (c) 2006 - 2010, 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 EXTERNDEF   mCode16Size:QWORD
     23 
     24     .const
     25 
     26 mCode16Size     DQ      _Code16End - _Code16Addr
     27 
     28     .data
     29 
     30 NullSegSel      DQ      0
     31 _16CsSegSel     LABEL   QWORD
     32                 DW      -1
     33                 DW      0
     34                 DB      0
     35                 DB      9bh
     36                 DB      8fh             ; 16-bit segment
     37                 DB      0
     38 _16DsSegSel     LABEL   QWORD
     39                 DW      -1
     40                 DW      0
     41                 DB      0
     42                 DB      93h
     43                 DB      8fh             ; 16-bit segment
     44                 DB      0
     45 
     46 _16Gdtr         LABEL   FWORD
     47                 DW      $ - offset NullSegSel - 1
     48                 DQ      offset NullSegSel
     49 
     50     .code
     51 
     52 STACK_PARAM_SIZE  EQU  16
     53 
     54 IA32_REGS   STRUC   4t
     55 _EDI        DD      ?
     56 _ESI        DD      ?
     57 _EBP        DD      ?
     58 _ESP        DD      ?
     59 _EBX        DD      ?
     60 _EDX        DD      ?
     61 _ECX        DD      ?
     62 _EAX        DD      ?
     63 _DS         DW      ?
     64 _ES         DW      ?
     65 _FS         DW      ?
     66 _GS         DW      ?
     67 _RFLAGS     DQ      ?
     68 _EIP        DD      ?
     69 _CS         DW      ?
     70 _SS         DW      ?
     71 IA32_REGS   ENDS
     72 
     73 _STK16      STRUC   1t
     74 RetEip      DD      ?
     75 RetCs       DW      ?
     76 ThunkFlags  DW      ?
     77 SavedGdtr   FWORD   ?
     78 Resvd1      DW      ?
     79 SavedCr0    DD      ?
     80 SavedCr4    DD      ?
     81 _STK16      ENDS
     82 
     83 _Thunk16    PROC    USES    rbp rbx rsi rdi r12 r13 r14 r15
     84 
     85     push    fs
     86     push    gs
     87 
     88     mov     r12d, ds
     89     mov     r13d, es
     90     mov     r14d, ss
     91     mov     r15, rsp
     92     mov     rsi, rcx
     93     movzx   r10, (IA32_REGS ptr [rsi])._SS
     94     xor     rdi, rdi
     95     mov     edi, (IA32_REGS ptr [rsi])._ESP
     96     add     rdi, - sizeof (IA32_REGS) - sizeof (_STK16)
     97     push    rdi
     98     imul    rax, r10, 16
     99     add     rdi, rax
    100     push    sizeof (IA32_REGS) / 4
    101     pop     rcx
    102     rep     movsd
    103 
    104     ; copy eflags to stack frame
    105     mov     rax, (IA32_REGS ptr [rsi - sizeof(IA32_REGS)])._RFLAGS
    106     mov     [rdi - sizeof(IA32_REGS) - STACK_PARAM_SIZE - 8], rax
    107 
    108     pop     rbx                         ; rbx <- 16-bit stack offset
    109     lea     eax, @F                     ; return offset
    110     stosd
    111     mov     eax, cs                     ; return segment
    112     stosw
    113     mov     eax, edx                    ; THUNK Flags
    114     stosw
    115     sgdt    fword ptr [rsp + 58h]       ; save GDTR
    116     mov     rax, [rsp + 58h]
    117     stosq
    118     mov     rax, cr0                    ; save CR0
    119     mov     esi, eax                    ; esi <- CR0 to set
    120     stosd
    121     mov     rax, cr4                    ; save CR4
    122     stosd
    123     sidt    fword ptr [rsp + 58h]       ; save IDTR
    124     and     esi, 07ffffffeh             ; clear PE & PG bits
    125     mov     rdi, r10                    ; rdi <- 16-bit stack segment
    126 
    127     shl     r8, 16
    128     push    r8                          ; far jmp address
    129     lea     eax, @16Bit
    130     push    rax
    131     mov     word ptr [rsp + 4], 8
    132     lgdt    _16Gdtr
    133     retf
    134 @16Bit:
    135     DB      66h
    136     mov     ecx, 0c0000080h
    137     mov     cr0, rsi                    ; disable PE & PG
    138     rdmsr
    139     and     ah, NOT 1
    140     wrmsr                               ; clear LME bit
    141     mov     rax, cr4
    142     and     al, NOT 30h                 ; clear PAE & PSE
    143     mov     cr4, rax
    144     retf
    145 @@:
    146     xor     rax, rax
    147     mov     ax, ss
    148     shl     eax, 4
    149     add     eax, esp                    ; rax <- address of 16-bit stack
    150     mov     rsp, r15
    151     lidt    fword ptr [rsp + 58h]       ; restore IDTR
    152     mov     ds, r12d
    153     mov     es, r13d
    154     mov     ss, r14d
    155     pop     gs
    156     pop     fs
    157     ret
    158 _Thunk16    ENDP
    159 
    160     ALIGN   10h
    161 
    162 _Code16Addr PROC
    163 _Code16Addr ENDP
    164 
    165 RealMode    PROC
    166     mov     ss, edi
    167     mov     sp, bx                      ; set up 16-bit stack
    168     DB      2eh, 0fh, 1, 1eh
    169     DW      _16Idtr - _Code16Addr       ; lidt _16Idtr
    170     DB      66h, 61h                    ; popad
    171     DB      1fh                         ; pop ds
    172     DB      7                           ; pop es
    173     pop     fs
    174     pop     gs
    175     sub     esp, (sizeof(IA32_REGS) - 16) + STACK_PARAM_SIZE + 8
    176 
    177     DB      66h, 9Dh                    ; popfd
    178     add     esp, 4                      ; skip high part of RFLAGS
    179     DB      67h, 0f7h, 44h, 24h         ; test    (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
    180     DB      (STACK_PARAM_SIZE + sizeof(IA32_REGS) + 6)
    181     DB      1, 0
    182     jz      @F
    183     pushfq                              ; pushf, actually, when it's INT#
    184 @@:
    185     DB      0eh                         ; push cs
    186     DB      68h                         ; push /iw
    187     DW      @FarCallRet - _Code16Addr
    188     jz      @F
    189     DB      66h
    190     jmp     fword ptr [esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
    191 @@:
    192     DB      66h
    193     jmp     fword ptr [esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
    194 @FarCallRet:
    195     add     esp, (sizeof(IA32_REGS) - 16) + STACK_PARAM_SIZE + 8
    196     DB      66h
    197     push    0                           ; push a dword of zero
    198     pushf                               ; pushfd, actually
    199     push    gs
    200     push    fs
    201     DB      6                           ; push es
    202     DB      1eh                         ; push ds
    203     DB      66h, 60h                    ; pushad
    204     cli
    205 
    206     DB      66h
    207     lgdt    (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedGdtr
    208     DB      66h
    209     mov     eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr4
    210     mov     cr4, rax
    211     DB      66h
    212     mov     ecx, 0c0000080h
    213     rdmsr
    214     or      ah, 1
    215     wrmsr                               ; set LME
    216     DB      66h
    217     mov     eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr0
    218     mov     cr0, rax
    219     DB      66h
    220     jmp     fword ptr (_STK16 ptr [esp + sizeof(IA32_REGS)]).RetEip
    221 
    222 RealMode    ENDP
    223 
    224 _16Idtr     FWORD   (1 SHL 10) - 1
    225 
    226 _Code16End:
    227 
    228     END
    229