--- /dev/null
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
+# Portions copyright (c) 2011, Apple Inc. All rights reserved. \r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php.\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Module Name:\r
+#\r
+# InternalSwitchStack.S\r
+#\r
+# Abstract:\r
+#\r
+# Implementation of a stack switch on IA-32.\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+ASM_GLOBAL ASM_PFX(InternalSwitchStack)\r
+\r
+#------------------------------------------------------------------------------\r
+# VOID\r
+# EFIAPI\r
+# InternalSwitchStack (\r
+# IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
+# IN VOID *Context1, OPTIONAL\r
+# IN VOID *Context2, OPTIONAL\r
+# IN VOID *NewStack\r
+# );\r
+#------------------------------------------------------------------------------\r
+ASM_PFX(InternalSwitchStack):\r
+ pushl %ebp\r
+ movl %esp, %ebp\r
+\r
+ movl 20(%ebp), %esp # switch stack\r
+ subl $8, %esp\r
+\r
+ movl 16(%ebp), %eax\r
+ movl %eax, 4(%esp)\r
+ movl 12(%ebp), %eax\r
+ movl %eax, (%esp)\r
+ pushl $0 # keeps gdb from unwinding stack\r
+ jmp *8(%ebp) # call and never return \r
+\r
.set IA32_REGS_SIZE, 56\r
\r
.data\r
-\r
-ASM_PFX(m16Size): .word ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)\r
-ASM_PFX(mThunk16Attr): .word _ThunkAttr - ASM_PFX(m16Start)\r
-ASM_PFX(m16Gdt): .word ASM_PFX(NullSeg) - ASM_PFX(m16Start)\r
-ASM_PFX(m16GdtrBase): .word _16GdtrBase - ASM_PFX(m16Start)\r
-ASM_PFX(mTransition): .word _EntryPoint - ASM_PFX(m16Start)\r
+ \r
+.set Lm16Size, ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)\r
+ASM_PFX(m16Size): .word Lm16Size\r
+.set LmThunk16Attr, L_ThunkAttr - ASM_PFX(m16Start)\r
+ASM_PFX(mThunk16Attr): .word LmThunk16Attr\r
+.set Lm16Gdt, ASM_PFX(NullSeg) - ASM_PFX(m16Start)\r
+ASM_PFX(m16Gdt): .word Lm16Gdt\r
+.set Lm16GdtrBase, _16GdtrBase - ASM_PFX(m16Start)\r
+ASM_PFX(m16GdtrBase): .word Lm16GdtrBase\r
+.set LmTransition, _EntryPoint - ASM_PFX(m16Start)\r
+ASM_PFX(mTransition): .word LmTransition\r
\r
.text\r
\r
.byte 0x1e # push ds\r
.byte 0x66,0x60 # pushad\r
.byte 0x66,0xba # mov edx, imm32\r
-_ThunkAttr: .space 4\r
+L_ThunkAttr: .space 4\r
testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl\r
jz L_1\r
movl $0x15cd2401,%eax # mov ax, 2401h & int 15h\r
.byte 0x66,0x2e,0x89,0x87 # mov cs:[bx + (L_64Eip - L_Base)], eax\r
.word L_64Eip - L_Base\r
.byte 0x66,0xb8 # mov eax, imm32\r
-SavedCr4: .space 4\r
+L_SavedCr4: .long 0\r
movq %rax, %cr4\r
#\r
# rdi in the instruction below is indeed bx in 16-bit code\r
orb $1,%ah\r
wrmsr\r
.byte 0x66,0xb8 # mov eax, imm32\r
-SavedCr0: .space 4\r
+L_SavedCr0: .long \r
movq %rax, %cr0\r
.byte 0x66,0xea # jmp far cs:L_64Bit\r
-L_64Eip: .space 4\r
-SavedCs: .space 2\r
+L_64Eip: .long 0\r
+L_SavedCs: .space 2\r
L_64BitCode: \r
.byte 0x90\r
.byte 0x67,0xbc # mov esp, imm32\r
-SavedSp: .space 4 # restore stack\r
+L_SavedSp: .long # restore stack\r
nop\r
ret\r
\r
popq %rcx\r
rep\r
movsl # copy RegSet\r
- lea (SavedCr4 - ASM_PFX(m16Start))(%rdx), %ecx\r
+ lea (L_SavedCr4 - ASM_PFX(m16Start))(%rdx), %ecx\r
movl %edx,%eax # eax <- transition code address\r
andl $0xf,%edx\r
shll $12,%eax # segment address in high order 16 bits\r
- lea (ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start))(%rdx), %ax\r
+ .set LBackFromUserCodeDelta, ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start) \r
+ lea (LBackFromUserCodeDelta)(%rdx), %ax\r
stosl # [edi] <- return address of user code\r
sgdt 0x60(%rsp) # save GDT stack in argument space\r
movzwq 0x60(%rsp), %r10 # r10 <- GDT limit \r
- lea ((ASM_PFX(InternalAsmThunk16) - SavedCr4) + 0xf)(%rcx), %r11 \r
+ lea ((ASM_PFX(InternalAsmThunk16) - L_SavedCr4) + 0xf)(%rcx), %r11 \r
andq $0xfffffffffffffff0, %r11 # r11 <- 16-byte aligned shadowed GDT table in real mode buffer \r
\r
- movw %r10w, (SavedGdt - SavedCr4)(%rcx) # save the limit of shadowed GDT table\r
- movq %r11, (SavedGdt - SavedCr4 + 0x2)(%rcx) # save the base address of shadowed GDT table\r
+ movw %r10w, (SavedGdt - L_SavedCr4)(%rcx) # save the limit of shadowed GDT table\r
+ movq %r11, (SavedGdt - L_SavedCr4 + 0x2)(%rcx) # save the base address of shadowed GDT table\r
\r
movq 0x62(%rsp) ,%rsi # rsi <- the original GDT base address\r
xchg %r10, %rcx # save rcx to r10 and initialize rcx to be the limit of GDT table \r
\r
sidt 0x50(%rsp)\r
movq %cr0, %rax\r
- movl %eax, (SavedCr0 - SavedCr4)(%rcx)\r
+ .set LSavedCrDelta, L_SavedCr0 - L_SavedCr4\r
+ movl %eax, (LSavedCrDelta)(%rcx)\r
andl $0x7ffffffe,%eax # clear PE, PG bits\r
movq %cr4, %rbp\r
movl %ebp, (%rcx) # save CR4 in SavedCr4\r
movl %r8d, %esi # esi <- 16-bit stack segment\r
.byte 0x6a, DATA32\r
popq %rdx\r
- lgdt (_16Gdtr - SavedCr4)(%rcx)\r
+ lgdt (_16Gdtr - L_SavedCr4)(%rcx)\r
movl %edx,%ss\r
pushfq\r
lea -8(%rdx), %edx\r
lea L_RetFromRealMode(%rip), %r8\r
pushq %r8\r
movl %cs, %r8d\r
- movw %r8w, (SavedCs - SavedCr4)(%rcx)\r
- movl %esp, (SavedSp - SavedCr4)(%rcx)\r
- .byte 0xff, 0x69 # jmp (_EntryPoint - SavedCr4)(%rcx)\r
- .byte _EntryPoint - SavedCr4\r
+ movw %r8w, (L_SavedCs - L_SavedCr4)(%rcx)\r
+ movl %esp, (L_SavedSp - L_SavedCr4)(%rcx)\r
+ .byte 0xff, 0x69 # jmp (_EntryPoint - L_SavedCr4)(%rcx)\r
+ .set Ltemp1, _EntryPoint - L_SavedCr4\r
+ .byte Ltemp1\r
L_RetFromRealMode: \r
popfq\r
lgdt 0x60(%rsp) # restore protected mode GDTR\r