Commit | Line | Data |
---|---|---|
b341712e | 1 | #*****************************************************************************\r |
2 | #*\r | |
3e99020d | 3 | #* Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r |
4ea9375a | 4 | #* This program and the accompanying materials \r |
b341712e | 5 | #* are licensed and made available under the terms and conditions of the BSD License \r |
6 | #* which accompanies this distribution. The full text of the license may be found at \r | |
7 | #* http://opensource.org/licenses/bsd-license.php \r | |
8 | #* \r | |
9 | #* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r | |
10 | #* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r | |
11 | #* \r | |
12 | #* Module Name:\r | |
13 | #*\r | |
14 | #* Thunk.S\r | |
15 | #* \r | |
16 | #* Abstract:\r | |
17 | #* \r | |
18 | #* Real mode thunk\r | |
19 | #* \r | |
20 | #*****************************************************************************\r | |
21 | #include <EfiBind.h>\r | |
22 | \r | |
23 | \r | |
24 | \r | |
25 | .data\r | |
26 | \r | |
27 | .globl ASM_PFX(mCode16Size)\r | |
28 | \r | |
29 | .data\r | |
30 | mCode16Size: .long _Code16End - _Code16Addr\r | |
31 | \r | |
32 | \r | |
33 | NullSegSel: .quad 0\r | |
34 | _16CsSegSel: \r | |
35 | .word -1\r | |
36 | .word 0\r | |
37 | .byte 0\r | |
38 | .byte 0x9b\r | |
39 | .byte 0x8f #16-bit segment\r | |
40 | .byte 0\r | |
41 | _16DsSegSel:\r | |
42 | .word -1\r | |
43 | .word 0\r | |
44 | .byte 0\r | |
45 | .byte 0x93\r | |
46 | .byte 0x8f #16-bit segment\r | |
47 | .byte 0\r | |
48 | \r | |
49 | _16Gdtr:\r | |
50 | .word _16Gdtr - NullSegSel - 1\r | |
51 | .long NullSegSel\r | |
52 | .code: \r | |
53 | \r | |
21a54a4d | 54 | #IA32_REGS STRUC 4t\r |
55 | #_EDI DD ?\r | |
56 | #_ESI DD ?\r | |
57 | #_EBP DD ?\r | |
58 | #_ESP DD ?\r | |
59 | #_EBX DD ?\r | |
60 | #_EDX DD ?\r | |
61 | #_ECX DD ?\r | |
62 | #_EAX DD ?\r | |
63 | #_DS DW ?\r | |
64 | #_ES DW ?\r | |
65 | #_FS DW ?\r | |
66 | #_GS DW ?\r | |
67 | #_RFLAGS DQ ?\r | |
68 | #_EIP DD ?\r | |
69 | #_CS DW ?\r | |
70 | #_SS DW ?\r | |
71 | #IA32_REGS ENDS\r | |
72 | \r | |
73 | #_STK16 STRUC 1t\r | |
74 | #RetEip DD ?\r | |
75 | #RetCs DW ?\r | |
76 | #ThunkFlags DW ?\r | |
77 | #SavedGdtr FWORD ?\r | |
78 | #Resvd1 DW ?\r | |
79 | #SavedCr0 DD ?\r | |
80 | #SavedCr4 DD ?\r | |
81 | #_STK16 ENDS\r | |
b341712e | 82 | \r |
83 | ASM_PFX(Thunk16):\r | |
84 | push %rbp\r | |
85 | push %rbx\r | |
86 | push %rsi\r | |
87 | push %rdi\r | |
88 | push %r12\r | |
89 | push %r13\r | |
90 | push %r14\r | |
91 | push %r15\r | |
92 | pushq %fs\r | |
93 | pushq %gs\r | |
94 | movl %ds,%r12d\r | |
95 | movl %es,%r13d\r | |
96 | movl %ss,%r14d\r | |
97 | mov %rsp,%r15\r | |
98 | mov %rcx,%rsi\r | |
99 | movzwq 0x36(%rsi),%r10 #movzx r10, (IA32_REGS ptr [rsi])._SS\r | |
100 | xor %rdi,%rdi\r | |
101 | mov 0xc(%rsi),%edi #mov edi, (IA32_REGS ptr [rsi])._ESP\r | |
102 | add $0xffffffffffffffb0,%rdi #add rdi, - sizeof (IA32_REGS) - sizeof (_STK16)\r | |
103 | push %rdi\r | |
104 | imul $0x10,%r10,%rax\r | |
105 | add %rax,%rdi\r | |
106 | pushq $0xe #push sizeof (IA32_REGS) / 4\r | |
107 | pop %rcx\r | |
108 | rep movsl %ds:(%rsi),%es:(%rdi)\r | |
3e99020d LG |
109 | #; copy eflags to stack frame\r |
110 | mov -16(%rsi), %rax\r | |
111 | mov %rax, -80(%rsi)\r | |
b341712e | 112 | pop %rbx #rbx <- 16-bit stack offset\r |
113 | lea Label,%eax #42 <_Thunk16+0x42>\r | |
114 | stos %eax,%es:(%rdi)\r | |
115 | movl %cs,%eax #return segment\r | |
116 | stos %ax,%es:(%rdi)\r | |
117 | mov %edx,%eax #THUNK Flags\r | |
118 | stos %ax,%es:(%rdi)\r | |
119 | sgdt 0x58(%rsp) #save GDTR\r | |
120 | mov 0x58(%rsp),%rax\r | |
121 | stos %rax,%es:(%rdi)\r | |
122 | mov %cr0,%rax #save CR0\r | |
123 | mov %eax,%esi #esi <- CR0 to set\r | |
124 | stos %eax,%es:(%rdi)\r | |
125 | mov %cr4,%rax #save CR4\r | |
126 | stos %eax,%es:(%rdi)\r | |
127 | sidt 0x58(%rsp) #save IDTR\r | |
128 | and $0x7ffffffe,%esi #clear PE & PG bits\r | |
129 | mov %r10,%rdi #rdi <- 16-bit stack segment\r | |
130 | shl $0x10,%r8\r | |
131 | push %r8 #far jmp address\r | |
132 | lea Label_16Bit,%eax \r | |
133 | push %rax\r | |
134 | movw $0x8,0x4(%rsp)\r | |
135 | lgdt _16Gdtr #bugbug: may not match.\r | |
136 | lret \r | |
137 | Label_16Bit:\r | |
138 | .byte 0x66\r | |
139 | movl $0xc0000080,%ecx\r | |
140 | mov %rsi,%cr0 #disable PE & PG \r | |
141 | rdmsr \r | |
142 | and $0xfe,%ah\r | |
143 | wrmsr #clear LME bit\r | |
144 | mov %cr4,%rax\r | |
145 | and $0xcf,%al #clear PAE & PSE\r | |
146 | mov %rax,%cr4\r | |
147 | lret \r | |
148 | \r | |
149 | Label:\r | |
150 | xor %rax,%rax\r | |
151 | movl %ss,%eax\r | |
152 | shl $0x4,%eax\r | |
153 | add %esp,%eax\r | |
154 | mov %r15,%rsp\r | |
155 | lidt 0x58(%rsp)\r | |
156 | movl %r12d,%ds\r | |
157 | movl %r13d,%es\r | |
158 | movl %r14d,%ss\r | |
159 | popq %gs\r | |
160 | popq %fs\r | |
161 | pop %r15\r | |
162 | pop %r14\r | |
163 | pop %r13\r | |
164 | pop %r12\r | |
165 | pop %rdi\r | |
166 | pop %rsi\r | |
167 | pop %rbx\r | |
168 | pop %rbp\r | |
169 | retq \r | |
170 | \r | |
171 | \r | |
f315cfa5 | 172 | .p2align 4\r |
b341712e | 173 | \r |
174 | _Code16Addr:\r | |
175 | ASM_PFX(RealMode):\r | |
176 | movl %edi,%ss\r | |
177 | mov %bx,%sp #set up 16-bit stack\r | |
178 | .byte 0x2e \r | |
179 | .byte 0x0f \r | |
180 | .byte 0x01\r | |
21a54a4d | 181 | .byte 0x1e\r |
182 | .word _16Idtr - _Code16Addr #lidt _16Idtr\r | |
b341712e | 183 | .byte 0x66\r |
21a54a4d | 184 | .byte 0x61 #popad\r |
185 | .byte 0x1f #pop ds\r | |
b341712e | 186 | .byte 0x07 #pop es\r |
21a54a4d | 187 | popq %fs\r |
188 | popq %gs\r | |
3e99020d LG |
189 | sub 64, %esp\r |
190 | .byte 0x66, 0x9d #popfd\r | |
191 | add $0x4,%esp #skip high part of RFLAGS\r | |
192 | .byte 0x67 #; test (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1\r | |
b341712e | 193 | .byte 0xf7 \r |
194 | .byte 0x44\r | |
195 | .byte 0x24\r | |
3e99020d | 196 | .byte 0x4e\r |
b341712e | 197 | .byte 0x01\r |
198 | .byte 0x00\r | |
199 | jz 1f\r | |
3e99020d | 200 | pushfq #pushf, actually, when it's INT#\r |
b341712e | 201 | 1:\r |
202 | .byte 0x0e #push cs\r | |
203 | .byte 0x68 #push /iw\r | |
204 | .word FarCallRet - _Code16Addr\r | |
205 | jz 2f\r | |
206 | .byte 0x66\r | |
3e99020d | 207 | ljmp *70(%esp)\r |
b341712e | 208 | 2: \r |
209 | .byte 0x66\r | |
3e99020d | 210 | ljmp *68(%esp)\r |
b341712e | 211 | FarCallRet: \r |
3e99020d | 212 | add 64, %esp\r |
b341712e | 213 | .byte 0x66\r |
214 | push $0x00 #push a dword of zero\r | |
215 | .byte 0x66\r | |
216 | pushf #pushfd, actually\r | |
217 | pushq %gs\r | |
218 | pushq %fs\r | |
219 | .byte 0x06 #push %es\r | |
220 | .byte 0x1e #push %ds\r | |
221 | .byte 0x66\r | |
222 | .byte 0x60\r | |
223 | cli\r | |
224 | .byte 0x66 #sizeof (IA32_REGS) = 13 * 4 = 52\r | |
225 | lgdt 64(%esp) #lgdt (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr\r | |
226 | .byte 0x66\r | |
227 | mov 76(%esp), %eax\r | |
228 | mov %rax, %cr4\r | |
229 | .byte 0x66\r | |
230 | mov $0xc0000080, %ecx\r | |
231 | rdmsr\r | |
232 | orb $1, %ah\r | |
233 | wrmsr\r | |
234 | .byte 0x66\r | |
235 | mov 72(%esp), %eax\r | |
236 | mov %rax, %cr0 #restore CR0\r | |
237 | .byte 0x66\r | |
238 | ljmpl *52(%esp) \r | |
239 | \r | |
240 | _16Idtr:\r | |
241 | .word 0x3ff #FWORD (1 SHL 10) - 1\r | |
242 | .byte 0x00\r |