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 #include <EfiBind.h>
     22 
     23     .686p:
     24 
     25 .globl ASM_PFX(mCode16Size)
     26 
     27 .data
     28 mCode16Size:    .long   _TEXT16SIZE
     29 
     30 .data
     31 
     32 NullSegSel:     .quad   0
     33 _16BitCsSel:
     34                 .word   -1
     35                 .word   0
     36                 .byte   0
     37                 .byte   0x9b
     38                 .byte   0x8f            # 16-bit segment
     39                 .byte   0
     40 _16BitSsSel:
     41                 .word   -1
     42                 .word   0
     43                 .byte   0
     44                 .byte   0x93
     45                 .byte   0x8f           # 16-bit segment
     46                 .byte   0
     47 
     48 _16Gdtr:
     49                 .word      _16Gdtr - NullSegSel - 1
     50                 .long      NullSegSel
     51 
     52 
     53 .text
     54 
     55 
     56 ASM_PFX(Thunk16):
     57     push   %ebp
     58     push   %ebx
     59     push   %esi
     60     push   %edi
     61     push   %ds
     62     push   %es
     63     push   %fs
     64     push   %gs
     65     mov    0x24(%esp),%esi
     66     movzwl 0x32(%esi),%edx
     67     mov    0xc(%esi),%edi
     68     add    $0xffffffb0,%edi
     69     push   %edi                       #; save stack offset
     70     imul   $0x10,%edx,%eax            #; eax <- edx*16
     71     add    %eax,%edi                  #; edi <- linear address of 16-bit stack
     72     push   $0xd
     73     pop    %ecx
     74     rep movsl %ds:(%esi),%es:(%edi)   #; copy context to 16-bit stack
     75     #; copy eflags to stack frame
     76     mov    -12(%esi), %eax
     77     mov    %eax, -72(%edi)
     78     pop    %ebx                       #; ebx <- 16-bit stack offset
     79     mov    $L_Lable1,%eax
     80     stos   %eax,%es:(%edi)
     81     movl   %cs,%eax
     82     stos   %ax,%es:(%edi)
     83     mov    0x28(%esp),%eax
     84     stos   %ax,%es:(%edi)
     85     mov    %esp,%eax
     86     stos   %eax,%es:(%edi)
     87     movl   %ss,%eax
     88     stos   %ax,%es:(%edi)
     89     sgdtl  (%edi)
     90     sidtl  0x24(%esp)
     91     mov    %cr0,%esi
     92     mov    %esi,0x6(%edi)             #; save CR0
     93     and    $0x7ffffffe,%esi           #; esi <- CR0 to set
     94     mov    %cr4,%eax
     95     mov    %eax,0xa(%edi)             #; save CR4
     96     and    $0xcf,%al                  #; clear PAE & PSE
     97     mov    %edx,%edi                  #; edi <- 16-bit stack segment
     98     mov    0x2c(%esp),%edx
     99     shl    $0x10,%edx
    100     push   %edx
    101     pop    %edx
    102     mov    $(_16BitSsSel - NullSegSel),%dx
    103     lgdtl  _16Gdtr                    #bugbug mismatch.
    104     .byte  0xea
    105     .long  L_16Bit                    #bugbug mismatch.
    106     .word  _16BitCsSel - NullSegSel
    107 L_16Bit:
    108     .byte  0x66
    109     movw   %dx,%ss
    110     mov    %esi,%cr0
    111     mov    %eax,%cr4
    112     .byte  0x67
    113     .byte  0xff
    114     .byte  0x6c
    115     .byte  0x24
    116     .byte  0xfc
    117 
    118 L_Lable1:
    119     xor    %eax,%eax
    120     movw   %ss,%ax
    121     shl    $0x4,%eax
    122     add    %esp,%eax
    123     lss    0x3c(%esp),%esp
    124     lidtl  0x24(%esp)
    125     pop    %gs
    126     pop    %fs
    127     pop    %es
    128     pop    %ds
    129     pop    %edi
    130     pop    %esi
    131     pop    %ebx
    132     pop    %ebp
    133     ret
    134 
    135 .code16
    136 _Code16Addr:
    137 ASM_PFX(RealMode):
    138     movw    %di, %ss                    # set up stack
    139     movl    %ebx, %esp
    140     lidt    %cs:_16Idtr - _Code16Addr  #lidt    fword ptr cs:[_16Idtr - _Code16Addr]
    141     .byte   0x66
    142     popaw
    143     popw    %ds
    144     popw    %es
    145     popw    %fs
    146     popw    %gs
    147     sub     60, %esp
    148     popfw
    149     testw   $1, 74(%esp)                #(_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
    150 
    151     jz      1f
    152     pushf                               # push Flags when it's INT#
    153 1:
    154     pushw   %cs
    155 #    push    @FarCallRet - _Code16Addr
    156     .byte   0x68                        # push /iw
    157     .word   FarCallRet - _Code16Addr
    158     jz      2f
    159     ljmp    *66(%esp)                   #[esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
    160 2:
    161     ljmp    *64(%esp)                   #[esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
    162 FarCallRet:
    163     add     60, %esp
    164     pushfl
    165     pushw   %gs
    166     pushw   %fs
    167     pushw   %es
    168     pushw   %ds
    169     pushal
    170     cli
    171     .byte   0x66                        # sizeof (IA32_REGS) = 13 * 4 = 52
    172     lgdt    66(%esp)                    #lgdt    (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr
    173     mov     76(%esp), %eax
    174     movl    %eax, %cr4
    175     mov     72(%esp), %eax
    176     movl    %eax, %cr0                   # restore CR0
    177     ljmpl   *52(%esp)
    178 #RealMode ENDP
    179 
    180 .text
    181 _16Idtr:
    182     .word 0x3ff                         #_16Idtr     FWORD   (1 SHL 10) - 1
    183     .byte 0x00
    184 
    185 _TEXT16END:
    186 
    187 _TEXT16SIZE = _TEXT16END - _Code16Addr
    188 
    189 
    190