VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TrapDefaultHandler.c@ 60112

Last change on this file since 60112 was 60088, checked in by vboxsync, 9 years ago

bs3kit: updates.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
1/* $Id: bs3-cmn-TrapDefaultHandler.c 60088 2016-03-18 00:07:33Z vboxsync $ */
2/** @file
3 * BS3Kit - Bs3TrapDefaultHandler
4 */
5
6/*
7 * Copyright (C) 2007-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*********************************************************************************************************************************
28* Header Files *
29*********************************************************************************************************************************/
30#include "bs3kit-template-header.h"
31
32
33/*********************************************************************************************************************************
34* Global Variables *
35*********************************************************************************************************************************/
36#define g_pBs3TrapSetJmpFrame BS3_DATA_NM(g_pBs3TrapSetJmpFrame)
37extern uint32_t g_pBs3TrapSetJmpFrame;
38
39#define g_Bs3TrapSetJmpCtx BS3_DATA_NM(g_Bs3TrapSetJmpCtx)
40extern BS3REGCTX g_Bs3TrapSetJmpCtx;
41
42
43#if TMPL_BITS != 64
44static void bs3TrapDefaultHandlerV8086Syscall(PBS3TRAPFRAME pTrapFrame)
45{
46 /* Minimal syscall. */
47 if (pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_PRINT_CHR)
48 Bs3PrintChr(pTrapFrame->Ctx.rcx.u8);
49 else if ( pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING0
50 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING1
51 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING2
52 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING3)
53 {
54 Bs3RegCtxConvertToRingX(&pTrapFrame->Ctx, pTrapFrame->Ctx.rax.u16 - BS3_SYSCALL_TO_RING0);
55 }
56 else
57 Bs3Panic();
58}
59#endif
60
61BS3_DECL(void) Bs3TrapDefaultHandler(PBS3TRAPFRAME pTrapFrame)
62{
63#if TMPL_BITS != 64
64 /*
65 * v8086 VMM tasks.
66 */
67 if (pTrapFrame->Ctx.rflags.u32 & X86_EFL_VM)
68 {
69 bool fHandled = true;
70 uint8_t cBitsOpcode = 16;
71 uint8_t bOpCode;
72 uint8_t const BS3_FAR *pbCodeStart;
73 uint8_t const BS3_FAR *pbCode;
74 uint16_t BS3_FAR *pusStack;
75
76 pusStack = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.ss, pTrapFrame->Ctx.rsp.u16);
77 pbCode = (uint8_t const BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.cs, pTrapFrame->Ctx.rip.u16);
78 pbCodeStart = pbCode;
79
80 /*
81 * Deal with GPs in V8086 mode.
82 */
83 if (pTrapFrame->bXcpt == X86_XCPT_GP)
84 {
85 bOpCode = *pbCode++;
86 if (bOpCode == 0x66)
87 {
88 cBitsOpcode = 32;
89 bOpCode = *pbCode++;
90 }
91
92 /* INT xx: Real mode behaviour, but intercepting and implementing most of our syscall interface. */
93 if (bOpCode == 0xcd)
94 {
95 uint8_t bVector = *pbCode++;
96 if (bVector == BS3_TRAP_SYSCALL)
97 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
98 else
99 {
100 /* Real mode behaviour. */
101 uint16_t BS3_FAR *pusIvte = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(0, 0);
102 pusIvte += (uint16_t)bVector *2;
103
104 pusStack[0] = pTrapFrame->Ctx.rflags.u16;
105 pusStack[1] = pTrapFrame->Ctx.cs;
106 pusStack[2] = pTrapFrame->Ctx.rip.u16 + (uint16_t)(pbCode - pbCodeStart);
107
108 pTrapFrame->Ctx.rip.u16 = pusIvte[0];
109 pTrapFrame->Ctx.cs = pusIvte[1];
110 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF; /** @todo this isn't all, but it'll do for now, I hope. */
111 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0/*fFlags*/); /* does not return. */
112 }
113 }
114 /* PUSHF: Real mode behaviour. */
115 else if (bOpCode == 0x9c)
116 {
117 if (cBitsOpcode == 32)
118 *pusStack++ = pTrapFrame->Ctx.rflags.au16[1] & ~(X86_EFL_VM | X86_EFL_RF);
119 *pusStack++ = pTrapFrame->Ctx.rflags.u16;
120 pTrapFrame->Ctx.rsp.u16 += cBitsOpcode / 8;
121 }
122 /* POPF: Real mode behaviour. */
123 else if (bOpCode == 0x9d)
124 {
125 if (cBitsOpcode == 32)
126 {
127 pTrapFrame->Ctx.rflags.u32 &= ~X86_EFL_POPF_BITS;
128 pTrapFrame->Ctx.rflags.u32 |= X86_EFL_POPF_BITS & *(uint32_t const *)pusStack;
129 }
130 else
131 {
132 pTrapFrame->Ctx.rflags.u32 &= ~(X86_EFL_POPF_BITS | UINT32_C(0xffff0000)) & ~X86_EFL_RF;
133 pTrapFrame->Ctx.rflags.u16 |= (uint16_t)X86_EFL_POPF_BITS & *pusStack;
134 }
135 pTrapFrame->Ctx.rsp.u16 -= cBitsOpcode / 8;
136 }
137 /* CLI: Real mode behaviour. */
138 else if (bOpCode == 0xfa)
139 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF;
140 /* STI: Real mode behaviour. */
141 else if (bOpCode == 0xfb)
142 pTrapFrame->Ctx.rflags.u16 |= X86_EFL_IF;
143 /* Unexpected. */
144 else
145 fHandled = false;
146 }
147 /*
148 * Deal with lock prefixed int xxh syscall in v8086 mode.
149 */
150 else if ( pTrapFrame->bXcpt == X86_XCPT_UD
151 && pbCode[0] == 0xf0
152 && pbCode[1] == 0xcd
153 && pbCode[2] == BS3_TRAP_SYSCALL
154 && pTrapFrame->Ctx.cs == BS3_SEL_TEXT16)
155 {
156 pbCode += 3;
157 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
158 }
159 else
160 fHandled = false;
161 if (fHandled)
162 {
163 pTrapFrame->Ctx.rip.u16 += (uint16_t)(pbCode - pbCodeStart);
164# if 0
165 Bs3Printf("Calling Bs3RegCtxRestore\n");
166 Bs3RegCtxPrint(&pTrapFrame->Ctx);
167# endif
168 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0 /*fFlags*/); /* does not return. */
169 return;
170 }
171 }
172#endif
173
174 /*
175 * Any pending setjmp?
176 */
177 if (g_pBs3TrapSetJmpFrame != 0)
178 {
179 PBS3TRAPFRAME pSetJmpFrame = (PBS3TRAPFRAME)Bs3XptrFlatToCurrent(g_pBs3TrapSetJmpFrame);
180 //Bs3Printf("Calling longjmp: pSetJmpFrame=%p (%#lx)\n", pSetJmpFrame, g_pBs3TrapSetJmpFrame);
181 g_pBs3TrapSetJmpFrame = 0;
182
183 Bs3MemCpy(pSetJmpFrame, pTrapFrame, sizeof(*pSetJmpFrame));
184 //Bs3RegCtxPrint(&g_Bs3TrapSetJmpCtx);
185 Bs3RegCtxRestore(&g_Bs3TrapSetJmpCtx, 0 /*fFlags*/);
186 }
187
188 /*
189 * Fatal.
190 */
191 Bs3TrapPrintFrame(pTrapFrame);
192 Bs3Panic();
193}
194
Note: See TracBrowser for help on using the repository browser.

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