summaryrefslogtreecommitdiff
path: root/EdkCompatibilityPkg/Foundation/Library/Thunk16/Ia32/Thunk16.S
blob: cf7776a6a3a207bf4190566b739bd4396c97167f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#*****************************************************************************
#*
#*   Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
#*   This program and the accompanying materials                          
#*   are licensed and made available under the terms and conditions of the BSD License         
#*   which accompanies this distribution.  The full text of the license may be found at        
#*   http://opensource.org/licenses/bsd-license.php                                            
#*                                                                                             
#*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
#*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
#*   
#*   Module Name:
#*
#*    Thunk.asm
#*  
#*   Abstract:
#*  
#*    Real mode thunk
#*  
#*****************************************************************************
#include <EfiBind.h>

    .686p: 

.globl ASM_PFX(mCode16Size)

.data
mCode16Size:    .long   _TEXT16SIZE

.data

NullSegSel:     .quad   0
_16BitCsSel:    
                .word   -1
                .word   0
                .byte   0
                .byte   0x9b
                .byte   0x8f            # 16-bit segment
                .byte   0
_16BitSsSel:
                .word   -1
                .word   0
                .byte   0
                .byte   0x93
                .byte   0x8f           # 16-bit segment
                .byte   0

_16Gdtr:
                .word      _16Gdtr - NullSegSel - 1
                .long      NullSegSel


.text


ASM_PFX(Thunk16):
    push   %ebp
    push   %ebx
    push   %esi
    push   %edi
    push   %ds
    push   %es
    push   %fs
    push   %gs
    mov    0x24(%esp),%esi
    movzwl 0x32(%esi),%edx
    mov    0xc(%esi),%edi
    add    $0xffffffb0,%edi
    push   %edi                       #; save stack offset
    imul   $0x10,%edx,%eax            #; eax <- edx*16
    add    %eax,%edi                  #; edi <- linear address of 16-bit stack
    push   $0xd
    pop    %ecx
    rep movsl %ds:(%esi),%es:(%edi)   #; copy context to 16-bit stack
    #; copy eflags to stack frame
    mov    -12(%esi), %eax
    mov    %eax, -72(%edi) 
    pop    %ebx                       #; ebx <- 16-bit stack offset
    mov    $L_Lable1,%eax
    stos   %eax,%es:(%edi)
    movl   %cs,%eax
    stos   %ax,%es:(%edi)
    mov    0x28(%esp),%eax
    stos   %ax,%es:(%edi)
    mov    %esp,%eax
    stos   %eax,%es:(%edi)
    movl   %ss,%eax
    stos   %ax,%es:(%edi)
    sgdtl  (%edi)
    sidtl  0x24(%esp)
    mov    %cr0,%esi
    mov    %esi,0x6(%edi)             #; save CR0
    and    $0x7ffffffe,%esi           #; esi <- CR0 to set
    mov    %cr4,%eax
    mov    %eax,0xa(%edi)             #; save CR4
    and    $0xcf,%al                  #; clear PAE & PSE
    mov    %edx,%edi                  #; edi <- 16-bit stack segment
    mov    0x2c(%esp),%edx
    shl    $0x10,%edx
    push   %edx
    pop    %edx
    mov    $(_16BitSsSel - NullSegSel),%dx
    lgdtl  _16Gdtr                    #bugbug mismatch.
    .byte  0xea
    .long  L_16Bit                    #bugbug mismatch.
    .word  _16BitCsSel - NullSegSel
L_16Bit:   
    .byte  0x66 
    movw   %dx,%ss
    mov    %esi,%cr0
    mov    %eax,%cr4
    .byte  0x67
    .byte  0xff
    .byte  0x6c
    .byte  0x24
    .byte  0xfc
    
L_Lable1:
    xor    %eax,%eax
    movw   %ss,%ax
    shl    $0x4,%eax
    add    %esp,%eax
    lss    0x3c(%esp),%esp
    lidtl  0x24(%esp)
    pop    %gs
    pop    %fs
    pop    %es
    pop    %ds
    pop    %edi
    pop    %esi
    pop    %ebx
    pop    %ebp
    ret 

.code16
_Code16Addr:
ASM_PFX(RealMode):
    movw    %di, %ss                    # set up stack
    movl    %ebx, %esp
    lidt    %cs:_16Idtr - _Code16Addr  #lidt    fword ptr cs:[_16Idtr - _Code16Addr]
    .byte   0x66
    popaw
    popw    %ds
    popw    %es
    popw    %fs
    popw    %gs
    sub     60, %esp
    popfw
    testw   $1, 74(%esp)                #(_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1

    jz      1f
    pushf                               # push Flags when it's INT#
1: 
    pushw   %cs
#    push    @FarCallRet - _Code16Addr
    .byte   0x68                        # push /iw
    .word   FarCallRet - _Code16Addr
    jz      2f
    ljmp    *66(%esp)                   #[esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
2: 
    ljmp    *64(%esp)                   #[esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
FarCallRet: 
    add     60, %esp
    pushfl
    pushw   %gs
    pushw   %fs
    pushw   %es
    pushw   %ds
    pushal
    cli
    .byte   0x66                        # sizeof (IA32_REGS) = 13 * 4 = 52
    lgdt    66(%esp)                    #lgdt    (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr
    mov     76(%esp), %eax
    movl    %eax, %cr4
    mov     72(%esp), %eax
    movl    %eax, %cr0                   # restore CR0
    ljmpl   *52(%esp)                    
#RealMode ENDP

.text
_16Idtr:
    .word 0x3ff                         #_16Idtr     FWORD   (1 SHL 10) - 1
    .byte 0x00

_TEXT16END: 

_TEXT16SIZE = _TEXT16END - _Code16Addr