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