;------------------------------------------------------------------------------\r
;\r
; Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\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
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
;\r
; Module Name:\r
;\r
;\r
; These are global constant to convey information to C code.\r
;\r
-ASM_PFX(m16Size) DW InternalAsmThunk16 - ASM_PFX(m16Start)\r
-ASM_PFX(mThunk16Attr) DW _ThunkAttr - ASM_PFX(m16Start)\r
+ASM_PFX(m16Size) DW ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start)\r
+ASM_PFX(mThunk16Attr) DW _BackFromUserCode.ThunkAttrEnd - 4 - ASM_PFX(m16Start)\r
ASM_PFX(m16Gdt) DW _NullSegDesc - ASM_PFX(m16Start)\r
ASM_PFX(m16GdtrBase) DW _16GdtrBase - ASM_PFX(m16Start)\r
ASM_PFX(mTransition) DW _EntryPoint - ASM_PFX(m16Start)\r
; in IA32_REGS structure. This facilitates wrapper function to extract them\r
; into that structure.\r
;\r
+BITS 16\r
push ss\r
push cs\r
- DB 66h\r
- call @Base ; push eip\r
-@Base:\r
- pushfw ; pushfd actually\r
+ ;\r
+ ; Note: We can't use o32 on the next instruction because of a bug\r
+ ; in NASM 2.09.04 through 2.10rc1.\r
+ ;\r
+ call dword .Base ; push eip\r
+.Base:\r
+ pushfd\r
cli ; disable interrupts\r
push gs\r
push fs\r
push es\r
push ds\r
- pushaw ; pushad actually\r
- DB 66h, 0bah ; mov edx, imm32\r
-_ThunkAttr: dd 0\r
+ pushad\r
+ mov edx, strict dword 0\r
+.ThunkAttrEnd:\r
test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15\r
- jz @1\r
- mov eax, 15cd2401h ; mov ax, 2401h & int 15h\r
+ jz .1\r
+ mov ax, 2401h\r
+ int 15h\r
cli ; disable interrupts\r
- jnc @2\r
-@1:\r
+ jnc .2\r
+.1:\r
test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL\r
- jz @2\r
+ jz .2\r
in al, 92h\r
or al, 2\r
out 92h, al ; deactivate A20M#\r
-@2:\r
- xor ax, ax ; xor eax, eax\r
- mov eax, ss ; mov ax, ss\r
- DB 67h\r
- lea bp, [esp + IA32_REGS.size]\r
- ;\r
- ; esi's in the following 2 instructions are indeed bp in 16-bit code. Fact\r
- ; is "esi" in 32-bit addressing mode has the same encoding of "bp" in 16-\r
- ; bit addressing mode.\r
- ;\r
- mov [esi - IA32_REGS.size + IA32_REGS._ESP], bp\r
- mov ebx, [esi - IA32_REGS.size + IA32_REGS._EIP]\r
- shl ax, 4 ; shl eax, 4\r
- add bp, ax ; add ebp, eax\r
- DB 66h, 0b8h ; mov eax, imm32\r
-SavedCr4: DD 0\r
+.2:\r
+ xor eax, eax\r
+ mov ax, ss\r
+ lea ebp, [esp + IA32_REGS.size]\r
+ mov [bp - IA32_REGS.size + IA32_REGS._ESP], ebp\r
+ mov bx, [bp - IA32_REGS.size + IA32_REGS._EIP]\r
+ shl eax, 4 ; shl eax, 4\r
+ add ebp, eax ; add ebp, eax\r
+ mov eax, strict dword 0\r
+.SavedCr4End:\r
mov cr4, eax\r
- DB 66h\r
- lgdt [cs:edi + (SavedGdt - @Base)]\r
- DB 66h, 0b8h ; mov eax, imm32\r
-SavedCr0: DD 0\r
+o32 lgdt [cs:bx + (SavedGdt - .Base)]\r
+ mov eax, strict dword 0\r
+.SavedCr0End:\r
mov cr0, eax\r
- DB 0b8h ; mov ax, imm16\r
-SavedSs DW 0\r
+ mov ax, strict word 0\r
+.SavedSsEnd:\r
mov ss, eax\r
- DB 66h, 0bch ; mov esp, imm32\r
-SavedEsp DD 0\r
- DB 66h\r
- retf ; return to protected mode\r
+ mov esp, strict dword 0\r
+.SavedEspEnd:\r
+o32 retf ; return to protected mode\r
\r
_EntryPoint:\r
DD _ToUserCode - ASM_PFX(m16Start)\r
_16Gdtr:\r
DW GdtEnd - _NullSegDesc - 1\r
_16GdtrBase:\r
- DD _NullSegDesc\r
+ DD 0\r
\r
;------------------------------------------------------------------------------\r
; _ToUserCode() takes control in real mode before passing control to user code.\r
; It will be shadowed to somewhere in memory below 1MB.\r
;------------------------------------------------------------------------------\r
_ToUserCode:\r
- mov edx, ss\r
- mov ss, ecx ; set new segment selectors\r
- mov ds, ecx\r
- mov es, ecx\r
- mov fs, ecx\r
- mov gs, ecx\r
+BITS 16\r
+ mov dx, ss\r
+ mov ss, cx ; set new segment selectors\r
+ mov ds, cx\r
+ mov es, cx\r
+ mov fs, cx\r
+ mov gs, cx\r
mov cr0, eax ; real mode starts at next instruction\r
; which (per SDM) *must* be a far JMP.\r
- DB 0eah\r
-_RealAddr: DW 0, 0\r
-\r
+ jmp 0:strict word 0\r
+.RealAddrEnd:\r
mov cr4, ebp\r
- mov ss, esi ; set up 16-bit stack segment\r
- xchg sp, bx ; set up 16-bit stack pointer\r
-\r
-; mov bp, [esp + sizeof(IA32_REGS)\r
- DB 67h\r
- mov ebp, [esp + IA32_REGS.size] ; BackFromUserCode address from stack\r
-\r
-; mov cs:[bp + (SavedSs - _BackFromUserCode)], dx\r
- mov [cs:esi + (SavedSs - _BackFromUserCode)], edx\r
+ mov ss, si ; set up 16-bit stack segment\r
+ xchg esp, ebx ; set up 16-bit stack pointer\r
+ mov bp, [esp + IA32_REGS.size]\r
+ mov [cs:bp + (_BackFromUserCode.SavedSsEnd - 2 - _BackFromUserCode)], dx\r
+ mov [cs:bp + (_BackFromUserCode.SavedEspEnd - 4 - _BackFromUserCode)], ebx\r
+ lidt [cs:bp + (_16Idtr - _BackFromUserCode)]\r
\r
-; mov cs:[bp + (SavedEsp - _BackFromUserCode)], ebx\r
- DB 2eh, 66h, 89h, 9eh\r
- DW SavedEsp - _BackFromUserCode\r
-\r
-; lidt cs:[bp + (_16Idtr - _BackFromUserCode)]\r
- DB 2eh, 66h, 0fh, 01h, 9eh\r
- DW _16Idtr - _BackFromUserCode\r
-\r
- popaw ; popad actually\r
+ popad\r
pop ds\r
pop es\r
pop fs\r
pop gs\r
- popfw ; popfd\r
+ popfd\r
\r
- DB 66h ; Use 32-bit addressing for "retf" below\r
- retf ; transfer control to user code\r
+o32 retf ; transfer control to user code\r
\r
ALIGN 16\r
_NullSegDesc DQ 0\r
;------------------------------------------------------------------------------\r
global ASM_PFX(InternalAsmThunk16)\r
ASM_PFX(InternalAsmThunk16):\r
+BITS 32\r
push ebp\r
push ebx\r
push esi\r
rep movsd ; copy RegSet\r
mov eax, [esp + 40] ; eax <- address of transition code\r
mov esi, edx ; esi <- 16-bit stack segment\r
- lea edx, [eax + (SavedCr0 - ASM_PFX(m16Start))]\r
+ lea edx, [eax + (_BackFromUserCode.SavedCr0End - ASM_PFX(m16Start))]\r
mov ecx, eax\r
and ecx, 0fh\r
shl eax, 12\r
lea ecx, [ecx + (_BackFromUserCode - ASM_PFX(m16Start))]\r
mov ax, cx\r
stosd ; [edi] <- return address of user code\r
- add eax, _RealAddr + 4 - _BackFromUserCode\r
- mov [edx + (_RealAddr - SavedCr0)], eax\r
- sgdt [edx + (SavedGdt - SavedCr0)]\r
+ add eax, _ToUserCode.RealAddrEnd - _BackFromUserCode\r
+ mov [edx + (_ToUserCode.RealAddrEnd - 4 - _BackFromUserCode.SavedCr0End)], eax\r
+ sgdt [edx + (SavedGdt - _BackFromUserCode.SavedCr0End)]\r
sidt [esp + 36] ; save IDT stack in argument space\r
mov eax, cr0\r
- mov [edx], eax ; save CR0 in SavedCr0\r
+ mov [edx - 4], eax ; save CR0 in _BackFromUserCode.SavedCr0End - 4\r
and eax, 7ffffffeh ; clear PE, PG bits\r
mov ebp, cr4\r
- mov [edx + (SavedCr4 - SavedCr0)], ebp\r
+ mov [edx + (_BackFromUserCode.SavedCr4End - 4 - _BackFromUserCode.SavedCr0End)], ebp\r
and ebp, ~30h ; clear PAE, PSE bits\r
push 10h\r
pop ecx ; ecx <- selector for data segments\r
- lgdt [edx + (_16Gdtr - SavedCr0)]\r
+ lgdt [edx + (_16Gdtr - _BackFromUserCode.SavedCr0End)]\r
pushfd ; Save df/if indeed\r
- call dword far [edx + (_EntryPoint - SavedCr0)]\r
+ call dword far [edx + (_EntryPoint - _BackFromUserCode.SavedCr0End)]\r
popfd\r
lidt [esp + 36] ; restore protected mode IDTR\r
lea eax, [ebp - IA32_REGS.size] ; eax <- the address of IA32_REGS\r