diff options
Diffstat (limited to '')
-rw-r--r-- | src/VBox/ValidationKit/bootsectors/bs3-cpu-state64-1-asm.asm | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/src/VBox/ValidationKit/bootsectors/bs3-cpu-state64-1-asm.asm b/src/VBox/ValidationKit/bootsectors/bs3-cpu-state64-1-asm.asm new file mode 100644 index 00000000..49d95f3f --- /dev/null +++ b/src/VBox/ValidationKit/bootsectors/bs3-cpu-state64-1-asm.asm @@ -0,0 +1,242 @@ +; $Id: bs3-cpu-state64-1-asm.asm $ +;; @file +; BS3Kit - bs3-cpu-state64-1 +; + +; +; Copyright (C) 2007-2023 Oracle and/or its affiliates. +; +; This file is part of VirtualBox base platform packages, as +; available from https://www.virtualbox.org. +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation, in version 3 of the +; License. +; +; This program is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, see <https://www.gnu.org/licenses>. +; +; The contents of this file may alternatively be used under the terms +; of the Common Development and Distribution License Version 1.0 +; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included +; in the VirtualBox 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. +; +; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +; + + +;********************************************************************************************************************************* +;* Header Files * +;********************************************************************************************************************************* +%include "bs3kit.mac" + + +;********************************************************************************************************************************* +;* Global Variables * +;********************************************************************************************************************************* +BS3_BEGIN_DATA16 +BS3_GLOBAL_DATA g_bs3CpuState64CtxCaller, BS3REGCTX_size + resb BS3REGCTX_size +BS3_GLOBAL_DATA g_bs3CpuState64CtxToLoad, BS3REGCTX_size + resb BS3REGCTX_size +BS3_GLOBAL_DATA g_bs3CpuState64CtxSaved, BS3REGCTX_size + resb BS3REGCTX_size + +BS3_GLOBAL_DATA g_bs3CpuState64RCX, 8 + dq 1 + + +;********************************************************************************************************************************* +;* External Symbols * +;********************************************************************************************************************************* +BS3_BEGIN_TEXT64 +EXTERN Bs3RegCtxRestore_c64 +EXTERN Bs3RegCtxSave_c64 + + +BS3_BEGIN_TEXT64 + BS3_SET_BITS 64 + +;; +;; Test worker that switches between 64-bit and 16-bit real mode, +;; only trashing RAX, BX, DS, RSP (preseved) and RIP. +;; +;; Caller puts the state to load in g_bs3CpuState64CtxToLoad, this function alters +;; the BX and RIP values before loading it. It then switches to 16-bit real mode, +;; executes the worker given as input, re-enters long mode and saves the state to +;; g_bs3CpuState64CtxSaved. +;; +;; @param rcx Address of worker (16-bit) to invoke while in real-mode. +;; +BS3_PROC_BEGIN NAME(bs3CpuState64Worker) + push rbp + mov rbp, rsp + sub rsp, 40h + mov [rbp + 16], rcx + + ; + ; Save the current register state so we can return with the exact state we entered. + ; + lea rcx, [BS3_WRT_RIP(BS3_DATA_NM(g_bs3CpuState64CtxCaller)) wrt FLAT] + mov [rsp], rcx + call NAME(Bs3RegCtxSave_c64) + + ; + ; Load the context. We modify the state to be loaded so that it fits + ; into the code flow here.. + ; + lea rcx, [BS3_WRT_RIP(BS3_DATA_NM(g_bs3CpuState64CtxToLoad)) wrt FLAT] + mov [rcx + BS3REGCTX.rsp], rsp + ;lea rdx, [BS3_WRT_RIP(.ctx_loaded) wrt FLAT] - absolute address cannot be relative. wtf? + mov edx, .ctx_loaded wrt FLAT + mov [rcx + BS3REGCTX.rip], rdx + mov edx, [rbp + 16] ; Worker address. Putting it in the BX register relative to 16-bit CS. + sub edx, BS3_ADDR_BS3TEXT16 + mov [rcx + BS3REGCTX.rbx], dx + mov edx, 0 ; fFlags + mov [rsp], rcx + mov [rsp + 8], rdx + call NAME(Bs3RegCtxRestore_c64) +.ctx_loaded: + + ; + ; Disable long mode. + ; + + ; Construct a far return for switching to 16-bit code. + push BS3_SEL_R0_CS16 + push .sixteen_bit_segment wrt CGROUP16 + xRETF +BS3_BEGIN_TEXT16 + BS3_SET_BITS 16 +BS3_GLOBAL_LOCAL_LABEL .sixteen_bit_segment + ; Make the DS usable from real mode. + mov ax, BS3_SEL_R0_DS16 + mov ds, ax + + ; Exit to real mode. + mov eax, cr0 + and eax, X86_CR0_NO_PE_NO_PG + mov cr0, eax + jmp CGROUP16:.reload_cs16 +BS3_GLOBAL_LOCAL_LABEL .reload_cs16 + + ; + ; Jump to the 16-bit worker function that will make state modifications. + ; + jmp bx +BS3_GLOBAL_LOCAL_LABEL .resume16 + + ; + ; Re-enter long mode. + ; + mov eax, cr0 + or eax, X86_CR0_PE | X86_CR0_PG + mov cr0, eax + jmp CGROUP16:.reload_cs_long_mode +BS3_GLOBAL_LOCAL_LABEL .reload_cs_long_mode + ; Construct a far return for switching to 64-bit code. + push dword BS3_SEL_R0_CS64 + push dword .sixtyfour_bit_segment wrt FLAT + o32 retf +BS3_BEGIN_TEXT64 +BS3_GLOBAL_LOCAL_LABEL .sixtyfour_bit_segment + BS3_SET_BITS 64 + + ; + ; We're back in long mode, save the context. + ; + mov [BS3_WRT_RIP(BS3_DATA_NM(g_bs3CpuState64RCX)) wrt FLAT], rcx + lea rcx, [BS3_WRT_RIP(BS3_DATA_NM(g_bs3CpuState64CtxSaved)) wrt FLAT] + mov [rsp], rcx + call NAME(Bs3RegCtxSave_c64) + lea rcx, [BS3_WRT_RIP(BS3_DATA_NM(g_bs3CpuState64CtxSaved)) wrt FLAT] + mov rax, [BS3_WRT_RIP(BS3_DATA_NM(g_bs3CpuState64RCX)) wrt FLAT] + mov [rcx + BS3REGCTX.rcx], rax + + ; + ; Load the caller's context. + ; + lea rcx, [BS3_WRT_RIP(BS3_DATA_NM(g_bs3CpuState64CtxCaller)) wrt FLAT] + ;lea rdx, [BS3_WRT_RIP(.return_sequence) wrt FLAT] - absolute address cannot be relative. wtf? + mov edx, .return_sequence wrt FLAT + mov [rcx + BS3REGCTX.rip], rdx + mov edx, 0 + mov [rsp], rcx + mov [rsp + 8], rdx + call NAME(Bs3RegCtxRestore_c64) +.return_sequence: + + add rsp, 40h + pop rbp + ret +BS3_PROC_END NAME(bs3CpuState64Worker) + + +BS3_BEGIN_TEXT16 +; +; Real-mod modification workers for bs3CpuState64Worker. +; + +BS3_PROC_BEGIN NAME(bs3CpuState64Worker_Nop) + nop + jmp NAME(bs3CpuState64Worker.resume16) +BS3_PROC_END NAME(bs3CpuState64Worker_Nop) + + +BS3_PROC_BEGIN NAME(bs3CpuState64Worker_ModAll32BitGrps) + mov eax, 0xc0ffee0d ; C code hardcodes these values too. + mov ecx, 0xc0ffee1d + mov edx, 0xc0ffee2d + mov ebx, 0xc0ffee3d + ; leave esp alone for now. + mov ebp, 0xc0ffee5d + mov esi, 0xc0ffee6d + mov edi, 0xc0ffee7d + jmp NAME(bs3CpuState64Worker.resume16) +BS3_PROC_END NAME(bs3CpuState64Worker_ModAll32BitGrps) + + +BS3_PROC_BEGIN NAME(bs3CpuState64Worker_ModAll16BitGrps) + mov ax, 0xfad0 ; C code hardcodes these values too. + mov cx, 0xfad1 + mov dx, 0xfad2 + mov bx, 0xfad3 + ; leave esp alone for now. + mov bp, 0xfad5 + mov si, 0xfad6 + mov di, 0xfad7 + jmp NAME(bs3CpuState64Worker.resume16) +BS3_PROC_END NAME(bs3CpuState64Worker_ModAll16BitGrps) + + +BS3_PROC_BEGIN NAME(bs3CpuState64Worker_ModAll8BitGrps) + mov al, 0x10 ; C code hardcodes these values too. + mov ah, 0x11 + mov cl, 0x20 + mov ch, 0x21 + mov dl, 0x30 + mov dh, 0x31 + mov bl, 0x40 + mov bh, 0x41 + jmp NAME(bs3CpuState64Worker.resume16) +BS3_PROC_END NAME(bs3CpuState64Worker_ModAll8BitGrps) + +BS3_PROC_BEGIN NAME(bs3CpuState64Worker_ModCr2) + mov eax, 0xf00dface ; C code hardcodes this value too. + mov cr2, eax + jmp NAME(bs3CpuState64Worker.resume16) +BS3_PROC_END NAME(bs3CpuState64Worker_ModCr2) + +;; @todo drX registers. + |