VirtualBox

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

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

bs3kit: got v8086 with 32-bit kernel working.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1/* $Id: bs3-cmn-TrapDefaultHandler.c 59976 2016-03-10 00:53:55Z 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#if TMPL_BITS != 64
34static void bs3TrapDefaultHandlerV8086Syscall(PBS3TRAPFRAME pTrapFrame)
35{
36 /* Minimal syscall. */
37 if (pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_PRINT_CHR)
38 Bs3PrintChr(pTrapFrame->Ctx.rax.u8);
39 else if ( pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING0
40 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING1
41 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING2
42 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING3)
43 {
44 Bs3RegCtxConvertToRingX(&pTrapFrame->Ctx, pTrapFrame->Ctx.rax.u16 - BS3_SYSCALL_TO_RING0);
45 }
46 else
47 Bs3Panic();
48}
49#endif
50
51BS3_DECL(void) Bs3TrapDefaultHandler(PBS3TRAPFRAME pTrapFrame)
52{
53#if TMPL_BITS != 64
54 /*
55 * v8086 VMM tasks.
56 */
57 if (pTrapFrame->Ctx.rflags.u32 & X86_EFL_VM)
58 {
59 bool fHandled = true;
60 uint8_t cBitsOpcode = 16;
61 uint8_t bOpCode;
62 uint8_t const BS3_FAR *pbCodeStart;
63 uint8_t const BS3_FAR *pbCode;
64 uint16_t BS3_FAR *pusStack;
65
66 pusStack = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.ss, pTrapFrame->Ctx.rsp.u16);
67 pbCode = (uint8_t const BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.cs, pTrapFrame->Ctx.rip.u16);
68 pbCodeStart = pbCode;
69
70 /*
71 * Deal with GPs in V8086 mode.
72 */
73 if (pTrapFrame->bXcpt == X86_XCPT_GP)
74 {
75 bOpCode = *pbCode++;
76 if (bOpCode == 0x66)
77 {
78 cBitsOpcode = 32;
79 bOpCode = *pbCode++;
80 }
81
82 /* INT xx: Real mode behaviour, but intercepting and implementing most of our syscall interface. */
83 if (bOpCode == 0xcd)
84 {
85 uint8_t bVector = *pbCode++;
86 if (bVector == BS3_TRAP_SYSCALL)
87 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
88 else
89 {
90 /* Real mode behaviour. */
91 uint16_t BS3_FAR *pusIvte = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(0, 0);
92 pusIvte += (uint16_t)bVector *2;
93
94 pusStack[0] = pTrapFrame->Ctx.rflags.u16;
95 pusStack[1] = pTrapFrame->Ctx.cs;
96 pusStack[2] = pTrapFrame->Ctx.rip.u16 + (uint16_t)(pbCode - pbCodeStart);
97
98 pTrapFrame->Ctx.rip.u16 = pusIvte[0];
99 pTrapFrame->Ctx.cs = pusIvte[1];
100 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF; /** @todo this isn't all, but it'll do for now, I hope. */
101 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0/*fFlags*/); /* does not return. */
102 }
103 }
104 /* PUSHF: Real mode behaviour. */
105 else if (bOpCode == 0x9c)
106 {
107 if (cBitsOpcode == 32)
108 *pusStack++ = pTrapFrame->Ctx.rflags.au16[1] & ~(X86_EFL_VM | X86_EFL_RF);
109 *pusStack++ = pTrapFrame->Ctx.rflags.u16;
110 pTrapFrame->Ctx.rsp.u16 += cBitsOpcode / 8;
111 }
112 /* POPF: Real mode behaviour. */
113 else if (bOpCode == 0x9d)
114 {
115 if (cBitsOpcode == 32)
116 {
117 pTrapFrame->Ctx.rflags.u32 &= ~X86_EFL_POPF_BITS;
118 pTrapFrame->Ctx.rflags.u32 |= X86_EFL_POPF_BITS & *(uint32_t const *)pusStack;
119 }
120 else
121 {
122 pTrapFrame->Ctx.rflags.u32 &= ~(X86_EFL_POPF_BITS | UINT32_C(0xffff0000)) & ~X86_EFL_RF;
123 pTrapFrame->Ctx.rflags.u16 |= (uint16_t)X86_EFL_POPF_BITS & *pusStack;
124 }
125 pTrapFrame->Ctx.rsp.u16 -= cBitsOpcode / 8;
126 }
127 /* CLI: Real mode behaviour. */
128 else if (bOpCode == 0xfa)
129 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF;
130 /* STI: Real mode behaviour. */
131 else if (bOpCode == 0xfb)
132 pTrapFrame->Ctx.rflags.u16 |= X86_EFL_IF;
133 /* Unexpected. */
134 else
135 fHandled = false;
136 }
137 /*
138 * Deal with lock prefixed int xxh syscall in v8086 mode.
139 */
140 else if ( pTrapFrame->bXcpt == X86_XCPT_UD
141 && pbCode[0] == 0xf0
142 && pbCode[1] == 0xcd
143 && pbCode[2] == BS3_TRAP_SYSCALL
144 && pTrapFrame->Ctx.cs == BS3_SEL_TEXT16)
145 {
146 pbCode += 3;
147 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
148 }
149 else
150 fHandled = false;
151 if (fHandled)
152 {
153 pTrapFrame->Ctx.rip.u16 += (uint16_t)(pbCode - pbCodeStart);
154 Bs3Printf("Calling Bs3RegCtxRestore\n");
155 Bs3RegCtxPrint(&pTrapFrame->Ctx);
156 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0 /*fFlags*/); /* does not return. */
157 return;
158 }
159 }
160#endif
161
162 /*
163 * Fatal.
164 */
165 Bs3TrapPrintFrame(pTrapFrame);
166 Bs3Panic();
167}
168
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