VirtualBox

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

Last change on this file since 72133 was 72133, checked in by vboxsync, 7 years ago

bs3kit: Added some more functions for setting and setting CRx and DRx registers from v8086 mode and such.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 KB
Line 
1/* $Id: bs3-cmn-TrapDefaultHandler.c 72133 2018-05-06 23:55:06Z vboxsync $ */
2/** @file
3 * BS3Kit - Bs3TrapDefaultHandler
4 */
5
6/*
7 * Copyright (C) 2007-2017 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/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "bs3kit-template-header.h"
32#if TMPL_BITS != 64
33# include <VBox/VMMDevTesting.h>
34# include <iprt/asm-amd64-x86.h>
35#endif
36
37
38/*********************************************************************************************************************************
39* Global Variables *
40*********************************************************************************************************************************/
41#define g_pBs3TrapSetJmpFrame BS3_DATA_NM(g_pBs3TrapSetJmpFrame)
42extern uint32_t g_pBs3TrapSetJmpFrame;
43
44#define g_Bs3TrapSetJmpCtx BS3_DATA_NM(g_Bs3TrapSetJmpCtx)
45extern BS3REGCTX g_Bs3TrapSetJmpCtx;
46
47
48#if TMPL_BITS != 64
49/**
50 * V86 syscall handler.
51 */
52static void bs3TrapDefaultHandlerV8086Syscall(PBS3TRAPFRAME pTrapFrame)
53{
54 /* Minimal syscall. */
55 uint16_t uSyscallNo = pTrapFrame->Ctx.rax.u16;
56 if (uSyscallNo == BS3_SYSCALL_PRINT_CHR)
57 Bs3PrintChr(pTrapFrame->Ctx.rcx.u8);
58 else if (uSyscallNo == BS3_SYSCALL_PRINT_STR)
59 Bs3PrintStrN(Bs3XptrFlatToCurrent(((uint32_t)pTrapFrame->Ctx.rcx.u16 << 4) + pTrapFrame->Ctx.rsi.u16),
60 pTrapFrame->Ctx.rdx.u16);
61 else if (uSyscallNo == BS3_SYSCALL_RESTORE_CTX)
62 Bs3RegCtxRestore(Bs3XptrFlatToCurrent(((uint32_t)pTrapFrame->Ctx.rcx.u16 << 4) + pTrapFrame->Ctx.rsi.u16),
63 pTrapFrame->Ctx.rdx.u16);
64 else if ( uSyscallNo == BS3_SYSCALL_TO_RING0
65 || uSyscallNo == BS3_SYSCALL_TO_RING1
66 || uSyscallNo == BS3_SYSCALL_TO_RING2
67 || uSyscallNo == BS3_SYSCALL_TO_RING3)
68 {
69 Bs3RegCtxConvertToRingX(&pTrapFrame->Ctx, pTrapFrame->Ctx.rax.u16 - BS3_SYSCALL_TO_RING0);
70 }
71 else if (uSyscallNo == BS3_SYSCALL_SET_DRX)
72 {
73 uint32_t uValue = pTrapFrame->Ctx.rsi.u32;
74 switch (pTrapFrame->Ctx.rdx.u8)
75 {
76 case 0: ASMSetDR0(uValue); break;
77 case 1: ASMSetDR1(uValue); break;
78 case 2: ASMSetDR2(uValue); break;
79 case 3: ASMSetDR3(uValue); break;
80 case 6: ASMSetDR6(uValue); break;
81 case 7: ASMSetDR7(uValue); break;
82 default: Bs3Panic();
83 }
84 }
85 else if (uSyscallNo == BS3_SYSCALL_GET_DRX)
86 {
87 uint32_t uValue;
88 switch (pTrapFrame->Ctx.rdx.u8)
89 {
90 case 0: uValue = ASMGetDR0(); break;
91 case 1: uValue = ASMGetDR1(); break;
92 case 2: uValue = ASMGetDR2(); break;
93 case 3: uValue = ASMGetDR3(); break;
94 case 6: uValue = ASMGetDR6(); break;
95 case 7: uValue = ASMGetDR7(); break;
96 default: uValue = 0; Bs3Panic();
97 }
98 pTrapFrame->Ctx.rax.u32 = uValue;
99 pTrapFrame->Ctx.rdx.u32 = uValue >> 16;
100 }
101 else if (uSyscallNo == BS3_SYSCALL_SET_CRX)
102 {
103 uint32_t uValue = pTrapFrame->Ctx.rsi.u32;
104 switch (pTrapFrame->Ctx.rdx.u8)
105 {
106 case 0: ASMSetCR0(uValue); break;
107 case 2: ASMSetCR2(uValue); break;
108 case 3: ASMSetCR3(uValue); break;
109 case 4: ASMSetCR4(uValue); break;
110 default: Bs3Panic();
111 }
112 }
113 else if (uSyscallNo == BS3_SYSCALL_GET_CRX)
114 {
115 uint32_t uValue;
116 switch (pTrapFrame->Ctx.rdx.u8)
117 {
118 case 0: uValue = ASMGetDR0(); break;
119 case 2: uValue = ASMGetCR2(); break;
120 case 3: uValue = ASMGetCR3(); break;
121 case 4: uValue = ASMGetCR4(); break;
122 default: uValue = 0; Bs3Panic();
123 }
124 pTrapFrame->Ctx.rax.u32 = uValue;
125 pTrapFrame->Ctx.rdx.u32 = uValue >> 16;
126 }
127 else
128 Bs3Panic();
129}
130#endif
131
132#undef Bs3TrapDefaultHandler
133BS3_CMN_DEF(void, Bs3TrapDefaultHandler,(PBS3TRAPFRAME pTrapFrame))
134{
135#if TMPL_BITS != 64
136 /*
137 * v8086 VMM tasks.
138 */
139//Bs3TestHostPrintf("Bs3____DefaultHandler: %02xh %04RX16:%08RX32 %08RX32 %04RX16:%08RX32 %d %d\n", pTrapFrame->bXcpt,
140// pTrapFrame->Ctx.cs, pTrapFrame->Ctx.rip.u32, pTrapFrame->Ctx.rflags.u32, pTrapFrame->Ctx.ss, pTrapFrame->Ctx.rsp.u32, g_fBs3TrapNoV86Assist, 42);
141 if ( (pTrapFrame->Ctx.rflags.u32 & X86_EFL_VM)
142 && !g_fBs3TrapNoV86Assist)
143 {
144 bool fHandled = true;
145 uint8_t cBitsOpcode = 16;
146 uint8_t bOpCode;
147 uint8_t const BS3_FAR *pbCodeStart;
148 uint8_t const BS3_FAR *pbCode;
149 uint16_t BS3_FAR *pusStack;
150
151 pusStack = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.ss, pTrapFrame->Ctx.rsp.u16);
152 pbCode = (uint8_t const BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.cs, pTrapFrame->Ctx.rip.u16);
153 pbCodeStart = pbCode;
154//Bs3TestHostPrintf("Bs3TrapDefaultHandler: V86 assist...\n");
155
156 /*
157 * Deal with GPs in V8086 mode.
158 */
159 if (pTrapFrame->bXcpt == X86_XCPT_GP)
160 {
161//Bs3TestHostPrintf("Bs3TrapDefaultHandler: #GP %04RX16:%08RX32 %08RX32\n", pTrapFrame->Ctx.cs, pTrapFrame->Ctx.rip.u32, pTrapFrame->Ctx.rflags.u32);
162 bOpCode = *pbCode++;
163 if (bOpCode == 0x66)
164 {
165 cBitsOpcode = 32;
166 bOpCode = *pbCode++;
167 }
168
169 /* INT xx: Real mode behaviour, but intercepting and implementing most of our syscall interface. */
170 if (bOpCode == 0xcd)
171 {
172 uint8_t bVector = *pbCode++;
173 if (bVector == BS3_TRAP_SYSCALL)
174 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
175 else
176 {
177 /* Real mode behaviour. */
178 uint16_t BS3_FAR *pusIvte = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(0, 0);
179 pusIvte += (uint16_t)bVector *2;
180
181 pusStack[0] = pTrapFrame->Ctx.rflags.u16;
182 pusStack[1] = pTrapFrame->Ctx.cs;
183 pusStack[2] = pTrapFrame->Ctx.rip.u16 + (uint16_t)(pbCode - pbCodeStart);
184
185 pTrapFrame->Ctx.rip.u16 = pusIvte[0];
186 pTrapFrame->Ctx.cs = pusIvte[1];
187 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF; /** @todo this isn't all, but it'll do for now, I hope. */
188 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0/*fFlags*/); /* does not return. */
189 }
190 }
191 /* PUSHF: Real mode behaviour. */
192 else if (bOpCode == 0x9c)
193 {
194 if (cBitsOpcode == 32)
195 *pusStack++ = pTrapFrame->Ctx.rflags.au16[1] & ~(X86_EFL_VM | X86_EFL_RF);
196 *pusStack++ = pTrapFrame->Ctx.rflags.u16;
197 pTrapFrame->Ctx.rsp.u16 += cBitsOpcode / 8;
198 }
199 /* POPF: Real mode behaviour. */
200 else if (bOpCode == 0x9d)
201 {
202 if (cBitsOpcode == 32)
203 {
204 pTrapFrame->Ctx.rflags.u32 &= ~X86_EFL_POPF_BITS;
205 pTrapFrame->Ctx.rflags.u32 |= X86_EFL_POPF_BITS & *(uint32_t const *)pusStack;
206 }
207 else
208 {
209 pTrapFrame->Ctx.rflags.u32 &= ~(X86_EFL_POPF_BITS | UINT32_C(0xffff0000)) & ~X86_EFL_RF;
210 pTrapFrame->Ctx.rflags.u16 |= (uint16_t)X86_EFL_POPF_BITS & *pusStack;
211 }
212 pTrapFrame->Ctx.rsp.u16 -= cBitsOpcode / 8;
213 }
214 /* CLI: Real mode behaviour. */
215 else if (bOpCode == 0xfa)
216 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF;
217 /* STI: Real mode behaviour. */
218 else if (bOpCode == 0xfb)
219 pTrapFrame->Ctx.rflags.u16 |= X86_EFL_IF;
220 /* OUT: byte I/O to VMMDev. */
221 else if ( bOpCode == 0xee
222 && ((unsigned)(pTrapFrame->Ctx.rdx.u16 - VMMDEV_TESTING_IOPORT_BASE) < (unsigned)VMMDEV_TESTING_IOPORT_COUNT))
223 ASMOutU8(pTrapFrame->Ctx.rdx.u16, pTrapFrame->Ctx.rax.u8);
224 /* OUT: [d]word I/O to VMMDev. */
225 else if ( bOpCode == 0xef
226 && ((unsigned)(pTrapFrame->Ctx.rdx.u16 - VMMDEV_TESTING_IOPORT_BASE) < (unsigned)VMMDEV_TESTING_IOPORT_COUNT))
227 {
228 if (cBitsOpcode != 32)
229 ASMOutU16(pTrapFrame->Ctx.rdx.u16, pTrapFrame->Ctx.rax.u16);
230 else
231 ASMOutU32(pTrapFrame->Ctx.rdx.u16, pTrapFrame->Ctx.rax.u32);
232 }
233 /* IN: byte I/O to VMMDev. */
234 else if ( bOpCode == 0xec
235 && ((unsigned)(pTrapFrame->Ctx.rdx.u16 - VMMDEV_TESTING_IOPORT_BASE) < (unsigned)VMMDEV_TESTING_IOPORT_COUNT))
236 pTrapFrame->Ctx.rax.u8 = ASMInU8(pTrapFrame->Ctx.rdx.u16);
237 /* IN: [d]word I/O to VMMDev. */
238 else if ( bOpCode == 0xed
239 && ((unsigned)(pTrapFrame->Ctx.rdx.u16 - VMMDEV_TESTING_IOPORT_BASE) < (unsigned)VMMDEV_TESTING_IOPORT_COUNT))
240 {
241 if (cBitsOpcode != 32)
242 pTrapFrame->Ctx.rax.u16 = ASMInU16(pTrapFrame->Ctx.rdx.u16);
243 else
244 pTrapFrame->Ctx.rax.u32 = ASMInU32(pTrapFrame->Ctx.rdx.u32);
245 }
246 /* Unexpected. */
247 else
248 fHandled = false;
249 }
250 /*
251 * Deal with lock prefixed int xxh syscall in v8086 mode.
252 */
253 else if ( pTrapFrame->bXcpt == X86_XCPT_UD
254 && pbCode[0] == 0xf0
255 && pbCode[1] == 0xcd
256 && pbCode[2] == BS3_TRAP_SYSCALL
257 && pTrapFrame->Ctx.cs == BS3_SEL_TEXT16)
258 {
259 pbCode += 3;
260 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
261 }
262 else
263 {
264//Bs3TestHostPrintf("Bs3TrapDefaultHandler: %02x %04RX16:%08RX32 %08RX32\n", pTrapFrame->bXcpt, pTrapFrame->Ctx.cs, pTrapFrame->Ctx.rip.u32, pTrapFrame->Ctx.rflags.u32);
265 fHandled = false;
266 }
267 if (fHandled)
268 {
269 pTrapFrame->Ctx.rip.u16 += (uint16_t)(pbCode - pbCodeStart);
270# if 0
271 Bs3Printf("Calling Bs3RegCtxRestore\n");
272 Bs3RegCtxPrint(&pTrapFrame->Ctx);
273# endif
274 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0 /*fFlags*/); /* does not return. */
275Bs3TestHostPrintf("Bs3TrapDefaultHandler: => Handled\n");
276 return;
277 }
278 }
279#endif
280
281 /*
282 * Any pending setjmp?
283 */
284 if (g_pBs3TrapSetJmpFrame != 0)
285 {
286 PBS3TRAPFRAME pSetJmpFrame = (PBS3TRAPFRAME)Bs3XptrFlatToCurrent(g_pBs3TrapSetJmpFrame);
287 //Bs3Printf("Calling longjmp: pSetJmpFrame=%p (%#lx)\n", pSetJmpFrame, g_pBs3TrapSetJmpFrame);
288 g_pBs3TrapSetJmpFrame = 0;
289 Bs3MemCpy(pSetJmpFrame, pTrapFrame, sizeof(*pSetJmpFrame));
290 //Bs3RegCtxPrint(&g_Bs3TrapSetJmpCtx);
291 Bs3RegCtxRestore(&g_Bs3TrapSetJmpCtx, 0 /*fFlags*/);
292 }
293
294 /*
295 * Fatal.
296 */
297 Bs3TestPrintf("*** GURU ***\n");
298 Bs3TrapPrintFrame(pTrapFrame);
299 Bs3Panic();
300}
301
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