Home | History | Annotate | Download | only in X64
      1 #*****************************************************************************
      2 #*
      3 #*   Copyright (c) 2008 - 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.S
     15 #*
     16 #*   Abstract:
     17 #*
     18 #*    Real mode thunk
     19 #*
     20 #*****************************************************************************
     21 #include <EfiBind.h>
     22 
     23 #ifndef __APPLE__
     24 
     25     .data
     26 
     27 .globl ASM_PFX(mCode16Size)
     28 
     29 .data
     30 mCode16Size:    .long   _Code16End - _Code16Addr
     31 
     32 
     33 NullSegSel:     .quad   0
     34 _16CsSegSel:
     35                 .word   -1
     36                 .word   0
     37                 .byte   0
     38                 .byte   0x9b
     39                 .byte   0x8f            #16-bit segment
     40                 .byte   0
     41 _16DsSegSel:
     42                 .word   -1
     43                 .word   0
     44                 .byte   0
     45                 .byte   0x93
     46                 .byte   0x8f           #16-bit segment
     47                 .byte   0
     48 
     49 _16Gdtr:
     50                 .word      _16Gdtr - NullSegSel - 1
     51                 .long      NullSegSel
     52     .code:
     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 ASM_PFX(Thunk16):
     84       push   %rbp
     85       push   %rbx
     86       push   %rsi
     87       push   %rdi
     88       push   %r12
     89       push   %r13
     90       push   %r14
     91       push   %r15
     92       pushq  %fs
     93       pushq  %gs
     94       movl   %ds,%r12d
     95       movl   %es,%r13d
     96       movl   %ss,%r14d
     97       mov    %rsp,%r15
     98       mov    %rcx,%rsi
     99       movzwq 0x36(%rsi),%r10            #movzx   r10, (IA32_REGS ptr [rsi])._SS
    100       xor    %rdi,%rdi
    101       mov    0xc(%rsi),%edi             #mov     edi, (IA32_REGS ptr [rsi])._ESP
    102       add    $0xffffffffffffffb0,%rdi   #add     rdi, - sizeof (IA32_REGS) - sizeof (_STK16)
    103       push   %rdi
    104       imul   $0x10,%r10,%rax
    105       add    %rax,%rdi
    106       pushq  $0xe                       #push    sizeof (IA32_REGS) / 4
    107       pop    %rcx
    108       rep movsl %ds:(%rsi),%es:(%rdi)
    109       #; copy eflags to stack frame
    110       mov    -16(%rsi), %rax
    111       mov    %rax, -80(%rsi)
    112       pop    %rbx                       #rbx <- 16-bit stack offset
    113       lea    Label,%eax                 #42 <_Thunk16+0x42>
    114       stos   %eax,%es:(%rdi)
    115       movl   %cs,%eax                   #return segment
    116       stos   %ax,%es:(%rdi)
    117       mov    %edx,%eax                  #THUNK Flags
    118       stos   %ax,%es:(%rdi)
    119       sgdt  0x58(%rsp)                  #save GDTR
    120       mov    0x58(%rsp),%rax
    121       stos   %rax,%es:(%rdi)
    122       mov    %cr0,%rax                  #save CR0
    123       mov    %eax,%esi                  #esi <- CR0 to set
    124       stos   %eax,%es:(%rdi)
    125       mov    %cr4,%rax                  #save CR4
    126       stos   %eax,%es:(%rdi)
    127       sidt   0x58(%rsp)                 #save IDTR
    128       and    $0x7ffffffe,%esi           #clear PE & PG bits
    129       mov    %r10,%rdi                  #rdi <- 16-bit stack segment
    130       shl    $0x10,%r8
    131       push   %r8                        #far jmp address
    132       lea    Label_16Bit,%eax
    133       push   %rax
    134       movw   $0x8,0x4(%rsp)
    135       lgdt   _16Gdtr                    #bugbug: may not match.
    136       lret
    137 Label_16Bit:
    138       .byte  0x66
    139       movl   $0xc0000080,%ecx
    140       mov    %rsi,%cr0                  #disable PE & PG
    141       rdmsr
    142       and    $0xfe,%ah
    143       wrmsr                             #clear LME bit
    144       mov    %cr4,%rax
    145       and    $0xcf,%al                  #clear PAE & PSE
    146       mov    %rax,%cr4
    147       lret
    148 
    149 Label:
    150       xor    %rax,%rax
    151       movw   %ss,%ax
    152       shl    $0x4,%eax
    153       add    %esp,%eax
    154       mov    %r15,%rsp
    155       lidt   0x58(%rsp)
    156       movl   %r12d,%ds
    157       movl   %r13d,%es
    158       movl   %r14d,%ss
    159       popq   %gs
    160       popq   %fs
    161       pop    %r15
    162       pop    %r14
    163       pop    %r13
    164       pop    %r12
    165       pop    %rdi
    166       pop    %rsi
    167       pop    %rbx
    168       pop    %rbp
    169       retq
    170 
    171 
    172     .p2align 4
    173 
    174 _Code16Addr:
    175 ASM_PFX(RealMode):
    176     movl   %edi,%ss
    177     mov    %bx,%sp                     #set up 16-bit stack
    178    .byte   0x2e
    179    .byte   0x0f
    180    .byte   0x01
    181    .byte   0x1e
    182    .word   _16Idtr - _Code16Addr       #lidt _16Idtr
    183    .byte   0x66
    184    .byte   0x61                        #popad
    185    .byte   0x1f                        #pop ds
    186    .byte   0x07                        #pop es
    187     popq   %fs
    188     popq   %gs
    189     sub    64, %esp
    190     .byte  0x66, 0x9d                  #popfd
    191     add    $0x4,%esp                   #skip high part of RFLAGS
    192    .byte   0x67                        #; test    (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
    193    .byte   0xf7
    194    .byte   0x44
    195    .byte   0x24
    196    .byte   0x4e
    197    .byte   0x01
    198    .byte   0x00
    199     jz      1f
    200     pushfq                             #pushf, actually, when it's INT#
    201 1:
    202    .byte   0x0e                        #push cs
    203    .byte   0x68                        #push /iw
    204    .word   FarCallRet - _Code16Addr
    205     jz     2f
    206    .byte   0x66
    207     ljmp   *70(%esp)
    208 2:
    209    .byte   0x66
    210     ljmp   *68(%esp)
    211 FarCallRet:
    212     add    64, %esp
    213    .byte   0x66
    214     push   $0x00                       #push a dword of zero
    215    .byte   0x66
    216     pushf                              #pushfd, actually
    217     pushq  %gs
    218     pushq  %fs
    219    .byte   0x06                        #push %es
    220    .byte   0x1e                        #push %ds
    221    .byte   0x66
    222    .byte   0x60
    223     cli
    224    .byte   0x66                        #sizeof (IA32_REGS) = 13 * 4 = 52
    225     lgdt   64(%esp)                    #lgdt    (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr
    226    .byte   0x66
    227     mov    76(%esp), %eax
    228     mov    %rax, %cr4
    229    .byte   0x66
    230     mov    $0xc0000080, %ecx
    231     rdmsr
    232     orb    $1, %ah
    233     wrmsr
    234    .byte   0x66
    235     mov    72(%esp), %eax
    236     mov    %rax, %cr0                   #restore CR0
    237    .byte   0x66
    238     ljmpl  *52(%esp)
    239 
    240 _16Idtr:
    241    .word 0x3ff                          #FWORD   (1 SHL 10) - 1
    242    .byte 0x00
    243 
    244 #endif
    245