VirtualBox

Ignore:
Timestamp:
Nov 5, 2015 3:45:36 PM (9 years ago)
Author:
vboxsync
Message:

bs3kit: kick off; to laptop.

Location:
trunk/src/VBox/ValidationKit/bootsectors
Files:
3 added
1 edited
4 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/Makefile.kmk

    r56295 r58588  
    187187
    188188
     189ifeq ($(USER),bird) # work in progress.
     190
     191#
     192# BS3Kit
     193#
     194
     195# Dummy CP "linker" tool.
     196TOOL_VBoxBsCpLd = Dummy copy linker.
     197TOOL_VBoxBsCpLd_LINK_MISCBIN_OUTPUT =
     198TOOL_VBoxBsCpLd_LINK_MISCBIN_DEPEND =
     199TOOL_VBoxBsCpLd_LINK_MISCBIN_DEPORD =
     200define TOOL_VBoxBsCpLd_LINK_MISCBIN_CMDS
     201        $(CP) -- $(objs) $(othersrc) "$(out)"
     202endef
     203
     204# Dummy exit 1 "linker" tool.
     205TOOL_VBoxBsUnusedLd = Dummy unused linker.
     206TOOL_VBoxBsUnusedLd_LINK_MISCBIN_OUTPUT =
     207TOOL_VBoxBsUnusedLd_LINK_MISCBIN_DEPEND =
     208TOOL_VBoxBsUnusedLd_LINK_MISCBIN_DEPORD =
     209define TOOL_VBoxBsUnusedLd_LINK_MISCBIN_CMDS
     210        echo "cannot use this template for linking"
     211        exit 1
     212endef
     213
     214# BS3Kit template for assembly and 16-bit code.
     215TEMPLATE_VBoxBS3KitImg = Template for building BS3Kit test images.
     216TEMPLATE_VBoxBS3KitImg_INST     = $(INST_VALIDATIONKIT)bootsectors/
     217TEMPLATE_VBoxBS3KitImg_BINSUFF  = .img
     218TEMPLATE_VBoxBS3KitImg_MODE     = 0644
     219TEMPLATE_VBoxBS3KitImg_ASTOOL   = NASM
     220TEMPLATE_VBoxBS3KitImg_ASFLAGS := -f obj -g -w+orphan-labels #-P $(PATH_SUB_CURRENT)/bootsector2-first.mac
     221TEMPLATE_VBoxBS3KitImg_ASDEFS   = ASM_FORMAT_OMF __NASM__
     222TEMPLATE_VBoxBS3KitImg_ARTOOL   = OPENWATCOM-16
     223TEMPLATE_VBoxBS3KitImg_CTOOL    = OPENWATCOM-16
     224TEMPLATE_VBoxBS3KitImg_CXXTOOL  = OPENWATCOM-16
     225TEMPLATE_VBoxBS3KitImg_CFLAGS   = -nt=TEXT16 -nd=DATA16 -nc=CODE16
     226TEMPLATE_VBoxBS3KitImg_CXXFLAGS = -nt=TEXT16 -nd=DATA16 -nc=CODE16
     227TEMPLATE_VBoxBS3KitImg_INCS     = bs3kit .
     228TEMPLATE_VBoxBS3KitImg_LDTOOL   = OPENWATCOM-WL
     229TEMPLATE_VBoxBS3KitImg_LDFLAGS  = \
     230        output raw offset=0x10000 \
     231        order \
     232         clname CODE16 \
     233          segment TEXT16  segaddr=0x1000 \
     234         clname DATA16 \
     235          segment DATA16  segaddr=0x1000 \
     236        clname CODE32 \
     237          segment TEXT32 \
     238        clname DATA32 \
     239          segment DATA32
     240
     241# BS3Kit template for 32-bit code.
     242TEMPLATE_VBoxBS3KitImg32 = Template for building BS3Kit test images.
     243TEMPLATE_VBoxBS3KitImg32_INSTTYPE = none
     244TEMPLATE_VBoxBS3KitImg32_ASTOOL   = NASM
     245TEMPLATE_VBoxBS3KitImg32_ASFLAGS := -f obj -g -w+orphan-labels #-P $(PATH_SUB_CURRENT)/bootsector2-first.mac
     246TEMPLATE_VBoxBS3KitImg32_ASDEFS   = ASM_FORMAT_OMF __NASM__
     247TEMPLATE_VBoxBS3KitImg32_ARTOOL   = OPENWATCOM
     248TEMPLATE_VBoxBS3KitImg32_CTOOL    = OPENWATCOM
     249TEMPLATE_VBoxBS3KitImg32_CXXTOOL  = OPENWATCOM
     250TEMPLATE_VBoxBS3KitImg32_CFLAGS   = -nt=TEXT32 -nd=DATA32 -nc=CODE32
     251TEMPLATE_VBoxBS3KitImg32_CXXFLAGS = -nt=TEXT32 -nd=DATA32 -nc=CODE32
     252TEMPLATE_VBoxBS3KitImg32_INCS     = bs3kit .
     253TEMPLATE_VBoxBS3KitImg32_LDTOOL   = VBoxBsUnusedLd
     254
     255# BS3Kit template for 64-bit code.
     256TEMPLATE_VBoxBS3KitImg64 = Template for building BS3Kit test images.
     257TEMPLATE_VBoxBS3KitImg64_INSTTYPE = none
     258TEMPLATE_VBoxBS3KitImg64_ASTOOL   = NASM
     259TEMPLATE_VBoxBS3KitImg64_ASFLAGS := -f elf64 -g -w+orphan-labels #-P $(PATH_SUB_CURRENT)/bootsector2-first.mac
     260TEMPLATE_VBoxBS3KitImg64_ASDEFS   = ASM_FORMAT_ELF __NASM__ TMPL
     261TEMPLATE_VBoxBS3KitImg64_ARTOOL   = OPENWATCOM
     262TEMPLATE_VBoxBS3KitImg64_CTOOL    = DUMMY
     263TEMPLATE_VBoxBS3KitImg64_CXXTOOL  = DUMMY
     264TEMPLATE_VBoxBS3KitImg64_INCS     = bs3kit .
     265TEMPLATE_VBoxBS3KitImg64_LDTOOL   = VBoxBsUnusedLd
     266
     267# BS3Kit template for the bootsector.
     268TEMPLATE_VBoxBS3KitBS = Template for building BS3Kit test images.
     269TEMPLATE_VBoxBS3KitBS_INST     = $(INST_VALIDATIONKIT)bootsectors/
     270TEMPLATE_VBoxBS3KitBS_INSTTYPE = none
     271TEMPLATE_VBoxBS3KitBS_BINSUFF  = .img
     272TEMPLATE_VBoxBS3KitBS_MODE     = 0644
     273TEMPLATE_VBoxBS3KitBS_ASTOOL   = YASM
     274TEMPLATE_VBoxBS3KitBS_ASFLAGS := -f bin --mapfile
     275TEMPLATE_VBoxBS3KitBS_ASDEFS   = ASM_FORMAT_BIN __YASM__
     276TEMPLATE_VBoxBS3KitBS_INCS     = bs3kit
     277TEMPLATE_VBoxBS3KitBS_LDTOOL   = VBoxBsCpLd
     278
     279# The boot sector.
     280MISCBINS += bs3-bootsector
     281bs3-bootsector_TEMPLATE = VBoxBS3KitBS
     282bs3-bootsector_SOURCES  = bs3kit/bs3-bootsector.asm
     283
     284# The BS3Kit library.
     285LIBRARIES += bs3kit-common-16
     286bs3kit-common-16_TEMPLATE = VBoxBS3KitImg
     287bs3kit-common-16_DEFS     = TMPL_PE16 BS3_CMN_ONLY
     288bs3kit-common-16_SOURCES  = \
     289        bs3kit/bs3-shutdown.asm
     290
     291# The 32-bit BS3Kit library.
     292LIBRARIES += bs3kit-common-32
     293bs3kit-common-32_TEMPLATE = VBoxBS3KitImg32
     294bs3kit-common-32_DEFS     = TMPL_PE32 BS3_CMN_ONLY
     295bs3kit-common-32_SOURCES  = \
     296        bs3kit/bs3-shutdown.asm
     297
     298# The 64-bit BS3Kit library.
     299LIBRARIES += bs3kit-common-64
     300bs3kit-common-64_TEMPLATE = VBoxBS3KitImg64
     301bs3kit-common-64_DEFS     = TMPL_LM64 BS3_CMN_ONLY
     302bs3kit-common-64_SOURCES  = \
     303        bs3kit/bs3-shutdown.asm
     304
     305endif # experimental
     306
    189307include $(FILE_KBUILD_SUB_FOOTER)
    190308
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-bootsector.asm

    r58574 r58588  
    11; $Id$
    22;; @file
    3 ; Common bootsector code init.
    4 ;
    5 ; In addition to initialize the stack at %7bf0 it loads the first 512KB of the
    6 ; floppy image at %7c00.  The control is handed over with interrupts disabled
    7 ; to a 'main' function defined by the includer.
    8 ;
    9 ; The following defines controls the mode we call main in:
    10 ;       - BS2_INIT_RM (default)
    11 ;       - BS2_INIT_PE32
    12 ;       - BS2_INIT_PP32
    13 ;       - BS2_INIT_PAE32
    14 ;       - BS2_INIT_LM64
    15 ;
    16 ; The following defines controls code inclusion:
    17 ;       - BS2_INC_RM
    18 ;       - BS2_INC_PE
    19 ;       - BS2_INC_PE16
    20 ;       - BS2_INC_PE32
    21 ;       - BS2_INC_PEV86
    22 ;       - BS2_INC_PP
    23 ;       - BS2_INC_PP16
    24 ;       - BS2_INC_PP32
    25 ;       - BS2_INC_PPV86
    26 ;       - BS2_INC_PAE
    27 ;       - BS2_INC_PAE16
    28 ;       - BS2_INC_PAE32
    29 ;       - BS2_INC_PAEV86
    30 ;       - BS2_INC_LM
    31 ;       - BS2_INC_LM16
    32 ;       - BS2_INC_LM32
    33 ;       - BS2_INC_LM64
    34 ;       - BS2_INC_CMN_R86
    35 ;       - BS2_INC_CMN_V86
    36 ;       - BS2_INC_CMN_P16
    37 ;       - BS2_INC_CMN_P32
    38 ;       - BS2_INC_CMN_P64
    39 ;       - BS2_WITH_TRAPS
     3; Generic bootsector for BS3.
     4;
     5; This sets up stack at %fff0 and loads the next sectors from the floppy at
     6; %10000 (1000:0000 in real mode), then starts executing at cs:ip=1000:0000.
    407;
    418
     
    6229
    6330
    64 ; map files should include symbols and everything.
     31
     32;*********************************************************************************************************************************
     33;*      Header Files                                                                                                             *
     34;*********************************************************************************************************************************
     35%include "bs3kit.mac"
     36%include "iprt/asmdefs.mac"
     37%include "iprt/x86.mac"
     38
     39
     40%ifdef __YASM__
    6541[map all]
    66 
    67 ;*******************************************************************************
    68 ;*      Header Files                                                           *
    69 ;*******************************************************************************
    70 %include "bootsector2-structures.mac"
    71 %include "bootsector2-common-macros-1.mac"
    72 
    73 
    74 ;*******************************************************************************
    75 ;*      Defined Constants And Macros                                           *
    76 ;*******************************************************************************
    77 ;; @name Static Memory Allocation
    78 ; @{
    79 ;; The boot sector load address.
    80 %define BS2_ADDR                07c00h
    81 ;; The stack is located before the code (and will overflow into the interrupt
    82 ; table and other essential system data).
    83 %define STACK_ADDR              (BS2_ADDR - 256)
    84 
    85 %ifdef BS2_WITH_TRAPS
    86 ;; The address of the ring-0 stack in bs2Tss32BitDf.
    87 %define BS2_DF_R0_STACK_ADDR    06800h
    88 ;; The address of the ring-0 stack in TSSxx.
    89 %define BS2_R0_STACK_ADDR       06000h
    90 ;; The address of the ring-1 stack in TSSxx.
    91 %define BS2_R1_STACK_ADDR       05000h
    92 ;; The address of the ring-2 stack in TSSxx.
    93 %define BS2_R2_STACK_ADDR       04800h
    94 %endif ; BS2_WITH_TRAPS
    95 
    96 ;;
    97 ; Where we save the boot registers during init.
    98 %define BS2_REG_SAVE_ADDR       06000h
    99 
    100 ;; The start of the memory area used for paging, stacks and so forth.
    101 %define BS2_PXX_BASE            080000h
    102 
    103 ;; The page map level 4 address (all entries point to BS2_LM_PDP_ADDR).
    104 %define BS2_LM_PML4_ADDR        080000h
    105 ;; The long mode page directory pointer table address.
    106 %define BS2_LM_PDP_ADDR         081000h
    107 ;; The PAE page directory pointer table address.
    108 %define BS2_PAE_PDP_ADDR        082000h
    109 ;; The address of the 4 PAE page directories.  Also used by long mode.
    110 %define BS2_PAE_PD_ADDR         083000h
    111 ;; The address of the 32-bit page directory.
    112 %define BS2_32B_PD_ADDR         087000h
    113 ;; User page table #0.
    114 %define BS2_USER_PX_0_ADDR      088000h
    115 ;; User page table #1.
    116 %define BS2_USER_PX_1_ADDR      089000h
    117 ;; User page table #2.
    118 %define BS2_USER_PX_2_ADDR      08a000h
    119 ;; User page table #3.
    120 %define BS2_USER_PX_3_ADDR      08b000h
    121 ;; User page table #4.
    122 %define BS2_USER_PX_4_ADDR      08c000h
    123 ;; User page table #5.
    124 %define BS2_USER_PX_5_ADDR      08d000h
    125 ;; User page table #6.
    126 %define BS2_USER_PX_6_ADDR      08e000h
    127 ;; User page table #7.
    128 %define BS2_USER_PX_7_ADDR      08f000h
    129 ;; The selector to use when accessing the PDP and PD from real mode.
    130 %define BS2_PXX_SEL             08000h
    131 ;; Converts a BS2_P*_ADDR into a BS2_PXX_SEL selector offset.
    132 %define BS2_PXX_OFF(Addr)       ( (Addr) - (BS2_PXX_SEL * 16) )
    133 
    134 ;; The base address in the default address spaces of the range where we are
    135 ; free to muck about as much as we like.  (This is a virtual address.)
    136 %define BS2_MUCK_ABOUT_BASE     000400000h
    137 
    138 ; We have some free space here 090000h...09a000h (stacks moved)
    139 
    140 ;; The address of the LDT.
    141 %define BS2_LDT_BASE            09b000h
    142 ;; The size of the LDT in bytes.
    143 %define BS2_LDT_SIZE            001fffh
    144 
    145 ;; The start of the memory area used for paging, stacks and so forth.
    146 %define BS2_PXX_LAST            09ffffh
    147 ;; @}
    148 
    149 
    150 ;;
    151 ; @name Group of 32-bit, 16-bit and 64-bit selectors for one ring.
    152 ; @{
    153 %define BS2_SEL_GRP_CS32            00h
    154 %define BS2_SEL_GRP_DS32            08h
    155 %define BS2_SEL_GRP_SS32            10h
    156 %define BS2_SEL_GRP_CS16            18h
    157 %define BS2_SEL_GRP_DS16            20h
    158 %define BS2_SEL_GRP_SS16            28h
    159 %define BS2_SEL_GRP_CS64            30h
    160 %define BS2_SEL_GRP_DS64            38h
    161 %define BS2_SEL_GRP_SS64            38h
    162 %define BS2_SEL_GRP_SIZE            40h
    163 ;; @}
    164 
    165 
    166 ;; Move to program.
    167 %ifndef BS2_WITHOUT_RAW_MODE
    168  %define BS2_WITH_RAW_MODE
    16942%endif
    170 
    171 ; Implicit code inclusion based on the init mode.
    172 %ifdef BS2_INIT_PE32
    173  %define BS2_INC_PE32
    174 %elifdef BS2_INIT_PP32
    175  %define BS2_INC_PP32
    176 %elifdef BS2_INIT_PAE32
    177  %define BS2_INC_PAE32
    178 %elifdef BS2_INIT_LM64
    179  %define BS2_INC_LM64
    180 %else
    181  %define BS2_INIT_RM                    ; the default
    182  %define BS2_INC_RM
    183 %endif
    184 
    185 ; Aliases.
    186 %ifdef BS2_INC_PE
    187  %define BS2_INC_PE16
    188  %define BS2_INC_PE32
    189  %define BS2_INC_PEV86
    190 %endif
    191 %ifdef BS2_INC_PP
    192  %define BS2_INC_PP16
    193  %define BS2_INC_PP32
    194  %define BS2_INC_PPV86
    195 %endif
    196 %ifdef BS2_INC_PAE
    197  %define BS2_INC_PAE16
    198  %define BS2_INC_PAE32
    199  %define BS2_INC_PAEV86
    200 %endif
    201 %ifdef BS2_INC_LM
    202  %define BS2_INC_LM16
    203  %define BS2_INC_LM32
    204  %define BS2_INC_LM64
    205 %endif
    206 
    207 ; Common code.
    208 %ifdef BS2_INC_RM
    209  %define BS2_INC_CMN_R86
    210 %endif
    211 %ifdef BS2_INC_PE16
    212  %define BS2_INC_CMN_P16
    213  %define BS2_INC_CMN_PE
    214  %define BS2_INC_CMN_PM
    215 %endif
    216 %ifdef BS2_INC_PE32
    217  %define BS2_INC_CMN_P32
    218  %define BS2_INC_CMN_PE
    219  %define BS2_INC_CMN_PM
    220 %endif
    221 %ifdef BS2_INC_PEV86
    222  %define BS2_INC_CMN_R86
    223  %define BS2_INC_CMN_V86
    224  %define BS2_INC_CMN_PE
    225  %define BS2_INC_CMN_PM
    226 %endif
    227 %ifdef BS2_INC_PP16
    228  %define BS2_INC_CMN_P16
    229  %define BS2_INC_CMN_PP
    230  %define BS2_INC_CMN_PM
    231 %endif
    232 %ifdef BS2_INC_PP32
    233  %define BS2_INC_CMN_P32
    234  %define BS2_INC_CMN_PP
    235  %define BS2_INC_CMN_PM
    236 %endif
    237 %ifdef BS2_INC_PPV86
    238  %define BS2_INC_CMN_R86
    239  %define BS2_INC_CMN_V86
    240  %define BS2_INC_CMN_PP
    241  %define BS2_INC_CMN_PM
    242 %endif
    243 %ifdef BS2_INC_PAE16
    244  %define BS2_INC_CMN_P16
    245  %define BS2_INC_CMN_PAE
    246  %define BS2_INC_CMN_PM
    247  %define BS2_INC_CMN_PAE_LM
    248 %endif
    249 %ifdef BS2_INC_PAE32
    250  %define BS2_INC_CMN_P32
    251  %define BS2_INC_CMN_PAE
    252  %define BS2_INC_CMN_PM
    253  %define BS2_INC_CMN_PAE_LM
    254 %endif
    255 %ifdef BS2_INC_PAEV86
    256  %define BS2_INC_CMN_R86
    257  %define BS2_INC_CMN_V86
    258  %define BS2_INC_CMN_PAE
    259  %define BS2_INC_CMN_PM
    260  %define BS2_INC_CMN_PAE_LM
    261 %endif
    262 %ifdef BS2_INC_LM16
    263  %define BS2_INC_CMN_P16
    264  %define BS2_INC_CMN_LM
    265  %define BS2_INC_CMN_PAE_LM
    266 %endif
    267 %ifdef BS2_INC_LM32
    268  %define BS2_INC_CMN_P32
    269  %define BS2_INC_CMN_LM
    270  %define BS2_INC_CMN_PAE_LM
    271 %endif
    272 %ifdef BS2_INC_LM64
    273  %define BS2_INC_CMN_LM64
    274  %define BS2_INC_CMN_LM
    275  %define BS2_INC_CMN_PAE_LM
    276 %endif
    277 
    278 
    279 ;
    280 ; Misc defines.
    281 ;
    282 ;; The offset of the TSS32.CR3 field.
    283 %define BS2_TSS32_CR3_OFF       01ch
    284 
    285 
    286 ;*******************************************************************************
    287 ;*      Structures and Typedefs                                                *
    288 ;*******************************************************************************
    289 
    29043
    29144;
     
    29346; Also declare all segments/sections to establish them and their order.
    29447;
    295         ORG BS2_ADDR
    296 
    297 section .text                                                   valign=16  align=16     progbits
    298 section .data       vfollows=.text          follows=.text       valign=16  align=16     progbits
    299 section .texthigh   vfollows=.data          follows=.data       valign=16  align=16     progbits
    300 section .traprecs   vfollows=.texthigh      follows=.texthigh   valign=8   align=8      progbits
    301 section .end        vfollows=.traprecs      follows=.traprecs   valign=512 align=512    progbits
    302 
    303 %define BEGINCODELOW    section .text     ;;< For 16-bit code.
    304 %define BEGINCODEHIGH   section .texthigh ;;< For 32-bit and 64-bit code.
    305 %define BEGINEND        section .end      ;;< For aligning image to 512 bytes.
    306 
    307 BEGINCODELOW
     48        ORG 07c00h
     49
    30850BITS 16
    30951start:
    310         jmp short bs2InitCode
    311         nop
    312         nop                             ; alignment
    313 
    314 ;
    315 ; Abuse the bios parameter block area for data storage.
    316 ;
    317 gdtr:
    318         dw  bs2GdtEnd - bs2Gdt - 1          ; limit 15:00
    319         dw  bs2Gdt                          ; base  15:00
    320         db  0                               ; base  23:16
    321         db  0                               ; unused
    322 
    323 idtr_null:
    324         dw  0                               ; limit 15:00
    325         dw  bs2Gdt                          ; base  15:00
    326         db  0                               ; base  23:16
    327         db  0                               ; unused
    328 
    329 %ifdef BS2_WITH_TRAPS
    330  %ifdef BS2_INC_CMN_PM
    331 idtr_32bit:
    332         dw  bs2Idt32bitEnd - bs2Idt32bit -1 ; limit 15:00
    333         dw  bs2Idt32bit                     ; base  15:00
    334         db  0                               ; base  23:16
    335         db  0                               ; unused
    336  %endif
    337 
    338  %ifdef BS2_INC_CMN_LM
    339 idtr_64bit:
    340         dw  bs2Idt64bitEnd - bs2Idt64bit -1 ; limit 15:00
    341         dw  bs2Idt64bit                     ; base  15:00
    342         db  0                               ; base  23:16
    343         db  0                               ; unused
    344  %endif
    345 
    346 %elifdef BS2_WITH_RAW_MODE
    347 idtr_dummy_32bit:
    348         dw  bs2DummyIdt32bitEnd - bs2DummyIdt32bit -1   ; limit 15:00
    349         dw  bs2DummyIdt32bit                            ; base  15:00
    350         db  0                                           ; base  23:16
    351         db  0                                           ; unused
    352 %endif
    353 
    354 idtr_real_mode:
    355         dw  01ffh                           ; limit 15:00
    356         dw  0                               ; base  15:00
    357         db  0                               ; base  23:16
    358         db  0                               ; unused
    359 
    360 g_achHex:
    361         db '0123456789abcdef', 0
    362 
    363 g_bBootDrv:
    364         db  80h                             ; Not in the official BPB location, but whatever.
    365 g_fCpuIntel:
     52        jmp short bs3InitCode
     53        db 0ah                          ; Should be nop, but this looks better.
     54g_OemId:                                ; 003h
     55        db 'BS3Kit', 0ah
     56
     57;
     58; DOS 4.0 Extended Bios Parameter Block:
     59;
     60g_cBytesPerSector:                      ; 00bh
     61        dw 512
     62g_cSectorsPerCluster:                   ; 00dh
     63        db 1
     64g_cReservedSectors:                     ; 00eh
     65        dw 1
     66g_cFATs:                                ; 010h
    36667        db 0
    367 g_fCpuAmd:
     68g_cRootDirEntries:                      ; 011h
     69        dw 0
     70g_cTotalSectors:                        ; 013h
     71        dw 0
     72g_bMediaDescriptor:                     ; 015h
    36873        db 0
    369 
    370 bs2BpbPadding:
    371         times 3dh - (bs2BpbPadding - start) db 0
     74g_cSectorsPerFAT:                       ; 016h
     75        dw 0
     76g_cPhysSectorsPerTrack:                 ; 018h
     77        dw 18
     78g_cHeads:                               ; 01ah
     79        dw 2
     80g_cHiddentSectors:                      ; 01ch
     81        dd 1
     82g_cLargeTotalSectors:                   ; 020h - We (ab)use this to indicate the number of sectors to load.
     83        dd 0
     84g_bBootDrv:                             ; 024h
     85        db 80h
     86g_bFlagsEtc:                            ; 025h
     87        db 0
     88g_bExtendedSignature:                   ; 026h
     89        db 0x29
     90g_dwSerialNumber:                       ; 027h
     91        dd 0x0a458634
     92g_abLabel:                              ; 02bh
     93        db 'VirtualBox', 0ah
     94g_abFSType:                             ; 036h
     95        db 'RawCode', 0ah
     96g_BpbEnd:                               ; 03ch
    37297
    37398
     
    375100; Where to real init code starts.
    376101;
    377 bs2InitCode:
     102bs3InitCode:
    378103        cli
    379104
    380 %ifdef BS2_INIT_SAVE_REGS
    381         ; save the registers if we've been asked to do so.
    382         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.rax], eax
    383         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.rsp], esp
    384         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.rbp], ebp
     105        ; save the registers.
     106        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.rax], eax
     107        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.rsp], esp
     108        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.rbp], ebp
    385109        mov     ax, ss
    386         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.ss], ax
     110        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.ss], ax
    387111        mov     ax, ds
    388         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.ds], ax
     112        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.ds], ax
    389113        mov     ax, es
    390         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.es], ax
     114        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.es], ax
    391115        mov     ax, fs
    392         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.fs], ax
     116        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.fs], ax
    393117        mov     ax, gs
    394 %endif
    395118
    396119        ; set up the segment reisters and stack.
     
    401124        mov     gs, ax
    402125        mov     ss, ax
    403         mov     esp, STACK_ADDR
     126        mov     esp, BS3_STACK_ADDR
    404127        mov     [esp],  eax             ; clear the first 16 bytes
    405128        mov     [esp + 04h],  eax
     
    408131        mov     ebp, esp
    409132
    410 %ifdef BS2_INIT_SAVE_REGS
    411133        ; Save more registers now that ds is known and the stack is usable.
    412134        pushfd
    413135        pop     eax
    414         mov     [BS2_REG_SAVE_ADDR + BS2REGS.rflags], eax
    415         mov     [BS2_REG_SAVE_ADDR + BS2REGS.rbx], ebx
    416         mov     [BS2_REG_SAVE_ADDR + BS2REGS.rcx], ecx
    417         mov     [BS2_REG_SAVE_ADDR + BS2REGS.rdx], edx
    418         mov     [BS2_REG_SAVE_ADDR + BS2REGS.rsi], esi
    419         mov     [BS2_REG_SAVE_ADDR + BS2REGS.rdi], edi
    420 %endif
     136        mov     [BS3_REG_SAVE_ADDR + BS3REGS.rflags], eax
     137        mov     [BS3_REG_SAVE_ADDR + BS3REGS.rbx], ebx
     138        mov     [BS3_REG_SAVE_ADDR + BS3REGS.rcx], ecx
     139        mov     [BS3_REG_SAVE_ADDR + BS3REGS.rdx], edx
     140        mov     [BS3_REG_SAVE_ADDR + BS3REGS.rsi], esi
     141        mov     [BS3_REG_SAVE_ADDR + BS3REGS.rdi], edi
     142        mov     eax, cr2
     143        mov     [BS3_REG_SAVE_ADDR + BS3REGS.cr2], eax
     144        mov     eax, cr3
     145        mov     [BS3_REG_SAVE_ADDR + BS3REGS.cr3], eax
     146        mov     eax, cr4
     147        mov     [BS3_REG_SAVE_ADDR + BS3REGS.cr4], eax
     148        mov     byte [BS3_REG_SAVE_ADDR + BS3REGS.cBits], 16
     149        xor     eax, eax
     150        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.cs], ax
     151        mov     ax, start
     152        mov     [cs:BS3_REG_SAVE_ADDR + BS3REGS.rip], eax
    421153
    422154        ; Make sure caching is enabled and alignment is off.
    423155        mov     eax, cr0
    424 %ifdef BS2_INIT_SAVE_REGS
    425         mov     [BS2_REG_SAVE_ADDR + BS2REGS.cr0], eax
    426 %endif
     156        mov     [BS3_REG_SAVE_ADDR + BS3REGS.cr0], eax
    427157        and     eax, ~(X86_CR0_NW | X86_CR0_CD | X86_CR0_AM)
    428158        mov     cr0, eax
    429159
    430160        ; Load all the code.
    431         call    bs2InitLoadImage
    432161        mov     [g_bBootDrv], dl
    433 
    434         ; Initialize the data structures for the included modes requiring this.
    435 %ifdef BS2_INC_CMN_PP
    436         call    bs2InitPagedProtMode
    437 %endif
    438 %ifdef BS2_INC_CMN_PAE
    439         call    bs2InitPaeProtMode
    440 %endif
    441 %ifdef BS2_INC_CMN_LM
    442         call    bs2InitLongMode
    443 %endif
    444 
    445         ; Entered the desired mode.
    446 %ifdef BS2_INIT_PE32
    447         call    Bs2EnterMode_rm_pe32
    448 BITS 32
    449 %endif
    450 %ifdef BS2_INIT_PP32
    451         call    Bs2EnterMode_rm_pp32
    452 BITS 32
    453 %endif
    454 %ifdef BS2_INIT_PAE32
    455         call    Bs2EnterMode_rm_pae32
    456 BITS 32
    457 %endif
    458 %ifdef BS2_INIT_LM64
    459         call    Bs2EnterMode_rm_lm64
    460 BITS 64
    461 %endif
    462 %ifdef BS2_INIT_RM
    463         call    SetCpuModeGlobals_rm
    464 %endif
    465 
    466 %ifdef BS2_WITH_RAW_MODE
    467         ;
    468         ; Mask interrupts and then set IF.
    469         ;
    470         mov     al, 0ffh
    471         out     021h, al
    472         out     0a1h, al
    473         sti
    474 %endif
    475 
    476         jmp     bs2DoneInit
     162        call    bs3InitLoadImage
     163
     164        ;
     165        ; Call the user 'main' procedure (shouldn't return).
     166        ;
     167        call    1000h:0000h
     168
     169        ; Panic/hang.
     170Bs3Panic:
     171        cli
     172        hlt
     173        jmp     Bs3Panic
     174
    477175
    478176
     
    480178; Loads the image off the floppy.
    481179;
    482 ; This uses the the_end label to figure out the length.  For this to work
    483 ; cleanly the label must be aligned on a sector boundrary.  Use BS2_PAD_IMAGE
    484 ; to make sure this is the case.
     180; This uses g_cLargeTotalSectors to figure out how much to load.
    485181;
    486182; Clobbers everything except ebp and esp.  Panics on failure.
     
    489185; @uses     ax, cx, bx, esi, di
    490186;
    491 BEGINCODELOW
    492 BITS 16
    493 BEGINPROC bs2InitLoadImage
     187BEGINPROC bs3InitLoadImage
    494188        push    bp
    495189        mov     bp, sp
     
    518212        ; Reload all the sectors one at a time (avoids problems).
    519213        ;
    520         lea     esi, [dword the_end]
    521         sub     esi, start
    522         shr     esi, 9                  ; si = number of sectors to load.
    523         mov     di, BS2_ADDR / 16       ; The current load segment.
    524         mov     cx, 0001h               ; ch/cylinder=0 (0-based); cl/sector=1 (1-based)
     214        mov     esi, [g_cLargeTotalSectors]
     215        dec     esi
     216        mov     di, BS3_LOAD_ADDR / 16  ; The current load segment.
     217        mov     cx, 0002h               ; ch/cylinder=0 (0-based); cl/sector=2 (1-based)
    525218        xor     dh, dh                  ; dh/head=0
    526219.the_load_loop:
     
    574267        movzx   bx, byte [bp - 2 - 1]    ; read the ah of the pusha frame
    575268        shr     bl, 4
    576         mov     al, [bx + g_achHex]
     269        mov     al, [bx + .s_achHex]
    577270        int     10h
    578271
    579272        movzx   bx, byte [bp - 2 - 1]    ; read the ah of the pusha frame
    580273        and     bl, 0fh
    581         mov     al, [bx + g_achHex]
     274        mov     al, [bx + .s_achHex]
    582275        int     10h
    583276
    584277        ; panic
    585278        popa
    586         call    Bs2Panic
     279        call    Bs3Panic
    587280.s_szErrMsg:
    588281        db 13, 10, 'read error: '
    589282.s_szErrMsgEnd:
    590 ENDPROC bs2InitLoadImage
    591 
    592 ;; Pads the image so bs2InitLoadImage can load it without trouble.
    593 %macro BS2_PAD_IMAGE 0
    594 bs2PadImageLabel:
    595 ;        times ( (512*18*2) - ( (bs2PadImageLabel - start) % (512*18*2) ) ) db 0        ; track aligned size.
    596         times ( 512 - ( (bs2PadImageLabel - start) % 512 ) ) db 0                       ; sector aligned size.
    597 ;        times ( 10000h - BS2_ADDR - (bs2PadImageLabel - start) ) db 0                   ; full segment 0 size.
    598 %endmacro
    599 
    600 
    601 ;;
    602 ; Shutdown routine that will work in real and protected  mode, providing
    603 ; that SS is valid that we can load it into DS.
    604 ;
    605 ; Does not return.
    606 ;
    607 BEGINCODELOW
    608 BITS 16
    609 BEGINPROC Bs2Shutdown
    610         cli
    611         mov     bl, 64
    612         mov     dx, 08900h
    613         mov     ax, ss
    614         mov     ds, ax
    615 .retry:
    616         mov     ecx, 8
    617         mov     esi, .s_szShutdown
    618         rep outsb
    619         dec     bl
    620         jnz     .retry
    621         ; Shutdown failed!
    622         jmp     Bs2Panic
    623 .s_szShutdown:
    624         db      'Shutdown', 0
    625 ENDPROC Bs2Shutdown
    626 
    627 
    628 ;;
    629 ; Panic routine for real mode.
    630 ;
    631 ; Does not return.
    632 ;
    633 BEGINCODELOW
    634 BITS 16
    635 BEGINPROC Bs2Panic
    636         cli
    637 .hlt_again:
    638         hlt
    639         jmp     .hlt_again
    640 ENDPROC Bs2Panic
    641 
    642 
    643 ;
    644 ; Padd the remainder of the sector with zeros and
    645 ; end it with the dos signature.
    646 ;
    647 bs2Padding:
    648         times 510 - (bs2Padding - start) db 0
    649         db 055h, 0aah
    650 
    651 
    652 ;
    653 ; The GDT (X86DESCGENERIC).
    654 ;
    655 align 8, db 0
    656 bs2Gdt:
    657         dw  00000h, 00000h, 00000h, 00000h      ; null selector
    658 %define BS2_SEL_R0_BASE                         08h
    659 %define BS2_SEL_CS32                            08h
    660         dw  0ffffh, 00000h, 09b00h, 000cfh      ; 32-bit flat code  segment.
    661 %define BS2_SEL_DS32                            10h
    662         dw  0ffffh, 00000h, 09300h, 000cfh      ; 32-bit flat data  segment.
    663 %define BS2_SEL_SS32                            18h
    664         dw  0ffffh, 00000h, 09300h, 000cfh      ; 32-bit flat stack segment.
    665 %define BS2_SEL_CS16                            20h
    666         dw  0ffffh, 00000h, 09b00h, 00000h      ; 16-bit code segment with base 0.
    667 %define BS2_SEL_DS16                            28h
    668         dw  0ffffh, 00000h, 09300h, 00000h      ; 16-bit data segment with base 0.
    669 %define BS2_SEL_SS16                            30h
    670         dw  0ffffh, 00000h, 09300h, 00000h      ; 16-bit stack segment with base 0.
    671 %define BS2_SEL_CS64                            38h
    672         dw  0ffffh, 00000h, 09a00h, 000afh      ; 64-bit code segment.
    673 %define BS2_SEL_DS64                            40h
    674 %define BS2_SEL_SS64                            40h
    675         dw  0ffffh, 00000h, 09300h, 000afh      ; 64-bit stack and data segment.
    676         dw  00000h, 00000h, 00000h, 00000h      ; Unused
    677 %define BS2_SEL_MMIO16                          50h
    678 %define BS2_SEL_MMIO16_BASE                     0100000h
    679         dw  0ffffh, 00000h, 09310h, 00000h      ; 16-bit VMMDev MMIO segment with base 0100000h.
    680         dw  00000h, 00000h, 00000h, 00000h      ; Unused
    681 %define BS2_SEL_LDT                             60h ; LDT usage requires manual LLDT and setting up.
    682         dw  BS2_LDT_SIZE, BS2_LDT_BASE & 0xffff, 08200h | ((BS2_LDT_BASE >> 16) & 0xff), 00000h
    683         dw  00000h, 00000h, 00000h, 00000h      ; zero for 64-bit mode.
    684 %define BS2_SEL_CS16_EO                         70h
    685         dw  0fffeh, 00000h, 09800h, 00000h      ; 16-bit code segment with base 0, not accessed, execute only, short limit.
    686         dw  00000h, 00000h, 00000h, 00000h      ; unused.
    687 %ifdef BS2_WITH_TRAPS
    688  %ifdef BS2_INC_CMN_PM
    689   %define BS2_SEL_TSS32                         80h
    690         dw  (bs2Tss32BitEnd - bs2Tss32Bit) - 1  ; 32-bit TSS.
    691         dw  bs2Tss32Bit
    692         db  0
    693         db  X86_SEL_TYPE_SYS_386_TSS_AVAIL | 0x80
    694         dw  0
    695   %define BS2_SEL_TSS32_DF                      88h
    696         dw  (bs2Tss32BitDfEnd - bs2Tss32BitDf) - 1; 32-bit TSS, double fault.
    697         dw  bs2Tss32BitDf
    698         db  0
    699         db  X86_SEL_TYPE_SYS_386_TSS_AVAIL | 0x80
    700         dw  0
    701  %else
    702         dw  00000h, 00000h, 00000h, 00000h
    703         dw  00000h, 00000h, 00000h, 00000h
    704  %endif
    705  %ifdef BS2_INC_CMN_LM
    706   %define BS2_SEL_TSS64                         90h
    707         dw  (bs2Tss64BitEnd - bs2Tss64Bit) - 1  ; 32-bit TSS.
    708         dw  bs2Tss64Bit
    709         db  0
    710         db  AMD64_SEL_TYPE_SYS_TSS_AVAIL | 0x80
    711         dw  0
    712         dw  00000h, 00000h, 00000h, 00000h      ; 2nd half of the 64-bit selector (not necessary).
    713  %else
    714         dw  00000h, 00000h, 00000h, 00000h
    715         dw  00000h, 00000h, 00000h, 00000h
    716  %endif
    717 %endif
    718         ; Ring-1 selectors.
    719 %define BS2_SEL_R1_BASE                         0a0h
    720 %define BS2_SEL_R1_CS32                         0a0h
    721         dw  0ffffh, 00000h, 0bb00h, 000cfh      ; Ring-1 32-bit flat code  segment.
    722 %define BS2_SEL_R1_DS32                         0a8h
    723         dw  0ffffh, 00000h, 0b300h, 000cfh      ; Ring-1 32-bit flat data  segment.
    724 %define BS2_SEL_R1_SS32                         0b0h
    725         dw  0ffffh, 00000h, 0b300h, 000cfh      ; Ring-1 32-bit flat stack segment.
    726 %define BS2_SEL_R1_CS16                         0b8h
    727         dw  0ffffh, 00000h, 0bb00h, 00000h      ; Ring-1 16-bit code segment with base 0.
    728 %define BS2_SEL_R1_DS16                         0c0h
    729         dw  0ffffh, 00000h, 0b300h, 00000h      ; Ring-1 16-bit data segment with base 0.
    730 %define BS2_SEL_R1_SS16                         0c8h
    731         dw  0ffffh, 00000h, 0b300h, 00000h      ; Ring-1 16-bit stack segment with base 0.
    732 %define BS2_SEL_R1_CS64                         0d0h
    733         dw  0ffffh, 00000h, 0ba00h, 000afh      ; Ring-1 64-bit code segment.
    734 %define BS2_SEL_R1_DS64                         0d8h
    735 %define BS2_SEL_R1_SS64                         0d8h
    736         dw  0ffffh, 00000h, 0b300h, 000afh      ; Ring-1 64-bit stack and data segment.
    737 
    738         ; Ring-2 selectors.
    739 %define BS2_SEL_R2_BASE                         0e0h
    740 %define BS2_SEL_R2_CS32                         0e0h
    741         dw  0ffffh, 00000h, 0db00h, 000cfh      ; Ring-2 32-bit flat code  segment.
    742 %define BS2_SEL_R2_DS32                         0e8h
    743         dw  0ffffh, 00000h, 0d300h, 000cfh      ; Ring-2 32-bit flat data  segment.
    744 %define BS2_SEL_R2_SS32                         0f0h
    745         dw  0ffffh, 00000h, 0d300h, 000cfh      ; Ring-2 32-bit flat stack segment.
    746 %define BS2_SEL_R2_CS16                         0f8h
    747         dw  0ffffh, 00000h, 0db00h, 00000h      ; Ring-2 16-bit code segment with base 0.
    748 %define BS2_SEL_R2_DS16                         0f0h
    749         dw  0ffffh, 00000h, 0d300h, 00000h      ; Ring-2 16-bit data segment with base 0.
    750 %define BS2_SEL_R2_SS16                         108h
    751         dw  0ffffh, 00000h, 0d300h, 00000h      ; Ring-2 16-bit stack segment with base 0.
    752 %define BS2_SEL_R2_CS64                         110h
    753         dw  0ffffh, 00000h, 0da00h, 000afh      ; Ring-2 64-bit code segment.
    754 %define BS2_SEL_R2_DS64                         118h
    755 %define BS2_SEL_R2_SS64                         118h
    756         dw  0ffffh, 00000h, 0d300h, 000afh      ; Ring-2 64-bit stack and data segment.
    757 
    758         ; Ring-3 selectors.
    759 %define BS2_SEL_R3_BASE                         120h
    760 %define BS2_SEL_R3_CS32                         120h
    761         dw  0ffffh, 00000h, 0fb00h, 000cfh      ; Ring-3 32-bit flat code  segment.
    762 %define BS2_SEL_R3_DS32                         128h
    763         dw  0ffffh, 00000h, 0f300h, 000cfh      ; Ring-3 32-bit flat data  segment.
    764 %define BS2_SEL_R3_SS32                         130h
    765         dw  0ffffh, 00000h, 0f300h, 000cfh      ; Ring-3 32-bit flat stack segment.
    766 %define BS2_SEL_R3_CS16                         138h
    767         dw  0ffffh, 00000h, 0fb00h, 00000h      ; Ring-3 16-bit code segment with base 0.
    768 %define BS2_SEL_R3_DS16                         140h
    769         dw  0ffffh, 00000h, 0f300h, 00000h      ; Ring-3 16-bit data segment with base 0.
    770 %define BS2_SEL_R3_SS16                         148h
    771         dw  0ffffh, 00000h, 0f300h, 00000h      ; Ring-3 16-bit stack segment with base 0.
    772 %define BS2_SEL_R3_CS64                         150h
    773         dw  0ffffh, 00000h, 0fa00h, 000afh      ; Ring-1 64-bit code segment.
    774 %define BS2_SEL_R3_DS64                         158h
    775 %define BS2_SEL_R3_SS64                         158h
    776         dw  0ffffh, 00000h, 0f300h, 000afh      ; Ring-1 64-bit stack and data segment.
    777 
    778         ; Here follows a bunch of spare GDT entries for (ab)use in testing.
    779 %define BS2_SEL_SPARE0                          160h
    780 bs2GdtSpare0:
    781         dq 0
    782 %define BS2_SEL_SPARE1                          (BS2_SEL_SPARE0 + 08h)
    783 bs2GdtSpare1:
    784         dq 0
    785 %define BS2_SEL_SPARE2                          (BS2_SEL_SPARE0 + 10h)
    786 bs2GdtSpare2:
    787         dq 0
    788 %define BS2_SEL_SPARE3                          (BS2_SEL_SPARE0 + 18h)
    789 bs2GdtSpare3:
    790         dq 0
    791 bs2GdtEnd:
    792 
    793 
    794 %ifndef BS2_WITH_TRAPS
    795  %ifdef BS2_WITH_RAW_MODE
    796 ;
    797 ; Dummy 32-bit IDT for making CSAM happy.
    798 ;
    799 align 16, db 0
    800 bs2DummyIdt32bit:
    801         dw 0, 0, 0, 0
    802         dw 0, 0, 0, 0
    803         dw 0, 0, 0, 0
    804         dw 0, 0, 0, 0
    805 bs2DummyIdt32bitEnd
    806  %endif
    807 %endif
    808 
    809 
    810 ;
    811 ; Mode initialization routines.
    812 ;
    813 
    814 %ifdef BS2_INC_CMN_PP
    815 ;;
    816 ; Initializes the paged protected mode structures during init.
    817 ;
    818 ; @uses     ebx, esi
    819 ;
    820 BEGINCODELOW
    821 BITS 16
    822 BEGINPROC bs2InitPagedProtMode
    823         push    ds
    824 
    825         ;
    826         ; Create a paging hierarchy
    827         ;
    828         mov     bx, BS2_PXX_SEL
    829         mov     ds, bx
    830         mov     ebx, BS2_PXX_OFF(BS2_32B_PD_ADDR)
    831         xor     esi, esi                    ; physical address
    832 
    833         ; The page directory.
    834 .pd_loop:
    835         mov     dword [bx], esi
    836         or      word [bx], X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_PS | X86_PDE4M_US
    837         add     esi, _4M
    838         add     bx, 4
    839         test    bx, 0fffh
    840         jnz     .pd_loop
    841 
    842 %ifdef BS2_WITH_RAW_MODE
    843         ;
    844         ; Make sure there is some free space for the hypervisor near the top
    845         ; of the address space (last 4MB is mapped).
    846         ;
    847         and     byte [bx - 08h], 0feh
    848         and     byte [bx - 0ch], 0feh
    849         and     byte [bx - 10h], 0feh
    850         and     byte [bx - 14h], 0feh
    851 %endif
    852 
    853         pop     ds
    854         ret
    855 ENDPROC   bs2InitPagedProtMode
    856 %endif ; BS2_INC_CMN_PP
    857 
    858 
    859 %ifdef BS2_INC_CMN_PAE_LM
    860 ;;
    861 ; Initializes the PAE page directories.
    862 ;
    863 ; Assumes ds is set to BS2_PXX_SEL already and that edx is zero.
    864 ;
    865 ; @uses         ebx, esi
    866 ; @internal
    867 ;
    868 BEGINPROC bs2InitPaePageDirs
    869         mov     esi, X86_PDE4M_P | X86_PDE4M_RW | X86_PDE4M_PS | X86_PDE4M_US
    870         mov     ebx, BS2_PXX_OFF(BS2_PAE_PD_ADDR)
    871 .pd_loop:
    872         mov     [bx], esi
    873         mov     [bx + 4], edx
    874         add     esi, _2M
    875         add     bx, 8
    876         test    bx, 0fffh
    877         jnz     .pd_loop
    878         cmp     bx, BS2_PXX_OFF(BS2_PAE_PD_ADDR + 4*_4K)
    879         jne     .pd_loop
    880 
    881 %ifdef BS2_WITH_RAW_MODE
    882         ;
    883         ; Make sure there is some free space for the hypervisor near the top
    884         ; of the address space (last 4MB is mapped).
    885         ;
    886         and     byte [bx - 10h], 0feh
    887         and     byte [bx - 18h], 0feh
    888         and     byte [bx - 20h], 0feh
    889         and     byte [bx - 28h], 0feh
    890 %endif
    891 
    892         ret
    893 ENDPROC   bs2InitPaePageDirs
    894 %endif ; BS2_INC_CMN_PAE_LM
    895 
    896 
    897 %ifdef BS2_INC_CMN_PAE
    898 ;;
    899 ; Initializes the PAE protected mode structures during init.
    900 ;
    901 ; @uses     edx, ebx, esi.
    902 ;
    903 BEGINCODELOW
    904 BITS 16
    905 BEGINPROC bs2InitPaeProtMode
    906         push    ds
    907 
    908         mov     dx, BS2_PXX_SEL
    909         mov     ds, dx
    910         xor     edx, edx
    911 
    912         ;
    913         ; Join paths with long mode.
    914         ;
    915         call    bs2InitPaePageDirs
    916 
    917         ;
    918         ; Create the page directory pointer table.
    919         ;
    920         mov     ebx, BS2_PXX_OFF(BS2_PAE_PDP_ADDR)
    921         mov     dword [bx],       (BS2_PAE_PD_ADDR        ) | X86_PDPE_P
    922         mov     dword [bx + 04h], edx
    923         mov     dword [bx + 08h], (BS2_PAE_PD_ADDR + 1000h) | X86_PDPE_P
    924         mov     dword [bx + 0ch], edx
    925         mov     dword [bx + 10h], (BS2_PAE_PD_ADDR + 2000h) | X86_PDPE_P
    926         mov     dword [bx + 14h], edx
    927         mov     dword [bx + 18h], (BS2_PAE_PD_ADDR + 3000h) | X86_PDPE_P
    928         mov     dword [bx + 1ch], edx
    929 
    930         pop     ds
    931         ret
    932 ENDPROC   bs2InitPaeProtMode
    933 %endif ; BS2_INC_CMN_PAE
    934 
    935 
    936 %ifdef BS2_INC_CMN_LM
    937 ;;
    938 ; Initializes the long mode structures during init.
    939 ;
    940 ; @uses     edx, ebx, esi
    941 ;
    942 BEGINCODELOW
    943 BITS 16
    944 BEGINPROC bs2InitLongMode
    945         push    ds
    946 
    947         mov     dx, BS2_PXX_SEL
    948         mov     ds, dx
    949         xor     edx, edx
    950 
    951         ;
    952         ; Join paths with the PAE code.
    953         ;
    954         call    bs2InitPaePageDirs
    955 
    956         ;
    957         ; Create the long mode page directory pointer table.
    958         ;
    959         mov     ebx, BS2_PXX_OFF(BS2_LM_PDP_ADDR)
    960 .pdptr_loop:
    961         mov     dword [bx],       (BS2_PAE_PD_ADDR        ) | X86_PDPE_P | X86_PDPE_RW | X86_PDPE_US
    962         mov     dword [bx + 04h], edx
    963         mov     dword [bx + 08h], (BS2_PAE_PD_ADDR + 1000h) | X86_PDPE_P | X86_PDPE_RW | X86_PDPE_US
    964         mov     dword [bx + 0ch], edx
    965         mov     dword [bx + 10h], (BS2_PAE_PD_ADDR + 2000h) | X86_PDPE_P | X86_PDPE_RW | X86_PDPE_US
    966         mov     dword [bx + 14h], edx
    967         mov     dword [bx + 18h], (BS2_PAE_PD_ADDR + 3000h) | X86_PDPE_P | X86_PDPE_RW | X86_PDPE_US
    968         mov     dword [bx + 1ch], edx
    969         add     bx, 20h
    970         test    bx, 0fffh
    971         jnz     .pdptr_loop
    972 
    973         ;
    974         ; Set up the page map level 4 table, all entries mapping the same PDPTR.
    975         ;
    976         mov     ebx, BS2_PXX_OFF(BS2_LM_PML4_ADDR)
    977 .pml4_loop:
    978         mov     dword [bx], BS2_LM_PDP_ADDR | X86_PML4E_P | X86_PML4E_RW | X86_PML4E_US
    979         mov     dword [bx + 4], edx
    980         add     bx, 8
    981         test    bx, 0fffh
    982         jnz     .pml4_loop
    983 
    984         pop     ds
    985         ret
    986 ENDPROC   bs2InitLongMode
    987 %endif ; BS2_INC_CMN_LM
    988 
    989 
    990 
    991 ;
    992 ; Routines for entering the different modes.
    993 ;
    994 
    995 %ifdef BS2_INC_RM
    996 ;;
    997 ; Dummy.
    998 BEGINCODELOW
    999 BITS 16
    1000 BEGINPROC Bs2EnterMode_rm_rm
    1001         ret
    1002 ENDPROC Bs2EnterMode_rm_rm
    1003 %endif ; BS2_INC_RM
    1004 
    1005 
    1006 %ifdef BS2_INC_PE16
    1007 ;;
    1008 ; Enters unpaged protected mode from real mode (cs = 0).
    1009 ;
    1010 ; @returns  cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
    1011 ;           ebp and esp converted to 32/16-bit.
    1012 ;           All other registers are preserved.
    1013 ; @uses     nothing
    1014 ;
    1015 BEGINCODELOW
    1016 BITS 16
    1017 BEGINPROC Bs2EnterMode_rm_pe16
    1018         push    eax
    1019         pushfd
    1020         cli
    1021 %ifndef BS2_NOINC_COMMON
    1022         push    word SetCpuModeGlobals_pe16
    1023 %endif
    1024 
    1025         ;
    1026         ; Switch to protected mode.
    1027         ;
    1028         xor     ax, ax
    1029         mov     ds, ax
    1030         lgdt    [gdtr]
    1031 %ifdef BS2_WITH_TRAPS
    1032         lidt    [idtr_32bit]
    1033 %elifdef BS2_WITH_RAW_MODE
    1034         lidt    [idtr_dummy_32bit]
    1035 %else
    1036         lidt    [idtr_null]
    1037 %endif
    1038 
    1039         mov     eax, cr0
    1040         or      eax, X86_CR0_PE
    1041         and     eax, 0ffffffffh - X86_CR0_PG
    1042         mov     cr0, eax
    1043         jmp far BS2_SEL_CS16:bs2ProtModeCode16Start_p16
    1044 ENDPROC   Bs2EnterMode_rm_pe16
    1045 %endif ; BS2_INC_PE16
    1046 
    1047 
    1048 %ifdef BS2_INC_PE32
    1049 ;;
    1050 ; Enters unpaged protected mode from real mode (cs = 0).
    1051 ;
    1052 ; @returns  cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
    1053 ;           ebp and esp converted to 32-bit.
    1054 ;           All other registers are preserved.
    1055 ; @uses     nothing
    1056 ;
    1057 BEGINCODELOW
    1058 BITS 16
    1059 BEGINPROC Bs2EnterMode_rm_pe32
    1060         push    word 0
    1061         push    eax
    1062         pushfd
    1063         cli
    1064 %ifndef BS2_NOINC_COMMON
    1065         push    dword SetCpuModeGlobals_pe32
    1066 %endif
    1067 
    1068         ; Do the mode switch.
    1069         xor     ax, ax
    1070         mov     ds, ax
    1071         lgdt    [gdtr]
    1072 %ifdef BS2_WITH_TRAPS
    1073         lidt    [idtr_32bit]
    1074 %elifdef BS2_WITH_RAW_MODE
    1075         lidt    [idtr_dummy_32bit]
    1076 %else
    1077         lidt    [idtr_null]
    1078 %endif
    1079 
    1080         mov     eax, cr0
    1081         or      eax, X86_CR0_PE
    1082         and     eax, 0ffffffffh - X86_CR0_PG
    1083         mov     cr0, eax
    1084         jmp far BS2_SEL_CS32:bs2ProtModeCode32Start_p32
    1085 ENDPROC   Bs2EnterMode_rm_pe32
    1086 %endif ; BS2_INC_PE32
    1087 
    1088 
    1089 ;; @todo BS2_INC_PEV86
    1090 
    1091 
    1092 %ifdef BS2_INC_PP16
    1093 ;;
    1094 ; Enters paged protected mode from real mode (cs = 0).
    1095 ;
    1096 ; @returns  cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
    1097 ;           ebp and esp converted to 16/32-bit.
    1098 ;           All other registers are preserved.
    1099 ; @uses     nothing
    1100 ;
    1101 BEGINCODELOW
    1102 BITS 16
    1103 BEGINPROC Bs2EnterMode_rm_pp16
    1104         push    eax
    1105         pushfd
    1106         cli
    1107 %ifndef BS2_NOINC_COMMON
    1108         push    word SetCpuModeGlobals_pp16
    1109 %endif
    1110 
    1111         ; Do the mode switch.
    1112         xor     ax, ax
    1113         mov     ds, ax
    1114         lgdt    [gdtr]
    1115 %ifdef BS2_WITH_TRAPS
    1116         lidt    [idtr_32bit]
    1117 %elifdef BS2_WITH_RAW_MODE
    1118         lidt    [idtr_dummy_32bit]
    1119 %else
    1120         lidt    [idtr_null]
    1121 %endif
    1122 
    1123         mov     eax, BS2_32B_PD_ADDR
    1124         mov     cr3, eax
    1125 %ifdef BS2_WITH_TRAPS
    1126         mov     [bs2Tss32BitDf + BS2_TSS32_CR3_OFF], eax
    1127 %endif
    1128 
    1129         mov     eax, cr4
    1130         or      eax, X86_CR4_PSE
    1131         and     eax, ~X86_CR4_PAE
    1132         mov     cr4, eax
    1133 
    1134         mov     eax, cr0
    1135         or      eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
    1136         mov     cr0, eax
    1137         jmp far BS2_SEL_CS16:bs2ProtModeCode16Start_p16
    1138 ENDPROC   Bs2EnterMode_rm_pp16
    1139 %endif ; BS2_INC_PP16
    1140 
    1141 
    1142 %ifdef BS2_INC_PP32
    1143 ;;
    1144 ; Enters paged protected mode from real mode (cs = 0).
    1145 ;
    1146 ; @returns  cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
    1147 ;           ebp and esp converted to 32-bit.
    1148 ;           All other registers are preserved.
    1149 ; @uses     nothing
    1150 ;
    1151 BEGINCODELOW
    1152 BITS 16
    1153 BEGINPROC Bs2EnterMode_rm_pp32
    1154         push    word 0
    1155         push    eax
    1156         pushfd
    1157         cli
    1158 %ifndef BS2_NOINC_COMMON
    1159         push    dword SetCpuModeGlobals_pp32
    1160 %endif
    1161 
    1162         ; Do the mode switch.
    1163         xor     ax, ax
    1164         mov     ds, ax
    1165         lgdt    [gdtr]
    1166 %ifdef BS2_WITH_TRAPS
    1167         lidt    [idtr_32bit]
    1168 %elifdef BS2_WITH_RAW_MODE
    1169         lidt    [idtr_dummy_32bit]
    1170 %else
    1171         lidt    [idtr_null]
    1172 %endif
    1173 
    1174         mov     eax, BS2_32B_PD_ADDR
    1175         mov     cr3, eax
    1176 %ifdef BS2_WITH_TRAPS
    1177         mov     [bs2Tss32BitDf + BS2_TSS32_CR3_OFF], eax
    1178 %endif
    1179 
    1180         mov     eax, cr4
    1181         or      eax, X86_CR4_PSE
    1182         and     eax, ~X86_CR4_PAE
    1183         mov     cr4, eax
    1184 
    1185         mov     eax, cr0
    1186         or      eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
    1187         mov     cr0, eax
    1188         jmp far BS2_SEL_CS32:bs2ProtModeCode32Start_p32
    1189 ENDPROC   Bs2EnterMode_rm_pp32
    1190 %endif ; BS2_INC_PP16
    1191 
    1192 
    1193 ;; @todo BS2_INC_PPV86
    1194 
    1195 
    1196 %ifdef BS2_INC_PAE16
    1197 ;;
    1198 ; Enters PAE protected mode from real mode (cs = 0).
    1199 ;
    1200 ; @returns  cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
    1201 ;           ebp and esp converted to 16/32-bit.
    1202 ;           All other registers are preserved.
    1203 ; @uses     nothing
    1204 ;
    1205 BEGINCODELOW
    1206 BITS 16
    1207 BEGINPROC Bs2EnterMode_rm_pae16
    1208         push    eax
    1209         pushfd
    1210         cli
    1211 %ifndef BS2_NOINC_COMMON
    1212         push    word SetCpuModeGlobals_pae16
    1213 %endif
    1214 
    1215         ; Do the mode switch.
    1216         xor     ax, ax
    1217         mov     ds, ax
    1218         lgdt    [gdtr]
    1219 %ifdef BS2_WITH_TRAPS
    1220         lidt    [idtr_32bit]
    1221 %elifdef BS2_WITH_RAW_MODE
    1222         lidt    [idtr_dummy_32bit]
    1223 %else
    1224         lidt    [idtr_null]
    1225 %endif
    1226 
    1227         mov     eax, BS2_PAE_PDP_ADDR
    1228         mov     cr3, eax
    1229 %ifdef BS2_WITH_TRAPS
    1230         mov     [bs2Tss32BitDf + BS2_TSS32_CR3_OFF], eax
    1231 %endif
    1232 
    1233         mov     eax, cr4
    1234         or      eax, X86_CR4_PAE | X86_CR4_PSE
    1235         mov     cr4, eax
    1236 
    1237         mov     eax, cr0
    1238         or      eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
    1239         mov     cr0, eax
    1240         jmp far BS2_SEL_CS16:bs2ProtModeCode16Start_p16
    1241 ENDPROC   Bs2EnterMode_rm_pae16
    1242 %endif ; BS2_INC_PAE16
    1243 
    1244 
    1245 %ifdef BS2_INC_PAE32
    1246 ;;
    1247 ; Enters PAE protected mode from real mode (cs = 0).
    1248 ;
    1249 ; @returns  cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
    1250 ;           ebp and esp converted to 32-bit.
    1251 ;           All other registers are preserved.
    1252 ; @uses     nothing
    1253 ;
    1254 BEGINCODELOW
    1255 BITS 16
    1256 BEGINPROC Bs2EnterMode_rm_pae32
    1257         push    word 0
    1258         push    eax
    1259         pushfd
    1260         cli
    1261 %ifndef BS2_NOINC_COMMON
    1262         push    dword SetCpuModeGlobals_pae32
    1263 %endif
    1264 
    1265         ; Do the mode switch.
    1266         xor     ax, ax
    1267         mov     ds, ax
    1268         lgdt    [gdtr]
    1269 %ifdef BS2_WITH_TRAPS
    1270         lidt    [idtr_32bit]
    1271 %elifdef BS2_WITH_RAW_MODE
    1272         lidt    [idtr_dummy_32bit]
    1273 %else
    1274         lidt    [idtr_null]
    1275 %endif
    1276 
    1277         mov     eax, BS2_PAE_PDP_ADDR
    1278         mov     cr3, eax
    1279 %ifdef BS2_WITH_TRAPS
    1280         mov     [bs2Tss32BitDf + BS2_TSS32_CR3_OFF], eax
    1281 %endif
    1282 
    1283         mov     eax, cr4
    1284         or      eax, X86_CR4_PAE | X86_CR4_PSE
    1285         mov     cr4, eax
    1286 
    1287         mov     eax, cr0
    1288         or      eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
    1289         mov     cr0, eax
    1290         jmp far BS2_SEL_CS32:bs2ProtModeCode32Start_p32
    1291 ENDPROC   Bs2EnterMode_rm_pae32
    1292 %endif ; BS2_INC_PAE32
    1293 
    1294 
    1295 ;; @todo BS2_INC_PAEV86
    1296 
    1297 
    1298 %ifdef BS2_INC_LM16
    1299 ;;
    1300 ; Enters long mode from real mode (cs = 0).
    1301 ;
    1302 ; @returns  cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
    1303 ;           rbp and rsp converted to 16/32/64-bit.
    1304 ;           All other registers are preserved.
    1305 ; @uses     nothing
    1306 ;
    1307 BEGINCODELOW
    1308 BITS 16
    1309 BEGINPROC Bs2EnterMode_rm_lm16
    1310         call    Bs2EnterMode_rm_lm64
    1311 BITS 64
    1312         call    Bs2Thunk_lm64_lm16
    1313 BITS 16
    1314         ret
    1315 ENDPROC   Bs2EnterMode_rm_lm16
    1316 %endif ; BS2_INC_LM16
    1317 
    1318 
    1319 %ifdef BS2_INC_LM32
    1320 ;;
    1321 ; Enters long mode from real mode (cs = 0).
    1322 ;
    1323 ; @returns  cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
    1324 ;           rbp and rsp converted to 16/32/64-bit.
    1325 ;           All other registers are preserved.
    1326 ; @uses     nothing
    1327 ;
    1328 BEGINCODELOW
    1329 BITS 16
    1330 BEGINPROC Bs2EnterMode_rm_lm32
    1331         ; Change the return address into a 32-bit one.
    1332         push    word 0                  ; Reserved 2 extra bytes for 32-bit return address.
    1333         push    eax                     ; Save eax.
    1334         movzx   eax, word [esp + 6h]    ; Read narrow return address.
    1335         mov     [esp + 4h], eax         ; Store wide return address.
    1336         pop     eax                     ; Restore eax.
    1337 
    1338         ; Do the mode switch and thunking.
    1339         call    Bs2EnterMode_rm_lm64
    1340 BITS 64
    1341         call    Bs2Thunk_lm64_lm32
    1342 BITS 32
    1343         ret
    1344 ENDPROC   Bs2EnterMode_rm_lm32
    1345 %endif ; BS2_INC_LM32
    1346 
    1347 
    1348 %ifdef BS2_INC_LM64
    1349 ;;
    1350 ; Enters long mode from real mode (cs = 0).
    1351 ;
    1352 ; @returns  cs,ds,ss,es,gs,fs loaded with 64-bit selectors.
    1353 ;           rbp and rsp converted to 64-bit.
    1354 ;           All other registers are preserved.
    1355 ; @uses     nothing
    1356 ;
    1357 BEGINCODELOW
    1358 BITS 16
    1359 BEGINPROC Bs2EnterMode_rm_lm64
    1360         push    word 0                  ; reserve bytes for 64-bit return address.
    1361         push    dword 0
    1362         push    dword 0                 ; rax
    1363         push    eax
    1364         push    dword 0                 ; rcx
    1365         push    ecx
    1366         push    dword 0                 ; rdx
    1367         push    edx
    1368         push    dword 0                 ; rflags
    1369         pushfd
    1370         cli
    1371 
    1372         ; Fix the return address.
    1373         mov     ax, [esp + 20h + 6h]
    1374         mov     word [esp + 20h + 6h], 0
    1375         mov     [esp + 20h], ax
    1376 
    1377         ;
    1378         ; Switch to long mode.
    1379         ;
    1380         xor     ax, ax
    1381         mov     ds, ax
    1382         lgdt    [gdtr]
    1383 %ifdef BS2_WITH_TRAPS
    1384         lidt    [idtr_64bit]
    1385 %else
    1386         lidt    [idtr_null]
    1387 %endif
    1388 
    1389         mov     eax, BS2_LM_PML4_ADDR
    1390         mov     cr3, eax
    1391 
    1392         mov     eax, cr4
    1393         or      eax, X86_CR4_PAE | X86_CR4_PSE
    1394         mov     cr4, eax
    1395 
    1396         mov     ecx, MSR_K6_EFER
    1397         rdmsr
    1398         or      eax, MSR_K6_EFER_LME
    1399         wrmsr
    1400 
    1401         mov     eax, cr0
    1402         or      eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_WP
    1403         mov     cr0, eax
    1404         jmp far BS2_SEL_CS64:.code64_start
    1405 
    1406 BITS 64
    1407 .code64_start:
    1408         mov     eax, BS2_SEL_DS64
    1409         mov     ds, ax
    1410         mov     es, ax
    1411         mov     fs, ax
    1412         mov     gs, ax
    1413         mov     ax, BS2_SEL_SS64
    1414         mov     ss, ax
    1415 %ifdef BS2_WITH_TRAPS
    1416         btr     dword [bs2Gdt + BS2_SEL_TSS64 + 32/8], 1+8      ; busy -> avail
    1417  %ifndef BS2_WITH_MANUAL_LTR
    1418         mov     ax, BS2_SEL_TSS64
    1419         ltr     ax
    1420  %endif
    1421 %endif
    1422 
    1423         and     ebp, 0ffffh
    1424         and     esp, 0ffffh
    1425         and     edi, 0ffffffffh
    1426         and     esi, 0ffffffffh
    1427         and     ebx, 0ffffffffh
    1428 
    1429 %ifndef BS2_NOINC_COMMON
    1430         call    SetCpuModeGlobals_lm64
    1431 %endif
    1432 
    1433         popf
    1434         pop     rdx
    1435         pop     rcx
    1436         pop     rax
    1437         ret
    1438 ENDPROC   Bs2EnterMode_rm_lm64
    1439 %endif ; BS2_INC_PAE32
    1440 
    1441 
    1442 
    1443 %ifdef BS2_INC_CMN_P16
    1444 ;;
    1445 ; Code shared by the three 16-bit protected mode switchers.
    1446 ;
    1447 ; @internal
    1448 ;
    1449 BEGINCODELOW
    1450 BITS 16
    1451 BEGINPROC bs2ProtModeCode16Start_p16
    1452         ; Initialize the registers.
    1453         mov     ax, BS2_SEL_DS16
    1454         mov     ds, ax
    1455         mov     es, ax
    1456         mov     fs, ax
    1457         mov     gs, ax
    1458         mov     ax, BS2_SEL_SS16
    1459         mov     ss, ax
    1460         and     esp, 0ffffh
    1461         and     ebp, 0ffffh
    1462 %ifdef BS2_WITH_TRAPS
    1463         btr     word [bs2Gdt + BS2_SEL_TSS32    + 32/8], 1+8    ; busy -> avail
    1464         btr     word [bs2Gdt + BS2_SEL_TSS32_DF + 32/8], 1+8    ; busy -> avail
    1465  %ifndef BS2_WITH_MANUAL_LTR
    1466         mov     ax, BS2_SEL_TSS32
    1467         ltr     ax
    1468  %endif
    1469 %endif
    1470 
    1471 %ifndef BS2_NOINC_COMMON
    1472         ; Set up mode specific global variables.
    1473         pop     ax
    1474         call    ax
    1475 %endif
    1476 
    1477         popfd
    1478         pop     eax
    1479         ret
    1480 ENDPROC   bs2ProtModeCode16Start_p16
    1481 %endif ; BS2_INC_CMN_P16
    1482 
    1483 
    1484 %ifdef BS2_INC_CMN_P32
    1485 ;;
    1486 ; Code shared by the three 32-bit protected mode switchers.
    1487 ;
    1488 ; @internal
    1489 ;
    1490 BEGINCODELOW
    1491 BITS 32
    1492 BEGINPROC bs2ProtModeCode32Start_p32
    1493         ; Initialize the registers.
    1494         mov     ax, BS2_SEL_DS32
    1495         mov     ds, ax
    1496         mov     es, ax
    1497         mov     fs, ax
    1498         mov     gs, ax
    1499         mov     ax, BS2_SEL_SS32
    1500         mov     ss, ax
    1501         and     esp, 0ffffh
    1502         and     ebp, 0ffffh
    1503 %ifdef BS2_WITH_TRAPS
    1504         btr     dword [bs2Gdt + BS2_SEL_TSS32    + 32/8], 1+8   ; busy -> avail
    1505         btr     dword [bs2Gdt + BS2_SEL_TSS32_DF + 32/8], 1+8   ; busy -> avail
    1506  %ifndef BS2_WITH_MANUAL_LTR
    1507         mov     ax, BS2_SEL_TSS32
    1508         ltr     ax
    1509  %endif
    1510 %endif
    1511 
    1512 %ifndef BS2_NOINC_COMMON
    1513         ; Set up mode specific global variables.
    1514         pop     eax
    1515         call    eax
    1516 %endif
    1517 
    1518         ; Make the return address 32-bit and then return.
    1519         movzx   eax, word [esp + 0ah]
    1520         mov     [esp + 8h], eax
    1521         popfd
    1522         pop     eax
    1523         ret
    1524 ENDPROC   bs2ProtModeCode32Start_p32
    1525 %endif ; BS2_INC_CMN_P32
    1526 
    1527 
    1528 
    1529 ;
    1530 ; Routines for exitting the different modes.
    1531 ;
    1532 
    1533 
    1534 %ifdef BS2_INC_RM
    1535 ;;
    1536 ; Dummy.
    1537 BEGINCODELOW
    1538 BITS 16
    1539 BEGINPROC Bs2ExitMode_rm
    1540         ret
    1541 ENDPROC Bs2ExitMode_rm
    1542 %endif ; BS2_INC_RM
    1543 
    1544 
    1545 %ifdef BS2_INC_PE16
    1546 ;;
    1547 ; See bs2ExitMode_p16.
    1548 BEGINCODELOW
    1549 BITS 16
    1550 BEGINPROC Bs2ExitMode_pe16
    1551         push    bs2ExitModeCleanupNop_rm
    1552         jmp     bs2ExitMode_p16
    1553 ENDPROC Bs2ExitMode_pe16
    1554 %endif ; BS2_INC_PE16
    1555 
    1556 
    1557 %ifdef BS2_INC_PE32
    1558 ;;
    1559 ; See bs2ExitMode_p32.
    1560 BEGINCODEHIGH
    1561 BITS 32
    1562 BEGINPROC Bs2ExitMode_pe32
    1563         push    bs2ExitModeCleanupNop_rm
    1564         jmp     bs2ExitMode_p32
    1565 ENDPROC Bs2ExitMode_pe32
    1566 %endif ; BS2_INC_PE32
    1567 
    1568 
    1569 %ifdef BS2_INC_PEV86
    1570 ;;
    1571 ; See Bs2ExitMode_v86.
    1572 BEGINCODELOW
    1573 BITS 16
    1574 BEGINPROC Bs2ExitMode_pev86
    1575         push    bs2ExitModeCleanupNop_rm
    1576         jmp     Bs2ExitMode_pv86
    1577 ENDPROC Bs2ExitMode_pev86
    1578 %endif ; BS2_INC_PEV86
    1579 
    1580 
    1581 %ifdef BS2_INC_PP16
    1582 ;;
    1583 ; See bs2ExitMode_p16.
    1584 BEGINCODELOW
    1585 BITS 16
    1586 BEGINPROC Bs2ExitMode_pp16
    1587         push    bs2ExitModeCleanupNop_rm
    1588         jmp     bs2ExitMode_p16
    1589 ENDPROC Bs2ExitMode_pp16
    1590 %endif ; BS2_INC_PP16
    1591 
    1592 
    1593 %ifdef BS2_INC_PP32
    1594 ;;
    1595 ; See bs2ExitMode_p32.
    1596 BEGINCODEHIGH
    1597 BITS 32
    1598 BEGINPROC Bs2ExitMode_pp32
    1599         push    bs2ExitModeCleanupNop_rm
    1600         jmp     bs2ExitMode_p32
    1601 ENDPROC Bs2ExitMode_pp32
    1602 %endif ; BS2_INC_PP32
    1603 
    1604 
    1605 %ifdef BS2_INC_PPV86
    1606 ;;
    1607 ; See Bs2ExitMode_v86.
    1608 BEGINCODELOW
    1609 BITS 16
    1610 BEGINPROC Bs2ExitMode_ppv86
    1611         push    bs2ExitModeCleanupNop_rm
    1612         jmp     Bs2ExitMode_pv86
    1613 ENDPROC Bs2ExitMode_ppv86
    1614 %endif ; BS2_INC_PPV86
    1615 
    1616 
    1617 
    1618 %ifdef BS2_INC_PAE16
    1619 ;;
    1620 ; See bs2ExitMode_p16.
    1621 BEGINCODELOW
    1622 BITS 16
    1623 BEGINPROC Bs2ExitMode_pae16
    1624         push    bs2ExitModeCleanupPae_rm
    1625         jmp     bs2ExitMode_p16
    1626 ENDPROC Bs2ExitMode_pae16
    1627 %endif ; BS2_INC_pae16
    1628 
    1629 
    1630 %ifdef BS2_INC_PAE32
    1631 ;;
    1632 ; See bs2ExitMode_p32.
    1633 BEGINCODEHIGH
    1634 BITS 32
    1635 BEGINPROC Bs2ExitMode_pae32
    1636         push    bs2ExitModeCleanupPae_rm
    1637         jmp     bs2ExitMode_p32
    1638 ENDPROC Bs2ExitMode_pae32
    1639 %endif ; BS2_INC_PAE32
    1640 
    1641 
    1642 %ifdef BS2_INC_PAEV86
    1643 ;;
    1644 ; See Bs2ExitMode_v86.
    1645 BEGINCODELOW
    1646 BITS 16
    1647 BEGINPROC Bs2ExitMode_paev86
    1648         push    bs2ExitModeCleanupPae_rm
    1649         jmp     Bs2ExitMode_pv86
    1650 ENDPROC Bs2ExitMode_paev86
    1651 %endif ; BS2_INC_PAEV86
    1652 
    1653 
    1654 %ifdef BS2_INC_LM16
    1655 ;;
    1656 ; See bs2ExitMode_p16.
    1657 BEGINCODELOW
    1658 BITS 16
    1659 BEGINPROC Bs2ExitMode_lm16
    1660         push    bs2ExitModeCleanupLm_rm
    1661         jmp     bs2ExitMode_p16
    1662 ENDPROC Bs2ExitMode_lm16
    1663 %endif ; BS2_INC_lm16
    1664 
    1665 
    1666 %ifdef BS2_INC_LM32
    1667 ;;
    1668 ; See bs2ExitMode_p32.
    1669 BEGINCODEHIGH
    1670 BITS 32
    1671 BEGINPROC Bs2ExitMode_lm32
    1672         push    bs2ExitModeCleanupLm_rm
    1673         jmp     bs2ExitMode_p32
    1674 ENDPROC Bs2ExitMode_lm32
    1675 %endif ; BS2_INC_LM32
    1676 
    1677 
    1678 %ifdef BS2_INC_LM64
    1679 ;;
    1680 ; See Bs2ExitMode_v86.
    1681 BEGINCODELOW
    1682 BITS 64
    1683 BEGINPROC Bs2ExitMode_lm64
    1684         call    Bs2Thunk_lm64_lm16
    1685 BITS 16
    1686         pop     dword [esp]
    1687         pop     word [esp]
    1688         push    bs2ExitModeCleanupLm_rm
    1689         jmp     bs2ExitMode_p16
    1690 ENDPROC Bs2ExitMode_lm64
    1691 %endif ; BS2_INC_LM64
    1692 
    1693 
    1694 ; Isn't there a better way to do this in yasm?
    1695 %ifdef BS2_INC_CMN_P16
    1696  %define BS2_INC_BS2EXITMODE_P16
    1697 %elifdef BS2_INC_CMN_LM
    1698  %define BS2_INC_BS2EXITMODE_P16
    1699 %elifdef BS2_INC_CMN_P32
    1700  %define BS2_INC_BS2EXITMODE_P16
    1701 %endif
    1702 
    1703 %ifdef BS2_INC_BS2EXITMODE_P16
    1704 ;;
    1705 ; Exit 16-bit protected or long mode (cs = CS16, ss = SS16).
    1706 ;
    1707 ; @returns  cs,ds,ss,es,gs,fs loaded with the 0 selector.
    1708 ;           All other registers are preserved.
    1709 ; @uses     nothing
    1710 ;
    1711 BEGINCODELOW
    1712 BITS 16
    1713 BEGINPROC bs2ExitMode_p16
    1714         push    eax
    1715         pushfd
    1716         cli
    1717 
    1718         ; Make sure we've got the right SS and CS values (paranoia).
    1719         mov     ax, BS2_SEL_SS16
    1720         mov     ss, ax
    1721         jmp far BS2_SEL_CS16:.code16_start
    1722 
    1723 .code16_start:
    1724         ; Turn off paging and protected mode.
    1725         mov     eax, cr0
    1726         and     eax, 0ffffffffh - X86_CR0_PE - X86_CR0_PG
    1727         mov     cr0, eax
    1728         jmp far 0000:.real_mode_start
    1729 
    1730 .real_mode_start:
    1731         ; Load the correct real mode segment registers.
    1732         xor     ax, ax
    1733         mov     ss, ax
    1734         mov     ds, ax
    1735         mov     es, ax
    1736         mov     fs, ax
    1737         mov     gs, ax
    1738 
    1739         ; Load the real mode idtr.
    1740         lidt    [idtr_real_mode]
    1741 
    1742         ; Cleanup.
    1743         mov     ax, [esp + 8h]
    1744         call    ax
    1745 
    1746 %ifndef BS2_NOINC_COMMON
    1747         ; Set globals.
    1748         call    SetCpuModeGlobals_rm
    1749 %endif
    1750 
    1751         popfd
    1752         pop     eax
    1753         add     sp, 2h                  ; cleanup routine address
    1754         ret
    1755 ENDPROC   bs2ExitMode_p16
    1756 %endif ; BS2_INC_CMN_P16
    1757 
    1758 
    1759 %ifdef BS2_INC_CMN_P32
    1760 ;;
    1761 ; Exit 32-bit protected or long mode (cs = CS32, ss = SS32).
    1762 ;
    1763 ; The return address as well as the stack registers must be somewhere within
    1764 ; the first 64KB of the address space.
    1765 ;
    1766 ; @returns  cs,ds,ss,es,gs,fs loaded with the 0 selector.
    1767 ;           All other registers are preserved.
    1768 ; @uses     nothing
    1769 ;
    1770 BEGINCODELOW
    1771 BITS 32
    1772 BEGINPROC bs2ExitMode_p32
    1773         push    eax
    1774         mov     eax, [esp + 8h]         ; return address
    1775         mov     [esp + 0ah], ax
    1776         mov     eax, [esp + 4h]         ; cleanup routine address
    1777         mov     [esp + 08h], ax
    1778         pop     eax
    1779         add     esp, 4h
    1780 
    1781         call    Bs2Thunk_p32_p16
    1782 BITS 16
    1783         jmp     bs2ExitMode_p16
    1784 ENDPROC   bs2ExitMode_p32
    1785 %endif ; BS2_INC_CMN_P32
    1786 
    1787 
    1788 ;;
    1789 ; Dummy cleanup routine.
    1790 BEGINCODELOW
    1791 BITS 16
    1792 BEGINPROC bs2ExitModeCleanupNop_rm
    1793         ret
    1794 ENDPROC   bs2ExitModeCleanupNop_rm
    1795 
    1796 
    1797 %ifdef BS2_INC_CMN_PAE
    1798 ;;
    1799 ; Cleans up after leaving PAE mode.
    1800 ; @uses     nothing
    1801 BEGINCODELOW
    1802 BITS 16
    1803 BEGINPROC bs2ExitModeCleanupPae_rm
    1804         push    eax
    1805         mov     eax, cr4
    1806         and     eax, ~X86_CR4_PAE
    1807         mov     cr4, eax
    1808         pop     eax
    1809         ret
    1810 ENDPROC   bs2ExitModeCleanupPae_rm
    1811 %endif
    1812 
    1813 
    1814 %ifdef BS2_INC_CMN_LM
    1815 ;;
    1816 ; Cleans up after leaving long mode.
    1817 ; @uses     nothing
    1818 BEGINCODELOW
    1819 BITS 16
    1820 BEGINPROC bs2ExitModeCleanupLm_rm
    1821         push    eax
    1822         push    edx
    1823         push    ecx
    1824 
    1825         mov     ecx, MSR_K6_EFER
    1826         rdmsr
    1827         and     eax, ~MSR_K6_EFER_LME
    1828         wrmsr
    1829 
    1830         pop     ecx
    1831         pop     edx
    1832         pop     eax
    1833         ret
    1834 ENDPROC   bs2ExitModeCleanupLm_rm
    1835 %endif
    1836 
    1837 
    1838 
    1839 ;
    1840 ; Thunking routines for switching between 16/32/64-bit code.
    1841 ;
    1842 
    1843 
    1844 %ifdef BS2_INC_CMN_PM
    1845 ;;
    1846 ; Switches from 32-bit to 16-bit mode ({eip,esp,ebp} < 64KB).
    1847 ;
    1848 ; @returns  cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
    1849 ;           All other registers are preserved.
    1850 ; @uses     nothing
    1851 ;
    1852 BEGINCODELOW
    1853 BITS 32
    1854 BEGINPROC Bs2Thunk_p32_p16
    1855         push    eax
    1856         pushf
    1857         cli
    1858         mov     ax, BS2_SEL_SS16
    1859         jmp far BS2_SEL_CS16:.code16_start
    1860 BITS 16
    1861 .code16_start:
    1862         mov     ss, ax
    1863         mov     ax, BS2_SEL_DS16
    1864         mov     ds, ax
    1865         mov     es, ax
    1866         mov     fs, ax
    1867         mov     gs, ax
    1868 
    1869         ; Fix the return address and then return.
    1870         mov     ax, [esp + 08h]
    1871         mov     [esp + 0ah], ax
    1872         popfd
    1873         pop     eax
    1874         add     sp, 2h
    1875         ret
    1876 ENDPROC   Bs2Thunk_p32_p16
    1877  %define Bs2Thunk_p32_pe16  Bs2Thunk_p32_p16 ; Alternative name for TMPL_NM
    1878  %define Bs2Thunk_p32_pp16  Bs2Thunk_p32_p16 ; Alternative name for TMPL_NM
    1879  %define Bs2Thunk_p32_pae16 Bs2Thunk_p32_p16 ; Alternative name for TMPL_NM
    1880 %endif ; BS2_INC_CMN_PM
    1881 
    1882 
    1883 %ifdef BS2_INC_CMN_PM
    1884 ;;
    1885 ; Switches from 16-bit to 32-bit mode (cs = CS16, ds = DS16).
    1886 ;
    1887 ; @returns  cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
    1888 ;           ebp and esp converted to 32bit.
    1889 ;           All other registers are preserved.
    1890 ; @uses     nothing
    1891 ;
    1892 BEGINCODELOW
    1893 BITS 16
    1894 BEGINPROC Bs2Thunk_p16_p32
    1895         push    word 0
    1896         push    eax
    1897         pushfd
    1898         cli
    1899         jmp far BS2_SEL_CS32:.code32_start
    1900 BITS 32
    1901 .code32_start:
    1902         mov     eax, BS2_SEL_SS32
    1903         mov     ss, ax
    1904         mov     ax, BS2_SEL_DS32
    1905         mov     ds, ax
    1906         mov     es, ax
    1907         mov     fs, ax
    1908         mov     gs, ax
    1909         and     ebp, 0ffffh
    1910         and     esp, 0ffffh
    1911 
    1912         ; Fix the return address and then return.
    1913         movzx   eax, word [esp + 0ah]
    1914         mov     [esp + 08h], eax
    1915         popfd
    1916         pop     eax
    1917         ret
    1918 ENDPROC   Bs2Thunk_p16_p32
    1919  %define Bs2Thunk_p16_pe32  Bs2Thunk_p16_p32 ; Alternative name for TMPL_NM
    1920  %define Bs2Thunk_p16_pp32  Bs2Thunk_p16_p32 ; Alternative name for TMPL_NM
    1921  %define Bs2Thunk_p16_pae32 Bs2Thunk_p16_p32 ; Alternative name for TMPL_NM
    1922 %endif ; BS2_INC_CMN_PM
    1923 
    1924 
    1925 %ifdef BS2_INC_CMN_LM
    1926 ;;
    1927 ; Switches from 64-bit to 16-bit mode ({rip,rsp,rbp} < 64KB).
    1928 ;
    1929 ; @returns  cs,ds,ss,es,gs,fs loaded with 16-bit selectors.
    1930 ;           All other registers are preserved.
    1931 ; @uses     nothing
    1932 ;
    1933 BEGINCODELOW
    1934 BITS 64
    1935 BEGINPROC Bs2Thunk_lm64_lm16
    1936         push    rax
    1937         pushf
    1938         cli
    1939         mov     ax, BS2_SEL_SS16
    1940         push    BS2_SEL_CS16
    1941         push    .code16_start
    1942         retf
    1943 BITS 16
    1944 .code16_start:
    1945         mov     ss, ax
    1946         mov     ax, BS2_SEL_DS16
    1947         mov     ds, ax
    1948         mov     es, ax
    1949         mov     fs, ax
    1950         mov     gs, ax
    1951 
    1952         ; Fix the return address and then return.
    1953         mov     ax, [esp + 10h]
    1954         mov     [esp + 16h], ax
    1955         popfd
    1956         add     sp, 4h
    1957         pop     eax
    1958         add     sp, 4h + 6h
    1959         ret
    1960 ENDPROC   Bs2Thunk_lm64_lm16
    1961  %define Bs2Thunk_p64_lm16 Bs2Thunk_lm64_lm16 ; Alternative name for TMPL_NM
    1962 %endif ; BS2_INC_CMN_LM
    1963 
    1964 
    1965 %ifdef BS2_INC_LM16
    1966 ;;
    1967 ; Switches from 16-bit to 64-bit mode (cs = CS16, ss = SS16).
    1968 ;
    1969 ; @returns  cs,ds,ss,es,gs,fs loaded with 64-bit selectors.
    1970 ;           rbp and rsp converted to 16/32/64-bit.
    1971 ;           All other registers are preserved.
    1972 ; @uses     nothing
    1973 ;
    1974 BEGINCODELOW
    1975 BITS 16
    1976 BEGINPROC Bs2Thunk_lm16_lm64
    1977         push    word 0
    1978         push    dword 0
    1979         push    dword 0
    1980         push    eax
    1981         push    dword 0
    1982         pushfd
    1983         cli
    1984         mov     eax, BS2_SEL_SS64
    1985         jmp far BS2_SEL_CS64:.code64_start
    1986 BITS 64
    1987 .code64_start:
    1988         mov     ss, ax
    1989         mov     ax, BS2_SEL_DS64
    1990         mov     ds, ax
    1991         mov     es, ax
    1992         mov     fs, ax
    1993         mov     gs, ax
    1994 
    1995         and     ebp, 0ffffh
    1996         and     esp, 0ffffh
    1997         and     edi, 0ffffffffh
    1998         and     esi, 0ffffffffh
    1999         and     ebx, 0ffffffffh
    2000 
    2001         ; Fix the return address and then return.
    2002         movzx   rax, word [rsp + 16h]
    2003         mov     [rsp + 10h], rax
    2004         popf
    2005         pop     rax
    2006         ret
    2007 ENDPROC   Bs2Thunk_lm16_lm64
    2008  %define Bs2Thunk_p16_lm64 Bs2Thunk_lm16_lm64 ; Alternative name for TMPL_NM
    2009 %endif ; BS2_INC_LM16
    2010 
    2011 
    2012 %ifdef BS2_INC_LM32
    2013 ;;
    2014 ; Switches from 64-bit to 32-bit mode ({rip,rsp,rbp} < 4GB).
    2015 ;
    2016 ; @returns  cs,ds,ss,es,gs,fs loaded with 32-bit selectors.
    2017 ;           All other registers are preserved.
    2018 ; @uses     nothing
    2019 ;
    2020 BEGINCODEHIGH
    2021 BITS 64
    2022 BEGINPROC Bs2Thunk_lm64_lm32
    2023         push    rax
    2024         pushf
    2025         cli
    2026         mov     ax, BS2_SEL_SS32
    2027         push    BS2_SEL_CS32
    2028         push    .code32_start
    2029         retf
    2030 BITS 32
    2031 .code32_start:
    2032         mov     ss, ax
    2033         mov     ax, BS2_SEL_DS32
    2034         mov     ds, ax
    2035         mov     es, ax
    2036         mov     fs, ax
    2037         mov     gs, ax
    2038 
    2039         ; Fix the return address and then return.
    2040         mov     eax, [esp + 10h]
    2041         mov     [esp + 14h], eax
    2042         popfd
    2043         mov     eax, [esp + 4h]
    2044         lea     esp, [esp + 10h]
    2045         ret
    2046 ENDPROC   Bs2Thunk_lm64_lm32
    2047  %define Bs2Thunk_p64_lm32 Bs2Thunk_lm64_lm32 ; Alternative name for TMPL_NM
    2048 %endif ; BS2_INC_LM32
    2049 
    2050 
    2051 %ifdef BS2_INC_LM32
    2052 ;;
    2053 ; Switches from 32-bit to 64-bit mode (cs = CS32, ss = SS32).
    2054 ;
    2055 ; @returns  cs,ds,ss,es,gs,fs loaded with 64-bit selectors.
    2056 ;           rbp and rsp converted to 32/64-bit.
    2057 ;           All other registers are preserved.
    2058 ; @uses     nothing
    2059 ;
    2060 BEGINCODEHIGH
    2061 BITS 32
    2062 BEGINPROC Bs2Thunk_lm32_lm64
    2063         push    dword 0
    2064         push    dword 0
    2065         push    eax
    2066         push    dword 0
    2067         pushfd
    2068         cli
    2069         mov     eax, BS2_SEL_SS64
    2070         jmp far BS2_SEL_CS64:.code64_start
    2071 BITS 64
    2072 .code64_start:
    2073         mov     ss, ax
    2074         mov     ax, BS2_SEL_DS64
    2075         mov     ds, ax
    2076         mov     es, ax
    2077         mov     fs, ax
    2078         mov     gs, ax
    2079 
    2080         and     ebp, 0ffffffffh
    2081         and     esp, 0ffffffffh
    2082         and     edi, 0ffffffffh
    2083         and     esi, 0ffffffffh
    2084         and     ebx, 0ffffffffh
    2085 
    2086         ; Fix the return address and then return.
    2087         mov     eax, [rsp + 14h]
    2088         mov     [rsp + 10h], rax
    2089         popf
    2090         pop     rax
    2091         ret
    2092 ENDPROC   Bs2Thunk_lm32_lm64
    2093  %define Bs2Thunk_p32_lm64 Bs2Thunk_lm32_lm64 ; Alternative name for TMPL_NM
    2094 %endif ; BS2_INC_LM32
    2095 
    2096 
    2097 
    2098 
    2099 ;
    2100 ; Routines for checking if mode is supported or not.
    2101 ;
    2102 ; @returns al=1 & ZF=0 if supported, al=0 & ZF=1 if not.
    2103 ; @uses    nothing.
    2104 ;
    2105 
    2106 ; These are easy.
    2107 BEGINCODELOW
    2108 BITS 16
    2109 BEGINPROC bs2IsModeSupportedYes_rm
    2110 GLOBALNAME Bs2IsModeSupported_rm_rm
    2111 GLOBALNAME Bs2IsModeSupported_rm_pe16
    2112 GLOBALNAME Bs2IsModeSupported_rm_pe32
    2113 GLOBALNAME Bs2IsModeSupported_rm_pev86
    2114 GLOBALNAME Bs2IsModeSupported_rm_pp16
    2115 GLOBALNAME Bs2IsModeSupported_rm_pp32
    2116 GLOBALNAME Bs2IsModeSupported_rm_ppv86
    2117         mov     al, 1
    2118         test    al, al
    2119         ret
    2120 ENDPROC   bs2IsModeSupportedYes_rm
    2121 
    2122 
    2123 %ifdef BS2_INC_CMN_PAE
    2124 BEGINCODELOW
    2125 BITS 16
    2126 BEGINPROC Bs2IsPaeSupported_16
    2127 GLOBALNAME Bs2IsModeSupported_rm_pae16
    2128 GLOBALNAME Bs2IsModeSupported_rm_pae32
    2129 GLOBALNAME Bs2IsModeSupported_rm_paev86
    2130         push    eax
    2131         push    ebx
    2132         push    ecx
    2133         push    edx
    2134 
    2135         mov     eax, 0
    2136         cpuid
    2137         cmp     eax, 1
    2138         jb      .no
    2139         cmp     eax, 1000h
    2140         ja      .no
    2141 
    2142         mov     eax, 1
    2143         cpuid
    2144         test    edx, X86_CPUID_FEATURE_EDX_PAE
    2145 
    2146         pop     edx
    2147         pop     ecx
    2148         pop     ebx
    2149         pop     eax
    2150 
    2151         mov     al, 0
    2152         jz      .no
    2153         mov     al, 1
    2154 .no:
    2155         ret
    2156 ENDPROC   Bs2IsPaeSupported_16
    2157 %endif ; BS2_INC_CMN_PAE
    2158 
    2159 
    2160 %ifdef BS2_INC_CMN_LM
    2161 BEGINCODELOW
    2162 BITS 16
    2163 BEGINPROC Bs2IsLongModeSupported_16
    2164 GLOBALNAME Bs2IsModeSupported_rm_lm16
    2165 GLOBALNAME Bs2IsModeSupported_rm_lm32
    2166 GLOBALNAME Bs2IsModeSupported_rm_lm64
    2167         push    eax
    2168         push    ebx
    2169         push    ecx
    2170         push    edx
    2171 
    2172         mov     eax, 080000000h
    2173         cpuid
    2174         cmp     eax, 080000001h
    2175         jb      .no
    2176         cmp     eax, 080001000h
    2177         ja      .no
    2178 
    2179         mov     eax, 080000001h
    2180         cpuid
    2181         test    edx, X86_CPUID_EXT_FEATURE_EDX_LONG_MODE
    2182 
    2183         pop     edx
    2184         pop     ecx
    2185         pop     ebx
    2186         pop     eax
    2187 
    2188         mov     al, 0
    2189         jz      .no
    2190         mov     al, 1
    2191 .no:
    2192         ret
    2193 ENDPROC   Bs2IsLongModeSupported_16
    2194 %endif ; BS2_INC_CMN_LM
    2195 
    2196 
    2197 ;
    2198 ; Include addition init/base code.
    2199 ;
    2200 %ifdef BS2_WITH_TRAPS
    2201  %include "bootsector2-common-init-traps.mac"
    2202 %endif
    2203 
    2204 
    2205 ;
    2206 ; Include common code.
    2207 ;
    2208 %ifndef BS2_NOINC_COMMON
    2209  %include "bootsector2-common-routines.mac"
    2210 %endif
    2211 
    2212 ;
    2213 ; Include trap records if requested.
    2214 ;
    2215 %ifdef BS2_WITH_TRAPRECS
    2216  %include "bootsector2-common-traprec.mac"
    2217 %endif
    2218 
    2219 ;
    2220 ; Map stuff for the initial environment.
    2221 ;
    2222 %ifdef BS2_INIT_RM
    2223  %define TMPL_RM
    2224 %endif
    2225 %ifdef BS2_INIT_PE32
    2226  %define TMPL_PE32
    2227 %endif
    2228 %ifdef BS2_INIT_PP32
    2229  %define TMPL_PP32
    2230 %endif
    2231 %ifdef BS2_INIT_PAE32
    2232  %define TMPL_PAE32
    2233 %endif
    2234 %ifdef BS2_INIT_LM64
    2235  %define TMPL_LM64
    2236 %endif
    2237 %include "bootsector2-template-header.mac"
    2238 
    2239 
    2240 ;
    2241 ; Where we jump after initialization.
    2242 ;
    2243 TMPL_BEGINCODE
    2244 BITS TMPL_BITS
    2245 bs2DoneInit:
    2246 %ifdef BS2_INIT_SAVE_REGS
    2247         mov     eax, cr2
    2248         mov     [BS2_REG_SAVE_ADDR + BS2REGS.cr2], eax
    2249         mov     eax, cr3
    2250         mov     [BS2_REG_SAVE_ADDR + BS2REGS.cr3], eax
    2251         mov     eax, cr4
    2252         mov     [BS2_REG_SAVE_ADDR + BS2REGS.cr4], eax
    2253         mov     byte [BS2_REG_SAVE_ADDR + BS2REGS.cBits], 16
    2254         xor     eax, eax
    2255         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.cs], ax
    2256         mov     ax, start
    2257         mov     [cs:BS2_REG_SAVE_ADDR + BS2REGS.rip], eax
    2258 %endif
    2259 
    2260 %ifdef BS2_WITH_TRAPRECS
    2261         ;
    2262         ; Install the trap records.
    2263         ;
    2264         BS2_TRAP_RECS_INSTALL
    2265 %endif
    2266 
    2267         ;
    2268         ; Detect the CPU.
    2269         ;
    2270         xor     eax, eax
    2271         mov     [g_fCpuIntel], al
    2272         mov     [g_fCpuAmd],   al
    2273         cpuid
    2274         cmp     ecx, 0x444d4163
    2275         jne     .not_amd
    2276         cmp     edx, 0x69746e65
    2277         jne     .not_amd
    2278         cmp     ebx, 0x68747541
    2279         jne     .not_amd
    2280         mov     byte [g_fCpuAmd], 1
    2281         jmp     .not_intel
    2282 
    2283 .not_amd:
    2284         cmp     ecx, 0x6c65746e
    2285         jne     .not_intel
    2286         cmp     edx, 0x49656e69
    2287         jne     .not_intel
    2288         cmp     ebx, 0x756e6547
    2289         jne     .not_intel
    2290         mov     byte [g_fCpuIntel], 1
    2291 .not_intel:
    2292 
    2293         ;
    2294         ; Call the user 'main' procedure (shouldn't return).
    2295         ;
    2296         call    main
    2297 .panic_again
    2298         call    Bs2Panic
    2299         jmp     .panic_again
    2300 
     283.s_achHex:
     284        db '0123456789abcdef'
     285ENDPROC bs3InitLoadImage
     286
     287
     288;
     289; Pad the remainder of the sector with int3's and end it with the DOS signature.
     290;
     291bs3Padding:
     292        times ( 510 - ( (bs3Padding - start) % 512 ) ) db 0cch
     293        db      055h, 0aah
     294
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-footer.mac

    r58574 r58588  
    11; $Id$
    22;; @file
    3 ; bootsector2 footer for multi-mode code templates.
     3; BS3Kit footer for multi-mode code templates.
    44;
    55
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-template-header.mac

    r58574 r58588  
    11; $Id$
    22;; @file
    3 ; bootsector2 header for multi-mode code templates.
     3; BS3Kit header for multi-mode code templates.
    44;
    55
     
    2424; terms and conditions of either the GPL or the CDDL or both.
    2525;
     26
     27%include "bs3kit.mac"
    2628
    2729;
     
    667669 %error "internal error"
    668670%endif
     671
     672
     673;
     674; Preferred spelling of TMPL_NM_CMN in BS3.
     675;
     676%define TMPL_CMN_NM(Name)      TMPL_NM_CMN(Name)
    669677
    670678
     
    769777;
    770778%ifdef TMPL_64BIT
    771  %define TMPL_BEGINCODE BEGINCODEHIGH
     779 %define TMPL_BEGIN_TEXT BS3_BEGIN_TEXT64
    772780%elifdef TMPL_32BIT
    773  %define TMPL_BEGINCODE BEGINCODEHIGH
     781 %define TMPL_BEGIN_TEXT BS3_BEGIN_TEXT32
    774782%elifdef TMPL_16BIT
    775  %define TMPL_BEGINCODE BEGINCODELOW
     783 %define TMPL_BEGIN_TEXT BS3_BEGIN_TEXT16
    776784%else
    777785 %error "Missing TMPL_xxBIT!"
    778786%endif
    779 TMPL_BEGINCODE
     787TMPL_BEGIN_TEXT
    780788
    781789;
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac

    r58574 r58588  
    11; $Id$
    22;; @file
    3 ; Common structures.
     3; BS3Kit - structures, symbols, macros and stuff.
    44;
    55
     
    2525;
    2626
    27 %ifndef ___bootsector2_structures_mac___
    28 %define ___bootsector2_structures_mac___
     27%ifndef ___bs3kit_mac___
     28%define ___bs3kit_mac___
     29
     30%include "iprt/asmdefs.mac"
     31%include "iprt/x86.mac"
     32
     33
     34;; @name Static Memory Allocation
     35; @{
     36;; The flat load address for the code after the bootsector.
     37%define BS3_LOAD_ADDR           010000h
     38;; Where we save the boot registers during init.
     39; Located right before the code.
     40%define BS3_REG_SAVE_ADDR       (BS3_LOAD_ADDR - BS3REGS_size - 8)
     41;; Where the stack starts (initial RSP value).
     42; Located right before the saved registers. SS.BASE=0.
     43%define BS3_STACK_ADDR          (BS3_REG_SAVE_ADDR - 16)
     44;; @}
    2945
    3046
     
    3248; Registers.  Used by traps and such.
    3349;
    34 struc BS2REGS
     50struc BS3REGS
    3551        .rax    resq 1
    3652        .rbx    resq 1
     
    7288; Trap record.
    7389;
    74 struc BS2TRAPREC
     90struc BS3TRAPREC
    7591        ;; The trap location relative to the base address given at
    7692        ; registration time.
     
    85101
    86102;; The size shift.
    87 %define BS2TRAPREC_SIZE_SHIFT   3
     103%define BS3TRAPREC_SIZE_SHIFT   3
    88104
     105
     106;; @name Segment definitions.
     107;; @{
     108%macro BS3_BEGIN_TEXT16 0
     109 %ifndef BS3_BEGIN_TEXT16_NOT_FIRST
     110  %define BS3_BEGIN_TEXT16_NOT_FIRST
     111        section TEXT16 CLASS=CODE16 PUBLIC USE16 ALIGN=1
     112 %else
     113        section TEXT16
     114 %endif
     115%endmacro
     116
     117%macro BS3_BEGIN_DATA16 0
     118 %ifndef BS3_BEGIN_DATA16_NOT_FIRST
     119  %define BS3_BEGIN_DATA16_NOT_FIRST
     120        section DATA16 CLASS=DATA16 PUBLIC USE16 ALIGN=2
     121 %else
     122        section DATA16
     123 %endif
     124%endmacro
     125
     126%macro BS3_BEGIN_TEXT32 0
     127 %ifndef BS3_BEGIN_TEXT16_NOT_FIRST
     128  %define BS3_BEGIN_TEXT16_NOT_FIRST
     129        section TEXT32 CLASS=CODE32 PUBLIC USE32 ALIGN=1
     130 %else
     131        section TEXT32
     132 %endif
     133%endmacro
     134
     135%macro BS3_BEGIN_DATA32 0
     136 %ifndef BS3_BEGIN_DATA32_NOT_FIRST
     137  %define BS3_BEGIN_DATA32_NOT_FIRST
     138        section DATA32 CLASS=DATA32 PUBLIC USE32 ALIGN=16
     139 %else
     140        section DATA32
     141 %endif
     142%endmacro
     143
     144%macro BS3_BEGIN_TEXT64 0
     145 %ifndef BS3_BEGIN_TEXT64_NOT_FIRST
     146  %define BS3_BEGIN_TEXT64_NOT_FIRST
     147  %ifdef ASM_FORMAT_ELF
     148        section TEXT64 ALIGN=1
     149  %else
     150        section TEXT64 CLASS=CODE64 PUBLIC USE32 ALIGN=1
     151  %endif
     152 %else
     153        section TEXT64
     154 %endif
     155%endmacro
     156
     157%macro BS3_BEGIN_DATA64 0
     158 %ifndef BS3_BEGIN_DATA64_NOT_FIRST
     159  %define BS3_BEGIN_DATA64_NOT_FIRST
     160  %ifdef ASM_FORMAT_ELF
     161        section DATA64 ALIGN=16
     162  %else
     163        section DATA64 CLASS=DATA64 PUBLIC USE32 ALIGN=16
     164  %endif
     165 %else
     166        section DATA64
     167 %endif
     168%endmacro
     169
     170;; @}
    89171
    90172%endif
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette