VirtualBox

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

最後變更 在這個檔案從60311是 60311,由 vboxsync 提交於 9 年 前

bs3kit: Use \#define with BS3_DATA_NM to map data symbols to names accessible in all context. (Underscores in 16-bit and 32-bit, no underscores in 64-bit.) Detect PSE.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.9 KB
 
1/* $Id: bs3-cmn-TrapDefaultHandler.c 60311 2016-04-04 17:01:14Z 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.alldomusa.eu.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_PRINT_STR)
50 Bs3PrintStrN(Bs3XptrFlatToCurrent((pTrapFrame->Ctx.rcx.u16 << 4) + pTrapFrame->Ctx.rsi.u16), pTrapFrame->Ctx.rdx.u16);
51 else if (pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_RESTORE_CTX)
52 Bs3RegCtxRestore(Bs3XptrFlatToCurrent((pTrapFrame->Ctx.rcx.u16 << 4) + pTrapFrame->Ctx.rsi.u16), pTrapFrame->Ctx.rdx.u16);
53 else if ( pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING0
54 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING1
55 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING2
56 || pTrapFrame->Ctx.rax.u16 == BS3_SYSCALL_TO_RING3)
57 {
58 Bs3RegCtxConvertToRingX(&pTrapFrame->Ctx, pTrapFrame->Ctx.rax.u16 - BS3_SYSCALL_TO_RING0);
59 }
60 else
61 Bs3Panic();
62}
63#endif
64
65BS3_DECL(void) Bs3TrapDefaultHandler(PBS3TRAPFRAME pTrapFrame)
66{
67#if TMPL_BITS != 64
68 /*
69 * v8086 VMM tasks.
70 */
71 if (pTrapFrame->Ctx.rflags.u32 & X86_EFL_VM)
72 {
73 bool fHandled = true;
74 uint8_t cBitsOpcode = 16;
75 uint8_t bOpCode;
76 uint8_t const BS3_FAR *pbCodeStart;
77 uint8_t const BS3_FAR *pbCode;
78 uint16_t BS3_FAR *pusStack;
79
80 pusStack = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.ss, pTrapFrame->Ctx.rsp.u16);
81 pbCode = (uint8_t const BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(pTrapFrame->Ctx.cs, pTrapFrame->Ctx.rip.u16);
82 pbCodeStart = pbCode;
83
84 /*
85 * Deal with GPs in V8086 mode.
86 */
87 if (pTrapFrame->bXcpt == X86_XCPT_GP)
88 {
89 bOpCode = *pbCode++;
90 if (bOpCode == 0x66)
91 {
92 cBitsOpcode = 32;
93 bOpCode = *pbCode++;
94 }
95
96 /* INT xx: Real mode behaviour, but intercepting and implementing most of our syscall interface. */
97 if (bOpCode == 0xcd)
98 {
99 uint8_t bVector = *pbCode++;
100 if (bVector == BS3_TRAP_SYSCALL)
101 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
102 else
103 {
104 /* Real mode behaviour. */
105 uint16_t BS3_FAR *pusIvte = (uint16_t BS3_FAR *)BS3_MAKE_PROT_R0PTR_FROM_REAL(0, 0);
106 pusIvte += (uint16_t)bVector *2;
107
108 pusStack[0] = pTrapFrame->Ctx.rflags.u16;
109 pusStack[1] = pTrapFrame->Ctx.cs;
110 pusStack[2] = pTrapFrame->Ctx.rip.u16 + (uint16_t)(pbCode - pbCodeStart);
111
112 pTrapFrame->Ctx.rip.u16 = pusIvte[0];
113 pTrapFrame->Ctx.cs = pusIvte[1];
114 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF; /** @todo this isn't all, but it'll do for now, I hope. */
115 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0/*fFlags*/); /* does not return. */
116 }
117 }
118 /* PUSHF: Real mode behaviour. */
119 else if (bOpCode == 0x9c)
120 {
121 if (cBitsOpcode == 32)
122 *pusStack++ = pTrapFrame->Ctx.rflags.au16[1] & ~(X86_EFL_VM | X86_EFL_RF);
123 *pusStack++ = pTrapFrame->Ctx.rflags.u16;
124 pTrapFrame->Ctx.rsp.u16 += cBitsOpcode / 8;
125 }
126 /* POPF: Real mode behaviour. */
127 else if (bOpCode == 0x9d)
128 {
129 if (cBitsOpcode == 32)
130 {
131 pTrapFrame->Ctx.rflags.u32 &= ~X86_EFL_POPF_BITS;
132 pTrapFrame->Ctx.rflags.u32 |= X86_EFL_POPF_BITS & *(uint32_t const *)pusStack;
133 }
134 else
135 {
136 pTrapFrame->Ctx.rflags.u32 &= ~(X86_EFL_POPF_BITS | UINT32_C(0xffff0000)) & ~X86_EFL_RF;
137 pTrapFrame->Ctx.rflags.u16 |= (uint16_t)X86_EFL_POPF_BITS & *pusStack;
138 }
139 pTrapFrame->Ctx.rsp.u16 -= cBitsOpcode / 8;
140 }
141 /* CLI: Real mode behaviour. */
142 else if (bOpCode == 0xfa)
143 pTrapFrame->Ctx.rflags.u16 &= ~X86_EFL_IF;
144 /* STI: Real mode behaviour. */
145 else if (bOpCode == 0xfb)
146 pTrapFrame->Ctx.rflags.u16 |= X86_EFL_IF;
147 /* Unexpected. */
148 else
149 fHandled = false;
150 }
151 /*
152 * Deal with lock prefixed int xxh syscall in v8086 mode.
153 */
154 else if ( pTrapFrame->bXcpt == X86_XCPT_UD
155 && pbCode[0] == 0xf0
156 && pbCode[1] == 0xcd
157 && pbCode[2] == BS3_TRAP_SYSCALL
158 && pTrapFrame->Ctx.cs == BS3_SEL_TEXT16)
159 {
160 pbCode += 3;
161 bs3TrapDefaultHandlerV8086Syscall(pTrapFrame);
162 }
163 else
164 fHandled = false;
165 if (fHandled)
166 {
167 pTrapFrame->Ctx.rip.u16 += (uint16_t)(pbCode - pbCodeStart);
168# if 0
169 Bs3Printf("Calling Bs3RegCtxRestore\n");
170 Bs3RegCtxPrint(&pTrapFrame->Ctx);
171# endif
172 Bs3RegCtxRestore(&pTrapFrame->Ctx, 0 /*fFlags*/); /* does not return. */
173 return;
174 }
175 }
176#endif
177
178 /*
179 * Any pending setjmp?
180 */
181 if (g_pBs3TrapSetJmpFrame != 0)
182 {
183 PBS3TRAPFRAME pSetJmpFrame = (PBS3TRAPFRAME)Bs3XptrFlatToCurrent(g_pBs3TrapSetJmpFrame);
184 //Bs3Printf("Calling longjmp: pSetJmpFrame=%p (%#lx)\n", pSetJmpFrame, g_pBs3TrapSetJmpFrame);
185 g_pBs3TrapSetJmpFrame = 0;
186 Bs3MemCpy(pSetJmpFrame, pTrapFrame, sizeof(*pSetJmpFrame));
187 //Bs3RegCtxPrint(&g_Bs3TrapSetJmpCtx);
188 Bs3RegCtxRestore(&g_Bs3TrapSetJmpCtx, 0 /*fFlags*/);
189 }
190
191 /*
192 * Fatal.
193 */
194 Bs3TrapPrintFrame(pTrapFrame);
195 Bs3Panic();
196}
197
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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