2 // Include common header file for this module.
4 #include "CommonHeader.h"
6 #------------------------------------------------------------------------------
8 # Copyright (c) 2006, Intel Corporation
9 # All rights reserved. This program and the accompanying materials
10 # are licensed and made available under the terms and conditions of the BSD License
11 # which accompanies this distribution. The full text of the license may be found at
12 # http://opensource.org/licenses/bsd-license.php
14 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 #------------------------------------------------------------------------------
27 .globl ASM_PFX(m16Start), ASM_PFX(m16Size), ASM_PFX(mThunk16Attr), ASM_PFX(m16Gdt), ASM_PFX(m16GdtrBase), ASM_PFX(mTransition)
28 .globl ASM_PFX(InternalAsmThunk16)
34 ASM_PFX(BackFromUserCode):
38 call L_Base1 # push eip
40 pushfw # pushfd actually
41 cli # disable interrupts
46 pushaw # pushad actually
47 .byte 0x66, 0xba # mov edx, imm32
48 ASM_PFX(ThunkAttr): .space 4
49 testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl
51 movl $0x15cd2401, %eax # mov ax, 2401h & int 15h
52 cli # disable interrupts
55 testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL, %dl
59 outb %al, $0x92 # deactivate A20M#
62 .byte 0x67, 0x66, 0x8d, 0x6c, 0x24, 0x34, 0x66
63 mov %ebp, 0xffffffd8(%esi)
64 mov 0xfffffff8(%esi), %ebx
65 shlw $4, %ax # shl eax, 4
66 addw %ax, %bp # add ebp, eax
67 .byte 0x66, 0xb8 # mov eax, imm32
70 lgdtw %cs:0xfffffff2(%edi)
71 .byte 0x66, 0xb8 # mov eax, imm32
74 .byte 0xb8 # mov ax, imm16
77 .byte 0x66, 0xbc # mov esp, imm32
80 lret # return to protected mode
82 _EntryPoint: .long ASM_PFX(ToUserCode) - ASM_PFX(m16Start)
86 _16Gdtr: .word GdtEnd - _NullSegDesc - 1
87 _16GdtrBase: .long _NullSegDesc
91 movl %ecx, %ss # set new segment selectors
97 movl %ebp, %cr4 # real mode starts at next instruction
98 movl %esi, %ss # set up 16-bit stack segment
99 xchgw %bx, %sp # set up 16-bit stack pointer
101 call L_Base # push eip
103 popw %bp # ebp <- offset L_Base
111 mov %edx, %cs:0xffffffc5(%esi)
112 mov %bx, %cs:0xffffffcb(%esi)
113 lidtw %cs:0xffffffd7(%esi)
114 popaw # popad actually
120 lretw # transfer control to user code
122 _NullSegDesc: .quad 0
128 .byte 0x8f # 16-bit segment, 4GB limit
135 .byte 0x8f # 16-bit segment, 4GB limit
140 # @param RegSet Pointer to a IA32_DWORD_REGS structure
141 # @param Transition Pointer to the transition code
142 # @return The address of the 16-bit stack after returning from user code
144 ASM_PFX(InternalAsmThunk16):
153 movl 36(%esp), %esi # esi <- RegSet
154 movzwl 0x32(%esi), %edx
156 add $0xffffffc8, %edi
157 movl %edi, %ebx # ebx <- stack offset
158 imul $0x10, %edx, %eax
160 addl %eax, %edi # edi <- linear address of 16-bit stack
164 movl 40(%esp), %eax # eax <- address of transition code
165 movl %edx, %esi # esi <- 16-bit stack segment
172 stosl # [edi] <- return address of user code
173 sgdtl 0xffffffa2(%edx)
176 movl %eax, (%edx) # save CR0 in SavedCr0
177 andl $0x7ffffffe, %eax # clear PE, PG bits
179 mov %ebp, 0xfffffff1(%edx)
180 andl $0x300, %ebp # clear all but PCE and OSFXSR bits
182 pop %ecx # ecx <- selector for data segments
188 lea 0xffffffcc(%ebp), %eax
201 ASM_PFX(m16Size): .word _InternalAsmThunk16 - ASM_PFX(m16Start)
202 ASM_PFX(mThunk16Attr): .word _ThunkAttr - ASM_PFX(m16Start)
203 ASM_PFX(m16Gdt): .word _NullSegDesc - ASM_PFX(m16Start)
204 ASM_PFX(m16GdtrBase): .word _16GdtrBase - ASM_PFX(m16Start)
205 ASM_PFX(mTransition): .word _EntryPoint - ASM_PFX(m16Start)