diff options
Diffstat (limited to 'src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesHlp.asm')
-rw-r--r-- | src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesHlp.asm | 1129 |
1 files changed, 1129 insertions, 0 deletions
diff --git a/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesHlp.asm b/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesHlp.asm new file mode 100644 index 00000000..dbe82b18 --- /dev/null +++ b/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-TestDoModesHlp.asm @@ -0,0 +1,1129 @@ +; $Id: bs3-mode-TestDoModesHlp.asm $ +;; @file +; BS3Kit - Bs3TestDoModes helpers +; + +; +; Copyright (C) 2007-2019 Oracle Corporation +; +; This file is part of VirtualBox Open Source Edition (OSE), as +; available from http://www.virtualbox.org. This file is free software; +; you can redistribute it and/or modify it under the terms of the GNU +; General Public License (GPL) as published by the Free Software +; Foundation, in version 2 as it comes in the "COPYING" file of the +; VirtualBox OSE distribution. VirtualBox OSE is distributed in the +; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL) only, as it comes in the "COPYING.CDDL" file of the +; VirtualBox OSE distribution, in which case the provisions of the +; CDDL are applicable instead of those of the GPL. +; +; You may elect to license modified versions of this file under the +; terms and conditions of either the GPL or the CDDL or both. +; + +;********************************************************************************************************************************* +;* Header Files * +;********************************************************************************************************************************* +%include "bs3kit-template-header.mac" + + +;********************************************************************************************************************************* +;* Defined Constants And Macros * +;********************************************************************************************************************************* +; +; We put most of this mess in the RMTEXT16 segment when in real mode. +; +%if TMPL_MODE == BS3_MODE_RM + %define MY_BEGIN_TEXT BS3_BEGIN_RMTEXT16 + %define MY_BEGIN_TEXT16 BS3_BEGIN_RMTEXT16 + %define MY_TEXT16_WRT(a_Label) a_Label wrt BS3GROUPRMTEXT16 +%else + %define MY_BEGIN_TEXT TMPL_BEGIN_TEXT + %define MY_BEGIN_TEXT16 BS3_BEGIN_TEXT16 + %define MY_TEXT16_WRT(a_Label) BS3_TEXT16_WRT(a_Label) +%endif + + +;********************************************************************************************************************************* +;* External Symbols * +;********************************************************************************************************************************* +%if TMPL_MODE == BS3_MODE_RM +BS3_BEGIN_TEXT16_FARSTUBS +extern TMPL_FAR_NM(Bs3SwitchToRM) +extern TMPL_FAR_NM(Bs3SwitchToPE16) +extern TMPL_FAR_NM(Bs3SwitchToPE16_32) +extern TMPL_FAR_NM(Bs3SwitchToPE16_V86) +extern TMPL_FAR_NM(Bs3SwitchToPE32) +extern TMPL_FAR_NM(Bs3SwitchToPE32_16) +extern TMPL_FAR_NM(Bs3SwitchToPEV86) +extern TMPL_FAR_NM(Bs3SwitchToPP16) +extern TMPL_FAR_NM(Bs3SwitchToPP16_32) +extern TMPL_FAR_NM(Bs3SwitchToPP16_V86) +extern TMPL_FAR_NM(Bs3SwitchToPP32) +extern TMPL_FAR_NM(Bs3SwitchToPP32_16) +extern TMPL_FAR_NM(Bs3SwitchToPPV86) +extern TMPL_FAR_NM(Bs3SwitchToPAE16) +extern TMPL_FAR_NM(Bs3SwitchToPAE16_32) +extern TMPL_FAR_NM(Bs3SwitchToPAE16_V86) +extern TMPL_FAR_NM(Bs3SwitchToPAE32) +extern TMPL_FAR_NM(Bs3SwitchToPAE32_16) +extern TMPL_FAR_NM(Bs3SwitchToPAEV86) +extern TMPL_FAR_NM(Bs3SwitchToLM16) +extern TMPL_FAR_NM(Bs3SwitchToLM32) +extern TMPL_FAR_NM(Bs3SwitchToLM64) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_rm_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pe16_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pe16_v86_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pe32_16_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pev86_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pp16_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pp16_v86_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pp32_16_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_ppv86_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pae16_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pae16_v86_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pae32_16_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_paev86_far) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_lm16_far) +%else +BS3_BEGIN_TEXT16 +extern TMPL_NM(Bs3SwitchToRM) +extern TMPL_NM(Bs3SwitchToPE16) +extern TMPL_NM(Bs3SwitchToPE16_32) +extern TMPL_NM(Bs3SwitchToPE16_V86) +extern TMPL_NM(Bs3SwitchToPE32) +extern TMPL_NM(Bs3SwitchToPE32_16) +extern TMPL_NM(Bs3SwitchToPEV86) +extern TMPL_NM(Bs3SwitchToPP16) +extern TMPL_NM(Bs3SwitchToPP16_32) +extern TMPL_NM(Bs3SwitchToPP16_V86) +extern TMPL_NM(Bs3SwitchToPP32) +extern TMPL_NM(Bs3SwitchToPP32_16) +extern TMPL_NM(Bs3SwitchToPPV86) +extern TMPL_NM(Bs3SwitchToPAE16) +extern TMPL_NM(Bs3SwitchToPAE16_32) +extern TMPL_NM(Bs3SwitchToPAE16_V86) +extern TMPL_NM(Bs3SwitchToPAE32) +extern TMPL_NM(Bs3SwitchToPAE32_16) +extern TMPL_NM(Bs3SwitchToPAEV86) +extern TMPL_NM(Bs3SwitchToLM16) +extern TMPL_NM(Bs3SwitchToLM32) +extern TMPL_NM(Bs3SwitchToLM64) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_rm) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe16) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe16_v86) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe32_16) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pev86) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp16) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp16_v86) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp32_16) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_ppv86) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae16) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae16_v86) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae32_16) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_paev86) +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_lm16) +%endif +BS3_BEGIN_TEXT16 +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe16_32):wrt BS3FLAT +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe32):wrt BS3FLAT +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp16_32):wrt BS3FLAT +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp32):wrt BS3FLAT +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae16_32):wrt BS3FLAT +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae32):wrt BS3FLAT +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_lm32):wrt BS3FLAT +extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_lm64):wrt BS3FLAT + + +MY_BEGIN_TEXT16 ; need the group definition +MY_BEGIN_TEXT + +;; +; Shared prologue code. +; @param xAX Where to jump to for the main event. +; +BS3_GLOBAL_NAME_EX TMPL_NM(bs3TestCallDoerPrologue), , 0 + BS3_CALL_CONV_PROLOG 1 + push xBP + mov xBP, xSP + xPUSHF + + ; Save non-volatile registers so the DO function doesn't have to. + push xBX + push xCX + push xDX + push xSI + push xDI +%if TMPL_BITS != 64 + push ds + push es + push ss + %if TMPL_BITS != 16 + push fs + push gs + %endif +%endif +%if TMPL_BITS == 64 + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 +%endif + + ; Jump to the main code. + jmp xAX + +;; +; Shared epilogue code. +; @param xAX Return code. +; +BS3_GLOBAL_NAME_EX TMPL_NM(bs3TestCallDoerEpilogue), , 0 + ; Restore registers. +%if TMPL_BITS == 16 + sub bp, (1+5+3)*2 + mov sp, bp +%elif TMPL_BITS == 32 + lea xSP, [xBP - (1+5+5)*4] +%else + lea xSP, [xBP - (1+5+8)*8] + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 +%endif +%if TMPL_BITS != 64 + %if TMPL_BITS != 16 + pop gs + pop fs + %endif + pop ss + pop es + pop ds +%endif + pop xDI + pop xSI + pop xDX + pop xCX + pop xBX + xPOPF + pop xBP + ret + +; +; For checking that the mode switching macros doesn't screw up GPRs. +; Note! Does not work on pre 286 hardware! So, for debugging only. +; +%if 0 + %macro STRICT_SAVE_REGS 0 + movzx esp, sp + sub esp, BS3REGCTX_size + mov [esp + BS3REGCTX.rax], eax + mov dword [esp + BS3REGCTX.rax+4], 0xdead0000 + mov [esp + BS3REGCTX.rcx], ecx + mov dword [esp + BS3REGCTX.rcx+4], 0xdead0001 + mov [esp + BS3REGCTX.rdx], edx + mov dword [esp + BS3REGCTX.rdx+4], 0xdead0002 + mov [esp + BS3REGCTX.rbx], ebx + mov dword [esp + BS3REGCTX.rbx+4], 0xdead0003 + mov [esp + BS3REGCTX.rbp], ebp + mov [esp + BS3REGCTX.rsp], esp + mov [esp + BS3REGCTX.rsi], esi + mov [esp + BS3REGCTX.rdi], edi + %endmacro + + %macro STRICT_CHECK_REGS 0 +%%_esp: cmp [esp + BS3REGCTX.rsp], esp + jne %%_esp +%%_eax: cmp [esp + BS3REGCTX.rax], eax + jne %%_eax +%%_ecx: mov [esp + BS3REGCTX.rcx], ecx + jne %%_ecx +%%_edx: cmp [esp + BS3REGCTX.rdx], edx + jne %%_edx +%%_ebx: cmp [esp + BS3REGCTX.rbx], ebx + jne %%_ebx +%%_ebp: cmp [esp + BS3REGCTX.rbp], ebp + jne %%_ebp +%%_esi: cmp [esp + BS3REGCTX.rsi], esi + jne %%_esi +%%_edi: cmp [esp + BS3REGCTX.rdi], edi + jne %%_edi + add esp, BS3REGCTX_size + %endmacro +%else + + %macro STRICT_SAVE_REGS 0 + %endmacro + %macro STRICT_CHECK_REGS 0 + %endmacro +%endif + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Real mode +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInRM(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInRM, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToRM) +%else + call TMPL_NM(Bs3SwitchToRM) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + mov cx, BS3_MODE_RM + push cx + push cs + mov cx, .return + push cx + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_rm_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_rm) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInRM + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Unpage protection mode. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPE16(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPE16, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPE16) +%else + call TMPL_NM(Bs3SwitchToPE16) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PE16 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pe16_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe16) +%endif + BS3_SET_BITS TMPL_BITS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPE16 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPE16_32(uint32_t FlatWorkerAddr, uint8_t bMode); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPE16_32, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +.doit: + mov eax, [xBP + xCB + cbCurRetAddr] ; Load function pointer. + movzx edx, byte [xBP + xCB + cbCurRetAddr + sCB] ; bMode + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPE16_32) +%else + call TMPL_NM(Bs3SwitchToPE16_32) +%endif + BS3_SET_BITS 32 + STRICT_CHECK_REGS + + push edx ; bMode + call eax + + STRICT_SAVE_REGS + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe16_32) + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +BS3_PROC_END_MODE Bs3TestCallDoerInPE16_32 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPE16_V86(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPE16_V86, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPE16_V86) +%else + call TMPL_NM(Bs3SwitchToPE16_V86) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PE16_V86 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pe16_v86_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe16_v86) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPE16_V86 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPE32(uint32_t FlatWorkerAddr, uint8_t bMode); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPE32, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +.doit: + mov eax, [xBP + xCB + cbCurRetAddr] ; Load function pointer. + movzx edx, byte [xBP + xCB + cbCurRetAddr + sCB] ; bMode + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPE32) +%else + call TMPL_NM(Bs3SwitchToPE32) +%endif + BS3_SET_BITS 32 + STRICT_CHECK_REGS + + push edx ; bMode + call eax + + STRICT_SAVE_REGS + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe32) + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +BS3_PROC_END_MODE Bs3TestCallDoerInPE32 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPE32_16(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPE32_16, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPE32_16) +%else + call TMPL_NM(Bs3SwitchToPE32_16) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PE32_16 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pe32_16_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pe32_16) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPE32_16 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPEV86(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPEV86, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPEV86) +%else + call TMPL_NM(Bs3SwitchToPEV86) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PEV86 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pev86_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pev86) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPEV86 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Page protection mode. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPP16(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPP16, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPP16) +%else + call TMPL_NM(Bs3SwitchToPP16) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PP16 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pp16_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp16) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPP16 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPP16_32(uint32_t uFlatWorkerAddr, uint8_t bMode); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPP16_32, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +.doit: + mov eax, [xBP + xCB + cbCurRetAddr] ; Load function pointer. + movzx edx, byte [xBP + xCB + cbCurRetAddr + sCB] ; bMode + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPP16_32) +%else + call TMPL_NM(Bs3SwitchToPP16_32) +%endif + BS3_SET_BITS 32 + STRICT_CHECK_REGS + + push edx + call eax + + STRICT_SAVE_REGS + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp16_32) + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +BS3_PROC_END_MODE Bs3TestCallDoerInPP16_32 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPP16_V86(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPP16_V86, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPP16_V86) +%else + call TMPL_NM(Bs3SwitchToPP16_V86) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PP16_V86 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pp16_v86_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp16_v86) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPP16_V86 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPP32(uint32_t uFlatWorkerAddr, uint8_t bMode); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPP32, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +.doit: + mov eax, [xBP + xCB + cbCurRetAddr] ; Load function pointer. + movzx edx, byte [xBP + xCB + cbCurRetAddr + sCB] ; bMode + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPP32) +%else + call TMPL_NM(Bs3SwitchToPP32) +%endif + BS3_SET_BITS 32 + STRICT_CHECK_REGS + + push edx ; bMode + call eax + + STRICT_SAVE_REGS + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp32) + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +BS3_PROC_END_MODE Bs3TestCallDoerInPP32 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPP32_16(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPP32_16, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPP32_16) +%else + call TMPL_NM(Bs3SwitchToPP32_16) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PP32_16 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pp32_16_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pp32_16) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPP32_16 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPPV86(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPPV86, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPPV86) +%else + call TMPL_NM(Bs3SwitchToPPV86) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PPV86 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_ppv86_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_ppv86) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPPV86 + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PAE paged protection mode. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPAE16(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPAE16, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPAE16) +%else + call TMPL_NM(Bs3SwitchToPAE16) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PAE16 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pae16_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae16) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPAE16 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPAE16_32(uint32_t uFlatWorkerAddr, uint8_t bMode); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPAE16_32, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +.doit: + mov eax, [xBP + xCB + cbCurRetAddr] ; Load function pointer. + movzx edx, byte [xBP + xCB + cbCurRetAddr + sCB] ; bMode + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPAE16_32) +%else + call TMPL_NM(Bs3SwitchToPAE16_32) +%endif + BS3_SET_BITS 32 + STRICT_CHECK_REGS + + push edx ; bMode + call eax + + STRICT_SAVE_REGS + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae16_32) + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +BS3_PROC_END_MODE Bs3TestCallDoerInPAE16_32 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPAE16_V86(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPAE16_V86, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPAE16_V86) +%else + call TMPL_NM(Bs3SwitchToPAE16_V86) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PAE16_V86 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pae16_v86_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae16_v86) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPAE16_V86 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPAE32(uint32_t uFlatWorkerAddr, uint8_t bMode); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPAE32, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +.doit: + mov eax, [xBP + xCB + cbCurRetAddr] ; Load function pointer. + movzx edx, byte [xBP + xCB + cbCurRetAddr + sCB] ; bMode + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPAE32) +%else + call TMPL_NM(Bs3SwitchToPAE32) +%endif + BS3_SET_BITS 32 + STRICT_CHECK_REGS + + push edx ; bMode + call eax + + STRICT_SAVE_REGS + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae32) + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +BS3_PROC_END_MODE Bs3TestCallDoerInPAE32 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPAE32_16(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPAE32_16, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPAE32_16) +%else + call TMPL_NM(Bs3SwitchToPAE32_16) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PAE32_16 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_pae32_16_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_pae32_16) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPAE32_16 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInPAEV86(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInPAEV86, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToPAEV86) +%else + call TMPL_NM(Bs3SwitchToPAEV86) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_PAEV86 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_paev86_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_paev86) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInPAEV86 + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Long mode +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInLM16(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInLM16, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +MY_BEGIN_TEXT16 +BS3_SET_BITS TMPL_BITS +BS3_GLOBAL_LOCAL_LABEL .doit + mov ax, [xBP + xCB + cbCurRetAddr] ; Load far function pointer. + mov dx, [xBP + xCB + cbCurRetAddr + 2] + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToLM16) +%else + call TMPL_NM(Bs3SwitchToLM16) +%endif + BS3_SET_BITS 16 + STRICT_CHECK_REGS + + push BS3_MODE_LM16 + push cs + push .return + push dx + push ax + retf +.return: + + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_lm16_far) +%else + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_lm16) +%endif + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +MY_BEGIN_TEXT +BS3_PROC_END_MODE Bs3TestCallDoerInLM16 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInLM32(uint16_t offBs3Text16); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInLM32, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +.doit: + mov eax, [xBP + xCB + cbCurRetAddr] ; Load function pointer. + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToLM32) +%else + call TMPL_NM(Bs3SwitchToLM32) +%endif + BS3_SET_BITS 32 + STRICT_CHECK_REGS + + and esp, ~03h + push BS3_MODE_LM32 + call eax + + STRICT_SAVE_REGS + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_lm32) + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +BS3_PROC_END_MODE Bs3TestCallDoerInLM32 + +;; +; @cproto BS3_DECL(uint8_t) Bs3TestCallDoerInLM64(uint32_t uFlatWorkerAddr, uint8_t bMode); +; @uses rax +BS3_PROC_BEGIN_MODE Bs3TestCallDoerInLM64, BS3_PBC_NEAR + BS3_LEA_MOV_WRT_RIP(xAX, MY_TEXT16_WRT(.doit)) + jmp TMPL_NM(bs3TestCallDoerPrologue) +.doit: + mov eax, [xBP + xCB + cbCurRetAddr] ; Load function pointer. + movzx edx, byte [xBP + xCB + cbCurRetAddr + sCB] ; bMode + + ; Mode switch, make the call, switch back. + STRICT_SAVE_REGS +%if TMPL_MODE == BS3_MODE_RM + call far TMPL_FAR_NM(Bs3SwitchToLM64) +%else + call TMPL_NM(Bs3SwitchToLM64) +%endif + BS3_SET_BITS 64 + STRICT_CHECK_REGS + + and rsp, ~0fh + sub rsp, 18h + push rdx ; bMode + BS3_CALL rax, 1 + + STRICT_SAVE_REGS + call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_lm64) + BS3_SET_BITS TMPL_BITS + STRICT_CHECK_REGS + jmp TMPL_NM(bs3TestCallDoerEpilogue) +BS3_PROC_END_MODE Bs3TestCallDoerInLM64 + |