diff options
Diffstat (limited to 'src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-UtilSetFullGdtr.asm')
-rw-r--r-- | src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-UtilSetFullGdtr.asm | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-UtilSetFullGdtr.asm b/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-UtilSetFullGdtr.asm new file mode 100644 index 00000000..aff470da --- /dev/null +++ b/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-UtilSetFullGdtr.asm @@ -0,0 +1,185 @@ +; $Id: bs3-cmn-UtilSetFullGdtr.asm $ +;; @file +; BS3Kit - Bs3UtilSetFullGdtr +; + +; +; 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" + + +;********************************************************************************************************************************* +;* External Symbols * +;********************************************************************************************************************************* +%if TMPL_BITS == 16 +BS3_EXTERN_DATA16 g_uBs3CpuDetected +%endif +%if TMPL_BITS != 64 +BS3_EXTERN_DATA16 g_bBs3CurrentMode +%endif +TMPL_BEGIN_TEXT + + + +;; +; @cproto BS3_CMN_PROTO_NOSB(void, Bs3UtilSetFullGdtr,(uint16_t cbLimit, uint64_t uBase)); +; +; @remarks Does not require 20h of parameter scratch space in 64-bit mode. +; @uses eax/rax; cbLimit on stack in 32-bit mode. +; +BS3_PROC_BEGIN_CMN Bs3UtilSetFullGdtr, BS3_PBC_HYBRID +TONLY16 inc xBP + push xBP + mov xBP, xSP + +%if TMPL_BITS == 64 + ; + ; It doesn't (currently) get any better than 64-bit mode. + ; + push rdx + mov rax, rcx + shl rax, 48 + push rax + lgdt [rsp + 6] + add rsp, 10h + + +%elif TMPL_BITS == 32 + ; + ; Move the limit up two bytes so we can use it directly. + ; + shl dword [xBP + xCB + cbCurRetAddr], 16 + + ; + ; If the system is currently running in long mode, we have to switch to + ; it in order to do the job with the highest precision. + ; + mov al, [BS3_DATA16_WRT(g_bBs3CurrentMode)] + and al, BS3_MODE_SYS_MASK + cmp al, BS3_MODE_SYS_LM + je .do_64bit + + ; 32-bit is the best we can do. +.do_32bit: + lgdt [xBP + xCB + cbCurRetAddr + 2] + jmp .return + + ; Must switch to long mode and do it there. +.do_64bit: + jmp BS3_SEL_R0_CS64:.in_64bit wrt FLAT +.in_64bit: + BS3_SET_BITS 64 + lgdt [xSP + 4 + cbCurRetAddr + 2] + push BS3_SEL_R0_CS32 + push .return wrt FLAT + o64 retf + BS3_SET_BITS 32 + + +%elif TMPL_BITS == 16 + ; + ; All options are open here, we can be in any 16-bit mode, + ; including real mode. + ; + mov al, [BS3_DATA16_WRT(g_bBs3CurrentMode)] + test al, BS3_MODE_CODE_V86 + jnz .do_v8086 + and al, BS3_MODE_SYS_MASK + cmp al, BS3_MODE_SYS_LM + je .do_64bit + cmp al, BS3_MODE_SYS_RM + je .do_16bit + cmp byte [ BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80386 + jae .do_32bit + + ; + ; We're in real mode or in 16-bit protected mode on a 286. + ; +.do_16bit: ;ba x 1 127f5 + lgdt [xBP + xCB + cbCurRetAddr] + jmp .return + + ; + ; We're in some kind of protected mode on a 386 or better. + ; +.do_32bit: + jmp dword BS3_SEL_R0_CS32:.in_32bit wrt FLAT +.in_32bit: + BS3_SET_BITS 32 + lgdt [bp + 2 + cbCurRetAddr] + jmp BS3_SEL_R0_CS16:.return wrt CGROUP16 + BS3_SET_BITS 16 + + ; + ; V8086 mode - need to switch to 32-bit kernel code to do stuff here. + ; +.do_v8086: + BS3_EXTERN_CMN Bs3SwitchTo32Bit + call Bs3SwitchTo32Bit + BS3_SET_BITS 32 + + lgdt [xSP + 2 + cbCurRetAddr] + + extern _Bs3SwitchTo16BitV86_c32 + call _Bs3SwitchTo16BitV86_c32 + BS3_SET_BITS 16 + jmp .return + + ; + ; System is in long mode, so we can switch to 64-bit mode and do the job there. + ; +.do_64bit: + push edx ; save + push ss + push 0 + push bp + BS3_EXTERN_CMN Bs3SelFar32ToFlat32NoClobber + call Bs3SelFar32ToFlat32NoClobber + add sp, 6 + shl edx, 16 + mov dx, ax + mov eax, edx ; eax = flattened ss:bp + pop edx ; restore + jmp dword BS3_SEL_R0_CS64:.in_64bit wrt FLAT +.in_64bit: + BS3_SET_BITS 64 + lgdt [rax + 2 + cbCurRetAddr] + + push BS3_SEL_R0_CS16 + push .return wrt CGROUP16 + o64 retf + BS3_SET_BITS 16 + +%else + %error "TMPL_BITS!" +%endif + +.return: + pop xBP +TONLY16 dec xBP + BS3_HYBRID_RET +BS3_PROC_END_CMN Bs3UtilSetFullGdtr + |