bootsector2-triple-fault-1.asm revision cf22150eaeeb72431bf1cf65c309a431454fb22b
; $Id$
;; @file
; Bootsector for testing triple faults.
;
;
; Copyright (C) 2007-2014 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.
;
%include "iprt/asmdefs.mac"
%include "iprt/x86.mac"
%include "VBox/VMMDevTesting.mac"
;; The number of instructions to test.
%define TEST_INSTRUCTION_COUNT_IO 2000000
;; The number of instructions to test.
%define TEST_INSTRUCTION_COUNT_MMIO 750000
;; Define this to drop unnecessary test variations.
%define QUICK_TEST
;
; Include and execute the init code.
;
%define BS2_INIT_RM
%define BS2_INC_PE16
%define BS2_INC_PE32
%define BS2_INC_PP32
%define BS2_INC_PAE32
%define BS2_INC_LM64
%include "bootsector2-common-init-code.mac"
;
; The test driver
;
BEGINPROC main
;
; Test prologue.
;
mov ax, .s_szTstName
call TestInit_r86
call Bs2EnableA20_r86
;
; Did we get here from a reboot triggered below?
;
push ds
mov ax, 2000h ; 128 KB is enough for the test program
.boot_check_loop:
mov ds, ax
cmp dword [0], 064726962h
jne .boot_check_next
cmp dword [4], 062697264h
je .warm_reset_broken
.boot_check_next:
mov dword [0], 064726962h
mov dword [4], 062697264h
add ax, 1000h
cmp ax, 8000h
jbe .boot_check_loop
pop ds
jmp .fine
.warm_reset_broken:
pop ds
mov ax, .s_szWarmResetBroken
call NAME(TestFailed_r86)
jmp .done
.s_szWarmResetBroken:
db 'Warm reset vector support is broken', 0dh, 0ah, 0
.fine:
;
; Test that the warm reset interface works.
;
mov ax, .s_szPrecondTest5
call NAME(TestSub_r86)
mov al, 05h
call NAME(SetWarmResetJmp)
cmp ax, 0
jne .precond_test_A
call NAME(TestReboot_r86)
.precond_test_A:
mov ax, .s_szPrecondTestA
call NAME(TestSub_r86)
mov al, 0Ah
call NAME(SetWarmResetJmp)
cmp ax, 0
jne .precond_test_A_passed
call NAME(TestReboot_r86)
.precond_test_A_passed:
call NAME(TestSubDone_r86)
;
; The real tests.
;
;
; We're done.
;
.done:
call NAME(TestTerm_r86)
call Bs2Panic
.s_szTstName:
db 'tstTriple', 0
.s_szPrecondTest5:
db 'Shutdown Action 5', 0
.s_szPrecondTestA:
db 'Shutdown Action A', 0
ENDPROC main
;;
; Sets up the warm reset vector.
;
; @param ax Where to resume exeuction.
; @param dl Shutdown action command to use, 5h or Fh.
;
; @uses nothing
;
BEGINPROC SetUpWarmReset
push bp
mov bp, sp
push eax
push ebx
push ecx
push edx
push edi
push esi
push es
;
; Set up the warm reboot vector.
;
mov bx, 40h
mov es, bx
mov ecx, [es:67h] ; debug
mov word [es:67h], ax
mov bx, cs
mov word [es:67h+2], bx
mov bx, [es:72h] ; debug
mov word [es:72h], 1234h ; warm reboot
wbinvd
mov al, 0fh
out 70h, al ; set register index
in al, 71h
mov ah, al ; debug
mov al, dl ; shutdown action command
out 71h, al ; set cmos[f] = a - invoke testResume as early as possible.
in al, 71h ; debug / paranoia
movzx si, al
; Debug print.
%if 1
mov di, sp ; save sp (lazy bird)
in al, 64h
push ax ; kbd status
push si ; cmos[f] after
mov al, ah ; cmos[f] before
push ax
push word [0472h] ; 40:72 word after
push bx ; 40:72 word before
push word [0467h] ; 40:67 far addr after
push word [0469h]
push cx ; 40:67 far addr before
shr ecx, 16
push dx
push ds
push .s_szDebugFmt
call NAME(PrintF_r86)
mov sp, di ; restore sp.
;.forever:
; cli
; hlt
; jmp .forever
%endif
pop es
pop esi
pop edi
pop edx
pop ecx
pop ebx
pop eax
leave
ret
.s_szDebugFmt:
db 'dbg: 40:67=%RX16:%RX16 (%RX16:%RX16) 40:72=%RX16 (%RX16) cmos[f]=%RX8 (%RX8) kbdsts=%RX8', 0dh, 0ah, 0
ENDPROC SetUpWarmReset
;;
; Sets up the warm reset vector.
;
; @returns ax = 0 on setup call, ax = 1 on resume return.
; @param al Shutdown action command to use, 5h or Fh.
; @uses ax
;
BEGINPROC SetWarmResetJmp
push bp
mov bp, sp
push dx
mov dl, al
mov ax, .resume
call NAME(SetUpWarmReset)
%ifdef DEBUG
push cs
push .s_szDbg1
call NAME(PrintF_r86)
add sp, 4
%endif
mov ax, .s_ResumeRegs
call NAME(TestSaveRegisters_r86)
%ifdef DEBUG
push cs
push .s_szDbg2
call NAME(PrintF_r86)
add sp, 4
%endif
mov dx, [bp - 2]
mov [.s_ResumeRegs + BS2REGS.rdx], dx
mov ax, bp
add ax, 4
mov [.s_ResumeRegs + BS2REGS.rsp], ax
mov ax, [bp]
mov [.s_ResumeRegs + BS2REGS.rbp], ax
mov ax, [bp + 2]
mov [.s_ResumeRegs + BS2REGS.rip], ax
mov word [.s_ResumeRegs + BS2REGS.rax], 1
%ifdef DEBUG
push cs
push .s_szDbg3
call NAME(PrintF_r86)
add sp, 4
%endif
xor ax, ax
.done:
pop dx
leave
ret
.resume:
cli
xor ax, ax
mov ds, ax
mov es, ax
mov ax, [.s_ResumeRegs + BS2REGS.ss]
mov ss, ax
mov esp, [.s_ResumeRegs + BS2REGS.rsp]
mov ebp, [.s_ResumeRegs + BS2REGS.rbp]
%ifdef DEBUG
push ds
push .s_szDbg4
call NAME(PrintF_r86)
add sp, 4
%endif
mov ax, .s_ResumeRegs
call NAME(TestRestoreRegisters_r86)
mov ax, [.s_ResumeRegs + BS2REGS.rip]
push ax
mov ax, 1
ret
;jmp word [.s_ResumeRegs + BS2REGS.rip]
.s_ResumeRegs:
times (BS2REGS_size) db 0
%ifdef DEBUG
.s_szDbg1:
db 'dbg 1', 0dh, 0ah, 0
.s_szDbg2:
db 'dbg 2', 0dh, 0ah, 0
.s_szDbg3:
db 'dbg 3', 0dh, 0ah, 0
.s_szDbg4:
db 'dbg 4', 0dh, 0ah, 0
%endif
ENDPROC SetWarmResetJmp
;;
; Reboot the machine. Will not return.
;
BEGINPROC TestReboot_r86
%ifdef DEBUG
; Debug
push ds
push .s_szDbg
call NAME(PrintF_r86)
%endif
; Via port A
in al, 92h
and al, ~1
out 92h, al
or al, 1
out 92h, al
in al, 92h
.forever:
cli
hlt
jmp .forever
%ifdef DEBUG
.s_szDbg:
db 'Rebooting...', 0dh, 0ah, 0
%endif
ENDPROC TestReboot_r86
;
; Instantiate the template code.
;
%include "bootsector2-template-footer.mac" ; reset the initial environemnt.
;%define TMPL_RM
;%include "bootsector2-test1-template.mac"
;%define TMPL_CMN_V86
;%include "bootsector2-test1-template.mac"
;%define TMPL_PE16
;%include "bootsector2-test1-template.mac"
;%define TMPL_PE32
;%include "bootsector2-test1-template.mac"
;%define TMPL_PP16
;%include "bootsector2-test1-template.mac"
;%define TMPL_PP32
;%include "bootsector2-test1-template.mac"
;%define TMPL_PAE16
;%include "bootsector2-test1-template.mac"
;%define TMPL_PAE32
;%include "bootsector2-test1-template.mac"
;%define TMPL_LM16
;%include "bootsector2-test1-template.mac"
;%define TMPL_LM32
;%include "bootsector2-test1-template.mac"
;%define TMPL_LM64
;%include "bootsector2-test1-template.mac"
;
; End sections and image.
;
%include "bootsector2-common-end.mac"