VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-x0.c@ 77807

Last change on this file since 77807 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.0 KB
Line 
1/* $Id: bs3-cpu-weird-1-x0.c 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * BS3Kit - bs3-cpu-weird-2, C test driver code (16-bit).
4 */
5
6/*
7 * Copyright (C) 2007-2019 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#define BS3_USE_X0_TEXT_SEG
32#include <bs3kit.h>
33#include <iprt/asm.h>
34#include <iprt/asm-amd64-x86.h>
35
36
37/*********************************************************************************************************************************
38* Defined Constants And Macros *
39*********************************************************************************************************************************/
40#undef CHECK_MEMBER
41#define CHECK_MEMBER(a_szName, a_szFmt, a_Actual, a_Expected) \
42 do \
43 { \
44 if ((a_Actual) == (a_Expected)) { /* likely */ } \
45 else bs3CpuWeird1_FailedF(a_szName "=" a_szFmt " expected " a_szFmt, (a_Actual), (a_Expected)); \
46 } while (0)
47
48
49/*********************************************************************************************************************************
50* External Symbols *
51*********************************************************************************************************************************/
52extern FNBS3FAR bs3CpuWeird1_InhibitedInt80_c16;
53extern FNBS3FAR bs3CpuWeird1_InhibitedInt80_c32;
54extern FNBS3FAR bs3CpuWeird1_InhibitedInt80_c64;
55extern FNBS3FAR bs3CpuWeird1_InhibitedInt80_int80_c16;
56extern FNBS3FAR bs3CpuWeird1_InhibitedInt80_int80_c32;
57extern FNBS3FAR bs3CpuWeird1_InhibitedInt80_int80_c64;
58
59extern FNBS3FAR bs3CpuWeird1_InhibitedInt3_c16;
60extern FNBS3FAR bs3CpuWeird1_InhibitedInt3_c32;
61extern FNBS3FAR bs3CpuWeird1_InhibitedInt3_c64;
62extern FNBS3FAR bs3CpuWeird1_InhibitedInt3_int3_c16;
63extern FNBS3FAR bs3CpuWeird1_InhibitedInt3_int3_c32;
64extern FNBS3FAR bs3CpuWeird1_InhibitedInt3_int3_c64;
65
66extern FNBS3FAR bs3CpuWeird1_InhibitedBp_c16;
67extern FNBS3FAR bs3CpuWeird1_InhibitedBp_c32;
68extern FNBS3FAR bs3CpuWeird1_InhibitedBp_c64;
69extern FNBS3FAR bs3CpuWeird1_InhibitedBp_int3_c16;
70extern FNBS3FAR bs3CpuWeird1_InhibitedBp_int3_c32;
71extern FNBS3FAR bs3CpuWeird1_InhibitedBp_int3_c64;
72
73
74/*********************************************************************************************************************************
75* Global Variables *
76*********************************************************************************************************************************/
77static const char BS3_FAR *g_pszTestMode = (const char *)1;
78static BS3CPUVENDOR g_enmCpuVendor = BS3CPUVENDOR_INTEL;
79static bool g_fVME = false;
80//static uint8_t g_bTestMode = 1;
81//static bool g_f16BitSys = 1;
82
83
84
85/**
86 * Sets globals according to the mode.
87 *
88 * @param bTestMode The test mode.
89 */
90static void bs3CpuWeird1_SetGlobals(uint8_t bTestMode)
91{
92// g_bTestMode = bTestMode;
93 g_pszTestMode = Bs3GetModeName(bTestMode);
94// g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bTestMode);
95 g_usBs3TestStep = 0;
96 g_enmCpuVendor = Bs3GetCpuVendor();
97 g_fVME = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486
98 && (Bs3RegGetCr4() & X86_CR4_VME);
99}
100
101
102/**
103 * Wrapper around Bs3TestFailedF that prefixes the error with g_usBs3TestStep
104 * and g_pszTestMode.
105 */
106static void bs3CpuWeird1_FailedF(const char *pszFormat, ...)
107{
108 va_list va;
109
110 char szTmp[168];
111 va_start(va, pszFormat);
112 Bs3StrPrintfV(szTmp, sizeof(szTmp), pszFormat, va);
113 va_end(va);
114
115 Bs3TestFailedF("%u - %s: %s", g_usBs3TestStep, g_pszTestMode, szTmp);
116}
117
118
119/**
120 * Compares interrupt stuff.
121 */
122static void bs3CpuWeird1_CompareDbgInhibitRingXfer(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint8_t bXcpt,
123 int8_t cbPcAdjust, int8_t cbSpAdjust, uint32_t uDr6Expected,
124 uint8_t cbIretFrame, uint64_t uHandlerRsp)
125{
126 uint32_t uDr6 = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386 ? Bs3RegGetDr6() : X86_DR6_INIT_VAL;
127 uint16_t const cErrorsBefore = Bs3TestSubErrorCount();
128 CHECK_MEMBER("bXcpt", "%#04x", pTrapCtx->bXcpt, bXcpt);
129 CHECK_MEMBER("bErrCd", "%#06RX64", pTrapCtx->uErrCd, 0);
130 CHECK_MEMBER("cbIretFrame", "%#04x", pTrapCtx->cbIretFrame, cbIretFrame);
131 CHECK_MEMBER("uHandlerRsp", "%#06RX64", pTrapCtx->uHandlerRsp, uHandlerRsp);
132 if (uDr6 != uDr6Expected)
133 bs3CpuWeird1_FailedF("dr6=%#010RX32 expected %#010RX32", uDr6, uDr6Expected);
134 Bs3TestCheckRegCtxEx(&pTrapCtx->Ctx, pStartCtx, cbPcAdjust, cbSpAdjust, 0 /*fExtraEfl*/, g_pszTestMode, g_usBs3TestStep);
135 if (Bs3TestSubErrorCount() != cErrorsBefore)
136 {
137 Bs3TrapPrintFrame(pTrapCtx);
138 Bs3TestPrintf("DR6=%#RX32; Handler: CS=%04RX16 SS:ESP=%04RX16:%08RX64 EFL=%RX64 cbIret=%#x\n",
139 uDr6, pTrapCtx->uHandlerCs, pTrapCtx->uHandlerSs, pTrapCtx->uHandlerRsp,
140 pTrapCtx->fHandlerRfl, pTrapCtx->cbIretFrame);
141#if 0
142 Bs3TestPrintf("Halting in CompareIntCtx: bXcpt=%#x\n", bXcpt);
143 ASMHalt();
144#endif
145 }
146}
147
148static uint64_t bs3CpuWeird1_GetTrapHandlerEIP(uint8_t bXcpt, uint8_t bMode, bool fV86)
149{
150 if ( BS3_MODE_IS_RM_SYS(bMode)
151 || (fV86 && BS3_MODE_IS_V86(bMode)))
152 {
153 PRTFAR16 paIvt = (PRTFAR16)Bs3XptrFlatToCurrent(0);
154 return paIvt[bXcpt].off;
155 }
156 if (BS3_MODE_IS_16BIT_SYS(bMode))
157 return Bs3Idt16[bXcpt].Gate.u16OffsetLow;
158 if (BS3_MODE_IS_32BIT_SYS(bMode))
159 return RT_MAKE_U32(Bs3Idt32[bXcpt].Gate.u16OffsetLow, Bs3Idt32[bXcpt].Gate.u16OffsetHigh);
160 return RT_MAKE_U64(RT_MAKE_U32(Bs3Idt64[bXcpt].Gate.u16OffsetLow, Bs3Idt32[bXcpt].Gate.u16OffsetHigh),
161 Bs3Idt64[bXcpt].Gate.u32OffsetTop);
162}
163
164
165static int bs3CpuWeird1_DbgInhibitRingXfer_Worker(uint8_t bTestMode, uint8_t bIntGate, uint8_t cbRingInstr, int8_t cbSpAdjust,
166 FPFNBS3FAR pfnTestCode, FPFNBS3FAR pfnTestLabel)
167{
168 BS3TRAPFRAME TrapCtx;
169 BS3TRAPFRAME TrapExpect;
170 BS3REGCTX Ctx;
171 uint8_t bSavedDpl;
172 uint8_t const offTestLabel = BS3_FP_OFF(pfnTestLabel) - BS3_FP_OFF(pfnTestCode);
173 //uint8_t const cbIretFrameSame = BS3_MODE_IS_RM_SYS(bTestMode) ? 6
174 // : BS3_MODE_IS_16BIT_SYS(bTestMode) ? 12
175 // : BS3_MODE_IS_64BIT_SYS(bTestMode) ? 40 : 12;
176 uint8_t cbIretFrameInt;
177 uint8_t cbIretFrameIntDb;
178 uint8_t const cbIretFrameSame = BS3_MODE_IS_16BIT_SYS(bTestMode) ? 6
179 : BS3_MODE_IS_32BIT_SYS(bTestMode) ? 12 : 40;
180 uint8_t const cbSpAdjSame = BS3_MODE_IS_64BIT_SYS(bTestMode) ? 48 : cbIretFrameSame;
181 uint8_t bVmeMethod = 0;
182 uint64_t uHandlerRspInt;
183 uint64_t uHandlerRspIntDb;
184 BS3_XPTR_AUTO(uint32_t, StackXptr);
185
186 /* make sure they're allocated */
187 Bs3MemZero(&Ctx, sizeof(Ctx));
188 Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
189 Bs3MemZero(&TrapExpect, sizeof(TrapExpect));
190
191 /*
192 * Make INT xx accessible from DPL 3 and create a ring-3 context that we can work with.
193 */
194 bSavedDpl = Bs3TrapSetDpl(bIntGate, 3);
195
196 Bs3RegCtxSaveEx(&Ctx, bTestMode, 1024);
197 Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, pfnTestCode);
198 if (BS3_MODE_IS_16BIT_SYS(bTestMode))
199 g_uBs3TrapEipHint = Ctx.rip.u32;
200 Ctx.rflags.u32 &= ~X86_EFL_RF;
201
202 /* Raw-mode enablers. */
203 Ctx.rflags.u32 |= X86_EFL_IF;
204 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486)
205 Ctx.cr0.u32 |= X86_CR0_WP;
206
207 /* We put the SS value on the stack so we can easily set breakpoints there. */
208 Ctx.rsp.u32 -= 8;
209 BS3_XPTR_SET_FLAT(uint32_t, StackXptr, Ctx.rsp.u32); /* ASSUMES SS.BASE == 0!! */
210
211 /* ring-3 */
212 if (!BS3_MODE_IS_RM_OR_V86(bTestMode))
213 Bs3RegCtxConvertToRingX(&Ctx, 3);
214
215 /* V8086: Set IOPL to 3. */
216 if (BS3_MODE_IS_V86(bTestMode))
217 {
218 Ctx.rflags.u32 |= X86_EFL_IOPL;
219 if (g_fVME)
220 {
221 Bs3RegSetTr(BS3_SEL_TSS32_IRB);
222#if 0
223 /* SDMv3b, 20.3.3 method 5: */
224 ASMBitClear(&Bs3SharedIntRedirBm, bIntGate);
225 bVmeMethod = 5;
226#else
227 /* SDMv3b, 20.3.3 method 4 (similar to non-VME): */
228 ASMBitSet(&Bs3SharedIntRedirBm, bIntGate);
229 bVmeMethod = 4;
230 }
231#endif
232 }
233
234 /*
235 * Test #0: Test run. Calc expected delayed #DB from it.
236 */
237 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
238 {
239 Bs3RegSetDr7(0);
240 Bs3RegSetDr6(X86_DR6_INIT_VAL);
241 }
242 *BS3_XPTR_GET(uint32_t, StackXptr) = Ctx.ss;
243 Bs3TrapSetJmpAndRestore(&Ctx, &TrapExpect);
244 if (TrapExpect.bXcpt != bIntGate)
245 {
246
247 Bs3TestFailedF("%u: bXcpt is %#x, expected %#x!\n", g_usBs3TestStep, TrapExpect.bXcpt, bIntGate);
248 Bs3TrapPrintFrame(&TrapExpect);
249 return 1;
250 }
251
252 cbIretFrameInt = TrapExpect.cbIretFrame;
253 cbIretFrameIntDb = cbIretFrameInt + cbIretFrameSame;
254 uHandlerRspInt = TrapExpect.uHandlerRsp;
255 uHandlerRspIntDb = uHandlerRspInt - cbSpAdjSame;
256
257 TrapExpect.Ctx.bCpl = 0;
258 TrapExpect.Ctx.cs = TrapExpect.uHandlerCs;
259 TrapExpect.Ctx.ss = TrapExpect.uHandlerSs;
260 TrapExpect.Ctx.rsp.u64 = TrapExpect.uHandlerRsp;
261 TrapExpect.Ctx.rflags.u64 = TrapExpect.fHandlerRfl;
262 if (BS3_MODE_IS_V86(bTestMode))
263 {
264 if (bVmeMethod >= 5)
265 {
266 TrapExpect.Ctx.rflags.u32 |= X86_EFL_VM;
267 TrapExpect.Ctx.bCpl = 3;
268 TrapExpect.Ctx.rip.u64 = bs3CpuWeird1_GetTrapHandlerEIP(bIntGate, bTestMode, true);
269 cbIretFrameIntDb = 36;
270 if (BS3_MODE_IS_16BIT_SYS(bTestMode))
271 uHandlerRspIntDb = Bs3Tss16.sp0 - cbIretFrameIntDb;
272 else
273 uHandlerRspIntDb = Bs3Tss32.esp0 - cbIretFrameIntDb;
274 }
275 else
276 {
277 TrapExpect.Ctx.ds = 0;
278 TrapExpect.Ctx.es = 0;
279 TrapExpect.Ctx.fs = 0;
280 TrapExpect.Ctx.gs = 0;
281 }
282 }
283
284 /*
285 * Test #1: Single stepping ring-3. Ignored except for V8086 w/ VME.
286 */
287 g_usBs3TestStep++;
288 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
289 {
290 Bs3RegSetDr7(0);
291 Bs3RegSetDr6(X86_DR6_INIT_VAL);
292 }
293 *BS3_XPTR_GET(uint32_t, StackXptr) = Ctx.ss;
294 Ctx.rflags.u32 |= X86_EFL_TF;
295
296 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
297 if ( !BS3_MODE_IS_V86(bTestMode)
298 || bVmeMethod < 5)
299 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &Ctx, bIntGate, offTestLabel + cbRingInstr, cbSpAdjust,
300 X86_DR6_INIT_VAL, cbIretFrameInt, uHandlerRspInt);
301 else
302 {
303 TrapExpect.Ctx.rflags.u32 |= X86_EFL_TF;
304 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &TrapExpect.Ctx, X86_XCPT_DB, offTestLabel, -2,
305 X86_DR6_INIT_VAL | X86_DR6_BS, cbIretFrameIntDb, uHandlerRspIntDb);
306 TrapExpect.Ctx.rflags.u32 &= ~X86_EFL_TF;
307 }
308
309 Ctx.rflags.u32 &= ~X86_EFL_TF;
310 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
311 {
312 uint32_t uDr6Expect;
313
314 /*
315 * Test #2: Execution breakpoint on ring transition instruction.
316 * This hits on AMD-V (threadripper) but not on VT-x (skylake).
317 */
318 g_usBs3TestStep++;
319 Bs3RegSetDr0(Bs3SelRealModeCodeToFlat(pfnTestLabel));
320 Bs3RegSetDr7(X86_DR7_L0 | X86_DR7_G0 | X86_DR7_RW(0, X86_DR7_RW_EO) | X86_DR7_LEN(0, X86_DR7_LEN_BYTE));
321 Bs3RegSetDr6(X86_DR6_INIT_VAL);
322 *BS3_XPTR_GET(uint32_t, StackXptr) = Ctx.ss;
323
324 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
325 Bs3RegSetDr7(0);
326 if (g_enmCpuVendor == BS3CPUVENDOR_AMD)
327 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &Ctx, X86_XCPT_DB, offTestLabel, cbSpAdjust,
328 X86_DR6_INIT_VAL | X86_DR6_B0, cbIretFrameInt, uHandlerRspInt);
329 else
330 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &Ctx, bIntGate, offTestLabel + cbRingInstr, cbSpAdjust,
331 X86_DR6_INIT_VAL, cbIretFrameInt, uHandlerRspInt);
332
333 /*
334 * Test #3: Same as above, but with the LE and GE flags set.
335 */
336 g_usBs3TestStep++;
337 Bs3RegSetDr0(Bs3SelRealModeCodeToFlat(pfnTestLabel));
338 Bs3RegSetDr7(X86_DR7_L0 | X86_DR7_G0 | X86_DR7_RW(0, X86_DR7_RW_EO) | X86_DR7_LEN(0, X86_DR7_LEN_BYTE) | X86_DR7_LE | X86_DR7_GE);
339 Bs3RegSetDr6(X86_DR6_INIT_VAL);
340 *BS3_XPTR_GET(uint32_t, StackXptr) = Ctx.ss;
341
342 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
343 if (g_enmCpuVendor == BS3CPUVENDOR_AMD)
344 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &Ctx, X86_XCPT_DB, offTestLabel, cbSpAdjust,
345 X86_DR6_INIT_VAL | X86_DR6_B0, cbIretFrameInt, uHandlerRspInt);
346 else
347 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &Ctx, bIntGate, offTestLabel + cbRingInstr, cbSpAdjust,
348 X86_DR6_INIT_VAL, cbIretFrameInt, uHandlerRspInt);
349
350 /*
351 * Test #4: Execution breakpoint on pop ss / mov ss. Hits.
352 * Note! In real mode AMD-V updates the stack pointer, or something else is busted. Totally weird!
353 */
354 g_usBs3TestStep++;
355 Bs3RegSetDr0(Bs3SelRealModeCodeToFlat(pfnTestCode));
356 Bs3RegSetDr7(X86_DR7_L0 | X86_DR7_G0 | X86_DR7_RW(0, X86_DR7_RW_EO) | X86_DR7_LEN(0, X86_DR7_LEN_BYTE));
357 Bs3RegSetDr6(X86_DR6_INIT_VAL);
358 *BS3_XPTR_GET(uint32_t, StackXptr) = Ctx.ss;
359
360 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
361 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &Ctx, X86_XCPT_DB, 0, 0, X86_DR6_INIT_VAL | X86_DR6_B0,
362 cbIretFrameInt,
363 uHandlerRspInt - (BS3_MODE_IS_RM_SYS(bTestMode) ? 2 : 0) );
364
365 /*
366 * Test #5: Same as above, but with the LE and GE flags set.
367 */
368 g_usBs3TestStep++;
369 Bs3RegSetDr0(Bs3SelRealModeCodeToFlat(pfnTestCode));
370 Bs3RegSetDr7(X86_DR7_L0 | X86_DR7_G0 | X86_DR7_RW(0, X86_DR7_RW_EO) | X86_DR7_LEN(0, X86_DR7_LEN_BYTE) | X86_DR7_LE | X86_DR7_GE);
371 Bs3RegSetDr6(X86_DR6_INIT_VAL);
372 *BS3_XPTR_GET(uint32_t, StackXptr) = Ctx.ss;
373
374 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
375 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &Ctx, X86_XCPT_DB, 0, 0, X86_DR6_INIT_VAL | X86_DR6_B0,
376 cbIretFrameInt,
377 uHandlerRspInt - (BS3_MODE_IS_RM_SYS(bTestMode) ? 2 : 0) );
378
379 /*
380 * Test #6: Data breakpoint on SS load. The #DB is delivered after ring transition. Weird!
381 *
382 * Note! Intel loses the B0 status, probably for reasons similar to Pentium Pro errata 3. Similar
383 * erratum is seen with virtually every march since, e.g. skylake SKL009 & SKL111.
384 * Weirdly enougth, they seem to get this right in real mode. Go figure.
385 */
386 g_usBs3TestStep++;
387 *BS3_XPTR_GET(uint32_t, StackXptr) = Ctx.ss;
388 Bs3RegSetDr0(BS3_XPTR_GET_FLAT(uint32_t, StackXptr));
389 Bs3RegSetDr7(X86_DR7_L0 | X86_DR7_G0 | X86_DR7_RW(0, X86_DR7_RW_RW) | X86_DR7_LEN(0, X86_DR7_LEN_WORD));
390 Bs3RegSetDr6(X86_DR6_INIT_VAL);
391
392 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
393 TrapExpect.Ctx.rip = TrapCtx.Ctx.rip; /// @todo fixme
394 Bs3RegSetDr7(0);
395 uDr6Expect = X86_DR6_INIT_VAL | X86_DR6_B0;
396 if (g_enmCpuVendor == BS3CPUVENDOR_INTEL && bTestMode != BS3_MODE_RM)
397 uDr6Expect = X86_DR6_INIT_VAL;
398 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &TrapExpect.Ctx, X86_XCPT_DB, 0, 0, uDr6Expect,
399 cbIretFrameSame, uHandlerRspIntDb);
400
401 /*
402 * Test #7: Same as above, but with the LE and GE flags set.
403 */
404 g_usBs3TestStep++;
405 *BS3_XPTR_GET(uint32_t, StackXptr) = Ctx.ss;
406 Bs3RegSetDr0(BS3_XPTR_GET_FLAT(uint32_t, StackXptr));
407 Bs3RegSetDr7(X86_DR7_L0 | X86_DR7_G0 | X86_DR7_RW(0, X86_DR7_RW_RW) | X86_DR7_LEN(0, X86_DR7_LEN_WORD) | X86_DR7_LE | X86_DR7_GE);
408 Bs3RegSetDr6(X86_DR6_INIT_VAL);
409
410 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
411 TrapExpect.Ctx.rip = TrapCtx.Ctx.rip; /// @todo fixme
412 Bs3RegSetDr7(0);
413 uDr6Expect = X86_DR6_INIT_VAL | X86_DR6_B0;
414 if (g_enmCpuVendor == BS3CPUVENDOR_INTEL && bTestMode != BS3_MODE_RM)
415 uDr6Expect = X86_DR6_INIT_VAL;
416 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &TrapExpect.Ctx, X86_XCPT_DB, 0, 0, uDr6Expect,
417 cbIretFrameSame, uHandlerRspIntDb);
418
419 if (!BS3_MODE_IS_RM_OR_V86(bTestMode))
420 {
421 /*
422 * Test #8: Data breakpoint on SS GDT entry. Half weird!
423 * Note! Intel loses the B1 status, see test #6.
424 */
425 g_usBs3TestStep++;
426 *BS3_XPTR_GET(uint32_t, StackXptr) = (Ctx.ss & X86_SEL_RPL) | BS3_SEL_SPARE_00;
427 Bs3GdteSpare00 = Bs3Gdt[Ctx.ss / sizeof(Bs3Gdt[0])];
428
429 Bs3RegSetDr1(Bs3SelPtrToFlat(&Bs3GdteSpare00));
430 Bs3RegSetDr7(X86_DR7_L1 | X86_DR7_G1 | X86_DR7_RW(1, X86_DR7_RW_RW) | X86_DR7_LEN(1, X86_DR7_LEN_DWORD));
431 Bs3RegSetDr6(X86_DR6_INIT_VAL);
432
433 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
434 TrapExpect.Ctx.rip = TrapCtx.Ctx.rip; /// @todo fixme
435 Bs3RegSetDr7(0);
436 uDr6Expect = g_enmCpuVendor == BS3CPUVENDOR_INTEL ? X86_DR6_INIT_VAL : X86_DR6_INIT_VAL | X86_DR6_B1;
437 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &TrapExpect.Ctx, X86_XCPT_DB, 0, 0, uDr6Expect,
438 cbIretFrameSame, uHandlerRspIntDb);
439
440 /*
441 * Test #9: Same as above, but with the LE and GE flags set.
442 */
443 g_usBs3TestStep++;
444 *BS3_XPTR_GET(uint32_t, StackXptr) = (Ctx.ss & X86_SEL_RPL) | BS3_SEL_SPARE_00;
445 Bs3GdteSpare00 = Bs3Gdt[Ctx.ss / sizeof(Bs3Gdt[0])];
446
447 Bs3RegSetDr1(Bs3SelPtrToFlat(&Bs3GdteSpare00));
448 Bs3RegSetDr7(X86_DR7_L1 | X86_DR7_G1 | X86_DR7_RW(1, X86_DR7_RW_RW) | X86_DR7_LEN(1, X86_DR7_LEN_DWORD) | X86_DR7_LE | X86_DR7_GE);
449 Bs3RegSetDr6(X86_DR6_INIT_VAL);
450
451 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
452 TrapExpect.Ctx.rip = TrapCtx.Ctx.rip; /// @todo fixme
453 Bs3RegSetDr7(0);
454 uDr6Expect = g_enmCpuVendor == BS3CPUVENDOR_INTEL ? X86_DR6_INIT_VAL : X86_DR6_INIT_VAL | X86_DR6_B1;
455 bs3CpuWeird1_CompareDbgInhibitRingXfer(&TrapCtx, &TrapExpect.Ctx, X86_XCPT_DB, 0, 0, uDr6Expect,
456 cbIretFrameSame, uHandlerRspIntDb);
457 }
458
459 /*
460 * Cleanup.
461 */
462 Bs3RegSetDr0(0);
463 Bs3RegSetDr1(0);
464 Bs3RegSetDr2(0);
465 Bs3RegSetDr3(0);
466 Bs3RegSetDr6(X86_DR6_INIT_VAL);
467 Bs3RegSetDr7(0);
468 }
469 Bs3TrapSetDpl(bIntGate, bSavedDpl);
470 return 0;
471}
472
473
474BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuWeird1_DbgInhibitRingXfer)(uint8_t bMode)
475{
476 if (BS3_MODE_IS_V86(bMode))
477 switch (bMode)
478 {
479 /** @todo some busted stack stuff with the 16-bit guys. Also, if VME is
480 * enabled, we're probably not able to do any sensible testing. */
481 case BS3_MODE_PP16_V86:
482 case BS3_MODE_PE16_V86:
483 case BS3_MODE_PAE16_V86:
484 return BS3TESTDOMODE_SKIPPED;
485 }
486 //if (bMode != BS3_MODE_PE16_V86) return BS3TESTDOMODE_SKIPPED;
487 //if (bMode != BS3_MODE_PAEV86) return BS3TESTDOMODE_SKIPPED;
488
489 bs3CpuWeird1_SetGlobals(bMode);
490
491 /** @todo test sysenter and syscall too. */
492 /** @todo test INTO. */
493 /** @todo test all V8086 software INT delivery modes (currently only 4 and 1). */
494
495 /* Note! Both ICEBP and BOUND has be checked cursorily and found not to be affected. */
496 if (BS3_MODE_IS_16BIT_CODE(bMode))
497 {
498 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x80, 2, 2, bs3CpuWeird1_InhibitedInt80_c16, bs3CpuWeird1_InhibitedInt80_int80_c16);
499 if (!BS3_MODE_IS_V86(bMode) || !g_fVME)
500 {
501 /** @todo explain why these GURU */
502 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x03, 2, 2, bs3CpuWeird1_InhibitedInt3_c16, bs3CpuWeird1_InhibitedInt3_int3_c16);
503 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x03, 1, 2, bs3CpuWeird1_InhibitedBp_c16, bs3CpuWeird1_InhibitedBp_int3_c16);
504 }
505 }
506 else if (BS3_MODE_IS_32BIT_CODE(bMode))
507 {
508 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x80, 2, 4, bs3CpuWeird1_InhibitedInt80_c32, bs3CpuWeird1_InhibitedInt80_int80_c32);
509 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x03, 2, 4, bs3CpuWeird1_InhibitedInt3_c32, bs3CpuWeird1_InhibitedInt3_int3_c32);
510 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x03, 1, 4, bs3CpuWeird1_InhibitedBp_c32, bs3CpuWeird1_InhibitedBp_int3_c32);
511 }
512 else
513 {
514 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x80, 2, 0, bs3CpuWeird1_InhibitedInt80_c64, bs3CpuWeird1_InhibitedInt80_int80_c64);
515 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x03, 2, 0, bs3CpuWeird1_InhibitedInt3_c64, bs3CpuWeird1_InhibitedInt3_int3_c64);
516 bs3CpuWeird1_DbgInhibitRingXfer_Worker(bMode, 0x03, 1, 0, bs3CpuWeird1_InhibitedBp_c64, bs3CpuWeird1_InhibitedBp_int3_c64);
517 }
518
519 return 0;
520}
521
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