cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Common bootsector code init.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; In addition to initialize the stack at %7bf0 it loads the first 512KB of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; floppy image at %7c00. The control is handed over with interrupts disabled
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; to a 'main' function defined by the includer.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; The following defines controls the mode we call main in:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INIT_RM (default)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INIT_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INIT_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INIT_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INIT_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; The following defines controls code inclusion:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PP16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PPV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PAE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_PAEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_LM16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_CMN_R86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_CMN_V86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_INC_CMN_P64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; - BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Copyright (C) 2007-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; available from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; you can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; General Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; The contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; of the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; VirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; CDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; You may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; terms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;* Header Files *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;* Defined Constants And Macros *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; @name Static Memory Allocation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The boot sector load address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_ADDR 07c00h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The stack is located before the code (and will overflow into the interrupt
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; table and other essential system data).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define STACK_ADDR (BS2_ADDR - 256)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The address of the ring-0 stack in bs2Tss32BitDf.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_DF_R0_STACK_ADDR 06800h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The address of the ring-0 stack in TSSxx.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_R0_STACK_ADDR 06000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The address of the ring-1 stack in TSSxx.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_R1_STACK_ADDR 05000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The address of the ring-2 stack in TSSxx.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_R2_STACK_ADDR 04800h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Where we save the boot registers during init.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_REG_SAVE_ADDR 06000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The start of the memory area used for paging, stacks and so forth.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_PXX_BASE 080000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The page map level 4 address (all entries point to BS2_LM_PDP_ADDR).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_LM_PML4_ADDR 080000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The long mode page directory pointer table address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_LM_PDP_ADDR 081000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The PAE page directory pointer table address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_PAE_PDP_ADDR 082000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The address of the 4 PAE page directories. Also used by long mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_PAE_PD_ADDR 083000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The address of the 32-bit page directory.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_32B_PD_ADDR 087000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; User page table #0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_USER_PX_0_ADDR 088000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; User page table #1.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_USER_PX_1_ADDR 089000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; User page table #2.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_USER_PX_2_ADDR 08a000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; User page table #3.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_USER_PX_3_ADDR 08b000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; User page table #4.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_USER_PX_4_ADDR 08c000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; User page table #5.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_USER_PX_5_ADDR 08d000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; User page table #6.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_USER_PX_6_ADDR 08e000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; User page table #7.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_USER_PX_7_ADDR 08f000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The selector to use when accessing the PDP and PD from real mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_PXX_SEL 08000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; Converts a BS2_P*_ADDR into a BS2_PXX_SEL selector offset.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_PXX_OFF(Addr) ( (Addr) - (BS2_PXX_SEL * 16) )
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The base address in the default address spaces of the range where we are
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; free to muck about as much as we like. (This is a virtual address.)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_MUCK_ABOUT_BASE 000400000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; We have some free space here 090000h...09a000h (stacks moved)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The address of the LDT.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_LDT_BASE 09b000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The size of the LDT in bytes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_LDT_SIZE 001fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The start of the memory area used for paging, stacks and so forth.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_PXX_LAST 09ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @name Group of 32-bit, 16-bit and 64-bit selectors for one ring.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_CS32 00h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_DS32 08h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_SS32 10h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_CS16 18h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_DS16 20h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_SS16 28h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_CS64 30h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_DS64 38h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_SS64 38h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_GRP_SIZE 40h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; Move to program.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_WITHOUT_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Implicit code inclusion based on the init mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_INIT_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_INIT_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_INIT_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INIT_RM ; the default
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PP16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PPV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PAE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_PAEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_LM16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Common code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_R86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_R86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_V86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PP16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PPV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_R86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_V86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_R86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_V86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_CMN_PAE_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Misc defines.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; The offset of the TSS32.CR3 field.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_TSS32_CR3_OFF 01ch
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;* Structures and Typedefs *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Start with a jump just to follow the convention.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Also declare all segments/sections to establish them and their order.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ORG BS2_ADDR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncsection .text valign=16 align=16 progbits
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncsection .data vfollows=.text follows=.text valign=16 align=16 progbits
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncsection .texthigh vfollows=.data follows=.data valign=16 align=16 progbits
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncsection .traprecs vfollows=.texthigh follows=.texthigh valign=8 align=8 progbits
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncsection .end vfollows=.traprecs follows=.traprecs valign=512 align=512 progbits
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BEGINCODELOW section .text ;;< For 16-bit code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BEGINCODEHIGH section .texthigh ;;< For 32-bit and 64-bit code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BEGINEND section .end ;;< For aligning image to 512 bytes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp short bs2InitCode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync nop ; alignment
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Abuse the bios parameter block area for data storage.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2GdtEnd - bs2Gdt - 1 ; limit 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Gdt ; base 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; base 23:16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; unused
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0 ; limit 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Gdt ; base 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; base 23:16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; unused
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifdef BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Idt32bitEnd - bs2Idt32bit -1 ; limit 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Idt32bit ; base 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; base 23:16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; unused
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifdef BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Idt64bitEnd - bs2Idt64bit -1 ; limit 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Idt64bit ; base 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; base 23:16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; unused
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncidtr_dummy_32bit:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2DummyIdt32bitEnd - bs2DummyIdt32bit -1 ; limit 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2DummyIdt32bit ; base 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; base 23:16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; unused
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncidtr_real_mode:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 01ffh ; limit 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0 ; base 15:00
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; base 23:16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 0 ; unused
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db '0123456789abcdef', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 80h ; Not in the official BPB location, but whatever.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncg_fCpuIntel:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2BpbPadding:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync times 3dh - (bs2BpbPadding - start) db 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Where to real init code starts.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2InitCode:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_SAVE_REGS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; save the registers if we've been asked to do so.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.rax], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.rsp], esp
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.rbp], ebp
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.ss], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.ds], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.es], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.fs], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; set up the segment reisters and stack.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync xor eax, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov esp, STACK_ADDR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp], eax ; clear the first 16 bytes
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 04h], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 08h], eax ; fake rbp.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 0ch], eax ; fake ebp and bp
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ebp, esp
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_SAVE_REGS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Save more registers now that ds is known and the stack is usable.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.rflags], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.rbx], ebx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.rcx], ecx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.rdx], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.rsi], esi
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.rdi], edi
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Make sure caching is enabled and alignment is off.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_SAVE_REGS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.cr0], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and eax, ~(X86_CR0_NW | X86_CR0_CD | X86_CR0_AM)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Load all the code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call bs2InitLoadImage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [g_bBootDrv], dl
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Initialize the data structures for the included modes requiring this.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call bs2InitPagedProtMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call bs2InitPaeProtMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call bs2InitLongMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Entered the desired mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2EnterMode_rm_pe32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2EnterMode_rm_pp32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2EnterMode_rm_pae32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2EnterMode_rm_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call SetCpuModeGlobals_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Mask interrupts and then set IF.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov al, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync out 021h, al
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync out 0a1h, al
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2DoneInit
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Loads the image off the floppy.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; This uses the the_end label to figure out the length. For this to work
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; cleanly the label must be aligned on a sector boundrary. Use BS2_PAD_IMAGE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; to make sure this is the case.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Clobbers everything except ebp and esp. Panics on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param dl The boot drive number (from BIOS).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses ax, cx, bx, esi, di
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2InitLoadImage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define bSavedDiskNo byte [bp - 04h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define bMaxSector byte [bp - 06h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define bMaxHead byte [bp - 08h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define bMaxCylinder byte [bp - 0ah]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Try figure the geometry.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ah, 08h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jc .failure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov bMaxSector, cl
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov bMaxHead, dh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov bMaxCylinder, ch
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, bSavedDiskNo
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Reload all the sectors one at a time (avoids problems).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lea esi, [dword the_end]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sub esi, start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shr esi, 9 ; si = number of sectors to load.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov di, BS2_ADDR / 16 ; The current load segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cx, 0001h ; ch/cylinder=0 (0-based); cl/sector=1 (1-based)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync xor dh, dh ; dh/head=0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.the_load_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov es, di ; es:bx -> buffer
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, 0201h ; al=1 sector; ah=read function
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jc .failure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; advance to the next sector/head/cylinder.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp cl, bMaxSector
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jbe .adv_addr
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp dh, bMaxHead
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jbe .adv_addr
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add di, 512 / 16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .the_load_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sp, 3*2
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Something went wrong, display a message.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; print message
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov si, .s_szErrMsg
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ah, 0eh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.failure_next_char:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp si, .s_szErrMsgEnd
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jb .failure_next_char
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; format the error number.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync movzx bx, byte [bp - 2 - 1] ; read the ah of the pusha frame
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov al, [bx + g_achHex]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync movzx bx, byte [bp - 2 - 1] ; read the ah of the pusha frame
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and bl, 0fh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov al, [bx + g_achHex]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2Panic
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szErrMsg:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 13, 10, 'read error: '
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szErrMsgEnd:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2InitLoadImage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; Pads the image so bs2InitLoadImage can load it without trouble.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%macro BS2_PAD_IMAGE 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2PadImageLabel:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; times ( (512*18*2) - ( (bs2PadImageLabel - start) % (512*18*2) ) ) db 0 ; track aligned size.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync times ( 512 - ( (bs2PadImageLabel - start) % 512 ) ) db 0 ; sector aligned size.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; times ( 10000h - BS2_ADDR - (bs2PadImageLabel - start) ) db 0 ; full segment 0 size.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Shutdown routine that will work in real and protected mode, providing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; that SS is valid that we can load it into DS.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Does not return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2Shutdown
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dx, 08900h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov esi, .s_szShutdown
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Shutdown failed!
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp Bs2Panic
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szShutdown:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 'Shutdown', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2Shutdown
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Panic routine for real mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Does not return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2Panic
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp .hlt_again
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2Panic
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Padd the remainder of the sector with zeros and
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; end it with the dos signature.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync times 510 - (bs2Padding - start) db 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db 055h, 0aah
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; The GDT (X86DESCGENERIC).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncalign 8, db 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h ; null selector
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R0_BASE 08h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_CS32 08h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09b00h, 000cfh ; 32-bit flat code segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_DS32 10h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09300h, 000cfh ; 32-bit flat data segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_SS32 18h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09300h, 000cfh ; 32-bit flat stack segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_CS16 20h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09b00h, 00000h ; 16-bit code segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_DS16 28h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09300h, 00000h ; 16-bit data segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_SS16 30h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09300h, 00000h ; 16-bit stack segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_CS64 38h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09a00h, 000afh ; 64-bit code segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_DS64 40h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_SS64 40h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09300h, 000afh ; 64-bit stack and data segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h ; Unused
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_MMIO16 50h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_MMIO16_BASE 0100000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 09310h, 00000h ; 16-bit VMMDev MMIO segment with base 0100000h.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h ; Unused
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_LDT 60h ; LDT usage requires manual LLDT and setting up.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw BS2_LDT_SIZE, BS2_LDT_BASE & 0xffff, 08200h | ((BS2_LDT_BASE >> 16) & 0xff), 00000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h ; zero for 64-bit mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_CS16_EO 70h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0fffeh, 00000h, 09800h, 00000h ; 16-bit code segment with base 0, not accessed, execute only, short limit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h ; unused.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifdef BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_SEL_TSS32 80h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw (bs2Tss32BitEnd - bs2Tss32Bit) - 1 ; 32-bit TSS.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Tss32Bit
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db X86_SEL_TYPE_SYS_386_TSS_AVAIL | 0x80
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_SEL_TSS32_DF 88h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw (bs2Tss32BitDfEnd - bs2Tss32BitDf) - 1; 32-bit TSS, double fault.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Tss32BitDf
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db X86_SEL_TYPE_SYS_386_TSS_AVAIL | 0x80
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifdef BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_SEL_TSS64 90h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw (bs2Tss64BitEnd - bs2Tss64Bit) - 1 ; 32-bit TSS.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw bs2Tss64Bit
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db AMD64_SEL_TYPE_SYS_TSS_AVAIL | 0x80
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h ; 2nd half of the 64-bit selector (not necessary).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 00000h, 00000h, 00000h, 00000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Ring-1 selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_BASE 0a0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_CS32 0a0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0bb00h, 000cfh ; Ring-1 32-bit flat code segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_DS32 0a8h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0b300h, 000cfh ; Ring-1 32-bit flat data segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_SS32 0b0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0b300h, 000cfh ; Ring-1 32-bit flat stack segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_CS16 0b8h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0bb00h, 00000h ; Ring-1 16-bit code segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_DS16 0c0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0b300h, 00000h ; Ring-1 16-bit data segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_SS16 0c8h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0b300h, 00000h ; Ring-1 16-bit stack segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_CS64 0d0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0ba00h, 000afh ; Ring-1 64-bit code segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_DS64 0d8h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R1_SS64 0d8h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0b300h, 000afh ; Ring-1 64-bit stack and data segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Ring-2 selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_BASE 0e0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_CS32 0e0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0db00h, 000cfh ; Ring-2 32-bit flat code segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_DS32 0e8h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0d300h, 000cfh ; Ring-2 32-bit flat data segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_SS32 0f0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0d300h, 000cfh ; Ring-2 32-bit flat stack segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_CS16 0f8h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0db00h, 00000h ; Ring-2 16-bit code segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_DS16 0f0h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0d300h, 00000h ; Ring-2 16-bit data segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_SS16 108h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0d300h, 00000h ; Ring-2 16-bit stack segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_CS64 110h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0da00h, 000afh ; Ring-2 64-bit code segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_DS64 118h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R2_SS64 118h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0d300h, 000afh ; Ring-2 64-bit stack and data segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Ring-3 selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_BASE 120h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_CS32 120h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0fb00h, 000cfh ; Ring-3 32-bit flat code segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_DS32 128h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0f300h, 000cfh ; Ring-3 32-bit flat data segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_SS32 130h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0f300h, 000cfh ; Ring-3 32-bit flat stack segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_CS16 138h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0fb00h, 00000h ; Ring-3 16-bit code segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_DS16 140h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0f300h, 00000h ; Ring-3 16-bit data segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_SS16 148h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0f300h, 00000h ; Ring-3 16-bit stack segment with base 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_CS64 150h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0fa00h, 000afh ; Ring-1 64-bit code segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_DS64 158h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_R3_SS64 158h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0ffffh, 00000h, 0f300h, 000afh ; Ring-1 64-bit stack and data segment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Here follows a bunch of spare GDT entries for (ab)use in testing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_SPARE0 160h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2GdtSpare0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_SPARE1 (BS2_SEL_SPARE0 + 08h)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2GdtSpare1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_SPARE2 (BS2_SEL_SPARE0 + 10h)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2GdtSpare2:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define BS2_SEL_SPARE3 (BS2_SEL_SPARE0 + 18h)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2GdtSpare3:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Dummy 32-bit IDT for making CSAM happy.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncalign 16, db 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2DummyIdt32bit:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0, 0, 0, 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0, 0, 0, 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0, 0, 0, 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dw 0, 0, 0, 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2DummyIdt32bitEnd
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Mode initialization routines.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Initializes the paged protected mode structures during init.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses ebx, esi
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2InitPagedProtMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Create a paging hierarchy
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov bx, BS2_PXX_SEL
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ebx, BS2_PXX_OFF(BS2_32B_PD_ADDR)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync xor esi, esi ; physical address
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; The page directory.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx], esi
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or word [bx], X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_PS | X86_PDE4M_US
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add esi, _4M
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test bx, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .pd_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Make sure there is some free space for the hypervisor near the top
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; of the address space (last 4MB is mapped).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [bx - 08h], 0feh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [bx - 0ch], 0feh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [bx - 10h], 0feh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [bx - 14h], 0feh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2InitPagedProtMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PAE_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Initializes the PAE page directories.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Assumes ds is set to BS2_PXX_SEL already and that edx is zero.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses ebx, esi
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2InitPaePageDirs
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov esi, X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_PS | X86_PDE4M_US
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ebx, BS2_PXX_OFF(BS2_PAE_PD_ADDR)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [bx], esi
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [bx + 4], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add esi, _2M
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test bx, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .pd_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp bx, BS2_PXX_OFF(BS2_PAE_PD_ADDR + 4*_4K)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jne .pd_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Make sure there is some free space for the hypervisor near the top
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; of the address space (last 4MB is mapped).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [bx - 10h], 0feh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [bx - 18h], 0feh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [bx - 20h], 0feh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [bx - 28h], 0feh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2InitPaePageDirs
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_PAE_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Initializes the PAE protected mode structures during init.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses edx, ebx, esi.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2InitPaeProtMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dx, BS2_PXX_SEL
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync xor edx, edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Join paths with long mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call bs2InitPaePageDirs
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Create the page directory pointer table.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ebx, BS2_PXX_OFF(BS2_PAE_PDP_ADDR)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx], (BS2_PAE_PD_ADDR ) | X86_PDPE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 04h], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 08h], (BS2_PAE_PD_ADDR + 1000h) | X86_PDPE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 0ch], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 10h], (BS2_PAE_PD_ADDR + 2000h) | X86_PDPE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 14h], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 18h], (BS2_PAE_PD_ADDR + 3000h) | X86_PDPE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 1ch], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2InitPaeProtMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Initializes the long mode structures during init.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses edx, ebx, esi
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2InitLongMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dx, BS2_PXX_SEL
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync xor edx, edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Join paths with the PAE code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call bs2InitPaePageDirs
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Create the long mode page directory pointer table.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ebx, BS2_PXX_OFF(BS2_LM_PDP_ADDR)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.pdptr_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx], (BS2_PAE_PD_ADDR ) | X86_PDPE_P | X86_PDPE_RW | X86_PDPE_US
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 04h], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 08h], (BS2_PAE_PD_ADDR + 1000h) | X86_PDPE_P | X86_PDPE_RW | X86_PDPE_US
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 0ch], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 10h], (BS2_PAE_PD_ADDR + 2000h) | X86_PDPE_P | X86_PDPE_RW | X86_PDPE_US
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 14h], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 18h], (BS2_PAE_PD_ADDR + 3000h) | X86_PDPE_P | X86_PDPE_RW | X86_PDPE_US
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 1ch], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add bx, 20h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test bx, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .pdptr_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Set up the page map level 4 table, all entries mapping the same PDPTR.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ebx, BS2_PXX_OFF(BS2_LM_PML4_ADDR)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx], BS2_LM_PDP_ADDR | X86_PML4E_P | X86_PML4E_RW | X86_PML4E_US
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [bx + 4], edx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test bx, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .pml4_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2InitLongMode
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Routines for entering the different modes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters unpaged protected mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ebp and esp converted to 32/16-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_pe16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word SetCpuModeGlobals_pe16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Switch to protected mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lgdt [gdtr]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_dummy_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_null]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR0_PE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and eax, 0ffffffffh - X86_CR0_PG
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS16:bs2ProtModeCode16Start_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_pe16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters unpaged protected mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ebp and esp converted to 32-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_pe32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword SetCpuModeGlobals_pe32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the mode switch.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lgdt [gdtr]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_dummy_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_null]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR0_PE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and eax, 0ffffffffh - X86_CR0_PG
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS32:bs2ProtModeCode32Start_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_pe32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; @todo BS2_INC_PEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PP16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters paged protected mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ebp and esp converted to 16/32-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_pp16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word SetCpuModeGlobals_pp16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the mode switch.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lgdt [gdtr]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_dummy_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_null]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_32B_PD_ADDR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [bs2Tss32BitDf + BS2_TSS32_CR3_OFF], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR4_PSE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and eax, ~X86_CR4_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr4, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS16:bs2ProtModeCode16Start_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_pp16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PP16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters paged protected mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ebp and esp converted to 32-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_pp32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword SetCpuModeGlobals_pp32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the mode switch.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lgdt [gdtr]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_dummy_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_null]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_32B_PD_ADDR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [bs2Tss32BitDf + BS2_TSS32_CR3_OFF], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR4_PSE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and eax, ~X86_CR4_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr4, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS32:bs2ProtModeCode32Start_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_pp32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PP16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; @todo BS2_INC_PPV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters PAE protected mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ebp and esp converted to 16/32-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_pae16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word SetCpuModeGlobals_pae16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the mode switch.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lgdt [gdtr]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_dummy_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_null]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_PAE_PDP_ADDR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [bs2Tss32BitDf + BS2_TSS32_CR3_OFF], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR4_PAE | X86_CR4_PSE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr4, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS16:bs2ProtModeCode16Start_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_pae16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PAE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters PAE protected mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ebp and esp converted to 32-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_pae32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword SetCpuModeGlobals_pae32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the mode switch.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lgdt [gdtr]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_WITH_RAW_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_dummy_32bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_null]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_PAE_PDP_ADDR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [bs2Tss32BitDf + BS2_TSS32_CR3_OFF], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR4_PAE | X86_CR4_PSE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr4, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS32:bs2ProtModeCode32Start_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_pae32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;; @todo BS2_INC_PAEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters long mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; rbp and rsp converted to 16/32/64-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2EnterMode_rm_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2Thunk_lm64_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_LM16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters long mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; rbp and rsp converted to 16/32/64-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_lm32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Change the return address into a 32-bit one.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word 0 ; Reserved 2 extra bytes for 32-bit return address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push eax ; Save eax.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync movzx eax, word [esp + 6h] ; Read narrow return address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 4h], eax ; Store wide return address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pop eax ; Restore eax.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the mode switch and thunking.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2EnterMode_rm_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2Thunk_lm64_lm32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_lm32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Enters long mode from real mode (cs = 0).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 64-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; rbp and rsp converted to 64-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2EnterMode_rm_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word 0 ; reserve bytes for 64-bit return address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0 ; rax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0 ; rcx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0 ; rdx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0 ; rflags
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Fix the return address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, [esp + 20h + 6h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov word [esp + 20h + 6h], 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 20h], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Switch to long mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lgdt [gdtr]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_64bit]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_null]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_LM_PML4_ADDR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR4_PAE | X86_CR4_PSE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr4, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ecx, MSR_K6_EFER
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, MSR_K6_EFER_LME
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS64:.code64_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.code64_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_SEL_DS64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_SS64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync btr dword [bs2Gdt + BS2_SEL_TSS64 + 32/8], 1+8 ; busy -> avail
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifndef BS2_WITH_MANUAL_LTR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_TSS64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and edi, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esi, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebx, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call SetCpuModeGlobals_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2EnterMode_rm_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Code shared by the three 16-bit protected mode switchers.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2ProtModeCode16Start_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Initialize the registers.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_DS16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_SS16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync btr word [bs2Gdt + BS2_SEL_TSS32 + 32/8], 1+8 ; busy -> avail
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync btr word [bs2Gdt + BS2_SEL_TSS32_DF + 32/8], 1+8 ; busy -> avail
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifndef BS2_WITH_MANUAL_LTR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_TSS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Set up mode specific global variables.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2ProtModeCode16Start_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Code shared by the three 32-bit protected mode switchers.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2ProtModeCode32Start_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Initialize the registers.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_DS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_SS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync btr dword [bs2Gdt + BS2_SEL_TSS32 + 32/8], 1+8 ; busy -> avail
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync btr dword [bs2Gdt + BS2_SEL_TSS32_DF + 32/8], 1+8 ; busy -> avail
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifndef BS2_WITH_MANUAL_LTR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_TSS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Set up mode specific global variables.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Make the return address 32-bit and then return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync movzx eax, word [esp + 0ah]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 8h], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2ProtModeCode32Start_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Routines for exitting the different modes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See bs2ExitMode_p16.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_pe16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupNop_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_pe16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See bs2ExitMode_p32.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODEHIGH
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_pe32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupNop_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_pe32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See Bs2ExitMode_v86.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_pev86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupNop_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp Bs2ExitMode_pv86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_pev86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PP16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See bs2ExitMode_p16.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_pp16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupNop_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_pp16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PP16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See bs2ExitMode_p32.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODEHIGH
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_pp32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupNop_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_pp32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PPV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See Bs2ExitMode_v86.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_ppv86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupNop_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp Bs2ExitMode_pv86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_ppv86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PPV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAE16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See bs2ExitMode_p16.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_pae16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupPae_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_pae16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_pae16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See bs2ExitMode_p32.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODEHIGH
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_pae32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupPae_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_pae32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_PAEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See Bs2ExitMode_v86.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_paev86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupPae_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp Bs2ExitMode_pv86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_paev86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_PAEV86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See bs2ExitMode_p16.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupLm_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See bs2ExitMode_p32.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODEHIGH
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_lm32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupLm_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_lm32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; See Bs2ExitMode_v86.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2ExitMode_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2Thunk_lm64_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pop dword [esp]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pop word [esp]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push bs2ExitModeCleanupLm_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2ExitMode_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Isn't there a better way to do this in yasm?
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_BS2EXITMODE_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%elifdef BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BS2_INC_BS2EXITMODE_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_BS2EXITMODE_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Exit 16-bit protected or long mode (cs = CS16, ss = SS16).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with the 0 selector.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2ExitMode_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Make sure we've got the right SS and CS values (paranoia).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_SS16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS16:.code16_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.code16_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Turn off paging and protected mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and eax, 0ffffffffh - X86_CR0_PE - X86_CR0_PG
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr0, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far 0000:.real_mode_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.real_mode_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Load the correct real mode segment registers.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Load the real mode idtr.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lidt [idtr_real_mode]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, [esp + 8h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Set globals.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call SetCpuModeGlobals_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sp, 2h ; cleanup routine address
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2ExitMode_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_P16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Exit 32-bit protected or long mode (cs = CS32, ss = SS32).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; The return address as well as the stack registers must be somewhere within
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; the first 64KB of the address space.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with the 0 selector.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2ExitMode_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, [esp + 8h] ; return address
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 0ah], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, [esp + 4h] ; cleanup routine address
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 08h], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add esp, 4h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2Thunk_p32_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp bs2ExitMode_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2ExitMode_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_P32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Dummy cleanup routine.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2ExitModeCleanupNop_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2ExitModeCleanupNop_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Cleans up after leaving PAE mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2ExitModeCleanupPae_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and eax, ~X86_CR4_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr4, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2ExitModeCleanupPae_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Cleans up after leaving long mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2ExitModeCleanupLm_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ecx, MSR_K6_EFER
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and eax, ~MSR_K6_EFER_LME
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2ExitModeCleanupLm_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Thunking routines for switching between 16/32/64-bit code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Switches from 32-bit to 16-bit mode ({eip,esp,ebp} < 64KB).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2Thunk_p32_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_SS16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS16:.code16_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.code16_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_DS16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Fix the return address and then return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, [esp + 08h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 0ah], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2Thunk_p32_p16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p32_pe16 Bs2Thunk_p32_p16 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p32_pp16 Bs2Thunk_p32_p16 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p32_pae16 Bs2Thunk_p32_p16 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Switches from 16-bit to 32-bit mode (cs = CS16, ds = DS16).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ebp and esp converted to 32bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2Thunk_p16_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS32:.code32_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.code32_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_SEL_SS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_DS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Fix the return address and then return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync movzx eax, word [esp + 0ah]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 08h], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2Thunk_p16_p32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p16_pe32 Bs2Thunk_p16_p32 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p16_pp32 Bs2Thunk_p16_p32 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p16_pae32 Bs2Thunk_p16_p32 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_PM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Switches from 64-bit to 16-bit mode ({rip,rsp,rbp} < 64KB).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2Thunk_lm64_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_SS16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push BS2_SEL_CS16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push .code16_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.code16_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_DS16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Fix the return address and then return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, [esp + 10h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 16h], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sp, 4h + 6h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2Thunk_lm64_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p64_lm16 Bs2Thunk_lm64_lm16 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Switches from 16-bit to 64-bit mode (cs = CS16, ss = SS16).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 64-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; rbp and rsp converted to 16/32/64-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2Thunk_lm16_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push word 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_SEL_SS64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS64:.code64_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.code64_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_DS64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esp, 0ffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and edi, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esi, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebx, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Fix the return address and then return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync movzx rax, word [rsp + 16h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [rsp + 10h], rax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2Thunk_lm16_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p16_lm64 Bs2Thunk_lm16_lm64 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_LM16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Switches from 64-bit to 32-bit mode ({rip,rsp,rbp} < 4GB).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODEHIGH
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2Thunk_lm64_lm32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_SS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push BS2_SEL_CS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push .code32_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.code32_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_DS32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Fix the return address and then return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, [esp + 10h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [esp + 14h], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, [esp + 4h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lea esp, [esp + 10h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2Thunk_lm64_lm32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p64_lm32 Bs2Thunk_lm64_lm32 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Switches from 32-bit to 64-bit mode (cs = CS32, ss = SS32).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns cs,ds,ss,es,gs,fs loaded with 64-bit selectors.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; rbp and rsp converted to 32/64-bit.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; All other registers are preserved.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODEHIGH
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2Thunk_lm32_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push dword 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, BS2_SEL_SS64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp far BS2_SEL_CS64:.code64_start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.code64_start:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, BS2_SEL_DS64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebp, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esp, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and edi, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and esi, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and ebx, 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Fix the return address and then return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, [rsp + 14h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [rsp + 10h], rax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2Thunk_lm32_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define Bs2Thunk_p32_lm64 Bs2Thunk_lm32_lm64 ; Alternative name for TMPL_NM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_LM32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Routines for checking if mode is supported or not.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns al=1 & ZF=0 if supported, al=0 & ZF=1 if not.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; These are easy.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC bs2IsModeSupportedYes_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_pe16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_pe32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_pev86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_pp16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_pp32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_ppv86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test al, al
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC bs2IsModeSupportedYes_rm
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2IsPaeSupported_16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_pae16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_pae32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_paev86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp eax, 1000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test edx, X86_CPUID_FEATURE_EDX_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2IsPaeSupported_16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC Bs2IsLongModeSupported_16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_lm16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_lm32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGLOBALNAME Bs2IsModeSupported_rm_lm64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 080000000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp eax, 080000001h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp eax, 080001000h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 080000001h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test edx, X86_CPUID_EXT_FEATURE_EDX_LONG_MODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC Bs2IsLongModeSupported_16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; BS2_INC_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Include addition init/base code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Include common code.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifndef BS2_NOINC_COMMON
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Include trap records if requested.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPRECS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Map stuff for the initial environment.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define TMPL_RM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define TMPL_PE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define TMPL_PP32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define TMPL_PAE32
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define TMPL_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Where we jump after initialization.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTMPL_BEGINCODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBITS TMPL_BITS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncbs2DoneInit:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_INIT_SAVE_REGS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr2
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.cr2], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.cr3], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, cr4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [BS2_REG_SAVE_ADDR + BS2REGS.cr4], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov byte [BS2_REG_SAVE_ADDR + BS2REGS.cBits], 16
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync xor eax, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.cs], ax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, start
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [cs:BS2_REG_SAVE_ADDR + BS2REGS.rip], eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef BS2_WITH_TRAPRECS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Install the trap records.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync BS2_TRAP_RECS_INSTALL
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Detect the CPU.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync xor eax, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [g_fCpuIntel], al
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [g_fCpuAmd], al
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp ecx, 0x444d4163
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jne .not_amd
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp edx, 0x69746e65
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jne .not_amd
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp ebx, 0x68747541
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jne .not_amd
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov byte [g_fCpuAmd], 1
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp .not_intel
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp ecx, 0x6c65746e
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jne .not_intel
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp edx, 0x49656e69
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jne .not_intel
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cmp ebx, 0x756e6547
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jne .not_intel
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov byte [g_fCpuIntel], 1
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Call the user 'main' procedure (shouldn't return).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.panic_again
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2Panic
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp .panic_again