VirtualBox

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

Last change on this file since 61394 was 60657, 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: 9.6 KB
Line 
1/* $Id: bs3-cmn-TrapDefaultHandler.c 60657 2016-04-22 15:57:22Z 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#if TMPL_BITS != 64
32# include <VBox/VMMDevTesting.h>
33# include <iprt/asm-amd64-x86.h>
34#endif
35
36
37/*********************************************************************************************************************************
38* Global Variables *
39*********************************************************************************************************************************/
40#define g_pBs3TrapSetJmpFrame BS3_DATA_NM(g_pBs3TrapSetJmpFrame)
41extern uint32_t g_pBs3TrapSetJmpFrame;
42
43#define g_Bs3TrapSetJmpCtx BS3_DATA_NM(g_Bs3TrapSetJmpCtx)
44extern BS3REGCTX g_Bs3TrapSetJmpCtx;
45
46
47#if TMPL_BITS != 64
48static void bs3TrapDefaultHandlerV8086Syscall(PBS3TRAPFRAME pTrapFrame)
49{
50 /* Minimal syscall. */
51 if (pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_PRINT_CHR)
52 Bs3PrintChr(pTrapFrame->Ctx.rcx.u8);
53 else if (pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_PRINT_STR)
54 Bs3PrintStrN(Bs3XptrFlatToCurrent(((uint32_t)pTrapFrame->Ctx.rcx.u16 << 4) + pTrapFrame->Ctx.rsi.u16),
55 pTrapFrame->Ctx.rdx.u16);
56 else if (pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_RESTORE_CTX)
57 Bs3RegCtxRestore(Bs3XptrFlatToCurrent(((uint32_t)pTrapFrame->Ctx.rcx.u16 << 4) + pTrapFrame->Ctx.rsi.u16),
58 pTrapFrame->Ctx.rdx.u16);
59 else if ( pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING0
60 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING1
61 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING2
62 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING3)
63 {
64 Bs3RegCtxConvertToRingX(&pTrapFrame->Ctx, pTrapFrame->Ctx.rax.u16 - BS3_SYSCALL_TO_RING0);
65 }
66 else
67 Bs3Panic();
68}
69#endif
70
71#undef Bs3TrapDefaultHandler
72BS3_CMN_DEF(void, Bs3TrapDefaultHandler,(PBS3TRAPFRAME pTrapFrame))
73{
74#if TMPL_BITS != 64
75 /*
76 * v8086 VMM tasks.
77 */
78 if (pTrapFrame->Ctx.rflags.u32 & X86_EFL_VM)
79 {
80 bool fHandled = true;
81 uint8_t cBitsOpcode = 16;
82 uint8_t bOpCode;
83 uint8_t const BS3_FAR *pbCodeStart;
84 uint8_t const BS3_FAR *pbCode;
85 uint16_t BS3_FAR *pusStack;
86
87 pusStack = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.ss, pTrapFrame->Ctx.rsp.u16);
88 pbCode = (uint8_t const BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.cs, pTrapFrame->Ctx.rip.u16);
89 pbCodeStart = pbCode;
90
91 /*
92 * Deal with GPs in V8086 mode.
93 */
94 if (pTrapFrame->bXcpt == X86_XCPT_GP)
95 {
96 bOpCode = *pbCode++;
97 if (bOpCode == 0x66)
98 {
99 cBitsOpcode = 32;
100 bOpCode = *pbCode++;
101 }
102
103 /* INT xx: Real mode behaviour, but intercepting and implementing most of our syscall interface. */
104 if (bOpCode == 0xcd)
105 {
106 uint8_t bVector = *pbCode++;
107 if (bVector == BS3_TRAP_SYSCALL)
108 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
109 else
110 {
111 /* Real mode behaviour. */
112 uint16_t BS3_FAR *pusIvte = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(0, 0);
113 pusIvte += (uint16_t)bVector *2;
114
115 pusStack[0] = pTrapFrame->Ctx.rflags.u16;
116 pusStack[1] = pTrapFrame->Ctx.cs;
117 pusStack[2] = pTrapFrame->Ctx.rip.u16 + (uint16_t)(pbCode - pbCodeStart);
118
119 pTrapFrame->Ctx.rip.u16 = pusIvte[0];
120 pTrapFrame->Ctx.cs = pusIvte[1];
121 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF; /** @todo this isn't all, but it'll do for now, I hope. */
122 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0/*fFlags*/); /* does not return. */
123 }
124 }
125 /* PUSHF: Real mode behaviour. */
126 else if (bOpCode == 0x9c)
127 {
128 if (cBitsOpcode == 32)
129 *pusStack++ = pTrapFrame->Ctx.rflags.au16[1] & ~(X86_EFL_VM | X86_EFL_RF);
130 *pusStack++ = pTrapFrame->Ctx.rflags.u16;
131 pTrapFrame->Ctx.rsp.u16 += cBitsOpcode / 8;
132 }
133 /* POPF: Real mode behaviour. */
134 else if (bOpCode == 0x9d)
135 {
136 if (cBitsOpcode == 32)
137 {
138 pTrapFrame->Ctx.rflags.u32 &= ~X86_EFL_POPF_BITS;
139 pTrapFrame->Ctx.rflags.u32 |= X86_EFL_POPF_BITS & *(uint32_t const *)pusStack;
140 }
141 else
142 {
143 pTrapFrame->Ctx.rflags.u32 &= ~(X86_EFL_POPF_BITS | UINT32_C(0xffff0000)) & ~X86_EFL_RF;
144 pTrapFrame->Ctx.rflags.u16 |= (uint16_t)X86_EFL_POPF_BITS & *pusStack;
145 }
146 pTrapFrame->Ctx.rsp.u16 -= cBitsOpcode / 8;
147 }
148 /* CLI: Real mode behaviour. */
149 else if (bOpCode == 0xfa)
150 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF;
151 /* STI: Real mode behaviour. */
152 else if (bOpCode == 0xfb)
153 pTrapFrame->Ctx.rflags.u16 |= X86_EFL_IF;
154 /* OUT: byte I/O to VMMDev. */
155 else if ( bOpCode == 0xee
156 && ((unsigned)(pTrapFrame->Ctx.rdx.u16 - VMMDEV_TESTING_IOPORT_BASE) < (unsigned)VMMDEV_TESTING_IOPORT_COUNT))
157 ASMOutU8(pTrapFrame->Ctx.rdx.u16, pTrapFrame->Ctx.rax.u8);
158 /* OUT: [d]word I/O to VMMDev. */
159 else if ( bOpCode == 0xef
160 && ((unsigned)(pTrapFrame->Ctx.rdx.u16 - VMMDEV_TESTING_IOPORT_BASE) < (unsigned)VMMDEV_TESTING_IOPORT_COUNT))
161 {
162 if (cBitsOpcode != 32)
163 ASMOutU16(pTrapFrame->Ctx.rdx.u16, pTrapFrame->Ctx.rax.u16);
164 else
165 ASMOutU32(pTrapFrame->Ctx.rdx.u16, pTrapFrame->Ctx.rax.u32);
166 }
167 /* IN: byte I/O to VMMDev. */
168 else if ( bOpCode == 0xec
169 && ((unsigned)(pTrapFrame->Ctx.rdx.u16 - VMMDEV_TESTING_IOPORT_BASE) < (unsigned)VMMDEV_TESTING_IOPORT_COUNT))
170 pTrapFrame->Ctx.rax.u8 = ASMInU8(pTrapFrame->Ctx.rdx.u16);
171 /* IN: [d]word I/O to VMMDev. */
172 else if ( bOpCode == 0xed
173 && ((unsigned)(pTrapFrame->Ctx.rdx.u16 - VMMDEV_TESTING_IOPORT_BASE) < (unsigned)VMMDEV_TESTING_IOPORT_COUNT))
174 {
175 if (cBitsOpcode != 32)
176 pTrapFrame->Ctx.rax.u16 = ASMInU16(pTrapFrame->Ctx.rdx.u16);
177 else
178 pTrapFrame->Ctx.rax.u32 = ASMInU32(pTrapFrame->Ctx.rdx.u32);
179 }
180 /* Unexpected. */
181 else
182 fHandled = false;
183 }
184 /*
185 * Deal with lock prefixed int xxh syscall in v8086 mode.
186 */
187 else if ( pTrapFrame->bXcpt == X86_XCPT_UD
188 && pbCode[0] == 0xf0
189 && pbCode[1] == 0xcd
190 && pbCode[2] == BS3_TRAP_SYSCALL
191 && pTrapFrame->Ctx.cs == BS3_SEL_TEXT16)
192 {
193 pbCode += 3;
194 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
195 }
196 else
197 fHandled = false;
198 if (fHandled)
199 {
200 pTrapFrame->Ctx.rip.u16 += (uint16_t)(pbCode - pbCodeStart);
201# if 0
202 Bs3Printf("Calling Bs3RegCtxRestore\n");
203 Bs3RegCtxPrint(&pTrapFrame->Ctx);
204# endif
205 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0 /*fFlags*/); /* does not return. */
206 return;
207 }
208 }
209#endif
210
211 /*
212 * Any pending setjmp?
213 */
214 if (g_pBs3TrapSetJmpFrame != 0)
215 {
216 PBS3TRAPFRAME pSetJmpFrame = (PBS3TRAPFRAME)Bs3XptrFlatToCurrent(g_pBs3TrapSetJmpFrame);
217 //Bs3Printf("Calling longjmp: pSetJmpFrame=%p (%#lx)\n", pSetJmpFrame, g_pBs3TrapSetJmpFrame);
218 g_pBs3TrapSetJmpFrame = 0;
219 Bs3MemCpy(pSetJmpFrame, pTrapFrame, sizeof(*pSetJmpFrame));
220 //Bs3RegCtxPrint(&g_Bs3TrapSetJmpCtx);
221 Bs3RegCtxRestore(&g_Bs3TrapSetJmpCtx, 0 /*fFlags*/);
222 }
223
224 /*
225 * Fatal.
226 */
227 Bs3TrapPrintFrame(pTrapFrame);
228 Bs3Panic();
229}
230
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