Changeset 60750 in vbox
- Timestamp:
- Apr 28, 2016 8:11:10 PM (9 years ago)
- Location:
- trunk/src/VBox/ValidationKit/bootsectors
- Files:
-
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/Makefile.kmk
r60657 r60750 240 240 bs3kit/bs3-first-rm.asm \ 241 241 bs3-cpu-basic-2.c \ 242 bs3-cpu-basic-2-x0.c \ 242 243 bs3-cpu-basic-2-asm.asm \ 243 244 bs3kit/bs3-cmn-instantiate-x0.c16 \ -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c
r60749 r60750 44 44 } while (0) 45 45 46 47 #ifdef BS3_INSTANTIATING_CMN48 /** Indicating that we've got operand size prefix and that it matters. */49 # define BS3CB2SIDTSGDT_F_OPSIZE UINT8_C(0x01)50 /** Worker requires 386 or later. */51 # define BS3CB2SIDTSGDT_F_386PLUS UINT8_C(0x02)52 #endif53 46 54 47 #ifdef BS3_INSTANTIATING_MODE … … 91 84 uint8_t u1DescType; 92 85 } BS3CB2INVLDESCTYPE; 93 94 typedef struct BS3CB2SIDTSGDT95 {96 const char *pszDesc;97 FPFNBS3FAR fpfnWorker;98 uint8_t cbInstr;99 bool fSs;100 uint8_t bMode;101 uint8_t fFlags;102 } BS3CB2SIDTSGDT;103 86 #endif 104 87 … … 115 98 # define g_bs3CpuBasic2_ud2_FlatAddr BS3_DATA_NM(g_bs3CpuBasic2_ud2_FlatAddr) 116 99 extern uint32_t g_bs3CpuBasic2_ud2_FlatAddr; 117 118 extern FNBS3FAR bs3CpuBasic2_sidt_bx_ud2_c16;119 extern FNBS3FAR bs3CpuBasic2_sidt_bx_ud2_c32;120 extern FNBS3FAR bs3CpuBasic2_sidt_bx_ud2_c64;121 extern FNBS3FAR bs3CpuBasic2_sidt_ss_bx_ud2_c16;122 extern FNBS3FAR bs3CpuBasic2_sidt_ss_bx_ud2_c32;123 extern FNBS3FAR bs3CpuBasic2_sidt_rexw_bx_ud2_c64;124 extern FNBS3FAR bs3CpuBasic2_sidt_opsize_bx_ud2_c16;125 extern FNBS3FAR bs3CpuBasic2_sidt_opsize_bx_ud2_c32;126 extern FNBS3FAR bs3CpuBasic2_sidt_opsize_bx_ud2_c64;127 extern FNBS3FAR bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c16;128 extern FNBS3FAR bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c32;129 extern FNBS3FAR bs3CpuBasic2_sidt_opsize_rexw_bx_ud2_c64;130 131 extern FNBS3FAR bs3CpuBasic2_sgdt_bx_ud2_c16;132 extern FNBS3FAR bs3CpuBasic2_sgdt_bx_ud2_c32;133 extern FNBS3FAR bs3CpuBasic2_sgdt_bx_ud2_c64;134 extern FNBS3FAR bs3CpuBasic2_sgdt_ss_bx_ud2_c16;135 extern FNBS3FAR bs3CpuBasic2_sgdt_ss_bx_ud2_c32;136 extern FNBS3FAR bs3CpuBasic2_sgdt_rexw_bx_ud2_c64;137 extern FNBS3FAR bs3CpuBasic2_sgdt_opsize_bx_ud2_c16;138 extern FNBS3FAR bs3CpuBasic2_sgdt_opsize_bx_ud2_c32;139 extern FNBS3FAR bs3CpuBasic2_sgdt_opsize_bx_ud2_c64;140 extern FNBS3FAR bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c16;141 extern FNBS3FAR bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32;142 extern FNBS3FAR bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64;143 144 extern FNBS3FAR bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c16;145 extern FNBS3FAR bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c32;146 extern FNBS3FAR bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c64;147 extern FNBS3FAR bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c16;148 extern FNBS3FAR bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c32;149 extern FNBS3FAR bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64;150 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c16;151 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_bx__sidt32_es_di__lidt_es_si__ud2_c16;152 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c32;153 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c64;154 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c16;155 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c32;156 extern FNBS3FAR bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64;157 158 extern FNBS3FAR bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c16;159 extern FNBS3FAR bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c32;160 extern FNBS3FAR bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c64;161 extern FNBS3FAR bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c16;162 extern FNBS3FAR bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c32;163 extern FNBS3FAR bs3CpuBasic2_lgdt_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64;164 extern FNBS3FAR bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c16;165 extern FNBS3FAR bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c32;166 extern FNBS3FAR bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c64;167 extern FNBS3FAR bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c16;168 extern FNBS3FAR bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c32;169 extern FNBS3FAR bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64;170 171 100 #endif 172 101 … … 182 111 # define g_f16BitSys BS3_CMN_NM(g_f16BitSys) 183 112 static bool g_f16BitSys = 1; 184 185 186 /** SIDT test workers. */187 static BS3CB2SIDTSGDT const g_aSidtWorkers[] =188 {189 { "", bs3CpuBasic2_sidt_bx_ud2_c16, 3, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },190 { "", bs3CpuBasic2_sidt_ss_bx_ud2_c16, 4, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },191 { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c16, 4, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },192 { "", bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c16, 5, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },193 { "", bs3CpuBasic2_sidt_bx_ud2_c32, 3, false, BS3_MODE_CODE_32, 0 },194 { "", bs3CpuBasic2_sidt_ss_bx_ud2_c32, 4, true, BS3_MODE_CODE_32, 0 },195 { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c32, 4, false, BS3_MODE_CODE_32, 0 },196 { "", bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c32, 5, true, BS3_MODE_CODE_32, 0 },197 { "", bs3CpuBasic2_sidt_bx_ud2_c64, 3, false, BS3_MODE_CODE_64, 0 },198 { "", bs3CpuBasic2_sidt_rexw_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 },199 { "", bs3CpuBasic2_sidt_opsize_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 },200 { "", bs3CpuBasic2_sidt_opsize_rexw_bx_ud2_c64, 5, false, BS3_MODE_CODE_64, 0 },201 };202 203 /** SGDT test workers. */204 static BS3CB2SIDTSGDT const g_aSgdtWorkers[] =205 {206 { "", bs3CpuBasic2_sgdt_bx_ud2_c16, 3, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },207 { "", bs3CpuBasic2_sgdt_ss_bx_ud2_c16, 4, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },208 { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c16, 4, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },209 { "", bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c16, 5, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },210 { "", bs3CpuBasic2_sgdt_bx_ud2_c32, 3, false, BS3_MODE_CODE_32, 0 },211 { "", bs3CpuBasic2_sgdt_ss_bx_ud2_c32, 4, true, BS3_MODE_CODE_32, 0 },212 { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c32, 4, false, BS3_MODE_CODE_32, 0 },213 { "", bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32, 5, true, BS3_MODE_CODE_32, 0 },214 { "", bs3CpuBasic2_sgdt_bx_ud2_c64, 3, false, BS3_MODE_CODE_64, 0 },215 { "", bs3CpuBasic2_sgdt_rexw_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 },216 { "", bs3CpuBasic2_sgdt_opsize_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 },217 { "", bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64, 5, false, BS3_MODE_CODE_64, 0 },218 };219 220 /** LIDT test workers. */221 static BS3CB2SIDTSGDT const g_aLidtWorkers[] =222 {223 { "lidt [bx]", bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c16, 11, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },224 { "lidt [ss:bx]", bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c16, 12, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },225 { "o32 lidt [bx]", bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c16, 12, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },226 { "o32 lidt [bx]; sidt32", bs3CpuBasic2_lidt_opsize_bx__sidt32_es_di__lidt_es_si__ud2_c16, 27, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },227 { "o32 lidt [ss:bx]", bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c16, 13, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },228 { "lidt [ebx]", bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c32, 11, false, BS3_MODE_CODE_32, 0 },229 { "lidt [ss:ebx]", bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2_c32, 12, true, BS3_MODE_CODE_32, 0 },230 { "o16 lidt [ebx]", bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c32, 12, false, BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },231 { "o16 lidt [ss:ebx]", bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2_c32, 13, true, BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },232 { "lidt [rbx]", bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2_c64, 9, false, BS3_MODE_CODE_64, 0 },233 { "o64 lidt [rbx]", bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64, 10, false, BS3_MODE_CODE_64, 0 },234 { "o32 lidt [rbx]", bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2_c64, 10, false, BS3_MODE_CODE_64, 0 },235 { "o32 o64 lidt [rbx]", bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2_c64, 11, false, BS3_MODE_CODE_64, 0 },236 };237 238 /** LGDT test workers. */239 static BS3CB2SIDTSGDT const g_aLgdtWorkers[] =240 {241 { "lgdt [bx]", bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c16, 11, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },242 { "lgdt [ss:bx]", bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c16, 12, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },243 { "o32 lgdt [bx]", bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c16, 12, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },244 { "o32 lgdt [ss:bx]", bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c16, 13, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_OPSIZE | BS3CB2SIDTSGDT_F_386PLUS },245 { "lgdt [ebx]", bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c32, 11, false, BS3_MODE_CODE_32, 0 },246 { "lgdt [ss:ebx]", bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c32, 12, true, BS3_MODE_CODE_32, 0 },247 { "o16 lgdt [ebx]", bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c32, 12, false, BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },248 { "o16 lgdt [ss:ebx]", bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2_c32, 13, true, BS3_MODE_CODE_32, BS3CB2SIDTSGDT_F_OPSIZE },249 { "lgdt [rbx]", bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2_c64, 9, false, BS3_MODE_CODE_64, 0 },250 { "o64 lgdt [rbx]", bs3CpuBasic2_lgdt_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64, 10, false, BS3_MODE_CODE_64, 0 },251 { "o32 lgdt [rbx]", bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2_c64, 10, false, BS3_MODE_CODE_64, 0 },252 { "o32 o64 lgdt [rbx]", bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64, 11, false, BS3_MODE_CODE_64, 0 },253 };254 255 113 256 114 … … 1445 1303 } 1446 1304 1447 #if TMPL_BITS == 161448 1449 /**1450 * Executes one round of SIDT and SGDT tests using one assembly worker.1451 *1452 * This is written with driving everything from the 16-bit or 32-bit worker in1453 * mind, i.e. not assuming the test bitcount is the same as the current.1454 */1455 # define bs3CpuBasic2_sidt_sgdt_One BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_One)1456 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,1457 uint8_t const *pbExpected)1458 {1459 BS3TRAPFRAME TrapCtx;1460 BS3REGCTX Ctx;1461 BS3REGCTX CtxUdExpected;1462 BS3REGCTX TmpCtx;1463 uint8_t const cbBuf = 8*2; /* test buffer area */1464 uint8_t abBuf[8*2 + 8 + 8]; /* test buffer w/ misalignment test space and some extra guard. */1465 uint8_t BS3_FAR *pbBuf = abBuf;1466 uint8_t const cbIdtr = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 2+8 : 2+4;1467 bool const f286 = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80286;1468 uint8_t bFiller;1469 int off;1470 int off2;1471 unsigned cb;1472 uint8_t BS3_FAR *pbTest;1473 1474 /* make sure they're allocated */1475 Bs3MemZero(&Ctx, sizeof(Ctx));1476 Bs3MemZero(&CtxUdExpected, sizeof(CtxUdExpected));1477 Bs3MemZero(&TmpCtx, sizeof(TmpCtx));1478 Bs3MemZero(&TrapCtx, sizeof(TrapCtx));1479 Bs3MemZero(&abBuf, sizeof(abBuf));1480 1481 /* Create a context, give this routine some more stack space, point the context1482 at our SIDT [xBX] + UD2 combo, and point DS:xBX at abBuf. */1483 Bs3RegCtxSaveEx(&Ctx, bTestMode, 256 /*cbExtraStack*/);1484 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf);1485 Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, pWorker->fpfnWorker);1486 if (BS3_MODE_IS_16BIT_SYS(bTestMode))1487 g_uBs3TrapEipHint = Ctx.rip.u32;1488 if (!BS3_MODE_IS_RM_OR_V86(bTestMode))1489 Bs3RegCtxConvertToRingX(&Ctx, bRing);1490 1491 /* For successful SIDT attempts, we'll stop at the UD2. */1492 Bs3MemCpy(&CtxUdExpected, &Ctx, sizeof(Ctx));1493 CtxUdExpected.rip.u += pWorker->cbInstr;1494 1495 /*1496 * Check that it works at all and that only bytes we expect gets written to.1497 */1498 /* First with zero buffer. */1499 Bs3MemZero(abBuf, sizeof(abBuf));1500 if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), 0))1501 Bs3TestFailedF("ASMMemIsAllU8 or Bs3MemZero is busted: abBuf=%.*Rhxs\n", sizeof(abBuf), pbBuf);1502 if (!ASMMemIsZero(abBuf, sizeof(abBuf)))1503 Bs3TestFailedF("ASMMemIsZero or Bs3MemZero is busted: abBuf=%.*Rhxs\n", sizeof(abBuf), pbBuf);1504 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1505 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1506 if (f286 && abBuf[cbIdtr - 1] != 0xff)1507 Bs3TestFailedF("286: Top base byte isn't 0xff (#1): %#x\n", abBuf[cbIdtr - 1]);1508 if (!ASMMemIsZero(&abBuf[cbIdtr], cbBuf - cbIdtr))1509 Bs3TestFailedF("Unexpected buffer bytes set (#1): cbIdtr=%u abBuf=%.*Rhxs\n", cbIdtr, cbBuf, pbBuf);1510 if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0)1511 Bs3TestFailedF("Mismatch (#1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);1512 g_usBs3TestStep++;1513 1514 /* Again with a buffer filled with a byte not occuring in the previous result. */1515 bFiller = 0x55;1516 while (Bs3MemChr(abBuf, bFiller, cbBuf) != NULL)1517 bFiller++;1518 Bs3MemSet(abBuf, bFiller, sizeof(abBuf));1519 if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller))1520 Bs3TestFailedF("ASMMemIsAllU8 or Bs3MemSet is busted: bFiller=%#x abBuf=%.*Rhxs\n", bFiller, sizeof(abBuf), pbBuf);1521 1522 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1523 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1524 if (f286 && abBuf[cbIdtr - 1] != 0xff)1525 Bs3TestFailedF("286: Top base byte isn't 0xff (#2): %#x\n", abBuf[cbIdtr - 1]);1526 if (!ASMMemIsAllU8(&abBuf[cbIdtr], cbBuf - cbIdtr, bFiller))1527 Bs3TestFailedF("Unexpected buffer bytes set (#2): cbIdtr=%u bFiller=%#x abBuf=%.*Rhxs\n", cbIdtr, bFiller, cbBuf, pbBuf);1528 if (Bs3MemChr(abBuf, bFiller, cbIdtr) != NULL)1529 Bs3TestFailedF("Not all bytes touched: cbIdtr=%u bFiller=%#x abBuf=%.*Rhxs\n", cbIdtr, bFiller, cbBuf, pbBuf);1530 if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0)1531 Bs3TestFailedF("Mismatch (#2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);1532 g_usBs3TestStep++;1533 1534 /*1535 * Slide the buffer along 8 bytes to cover misalignment.1536 */1537 for (off = 0; off < 8; off++)1538 {1539 pbBuf = &abBuf[off];1540 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &abBuf[off]);1541 CtxUdExpected.rbx.u = Ctx.rbx.u;1542 1543 /* First with zero buffer. */1544 Bs3MemZero(abBuf, sizeof(abBuf));1545 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1546 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1547 if (off > 0 && !ASMMemIsZero(abBuf, off))1548 Bs3TestFailedF("Unexpected buffer bytes set before (#3): cbIdtr=%u off=%u abBuf=%.*Rhxs\n",1549 cbIdtr, off, off + cbBuf, abBuf);1550 if (!ASMMemIsZero(&abBuf[off + cbIdtr], sizeof(abBuf) - cbIdtr - off))1551 Bs3TestFailedF("Unexpected buffer bytes set after (#3): cbIdtr=%u off=%u abBuf=%.*Rhxs\n",1552 cbIdtr, off, off + cbBuf, abBuf);1553 if (f286 && abBuf[off + cbIdtr - 1] != 0xff)1554 Bs3TestFailedF("286: Top base byte isn't 0xff (#3): %#x\n", abBuf[off + cbIdtr - 1]);1555 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)1556 Bs3TestFailedF("Mismatch (#3): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);1557 g_usBs3TestStep++;1558 1559 /* Again with a buffer filled with a byte not occuring in the previous result. */1560 Bs3MemSet(abBuf, bFiller, sizeof(abBuf));1561 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1562 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1563 if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))1564 Bs3TestFailedF("Unexpected buffer bytes set before (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",1565 cbIdtr, off, bFiller, off + cbBuf, abBuf);1566 if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - cbIdtr - off, bFiller))1567 Bs3TestFailedF("Unexpected buffer bytes set after (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",1568 cbIdtr, off, bFiller, off + cbBuf, abBuf);1569 if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)1570 Bs3TestFailedF("Not all bytes touched (#4): cbIdtr=%u off=%u bFiller=%#x abBuf=%.*Rhxs\n",1571 cbIdtr, off, bFiller, off + cbBuf, abBuf);1572 if (f286 && abBuf[off + cbIdtr - 1] != 0xff)1573 Bs3TestFailedF("286: Top base byte isn't 0xff (#4): %#x\n", abBuf[off + cbIdtr - 1]);1574 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)1575 Bs3TestFailedF("Mismatch (#4): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);1576 g_usBs3TestStep++;1577 }1578 pbBuf = abBuf;1579 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf);1580 CtxUdExpected.rbx.u = Ctx.rbx.u;1581 1582 /*1583 * Play with the selector limit if the target mode supports limit checking1584 * We use BS3_SEL_TEST_PAGE_00 for this1585 */1586 if ( !BS3_MODE_IS_RM_OR_V86(bTestMode)1587 && !BS3_MODE_IS_64BIT_CODE(bTestMode))1588 {1589 uint16_t cbLimit;1590 uint32_t uFlatBuf = Bs3SelPtrToFlat(abBuf);1591 Bs3GdteTestPage00 = Bs3Gdte_DATA16;1592 Bs3GdteTestPage00.Gen.u2Dpl = bRing;1593 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatBuf;1594 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatBuf >> 16);1595 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatBuf >> 24);1596 1597 if (pWorker->fSs)1598 CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;1599 else1600 CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;1601 1602 /* Expand up (normal). */1603 for (off = 0; off < 8; off++)1604 {1605 CtxUdExpected.rbx.u = Ctx.rbx.u = off;1606 for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)1607 {1608 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;1609 Bs3MemSet(abBuf, bFiller, sizeof(abBuf));1610 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1611 if (off + cbIdtr <= cbLimit + 1)1612 {1613 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1614 if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)1615 Bs3TestFailedF("Not all bytes touched (#5): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1616 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1617 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)1618 Bs3TestFailedF("Mismatch (#5): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);1619 if (f286 && abBuf[off + cbIdtr - 1] != 0xff)1620 Bs3TestFailedF("286: Top base byte isn't 0xff (#5): %#x\n", abBuf[off + cbIdtr - 1]);1621 }1622 else1623 {1624 if (pWorker->fSs)1625 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);1626 else1627 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);1628 if (off + 2 <= cbLimit + 1)1629 {1630 if (Bs3MemChr(&abBuf[off], bFiller, 2) != NULL)1631 Bs3TestFailedF("Limit bytes not touched (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1632 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1633 if (Bs3MemCmp(&abBuf[off], pbExpected, 2) != 0)1634 Bs3TestFailedF("Mismatch (#6): expected %.2Rhxs, got %.2Rhxs\n", pbExpected, &abBuf[off]);1635 if (!ASMMemIsAllU8(&abBuf[off + 2], cbIdtr - 2, bFiller))1636 Bs3TestFailedF("Base bytes touched on #GP (#6): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1637 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1638 }1639 else if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller))1640 Bs3TestFailedF("Bytes touched on #GP: cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1641 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1642 }1643 1644 if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))1645 Bs3TestFailedF("Leading bytes touched (#7): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1646 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1647 if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - off - cbIdtr, bFiller))1648 Bs3TestFailedF("Trailing bytes touched (#7): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1649 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1650 1651 g_usBs3TestStep++;1652 }1653 }1654 1655 /* Expand down (weird). Inverted valid area compared to expand up,1656 so a limit of zero give us a valid range for 0001..0ffffh (instead of1657 a segment with one valid byte at 0000h). Whereas a limit of 0fffeh1658 means one valid byte at 0ffffh, and a limit of 0ffffh means none1659 (because in a normal expand up the 0ffffh means all 64KB are1660 accessible). */1661 Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;1662 for (off = 0; off < 8; off++)1663 {1664 CtxUdExpected.rbx.u = Ctx.rbx.u = off;1665 for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)1666 {1667 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;1668 Bs3MemSet(abBuf, bFiller, sizeof(abBuf));1669 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1670 1671 if (off > cbLimit)1672 {1673 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1674 if (Bs3MemChr(&abBuf[off], bFiller, cbIdtr) != NULL)1675 Bs3TestFailedF("Not all bytes touched (#8): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1676 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1677 if (Bs3MemCmp(&abBuf[off], pbExpected, cbIdtr) != 0)1678 Bs3TestFailedF("Mismatch (#8): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &abBuf[off]);1679 if (f286 && abBuf[off + cbIdtr - 1] != 0xff)1680 Bs3TestFailedF("286: Top base byte isn't 0xff (#8): %#x\n", abBuf[off + cbIdtr - 1]);1681 }1682 else1683 {1684 if (pWorker->fSs)1685 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);1686 else1687 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);1688 if (!ASMMemIsAllU8(abBuf, sizeof(abBuf), bFiller))1689 Bs3TestFailedF("Bytes touched on #GP: cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1690 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1691 }1692 1693 if (off > 0 && !ASMMemIsAllU8(abBuf, off, bFiller))1694 Bs3TestFailedF("Leading bytes touched (#9): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1695 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1696 if (!ASMMemIsAllU8(&abBuf[off + cbIdtr], sizeof(abBuf) - off - cbIdtr, bFiller))1697 Bs3TestFailedF("Trailing bytes touched (#9): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x abBuf=%.*Rhxs\n",1698 cbIdtr, off, cbLimit, bFiller, off + cbBuf, abBuf);1699 1700 g_usBs3TestStep++;1701 }1702 }1703 1704 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBuf);1705 CtxUdExpected.rbx.u = Ctx.rbx.u;1706 CtxUdExpected.ss = Ctx.ss;1707 CtxUdExpected.ds = Ctx.ds;1708 }1709 1710 /*1711 * Play with the paging.1712 */1713 if ( BS3_MODE_IS_PAGED(bTestMode)1714 && (!pWorker->fSs || bRing == 3) /* SS.DPL == CPL, we'll get some tiled ring-3 selector here. */1715 && (pbTest = (uint8_t BS3_FAR *)Bs3MemGuardedTestPageAlloc(BS3MEMKIND_TILED)) != NULL)1716 {1717 RTCCUINTXREG uFlatTest = Bs3SelPtrToFlat(pbTest);1718 1719 /*1720 * Slide the buffer towards the trailing guard page. We'll observe the1721 * first word being written entirely separately from the 2nd dword/qword.1722 */1723 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)1724 {1725 Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller, cbIdtr * 2);1726 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);1727 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1728 if (off + cbIdtr <= X86_PAGE_SIZE)1729 {1730 CtxUdExpected.rbx = Ctx.rbx;1731 CtxUdExpected.ss = Ctx.ss;1732 CtxUdExpected.ds = Ctx.ds;1733 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1734 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)1735 Bs3TestFailedF("Mismatch (#9): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);1736 }1737 else1738 {1739 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),1740 uFlatTest + RT_MAX(off, X86_PAGE_SIZE));1741 if ( off <= X86_PAGE_SIZE - 21742 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)1743 Bs3TestPrintf("Mismatch (#10): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",1744 pbExpected, &pbTest[off], off);1745 if ( off < X86_PAGE_SIZE - 21746 && !ASMMemIsAllU8(&pbTest[off + 2], X86_PAGE_SIZE - off - 2, bFiller))1747 Bs3TestPrintf("Wrote partial base on #PF (#10): bFiller=%#x, got %.*Rhxs; off=%#x\n",1748 bFiller, X86_PAGE_SIZE - off - 2, &pbTest[off + 2], off);1749 if (off == X86_PAGE_SIZE - 1 && pbTest[off] != bFiller)1750 Bs3TestPrintf("Wrote partial limit on #PF (#10): Expected %02x, got %02x\n", bFiller, pbTest[off]);1751 }1752 g_usBs3TestStep++;1753 }1754 1755 /*1756 * Now, do it the other way around. It should look normal now since writing1757 * the limit will #PF first and nothing should be written.1758 */1759 for (off = cbIdtr + 4; off >= -cbIdtr - 4; off--)1760 {1761 Bs3MemSet(pbTest, bFiller, 48);1762 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);1763 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1764 if (off >= 0)1765 {1766 CtxUdExpected.rbx = Ctx.rbx;1767 CtxUdExpected.ss = Ctx.ss;1768 CtxUdExpected.ds = Ctx.ds;1769 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1770 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)1771 Bs3TestFailedF("Mismatch (#11): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);1772 }1773 else1774 {1775 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0), uFlatTest + off);1776 if ( -off < cbIdtr1777 && !ASMMemIsAllU8(pbTest, cbIdtr + off, bFiller))1778 Bs3TestPrintf("Wrote partial content on #PF (#12): bFiller=%#x, found %.*Rhxs; off=%d\n",1779 bFiller, cbIdtr + off, pbTest, off);1780 }1781 if (!ASMMemIsAllU8(&pbTest[RT_MAX(cbIdtr + off, 0)], 16, bFiller))1782 Bs3TestPrintf("Wrote beyond expected area (#13): bFiller=%#x, found %.16Rhxs; off=%d\n",1783 bFiller, &pbTest[RT_MAX(cbIdtr + off, 0)], off);1784 g_usBs3TestStep++;1785 }1786 1787 /*1788 * Combine paging and segment limit and check ordering.1789 * This is kind of interesting here since it the instruction seems to1790 * be doing two separate writes.1791 */1792 if ( !BS3_MODE_IS_RM_OR_V86(bTestMode)1793 && !BS3_MODE_IS_64BIT_CODE(bTestMode))1794 {1795 uint16_t cbLimit;1796 1797 Bs3GdteTestPage00 = Bs3Gdte_DATA16;1798 Bs3GdteTestPage00.Gen.u2Dpl = bRing;1799 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatTest;1800 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);1801 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);1802 1803 if (pWorker->fSs)1804 CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;1805 else1806 CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;1807 1808 /* Expand up (normal), approaching tail guard page. */1809 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)1810 {1811 CtxUdExpected.rbx.u = Ctx.rbx.u = off;1812 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)1813 {1814 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;1815 Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller, cbIdtr * 2);1816 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1817 if (off + cbIdtr <= cbLimit + 1)1818 {1819 /* No #GP, but maybe #PF. */1820 if (off + cbIdtr <= X86_PAGE_SIZE)1821 {1822 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1823 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)1824 Bs3TestFailedF("Mismatch (#14): expected %.*Rhxs, got %.*Rhxs\n",1825 cbIdtr, pbExpected, cbIdtr, &pbTest[off]);1826 }1827 else1828 {1829 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),1830 uFlatTest + RT_MAX(off, X86_PAGE_SIZE));1831 if ( off <= X86_PAGE_SIZE - 21832 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)1833 Bs3TestPrintf("Mismatch (#15): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",1834 pbExpected, &pbTest[off], off);1835 cb = X86_PAGE_SIZE - off - 2;1836 if ( off < X86_PAGE_SIZE - 21837 && !ASMMemIsAllU8(&pbTest[off + 2], cb, bFiller))1838 Bs3TestPrintf("Wrote partial base on #PF (#15): bFiller=%#x, got %.*Rhxs; off=%#x\n",1839 bFiller, cb, &pbTest[off + 2], off);1840 if (off == X86_PAGE_SIZE - 1 && pbTest[off] != bFiller)1841 Bs3TestPrintf("Wrote partial limit on #PF (#15): Expected %02x, got %02x\n", bFiller, pbTest[off]);1842 }1843 }1844 else if (off + 2 <= cbLimit + 1)1845 {1846 /* [ig]tr.limit writing does not cause #GP, but may cause #PG, if not writing the base causes #GP. */1847 if (off <= X86_PAGE_SIZE - 2)1848 {1849 if (pWorker->fSs)1850 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);1851 else1852 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);1853 if (Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)1854 Bs3TestPrintf("Mismatch (#16): Expected limit %.2Rhxs, got %.2Rhxs; off=%#x\n",1855 pbExpected, &pbTest[off], off);1856 cb = X86_PAGE_SIZE - off - 2;1857 if ( off < X86_PAGE_SIZE - 21858 && !ASMMemIsAllU8(&pbTest[off + 2], cb, bFiller))1859 Bs3TestPrintf("Wrote partial base with limit (#16): bFiller=%#x, got %.*Rhxs; off=%#x\n",1860 bFiller, cb, &pbTest[off + 2], off);1861 }1862 else1863 {1864 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),1865 uFlatTest + RT_MAX(off, X86_PAGE_SIZE));1866 if ( off < X86_PAGE_SIZE1867 && !ASMMemIsAllU8(&pbTest[off], X86_PAGE_SIZE - off, bFiller))1868 Bs3TestPrintf("Mismatch (#16): Partial limit write on #PF: bFiller=%#x, got %.*Rhxs\n",1869 bFiller, X86_PAGE_SIZE - off, &pbTest[off]);1870 }1871 }1872 else1873 {1874 /* #GP/#SS on limit. */1875 if (pWorker->fSs)1876 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);1877 else1878 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);1879 if ( off < X86_PAGE_SIZE1880 && !ASMMemIsAllU8(&pbTest[off], X86_PAGE_SIZE - off, bFiller))1881 Bs3TestPrintf("Mismatch (#17): Partial write on #GP: bFiller=%#x, got %.*Rhxs\n",1882 bFiller, X86_PAGE_SIZE - off, &pbTest[off]);1883 }1884 1885 cb = RT_MIN(cbIdtr * 2, off - (X86_PAGE_SIZE - cbIdtr*2));1886 if (!ASMMemIsAllU8(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], cb, bFiller))1887 Bs3TestFailedF("Leading bytes touched (#18): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",1888 cbIdtr, off, cbLimit, bFiller, cb, pbTest[X86_PAGE_SIZE - cbIdtr * 2]);1889 1890 g_usBs3TestStep++;1891 1892 /* Set DS to 0 and check that we get #GP(0). */1893 if (!pWorker->fSs)1894 {1895 Ctx.ds = 0;1896 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1897 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);1898 Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;1899 g_usBs3TestStep++;1900 }1901 }1902 }1903 1904 /* Expand down. */1905 pbTest -= X86_PAGE_SIZE; /* Note! we're backing up a page to simplify things */1906 uFlatTest -= X86_PAGE_SIZE;1907 1908 Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;1909 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatTest;1910 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);1911 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);1912 1913 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)1914 {1915 CtxUdExpected.rbx.u = Ctx.rbx.u = off;1916 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)1917 {1918 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;1919 Bs3MemSet(&pbTest[X86_PAGE_SIZE], bFiller, cbIdtr * 2);1920 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1921 if (cbLimit < off && off >= X86_PAGE_SIZE)1922 {1923 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1924 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)1925 Bs3TestFailedF("Mismatch (#19): expected %.*Rhxs, got %.*Rhxs\n",1926 cbIdtr, pbExpected, cbIdtr, &pbTest[off]);1927 cb = X86_PAGE_SIZE + cbIdtr*2 - off;1928 if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], cb, bFiller))1929 Bs3TestFailedF("Trailing bytes touched (#20): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",1930 cbIdtr, off, cbLimit, bFiller, cb, pbTest[off + cbIdtr]);1931 }1932 else1933 {1934 if (cbLimit < off && off < X86_PAGE_SIZE)1935 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, X86_TRAP_PF_RW | (Ctx.bCpl == 3 ? X86_TRAP_PF_US : 0),1936 uFlatTest + off);1937 else if (pWorker->fSs)1938 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);1939 else1940 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);1941 cb = cbIdtr*2;1942 if (!ASMMemIsAllU8(&pbTest[X86_PAGE_SIZE], cb, bFiller))1943 Bs3TestFailedF("Trailing bytes touched (#20): cbIdtr=%u off=%u cbLimit=%u bFiller=%#x pbTest=%.*Rhxs\n",1944 cbIdtr, off, cbLimit, bFiller, cb, pbTest[X86_PAGE_SIZE]);1945 }1946 g_usBs3TestStep++;1947 }1948 }1949 1950 pbTest += X86_PAGE_SIZE;1951 uFlatTest += X86_PAGE_SIZE;1952 }1953 1954 Bs3MemGuardedTestPageFree(pbTest);1955 }1956 1957 /*1958 * Check non-canonical 64-bit space.1959 */1960 if ( BS3_MODE_IS_64BIT_CODE(bTestMode)1961 && (pbTest = (uint8_t BS3_FAR *)Bs3PagingSetupCanonicalTraps()) != NULL)1962 {1963 /* Make our references relative to the gap. */1964 pbTest += g_cbBs3PagingOneCanonicalTrap;1965 1966 /* Hit it from below. */1967 for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)1968 {1969 Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0x0000800000000000) + off;1970 Bs3MemSet(&pbTest[-64], bFiller, 64*2);1971 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);1972 if (off + cbIdtr <= 0)1973 {1974 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);1975 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)1976 Bs3TestFailedF("Mismatch (#21): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);1977 }1978 else1979 {1980 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);1981 if (off <= -2 && Bs3MemCmp(&pbTest[off], pbExpected, 2) != 0)1982 Bs3TestFailedF("Mismatch (#21): expected limit %.2Rhxs, got %.2Rhxs\n", pbExpected, &pbTest[off]);1983 off2 = off <= -2 ? 2 : 0;1984 cb = cbIdtr - off2;1985 if (!ASMMemIsAllU8(&pbTest[off + off2], cb, bFiller))1986 Bs3TestFailedF("Mismatch (#21): touched base %.*Rhxs, got %.*Rhxs\n",1987 cb, &pbExpected[off], cb, &pbTest[off + off2]);1988 }1989 if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller))1990 Bs3TestFailedF("Leading bytes touched (#21): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off]);1991 if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], 16, bFiller))1992 Bs3TestFailedF("Trailing bytes touched (#21): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off + cbIdtr]);1993 }1994 1995 /* Hit it from above. */1996 for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)1997 {1998 Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0xffff800000000000) + off;1999 Bs3MemSet(&pbTest[-64], bFiller, 64*2);2000 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2001 if (off >= 0)2002 {2003 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2004 if (Bs3MemCmp(&pbTest[off], pbExpected, cbIdtr) != 0)2005 Bs3TestFailedF("Mismatch (#22): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, &pbTest[off]);2006 }2007 else2008 {2009 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2010 if (!ASMMemIsAllU8(&pbTest[off], cbIdtr, bFiller))2011 Bs3TestFailedF("Mismatch (#22): touched base %.*Rhxs, got %.*Rhxs\n",2012 cbIdtr, &pbExpected[off], cbIdtr, &pbTest[off]);2013 }2014 if (!ASMMemIsAllU8(&pbTest[off - 16], 16, bFiller))2015 Bs3TestFailedF("Leading bytes touched (#22): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off]);2016 if (!ASMMemIsAllU8(&pbTest[off + cbIdtr], 16, bFiller))2017 Bs3TestFailedF("Trailing bytes touched (#22): bFiller=%#x, got %.16Rhxs\n", bFiller, &pbTest[off + cbIdtr]);2018 }2019 2020 }2021 }2022 2023 2024 # define bs3CpuBasic2_sidt_sgdt_Common BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_Common)2025 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,2026 uint8_t const *pbExpected)2027 {2028 unsigned idx;2029 unsigned bRing;2030 unsigned iStep = 0;2031 2032 /* Note! We skip the SS checks for ring-0 since we badly mess up SS in the2033 test and don't want to bother with double faults. */2034 for (bRing = 0; bRing <= 3; bRing++)2035 {2036 for (idx = 0; idx < cWorkers; idx++)2037 if ( (paWorkers[idx].bMode & (bTestMode & BS3_MODE_CODE_MASK))2038 && (!paWorkers[idx].fSs || bRing != 0 /** @todo || BS3_MODE_IS_64BIT_SYS(bTestMode)*/ ))2039 {2040 g_usBs3TestStep = iStep;2041 bs3CpuBasic2_sidt_sgdt_One(&paWorkers[idx], bTestMode, bRing, pbExpected);2042 iStep += 1000;2043 }2044 if (BS3_MODE_IS_RM_OR_V86(bTestMode))2045 break;2046 }2047 }2048 2049 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(uint8_t bMode)2050 {2051 union2052 {2053 RTIDTR Idtr;2054 uint8_t ab[16];2055 } Expected;2056 2057 g_pszTestMode = Bs3GetModeName(bMode);2058 g_bTestMode = bMode;2059 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bMode);2060 2061 2062 /*2063 * Pass to common worker which is only compiled once per mode.2064 */2065 Bs3MemZero(&Expected, sizeof(Expected));2066 ASMGetIDTR(&Expected.Idtr);2067 bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSidtWorkers, RT_ELEMENTS(g_aSidtWorkers), Expected.ab);2068 2069 /*2070 * Re-initialize the IDT.2071 */2072 Bs3TrapReInit();2073 return 0;2074 }2075 2076 2077 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)2078 {2079 uint64_t const uOrgAddr = Bs3Lgdt_Gdt.uAddr;2080 uint64_t uNew = 0;2081 union2082 {2083 RTGDTR Gdtr;2084 uint8_t ab[16];2085 } Expected;2086 2087 g_pszTestMode = Bs3GetModeName(bMode);2088 g_bTestMode = bMode;2089 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bMode);2090 2091 /*2092 * If paged mode, try push the GDT way up.2093 */2094 if (BS3_MODE_IS_PAGED(bMode))2095 {2096 /** @todo loading non-canonical base addresses. */2097 int rc;2098 uNew = BS3_MODE_IS_64BIT_SYS(bMode) ? UINT64_C(0xffff80fedcb70000) : UINT64_C(0xc2d28000);2099 uNew |= uOrgAddr & X86_PAGE_OFFSET_MASK;2100 rc = Bs3PagingAlias(uNew, uOrgAddr, Bs3Lgdt_Gdt.cb, X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_D | X86_PTE_A);2101 if (RT_SUCCESS(rc))2102 {2103 Bs3Lgdt_Gdt.uAddr = uNew;2104 Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uNew);2105 }2106 }2107 2108 /*2109 * Pass to common worker which is only compiled once per mode.2110 */2111 Bs3MemZero(&Expected, sizeof(Expected));2112 ASMGetGDTR(&Expected.Gdtr);2113 bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSgdtWorkers, RT_ELEMENTS(g_aSgdtWorkers), Expected.ab);2114 2115 /*2116 * Unalias the GDT.2117 */2118 if (uNew != 0)2119 {2120 Bs3Lgdt_Gdt.uAddr = uOrgAddr;2121 Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uOrgAddr);2122 Bs3PagingUnalias(uNew, Bs3Lgdt_Gdt.cb);2123 }2124 2125 /*2126 * Re-initialize the IDT.2127 */2128 Bs3TrapReInit();2129 return 0;2130 }2131 2132 2133 2134 /*2135 * LIDT & LGDT2136 */2137 2138 /**2139 * Executes one round of LIDT and LGDT tests using one assembly worker.2140 *2141 * This is written with driving everything from the 16-bit or 32-bit worker in2142 * mind, i.e. not assuming the test bitcount is the same as the current.2143 */2144 # define bs3CpuBasic2_lidt_lgdt_One BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_One)2145 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing,2146 uint8_t const *pbRestore, size_t cbRestore, uint8_t const *pbExpected)2147 {2148 static const struct2149 {2150 bool fGP;2151 uint16_t cbLimit;2152 uint64_t u64Base;2153 } s_aValues64[] =2154 {2155 { false, 0x0000, UINT64_C(0x0000000000000000) },2156 { false, 0x0001, UINT64_C(0x0000000000000001) },2157 { false, 0x0002, UINT64_C(0x0000000000000010) },2158 { false, 0x0003, UINT64_C(0x0000000000000123) },2159 { false, 0x0004, UINT64_C(0x0000000000001234) },2160 { false, 0x0005, UINT64_C(0x0000000000012345) },2161 { false, 0x0006, UINT64_C(0x0000000000123456) },2162 { false, 0x0007, UINT64_C(0x0000000001234567) },2163 { false, 0x0008, UINT64_C(0x0000000012345678) },2164 { false, 0x0009, UINT64_C(0x0000000123456789) },2165 { false, 0x000a, UINT64_C(0x000000123456789a) },2166 { false, 0x000b, UINT64_C(0x00000123456789ab) },2167 { false, 0x000c, UINT64_C(0x0000123456789abc) },2168 { false, 0x001c, UINT64_C(0x00007ffffeefefef) },2169 { false, 0xffff, UINT64_C(0x00007fffffffffff) },2170 { true, 0xf3f1, UINT64_C(0x0000800000000000) },2171 { true, 0x0000, UINT64_C(0x0000800000000000) },2172 { true, 0x0000, UINT64_C(0x0000800000000333) },2173 { true, 0x00f0, UINT64_C(0x0001000000000000) },2174 { true, 0x0ff0, UINT64_C(0x0012000000000000) },2175 { true, 0x0eff, UINT64_C(0x0123000000000000) },2176 { true, 0xe0fe, UINT64_C(0x1234000000000000) },2177 { true, 0x00ad, UINT64_C(0xffff300000000000) },2178 { true, 0x0000, UINT64_C(0xffff7fffffffffff) },2179 { true, 0x00f0, UINT64_C(0xffff7fffffffffff) },2180 { false, 0x5678, UINT64_C(0xffff800000000000) },2181 { false, 0x2969, UINT64_C(0xffffffffffeefefe) },2182 { false, 0x1221, UINT64_C(0xffffffffffffffff) },2183 { false, 0x1221, UINT64_C(0xffffffffffffffff) },2184 };2185 static const struct2186 {2187 uint16_t cbLimit;2188 uint32_t u32Base;2189 } s_aValues32[] =2190 {2191 { 0xdfdf, UINT32_C(0xefefefef) },2192 { 0x0000, UINT32_C(0x00000000) },2193 { 0x0001, UINT32_C(0x00000001) },2194 { 0x0002, UINT32_C(0x00000012) },2195 { 0x0003, UINT32_C(0x00000123) },2196 { 0x0004, UINT32_C(0x00001234) },2197 { 0x0005, UINT32_C(0x00012345) },2198 { 0x0006, UINT32_C(0x00123456) },2199 { 0x0007, UINT32_C(0x01234567) },2200 { 0x0008, UINT32_C(0x12345678) },2201 { 0x0009, UINT32_C(0x80204060) },2202 { 0x000a, UINT32_C(0xddeeffaa) },2203 { 0x000b, UINT32_C(0xfdecdbca) },2204 { 0x000c, UINT32_C(0x6098456b) },2205 { 0x000d, UINT32_C(0x98506099) },2206 { 0x000e, UINT32_C(0x206950bc) },2207 { 0x000f, UINT32_C(0x9740395d) },2208 { 0x0334, UINT32_C(0x64a9455e) },2209 { 0xb423, UINT32_C(0xd20b6eff) },2210 { 0x4955, UINT32_C(0x85296d46) },2211 { 0xffff, UINT32_C(0x07000039) },2212 { 0xefe1, UINT32_C(0x0007fe00) },2213 };2214 2215 BS3TRAPFRAME TrapCtx;2216 BS3REGCTX Ctx;2217 BS3REGCTX CtxUdExpected;2218 BS3REGCTX TmpCtx;2219 uint8_t abBufLoad[40]; /* Test buffer w/ misalignment test space and some (cbIdtr) extra guard. */2220 uint8_t abBufSave[32]; /* For saving the result after loading. */2221 uint8_t abBufRestore[24]; /* For restoring sane value (same seg as abBufSave!). */2222 uint8_t abExpectedFilled[32]; /* Same as pbExpected, except it's filled with bFiller2 instead of zeros. */2223 uint8_t BS3_FAR *pbBufSave; /* Correctly aligned pointer into abBufSave. */2224 uint8_t BS3_FAR *pbBufRestore; /* Correctly aligned pointer into abBufRestore. */2225 uint8_t const cbIdtr = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 2+8 : 2+4;2226 uint8_t const cbBaseLoaded = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 82227 : BS3_MODE_IS_16BIT_CODE(bTestMode) == !(pWorker->fFlags & BS3CB2SIDTSGDT_F_OPSIZE)2228 ? 3 : 4;2229 bool const f286 = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80286;2230 uint8_t const bTop16BitBase = f286 ? 0xff : 0x00;2231 uint8_t bFiller1; /* For filling abBufLoad. */2232 uint8_t bFiller2; /* For filling abBufSave and expectations. */2233 int off;2234 uint8_t BS3_FAR *pbTest;2235 unsigned i;2236 2237 /* make sure they're allocated */2238 Bs3MemZero(&Ctx, sizeof(Ctx));2239 Bs3MemZero(&CtxUdExpected, sizeof(CtxUdExpected));2240 Bs3MemZero(&TmpCtx, sizeof(TmpCtx));2241 Bs3MemZero(&TrapCtx, sizeof(TrapCtx));2242 Bs3MemZero(abBufSave, sizeof(abBufSave));2243 Bs3MemZero(abBufLoad, sizeof(abBufLoad));2244 Bs3MemZero(abBufRestore, sizeof(abBufRestore));2245 2246 /*2247 * Create a context, giving this routine some more stack space.2248 * - Point the context at our LIDT [xBX] + SIDT [xDI] + LIDT [xSI] + UD2 combo.2249 * - Point DS/SS:xBX at abBufLoad.2250 * - Point ES:xDI at abBufSave.2251 * - Point ES:xSI at abBufRestore.2252 */2253 Bs3RegCtxSaveEx(&Ctx, bTestMode, 256 /*cbExtraStack*/);2254 Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, pWorker->fpfnWorker);2255 if (BS3_MODE_IS_16BIT_SYS(bTestMode))2256 g_uBs3TrapEipHint = Ctx.rip.u32;2257 Ctx.rflags.u16 &= ~X86_EFL_IF;2258 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBufLoad);2259 2260 pbBufSave = abBufSave;2261 if ((BS3_FP_OFF(pbBufSave) + 2) & 7)2262 pbBufSave += 8 - ((BS3_FP_OFF(pbBufSave) + 2) & 7);2263 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rdi, &Ctx.es, pbBufSave);2264 2265 pbBufRestore = abBufRestore;2266 if ((BS3_FP_OFF(pbBufRestore) + 2) & 7)2267 pbBufRestore += 8 - ((BS3_FP_OFF(pbBufRestore) + 2) & 7);2268 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rsi, &Ctx.es, pbBufRestore);2269 Bs3MemCpy(pbBufRestore, pbRestore, cbRestore);2270 2271 if (!BS3_MODE_IS_RM_OR_V86(bTestMode))2272 Bs3RegCtxConvertToRingX(&Ctx, bRing);2273 2274 /* For successful SIDT attempts, we'll stop at the UD2. */2275 Bs3MemCpy(&CtxUdExpected, &Ctx, sizeof(Ctx));2276 CtxUdExpected.rip.u += pWorker->cbInstr;2277 2278 /*2279 * Check that it works at all.2280 */2281 Bs3MemZero(abBufLoad, sizeof(abBufLoad));2282 Bs3MemCpy(abBufLoad, pbBufRestore, cbIdtr);2283 Bs3MemZero(abBufSave, sizeof(abBufSave));2284 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2285 if (bRing != 0)2286 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2287 else2288 {2289 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2290 if (Bs3MemCmp(pbBufSave, pbExpected, cbIdtr * 2) != 0)2291 Bs3TestFailedF("Mismatch (%s, #1): expected %.*Rhxs, got %.*Rhxs\n",2292 pWorker->pszDesc, cbIdtr*2, pbExpected, cbIdtr*2, pbBufSave);2293 }2294 g_usBs3TestStep++;2295 2296 /* Determine two filler bytes that doesn't appear in the previous result or our expectations. */2297 bFiller1 = ~0x55;2298 while ( Bs3MemChr(pbBufSave, bFiller1, cbIdtr) != NULL2299 || Bs3MemChr(pbRestore, bFiller1, cbRestore) != NULL2300 || bFiller1 == 0xff)2301 bFiller1++;2302 bFiller2 = 0x33;2303 while ( Bs3MemChr(pbBufSave, bFiller2, cbIdtr) != NULL2304 || Bs3MemChr(pbRestore, bFiller2, cbRestore) != NULL2305 || bFiller2 == 0xff2306 || bFiller2 == bFiller1)2307 bFiller2++;2308 Bs3MemSet(abExpectedFilled, bFiller2, sizeof(abExpectedFilled));2309 Bs3MemCpy(abExpectedFilled, pbExpected, cbIdtr);2310 2311 /* Again with a buffer filled with a byte not occuring in the previous result. */2312 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));2313 Bs3MemCpy(abBufLoad, pbBufRestore, cbIdtr);2314 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2315 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2316 if (bRing != 0)2317 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2318 else2319 {2320 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2321 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)2322 Bs3TestFailedF("Mismatch (%s, #2): expected %.*Rhxs, got %.*Rhxs\n",2323 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2324 }2325 g_usBs3TestStep++;2326 2327 /*2328 * Try loading a bunch of different limit+base value to check what happens,2329 * especially what happens wrt the top part of the base in 16-bit mode.2330 */2331 if (BS3_MODE_IS_64BIT_CODE(bTestMode))2332 {2333 for (i = 0; i < RT_ELEMENTS(s_aValues64); i++)2334 {2335 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));2336 Bs3MemCpy(&abBufLoad[0], &s_aValues64[i].cbLimit, 2);2337 Bs3MemCpy(&abBufLoad[2], &s_aValues64[i].u64Base, 8);2338 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2339 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2340 if (bRing != 0 || s_aValues64[i].fGP)2341 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2342 else2343 {2344 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2345 if ( Bs3MemCmp(&pbBufSave[0], &s_aValues64[i].cbLimit, 2) != 02346 || Bs3MemCmp(&pbBufSave[2], &s_aValues64[i].u64Base, 8) != 02347 || !ASMMemIsAllU8(&pbBufSave[10], cbIdtr, bFiller2))2348 Bs3TestFailedF("Mismatch (%s, #2): expected %04RX16:%016RX64, fillers %#x %#x, got %.*Rhxs\n",2349 pWorker->pszDesc, s_aValues64[i].cbLimit, s_aValues64[i].u64Base,2350 bFiller1, bFiller2, cbIdtr*2, pbBufSave);2351 }2352 g_usBs3TestStep++;2353 }2354 }2355 else2356 {2357 for (i = 0; i < RT_ELEMENTS(s_aValues32); i++)2358 {2359 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));2360 Bs3MemCpy(&abBufLoad[0], &s_aValues32[i].cbLimit, 2);2361 Bs3MemCpy(&abBufLoad[2], &s_aValues32[i].u32Base, cbBaseLoaded);2362 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2363 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2364 if (bRing != 0)2365 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2366 else2367 {2368 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2369 if ( Bs3MemCmp(&pbBufSave[0], &s_aValues32[i].cbLimit, 2) != 02370 || Bs3MemCmp(&pbBufSave[2], &s_aValues32[i].u32Base, cbBaseLoaded) != 02371 || ( cbBaseLoaded != 42372 && pbBufSave[2+3] != bTop16BitBase)2373 || !ASMMemIsAllU8(&pbBufSave[8], cbIdtr, bFiller2))2374 Bs3TestFailedF("Mismatch (%s,#3): loaded %04RX16:%08RX32, fillers %#x %#x%s, got %.*Rhxs\n",2375 pWorker->pszDesc, s_aValues32[i].cbLimit, s_aValues32[i].u32Base, bFiller1, bFiller2,2376 f286 ? ", 286" : "", cbIdtr*2, pbBufSave);2377 }2378 g_usBs3TestStep++;2379 }2380 }2381 2382 /*2383 * Slide the buffer along 8 bytes to cover misalignment.2384 */2385 for (off = 0; off < 8; off++)2386 {2387 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &abBufLoad[off]);2388 CtxUdExpected.rbx.u = Ctx.rbx.u;2389 2390 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));2391 Bs3MemCpy(&abBufLoad[off], pbBufRestore, cbIdtr);2392 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2393 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2394 if (bRing != 0)2395 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2396 else2397 {2398 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2399 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)2400 Bs3TestFailedF("Mismatch (%s, #4): expected %.*Rhxs, got %.*Rhxs\n",2401 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2402 }2403 g_usBs3TestStep++;2404 }2405 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBufLoad);2406 CtxUdExpected.rbx.u = Ctx.rbx.u;2407 2408 /*2409 * Play with the selector limit if the target mode supports limit checking2410 * We use BS3_SEL_TEST_PAGE_00 for this2411 */2412 if ( !BS3_MODE_IS_RM_OR_V86(bTestMode)2413 && !BS3_MODE_IS_64BIT_CODE(bTestMode))2414 {2415 uint16_t cbLimit;2416 uint32_t uFlatBuf = Bs3SelPtrToFlat(abBufLoad);2417 Bs3GdteTestPage00 = Bs3Gdte_DATA16;2418 Bs3GdteTestPage00.Gen.u2Dpl = bRing;2419 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatBuf;2420 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatBuf >> 16);2421 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatBuf >> 24);2422 2423 if (pWorker->fSs)2424 CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;2425 else2426 CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;2427 2428 /* Expand up (normal). */2429 for (off = 0; off < 8; off++)2430 {2431 CtxUdExpected.rbx.u = Ctx.rbx.u = off;2432 for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)2433 {2434 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;2435 2436 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));2437 Bs3MemCpy(&abBufLoad[off], pbBufRestore, cbIdtr);2438 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2439 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2440 if (bRing != 0)2441 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2442 else if (off + cbIdtr <= cbLimit + 1)2443 {2444 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2445 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)2446 Bs3TestFailedF("Mismatch (%s, #5): expected %.*Rhxs, got %.*Rhxs\n",2447 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2448 }2449 else if (pWorker->fSs)2450 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);2451 else2452 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2453 g_usBs3TestStep++;2454 2455 /* Again with zero limit and messed up base (should trigger tripple fault if partially loaded). */2456 abBufLoad[off] = abBufLoad[off + 1] = 0;2457 abBufLoad[off + 2] |= 1;2458 abBufLoad[off + cbIdtr - 2] ^= 0x5a;2459 abBufLoad[off + cbIdtr - 1] ^= 0xa5;2460 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2461 if (bRing != 0)2462 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2463 else if (off + cbIdtr <= cbLimit + 1)2464 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2465 else if (pWorker->fSs)2466 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);2467 else2468 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2469 }2470 }2471 2472 /* Expand down (weird). Inverted valid area compared to expand up,2473 so a limit of zero give us a valid range for 0001..0ffffh (instead of2474 a segment with one valid byte at 0000h). Whereas a limit of 0fffeh2475 means one valid byte at 0ffffh, and a limit of 0ffffh means none2476 (because in a normal expand up the 0ffffh means all 64KB are2477 accessible). */2478 Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;2479 for (off = 0; off < 8; off++)2480 {2481 CtxUdExpected.rbx.u = Ctx.rbx.u = off;2482 for (cbLimit = 0; cbLimit < cbIdtr*2; cbLimit++)2483 {2484 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;2485 2486 Bs3MemSet(abBufLoad, bFiller1, sizeof(abBufLoad));2487 Bs3MemCpy(&abBufLoad[off], pbBufRestore, cbIdtr);2488 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2489 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2490 if (bRing != 0)2491 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2492 else if (off > cbLimit)2493 {2494 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2495 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)2496 Bs3TestFailedF("Mismatch (%s, #6): expected %.*Rhxs, got %.*Rhxs\n",2497 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2498 }2499 else if (pWorker->fSs)2500 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);2501 else2502 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2503 g_usBs3TestStep++;2504 2505 /* Again with zero limit and messed up base (should trigger triple fault if partially loaded). */2506 abBufLoad[off] = abBufLoad[off + 1] = 0;2507 abBufLoad[off + 2] |= 3;2508 abBufLoad[off + cbIdtr - 2] ^= 0x55;2509 abBufLoad[off + cbIdtr - 1] ^= 0xaa;2510 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2511 if (bRing != 0)2512 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2513 else if (off > cbLimit)2514 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2515 else if (pWorker->fSs)2516 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);2517 else2518 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2519 }2520 }2521 2522 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, abBufLoad);2523 CtxUdExpected.rbx.u = Ctx.rbx.u;2524 CtxUdExpected.ss = Ctx.ss;2525 CtxUdExpected.ds = Ctx.ds;2526 }2527 2528 /*2529 * Play with the paging.2530 */2531 if ( BS3_MODE_IS_PAGED(bTestMode)2532 && (!pWorker->fSs || bRing == 3) /* SS.DPL == CPL, we'll get some tiled ring-3 selector here. */2533 && (pbTest = (uint8_t BS3_FAR *)Bs3MemGuardedTestPageAlloc(BS3MEMKIND_TILED)) != NULL)2534 {2535 RTCCUINTXREG uFlatTest = Bs3SelPtrToFlat(pbTest);2536 2537 /*2538 * Slide the load buffer towards the trailing guard page.2539 */2540 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[X86_PAGE_SIZE]);2541 CtxUdExpected.ss = Ctx.ss;2542 CtxUdExpected.ds = Ctx.ds;2543 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)2544 {2545 Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller1, cbIdtr*2);2546 if (off < X86_PAGE_SIZE)2547 Bs3MemCpy(&pbTest[off], pbBufRestore, RT_MIN(X86_PAGE_SIZE - off, cbIdtr));2548 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);2549 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2550 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2551 if (bRing != 0)2552 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2553 else if (off + cbIdtr <= X86_PAGE_SIZE)2554 {2555 CtxUdExpected.rbx = Ctx.rbx;2556 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2557 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr*2) != 0)2558 Bs3TestFailedF("Mismatch (%s, #7): expected %.*Rhxs, got %.*Rhxs\n",2559 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2560 }2561 else2562 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + RT_MAX(off, X86_PAGE_SIZE));2563 g_usBs3TestStep++;2564 2565 /* Again with zero limit and maybe messed up base as well (triple fault if buggy).2566 The 386DX-40 here triple faults (or something) with off == 0xffe, nothing else. */2567 if ( off < X86_PAGE_SIZE && off + cbIdtr > X86_PAGE_SIZE2568 && ( off != X86_PAGE_SIZE - 22569 || (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) != BS3CPU_80386)2570 )2571 {2572 pbTest[off] = 0;2573 if (off + 1 < X86_PAGE_SIZE)2574 pbTest[off + 1] = 0;2575 if (off + 2 < X86_PAGE_SIZE)2576 pbTest[off + 2] |= 7;2577 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2578 if (bRing != 0)2579 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2580 else2581 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + RT_MAX(off, X86_PAGE_SIZE));2582 g_usBs3TestStep++;2583 }2584 }2585 2586 /*2587 * Now, do it the other way around. It should look normal now since writing2588 * the limit will #PF first and nothing should be written.2589 */2590 for (off = cbIdtr + 4; off >= -cbIdtr - 4; off--)2591 {2592 Bs3MemSet(pbTest, bFiller1, 48);2593 if (off >= 0)2594 Bs3MemCpy(&pbTest[off], pbBufRestore, cbIdtr);2595 else if (off + cbIdtr > 0)2596 Bs3MemCpy(pbTest, &pbBufRestore[-off], cbIdtr + off);2597 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rbx, pWorker->fSs ? &Ctx.ss : &Ctx.ds, &pbTest[off]);2598 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2599 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2600 if (bRing != 0)2601 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2602 else if (off >= 0)2603 {2604 CtxUdExpected.rbx = Ctx.rbx;2605 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2606 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr*2) != 0)2607 Bs3TestFailedF("Mismatch (%s, #8): expected %.*Rhxs, got %.*Rhxs\n",2608 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2609 }2610 else2611 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + off);2612 g_usBs3TestStep++;2613 2614 /* Again with messed up base as well (triple fault if buggy). */2615 if (off < 0 && off > -cbIdtr)2616 {2617 if (off + 2 >= 0)2618 pbTest[off + 2] |= 15;2619 pbTest[off + cbIdtr - 1] ^= 0xaa;2620 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2621 if (bRing != 0)2622 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2623 else2624 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + off);2625 g_usBs3TestStep++;2626 }2627 }2628 2629 /*2630 * Combine paging and segment limit and check ordering.2631 * This is kind of interesting here since it the instruction seems to2632 * actually be doing two separate read, just like it's S[IG]DT counterpart.2633 *2634 * Note! My 486DX4 does a DWORD limit read when the operand size is 32-bit,2635 * that's what f486Weirdness deals with.2636 */2637 if ( !BS3_MODE_IS_RM_OR_V86(bTestMode)2638 && !BS3_MODE_IS_64BIT_CODE(bTestMode))2639 {2640 bool const f486Weirdness = (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_804862641 && BS3_MODE_IS_32BIT_CODE(bTestMode) == !(pWorker->fFlags & BS3CB2SIDTSGDT_F_OPSIZE);2642 uint16_t cbLimit;2643 2644 Bs3GdteTestPage00 = Bs3Gdte_DATA16;2645 Bs3GdteTestPage00.Gen.u2Dpl = bRing;2646 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatTest;2647 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);2648 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);2649 2650 if (pWorker->fSs)2651 CtxUdExpected.ss = Ctx.ss = BS3_SEL_TEST_PAGE_00 | bRing;2652 else2653 CtxUdExpected.ds = Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;2654 2655 /* Expand up (normal), approaching tail guard page. */2656 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)2657 {2658 CtxUdExpected.rbx.u = Ctx.rbx.u = off;2659 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)2660 {2661 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;2662 Bs3MemSet(&pbTest[X86_PAGE_SIZE - cbIdtr * 2], bFiller1, cbIdtr * 2);2663 if (off < X86_PAGE_SIZE)2664 Bs3MemCpy(&pbTest[off], pbBufRestore, RT_MIN(cbIdtr, X86_PAGE_SIZE - off));2665 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2666 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2667 if (bRing != 0)2668 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2669 else if (off + cbIdtr <= cbLimit + 1)2670 {2671 /* No #GP, but maybe #PF. */2672 if (off + cbIdtr <= X86_PAGE_SIZE)2673 {2674 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2675 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)2676 Bs3TestFailedF("Mismatch (%s, #9): expected %.*Rhxs, got %.*Rhxs\n",2677 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2678 }2679 else2680 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + RT_MAX(off, X86_PAGE_SIZE));2681 }2682 /* No #GP/#SS on limit, but instead #PF? */2683 else if ( !f486Weirdness2684 ? off < cbLimit && off >= 0xfff2685 : off + 2 < cbLimit && off >= 0xffd)2686 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + RT_MAX(off, X86_PAGE_SIZE));2687 /* #GP/#SS on limit or base. */2688 else if (pWorker->fSs)2689 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);2690 else2691 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2692 2693 g_usBs3TestStep++;2694 2695 /* Set DS to 0 and check that we get #GP(0). */2696 if (!pWorker->fSs)2697 {2698 Ctx.ds = 0;2699 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2700 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2701 Ctx.ds = BS3_SEL_TEST_PAGE_00 | bRing;2702 g_usBs3TestStep++;2703 }2704 }2705 }2706 2707 /* Expand down. */2708 pbTest -= X86_PAGE_SIZE; /* Note! we're backing up a page to simplify things */2709 uFlatTest -= X86_PAGE_SIZE;2710 2711 Bs3GdteTestPage00.Gen.u4Type = X86_SEL_TYPE_RW_DOWN_ACC;2712 Bs3GdteTestPage00.Gen.u16BaseLow = (uint16_t)uFlatTest;2713 Bs3GdteTestPage00.Gen.u8BaseHigh1 = (uint8_t)(uFlatTest >> 16);2714 Bs3GdteTestPage00.Gen.u8BaseHigh2 = (uint8_t)(uFlatTest >> 24);2715 2716 for (off = X86_PAGE_SIZE - cbIdtr - 4; off < X86_PAGE_SIZE + 4; off++)2717 {2718 CtxUdExpected.rbx.u = Ctx.rbx.u = off;2719 for (cbLimit = X86_PAGE_SIZE - cbIdtr*2; cbLimit < X86_PAGE_SIZE + cbIdtr*2; cbLimit++)2720 {2721 Bs3GdteTestPage00.Gen.u16LimitLow = cbLimit;2722 Bs3MemSet(&pbTest[X86_PAGE_SIZE], bFiller1, cbIdtr * 2);2723 if (off >= X86_PAGE_SIZE)2724 Bs3MemCpy(&pbTest[off], pbBufRestore, cbIdtr);2725 else if (off > X86_PAGE_SIZE - cbIdtr)2726 Bs3MemCpy(&pbTest[X86_PAGE_SIZE], &pbBufRestore[X86_PAGE_SIZE - off], cbIdtr - (X86_PAGE_SIZE - off));2727 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2728 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2729 if (bRing != 0)2730 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2731 else if (cbLimit < off && off >= X86_PAGE_SIZE)2732 {2733 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2734 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)2735 Bs3TestFailedF("Mismatch (%s, #10): expected %.*Rhxs, got %.*Rhxs\n",2736 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2737 }2738 else if (cbLimit < off && off < X86_PAGE_SIZE)2739 bs3CpuBasic2_ComparePfCtx(&TrapCtx, &Ctx, 0, uFlatTest + off);2740 else if (pWorker->fSs)2741 bs3CpuBasic2_CompareSsCtx(&TrapCtx, &Ctx, 0, false /*f486ResumeFlagHint*/);2742 else2743 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2744 g_usBs3TestStep++;2745 }2746 }2747 2748 pbTest += X86_PAGE_SIZE;2749 uFlatTest += X86_PAGE_SIZE;2750 }2751 2752 Bs3MemGuardedTestPageFree(pbTest);2753 }2754 2755 /*2756 * Check non-canonical 64-bit space.2757 */2758 if ( BS3_MODE_IS_64BIT_CODE(bTestMode)2759 && (pbTest = (uint8_t BS3_FAR *)Bs3PagingSetupCanonicalTraps()) != NULL)2760 {2761 /* Make our references relative to the gap. */2762 pbTest += g_cbBs3PagingOneCanonicalTrap;2763 2764 /* Hit it from below. */2765 for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)2766 {2767 Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0x0000800000000000) + off;2768 Bs3MemSet(&pbTest[-64], bFiller1, 64*2);2769 Bs3MemCpy(&pbTest[off], pbBufRestore, cbIdtr);2770 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2771 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2772 if (off + cbIdtr > 0 || bRing != 0)2773 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2774 else2775 {2776 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2777 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)2778 Bs3TestFailedF("Mismatch (%s, #11): expected %.*Rhxs, got %.*Rhxs\n",2779 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2780 }2781 }2782 2783 /* Hit it from above. */2784 for (off = -cbIdtr - 8; off < cbIdtr + 8; off++)2785 {2786 Ctx.rbx.u = CtxUdExpected.rbx.u = UINT64_C(0xffff800000000000) + off;2787 Bs3MemSet(&pbTest[-64], bFiller1, 64*2);2788 Bs3MemCpy(&pbTest[off], pbBufRestore, cbIdtr);2789 Bs3MemSet(abBufSave, bFiller2, sizeof(abBufSave));2790 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);2791 if (off < 0 || bRing != 0)2792 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0);2793 else2794 {2795 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected);2796 if (Bs3MemCmp(pbBufSave, abExpectedFilled, cbIdtr * 2) != 0)2797 Bs3TestFailedF("Mismatch (%s, #19): expected %.*Rhxs, got %.*Rhxs\n",2798 pWorker->pszDesc, cbIdtr*2, abExpectedFilled, cbIdtr*2, pbBufSave);2799 }2800 }2801 2802 }2803 }2804 2805 2806 # define bs3CpuBasic2_lidt_lgdt_Common BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_Common)2807 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers,2808 void const *pvRestore, size_t cbRestore, uint8_t const *pbExpected)2809 {2810 unsigned idx;2811 unsigned bRing;2812 unsigned iStep = 0;2813 2814 /* Note! We skip the SS checks for ring-0 since we badly mess up SS in the2815 test and don't want to bother with double faults. */2816 for (bRing = BS3_MODE_IS_V86(bTestMode) ? 3 : 0; bRing <= 3; bRing++)2817 {2818 for (idx = 0; idx < cWorkers; idx++)2819 if ( (paWorkers[idx].bMode & (bTestMode & BS3_MODE_CODE_MASK))2820 && (!paWorkers[idx].fSs || bRing != 0 /** @todo || BS3_MODE_IS_64BIT_SYS(bTestMode)*/ )2821 && ( !(paWorkers[idx].fFlags & BS3CB2SIDTSGDT_F_386PLUS)2822 || ( bTestMode > BS3_MODE_PE162823 || ( bTestMode == BS3_MODE_PE162824 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)) ) )2825 {2826 //Bs3TestPrintf("idx=%-2d fpfnWorker=%p fSs=%d cbInstr=%d\n",2827 // idx, paWorkers[idx].fpfnWorker, paWorkers[idx].fSs, paWorkers[idx].cbInstr);2828 g_usBs3TestStep = iStep;2829 bs3CpuBasic2_lidt_lgdt_One(&paWorkers[idx], bTestMode, bRing, pvRestore, cbRestore, pbExpected);2830 iStep += 1000;2831 }2832 if (BS3_MODE_IS_RM_SYS(bTestMode))2833 break;2834 }2835 }2836 2837 2838 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_lidt)(uint8_t bMode)2839 {2840 union2841 {2842 RTIDTR Idtr;2843 uint8_t ab[32]; /* At least cbIdtr*2! */2844 } Expected;2845 2846 g_pszTestMode = Bs3GetModeName(bMode);2847 g_bTestMode = bMode;2848 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bMode);2849 2850 /*2851 * Pass to common worker which is only compiled once per mode.2852 */2853 Bs3MemZero(&Expected, sizeof(Expected));2854 ASMGetIDTR(&Expected.Idtr);2855 2856 if (BS3_MODE_IS_RM_SYS(bMode))2857 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),2858 &Bs3Lidt_Ivt, sizeof(Bs3Lidt_Ivt), Expected.ab);2859 else if (BS3_MODE_IS_16BIT_SYS(bMode))2860 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),2861 &Bs3Lidt_Idt16, sizeof(Bs3Lidt_Idt16), Expected.ab);2862 else if (BS3_MODE_IS_32BIT_SYS(bMode))2863 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),2864 &Bs3Lidt_Idt32, sizeof(Bs3Lidt_Idt32), Expected.ab);2865 else2866 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLidtWorkers, RT_ELEMENTS(g_aLidtWorkers),2867 &Bs3Lidt_Idt64, sizeof(Bs3Lidt_Idt64), Expected.ab);2868 2869 /*2870 * Re-initialize the IDT.2871 */2872 Bs3TrapReInit();2873 return 0;2874 }2875 2876 2877 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_lgdt)(uint8_t bMode)2878 {2879 union2880 {2881 RTGDTR Gdtr;2882 uint8_t ab[32]; /* At least cbIdtr*2! */2883 } Expected;2884 2885 g_pszTestMode = Bs3GetModeName(bMode);2886 g_bTestMode = bMode;2887 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bMode);2888 2889 /*2890 * Pass to common worker which is only compiled once per mode.2891 */2892 if (BS3_MODE_IS_RM_SYS(bMode))2893 ASMSetGDTR((PRTGDTR)&Bs3LgdtDef_Gdt);2894 Bs3MemZero(&Expected, sizeof(Expected));2895 ASMGetGDTR(&Expected.Gdtr);2896 2897 bs3CpuBasic2_lidt_lgdt_Common(bMode, g_aLgdtWorkers, RT_ELEMENTS(g_aLgdtWorkers),2898 &Bs3LgdtDef_Gdt, sizeof(Bs3LgdtDef_Gdt), Expected.ab);2899 2900 /*2901 * Re-initialize the IDT.2902 */2903 Bs3TrapReInit();2904 return 0;2905 }2906 #endif /* TMPL_BITS == 16 */2907 2908 2909 1305 # if ARCH_BITS != 64 2910 1306 … … 3152 1548 } 3153 1549 3154 3155 # if 03156 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sidt)(uint8_t bMode)3157 {3158 BS3_ASSERT(bMode == TMPL_MODE);3159 return BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(bMode);3160 }3161 3162 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sgdt)(uint8_t bMode)3163 {3164 BS3_ASSERT(bMode == TMPL_MODE);3165 return BS3_CMN_FAR_NM(bs3CpuBasic2_sgdt)(bMode);3166 }3167 3168 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lidt)(uint8_t bMode)3169 {3170 BS3_ASSERT(bMode == TMPL_MODE);3171 return BS3_CMN_FAR_NM(bs3CpuBasic2_lidt)(bMode);3172 }3173 3174 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lgdt)(uint8_t bMode)3175 {3176 BS3_ASSERT(bMode == TMPL_MODE);3177 return BS3_CMN_FAR_NM(bs3CpuBasic2_lgdt)(bMode);3178 }3179 # endif3180 3181 1550 #endif /* BS3_INSTANTIATING_MODE */ 3182 1551 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-x0.c
r60749 r60750 1 1 /* $Id$ */ 2 2 /** @file 3 * BS3Kit - bs3-cpu-basic-2, C code template.3 * BS3Kit - bs3-cpu-basic-2, C test driver code (16-bit). 4 4 */ 5 5 … … 29 29 * Header Files * 30 30 *********************************************************************************************************************************/ 31 #define BS3_USE_X0_TEXT_SEG 32 #include <bs3kit.h> 31 33 #include <iprt/asm.h> 32 34 #include <iprt/asm-amd64-x86.h> … … 45 47 46 48 47 #ifdef BS3_INSTANTIATING_CMN48 49 /** Indicating that we've got operand size prefix and that it matters. */ 49 # 50 #define BS3CB2SIDTSGDT_F_OPSIZE UINT8_C(0x01) 50 51 /** Worker requires 386 or later. */ 51 # define BS3CB2SIDTSGDT_F_386PLUS UINT8_C(0x02) 52 #endif 53 54 #ifdef BS3_INSTANTIATING_MODE 55 # undef MyBs3Idt 56 # undef MY_SYS_SEL_R0_CS 57 # undef MY_SYS_SEL_R0_CS_CNF 58 # undef MY_SYS_SEL_R0_DS 59 # undef MY_SYS_SEL_R0_SS 60 # if BS3_MODE_IS_16BIT_SYS(TMPL_MODE) 61 # define MyBs3Idt Bs3Idt16 62 # define MY_SYS_SEL_R0_CS BS3_SEL_R0_CS16 63 # define MY_SYS_SEL_R0_CS_CNF BS3_SEL_R0_CS16_CNF 64 # define MY_SYS_SEL_R0_DS BS3_SEL_R0_DS16 65 # define MY_SYS_SEL_R0_SS BS3_SEL_R0_SS16 66 # elif BS3_MODE_IS_32BIT_SYS(TMPL_MODE) 67 # define MyBs3Idt Bs3Idt32 68 # define MY_SYS_SEL_R0_CS BS3_SEL_R0_CS32 69 # define MY_SYS_SEL_R0_CS_CNF BS3_SEL_R0_CS32_CNF 70 # define MY_SYS_SEL_R0_DS BS3_SEL_R0_DS32 71 # define MY_SYS_SEL_R0_SS BS3_SEL_R0_SS32 72 # elif BS3_MODE_IS_64BIT_SYS(TMPL_MODE) 73 # define MyBs3Idt Bs3Idt64 74 # define MY_SYS_SEL_R0_CS BS3_SEL_R0_CS64 75 # define MY_SYS_SEL_R0_CS_CNF BS3_SEL_R0_CS64_CNF 76 # define MY_SYS_SEL_R0_DS BS3_SEL_R0_DS64 77 # define MY_SYS_SEL_R0_SS BS3_SEL_R0_DS64 78 # else 79 # error "TMPL_MODE" 80 # endif 81 #endif 52 #define BS3CB2SIDTSGDT_F_386PLUS UINT8_C(0x02) 82 53 83 54 … … 85 56 * Structures and Typedefs * 86 57 *********************************************************************************************************************************/ 87 #ifdef BS3_INSTANTIATING_CMN88 58 typedef struct BS3CB2INVLDESCTYPE 89 59 { … … 101 71 uint8_t fFlags; 102 72 } BS3CB2SIDTSGDT; 103 #endif104 73 105 74 … … 107 76 * External Symbols * 108 77 *********************************************************************************************************************************/ 109 #ifdef BS3_INSTANTIATING_CMN110 78 extern FNBS3FAR bs3CpuBasic2_Int80; 111 79 extern FNBS3FAR bs3CpuBasic2_Int81; … … 113 81 extern FNBS3FAR bs3CpuBasic2_Int83; 114 82 extern FNBS3FAR bs3CpuBasic2_ud2; 115 # defineg_bs3CpuBasic2_ud2_FlatAddr BS3_DATA_NM(g_bs3CpuBasic2_ud2_FlatAddr)83 #define g_bs3CpuBasic2_ud2_FlatAddr BS3_DATA_NM(g_bs3CpuBasic2_ud2_FlatAddr) 116 84 extern uint32_t g_bs3CpuBasic2_ud2_FlatAddr; 117 85 … … 169 137 extern FNBS3FAR bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2_c64; 170 138 171 #endif172 139 173 140 … … 175 142 * Global Variables * 176 143 *********************************************************************************************************************************/ 177 #ifdef BS3_INSTANTIATING_CMN 178 # define g_pszTestMode BS3_CMN_NM(g_pszTestMode) 144 #define g_pszTestMode BS3_CMN_NM(g_pszTestMode) 179 145 static const char BS3_FAR *g_pszTestMode = (const char *)1; 180 # defineg_bTestMode BS3_CMN_NM(g_bTestMode)146 #define g_bTestMode BS3_CMN_NM(g_bTestMode) 181 147 static uint8_t g_bTestMode = 1; 182 # defineg_f16BitSys BS3_CMN_NM(g_f16BitSys)148 #define g_f16BitSys BS3_CMN_NM(g_f16BitSys) 183 149 static bool g_f16BitSys = 1; 184 150 … … 187 153 static BS3CB2SIDTSGDT const g_aSidtWorkers[] = 188 154 { 189 { " ",bs3CpuBasic2_sidt_bx_ud2_c16, 3, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },190 { " ",bs3CpuBasic2_sidt_ss_bx_ud2_c16, 4, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },191 { " ",bs3CpuBasic2_sidt_opsize_bx_ud2_c16, 4, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },192 { " ",bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c16, 5, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },193 { " ",bs3CpuBasic2_sidt_bx_ud2_c32, 3, false, BS3_MODE_CODE_32, 0 },194 { " ",bs3CpuBasic2_sidt_ss_bx_ud2_c32, 4, true, BS3_MODE_CODE_32, 0 },195 { " ",bs3CpuBasic2_sidt_opsize_bx_ud2_c32, 4, false, BS3_MODE_CODE_32, 0 },196 { " ",bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c32, 5, true, BS3_MODE_CODE_32, 0 },197 { " ",bs3CpuBasic2_sidt_bx_ud2_c64, 3, false, BS3_MODE_CODE_64, 0 },198 { " ",bs3CpuBasic2_sidt_rexw_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 },199 { " ",bs3CpuBasic2_sidt_opsize_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 },200 { " ",bs3CpuBasic2_sidt_opsize_rexw_bx_ud2_c64, 5, false, BS3_MODE_CODE_64, 0 },155 { "sidt [bx]", bs3CpuBasic2_sidt_bx_ud2_c16, 3, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 }, 156 { "sidt [ss:bx]", bs3CpuBasic2_sidt_ss_bx_ud2_c16, 4, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 }, 157 { "o32 sidt [bx]", bs3CpuBasic2_sidt_opsize_bx_ud2_c16, 4, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS }, 158 { "o32 sidt [ss:bx]", bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c16, 5, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS }, 159 { "sidt [ebx]", bs3CpuBasic2_sidt_bx_ud2_c32, 3, false, BS3_MODE_CODE_32, 0 }, 160 { "sidt [ss:ebx]", bs3CpuBasic2_sidt_ss_bx_ud2_c32, 4, true, BS3_MODE_CODE_32, 0 }, 161 { "o16 sidt [ebx]", bs3CpuBasic2_sidt_opsize_bx_ud2_c32, 4, false, BS3_MODE_CODE_32, 0 }, 162 { "o16 sidt [ss:ebx]", bs3CpuBasic2_sidt_opsize_ss_bx_ud2_c32, 5, true, BS3_MODE_CODE_32, 0 }, 163 { "sidt [rbx]", bs3CpuBasic2_sidt_bx_ud2_c64, 3, false, BS3_MODE_CODE_64, 0 }, 164 { "o64 sidt [rbx]", bs3CpuBasic2_sidt_rexw_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 }, 165 { "o32 sidt [rbx]", bs3CpuBasic2_sidt_opsize_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 }, 166 { "o32 o64 sidt [rbx]", bs3CpuBasic2_sidt_opsize_rexw_bx_ud2_c64, 5, false, BS3_MODE_CODE_64, 0 }, 201 167 }; 202 168 … … 204 170 static BS3CB2SIDTSGDT const g_aSgdtWorkers[] = 205 171 { 206 { " ",bs3CpuBasic2_sgdt_bx_ud2_c16, 3, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },207 { " ",bs3CpuBasic2_sgdt_ss_bx_ud2_c16, 4, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 },208 { " ",bs3CpuBasic2_sgdt_opsize_bx_ud2_c16, 4, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },209 { " ",bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c16, 5, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS },210 { " ",bs3CpuBasic2_sgdt_bx_ud2_c32, 3, false, BS3_MODE_CODE_32, 0 },211 { " ",bs3CpuBasic2_sgdt_ss_bx_ud2_c32, 4, true, BS3_MODE_CODE_32, 0 },212 { " ",bs3CpuBasic2_sgdt_opsize_bx_ud2_c32, 4, false, BS3_MODE_CODE_32, 0 },213 { " ",bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32, 5, true, BS3_MODE_CODE_32, 0 },214 { " ",bs3CpuBasic2_sgdt_bx_ud2_c64, 3, false, BS3_MODE_CODE_64, 0 },215 { " ",bs3CpuBasic2_sgdt_rexw_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 },216 { " ",bs3CpuBasic2_sgdt_opsize_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 },217 { " ",bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64, 5, false, BS3_MODE_CODE_64, 0 },172 { "sgdt [bx]", bs3CpuBasic2_sgdt_bx_ud2_c16, 3, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 }, 173 { "sgdt [ss:bx]", bs3CpuBasic2_sgdt_ss_bx_ud2_c16, 4, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, 0 }, 174 { "o32 sgdt [bx]", bs3CpuBasic2_sgdt_opsize_bx_ud2_c16, 4, false, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS }, 175 { "o32 sgdt [ss:bx]", bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c16, 5, true, BS3_MODE_CODE_16 | BS3_MODE_CODE_V86, BS3CB2SIDTSGDT_F_386PLUS }, 176 { "sgdt [ebx]", bs3CpuBasic2_sgdt_bx_ud2_c32, 3, false, BS3_MODE_CODE_32, 0 }, 177 { "sgdt [ss:ebx]", bs3CpuBasic2_sgdt_ss_bx_ud2_c32, 4, true, BS3_MODE_CODE_32, 0 }, 178 { "o16 sgdt [ebx]", bs3CpuBasic2_sgdt_opsize_bx_ud2_c32, 4, false, BS3_MODE_CODE_32, 0 }, 179 { "o16 sgdt [ss:ebx]", bs3CpuBasic2_sgdt_opsize_ss_bx_ud2_c32, 5, true, BS3_MODE_CODE_32, 0 }, 180 { "sgdt [rbx]", bs3CpuBasic2_sgdt_bx_ud2_c64, 3, false, BS3_MODE_CODE_64, 0 }, 181 { "o64 sgdt [rbx]", bs3CpuBasic2_sgdt_rexw_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 }, 182 { "o32 sgdt [rbx]", bs3CpuBasic2_sgdt_opsize_bx_ud2_c64, 4, false, BS3_MODE_CODE_64, 0 }, 183 { "o32 o64 sgdt [rbx]", bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2_c64, 5, false, BS3_MODE_CODE_64, 0 }, 218 184 }; 219 185 … … 255 221 256 222 223 #if 0 257 224 /** Table containing invalid CS selector types. */ 258 225 static const BS3CB2INVLDESCTYPE g_aInvalidCsTypes[] = … … 312 279 { 15, 0 }, 313 280 }; 314 315 #endif /* BS3_INSTANTIATING_CMN - global */ 316 317 #ifdef BS3_INSTANTIATING_CMN 281 #endif 282 283 318 284 319 285 /** … … 321 287 * and g_pszTestMode. 322 288 */ 323 # define bs3CpuBasic2_FailedF BS3_CMN_NM(bs3CpuBasic2_FailedF) 324 BS3_DECL_NEAR(void) bs3CpuBasic2_FailedF(const char *pszFormat, ...) 289 static void bs3CpuBasic2_FailedF(const char *pszFormat, ...) 325 290 { 326 291 va_list va; … … 335 300 336 301 302 #if 0 337 303 /** 338 304 * Compares trap stuff. 339 305 */ 340 # define bs3CpuBasic2_CompareIntCtx1 BS3_CMN_NM(bs3CpuBasic2_CompareIntCtx1) 341 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareIntCtx1(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint8_t bXcpt) 306 static void bs3CpuBasic2_CompareIntCtx1(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint8_t bXcpt) 342 307 { 343 308 uint16_t const cErrorsBefore = Bs3TestSubErrorCount(); … … 355 320 } 356 321 } 357 358 322 #endif 323 324 325 #if 0 359 326 /** 360 327 * Compares trap stuff. 361 328 */ 362 # define bs3CpuBasic2_CompareTrapCtx2 BS3_CMN_NM(bs3CpuBasic2_CompareTrapCtx2) 363 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareTrapCtx2(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t cbIpAdjust, 364 uint8_t bXcpt, uint16_t uHandlerCs) 329 static void bs3CpuBasic2_CompareTrapCtx2(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t cbIpAdjust, 330 uint8_t bXcpt, uint16_t uHandlerCs) 365 331 { 366 332 uint16_t const cErrorsBefore = Bs3TestSubErrorCount(); … … 379 345 } 380 346 } 347 #endif 381 348 382 349 /** 383 350 * Compares a CPU trap. 384 351 */ 385 # define bs3CpuBasic2_CompareCpuTrapCtx BS3_CMN_NM(bs3CpuBasic2_CompareCpuTrapCtx) 386 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareCpuTrapCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd, 387 uint8_t bXcpt, bool f486ResumeFlagHint) 352 static void bs3CpuBasic2_CompareCpuTrapCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd, 353 uint8_t bXcpt, bool f486ResumeFlagHint) 388 354 { 389 355 uint16_t const cErrorsBefore = Bs3TestSubErrorCount(); … … 419 385 * Compares \#GP trap. 420 386 */ 421 # define bs3CpuBasic2_CompareGpCtx BS3_CMN_NM(bs3CpuBasic2_CompareGpCtx) 422 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareGpCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd) 387 static void bs3CpuBasic2_CompareGpCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd) 423 388 { 424 389 bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, uErrCd, X86_XCPT_GP, true /*f486ResumeFlagHint*/); 425 390 } 426 391 392 #if 0 427 393 /** 428 394 * Compares \#NP trap. 429 395 */ 430 # define bs3CpuBasic2_CompareNpCtx BS3_CMN_NM(bs3CpuBasic2_CompareNpCtx) 431 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareNpCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd) 396 static void bs3CpuBasic2_CompareNpCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd) 432 397 { 433 398 bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, uErrCd, X86_XCPT_NP, true /*f486ResumeFlagHint*/); 434 399 } 400 #endif 435 401 436 402 /** 437 403 * Compares \#SS trap. 438 404 */ 439 # define bs3CpuBasic2_CompareSsCtx BS3_CMN_NM(bs3CpuBasic2_CompareSsCtx) 440 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareSsCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd, bool f486ResumeFlagHint) 405 static void bs3CpuBasic2_CompareSsCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd, bool f486ResumeFlagHint) 441 406 { 442 407 bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, uErrCd, X86_XCPT_SS, f486ResumeFlagHint); 443 408 } 444 409 410 #if 0 445 411 /** 446 412 * Compares \#TS trap. 447 413 */ 448 # define bs3CpuBasic2_CompareTsCtx BS3_CMN_NM(bs3CpuBasic2_CompareTsCtx) 449 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareTsCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd) 414 static void bs3CpuBasic2_CompareTsCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint16_t uErrCd) 450 415 { 451 416 bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, uErrCd, X86_XCPT_TS, false /*f486ResumeFlagHint*/); 452 417 } 418 #endif 453 419 454 420 /** 455 421 * Compares \#PF trap. 456 422 */ 457 # define bs3CpuBasic2_ComparePfCtx BS3_CMN_NM(bs3CpuBasic2_ComparePfCtx) 458 BS3_DECL_NEAR(void) bs3CpuBasic2_ComparePfCtx(PCBS3TRAPFRAME pTrapCtx, PBS3REGCTX pStartCtx, uint16_t uErrCd, uint64_t uCr2Expected) 423 static void bs3CpuBasic2_ComparePfCtx(PCBS3TRAPFRAME pTrapCtx, PBS3REGCTX pStartCtx, uint16_t uErrCd, uint64_t uCr2Expected) 459 424 { 460 425 uint64_t const uCr2Saved = pStartCtx->cr2.u; … … 467 432 * Compares \#UD trap. 468 433 */ 469 # define bs3CpuBasic2_CompareUdCtx BS3_CMN_NM(bs3CpuBasic2_CompareUdCtx) 470 BS3_DECL_NEAR(void) bs3CpuBasic2_CompareUdCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx) 434 static void bs3CpuBasic2_CompareUdCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx) 471 435 { 472 436 bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, 0 /*no error code*/, X86_XCPT_UD, true /*f486ResumeFlagHint*/); … … 474 438 475 439 476 # define bs3CpuBasic2_RaiseXcpt1Common BS3_CMN_NM(bs3CpuBasic2_RaiseXcpt1Common)477 BS3_DECL_NEAR(void)bs3CpuBasic2_RaiseXcpt1Common(uint16_t const uSysR0Cs, uint16_t const uSysR0CsConf, uint16_t const uSysR0Ss,478 440 #if 0 /* convert me */ 441 static void bs3CpuBasic2_RaiseXcpt1Common(uint16_t const uSysR0Cs, uint16_t const uSysR0CsConf, uint16_t const uSysR0Ss, 442 PX86DESC const paIdt, unsigned const cIdteShift) 479 443 { 480 444 BS3TRAPFRAME TrapCtx; … … 1444 1408 # endif 1445 1409 } 1446 1447 #if TMPL_BITS == 16 1410 #endif /* convert me */ 1411 1448 1412 1449 1413 /** … … 1453 1417 * mind, i.e. not assuming the test bitcount is the same as the current. 1454 1418 */ 1455 # define bs3CpuBasic2_sidt_sgdt_One BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_One) 1456 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing, 1457 uint8_t const *pbExpected) 1419 static void bs3CpuBasic2_sidt_sgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing, 1420 uint8_t const *pbExpected) 1458 1421 { 1459 1422 BS3TRAPFRAME TrapCtx; … … 1509 1472 Bs3TestFailedF("Unexpected buffer bytes set (#1): cbIdtr=%u abBuf=%.*Rhxs\n", cbIdtr, cbBuf, pbBuf); 1510 1473 if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0) 1511 Bs3TestFailedF("Mismatch ( #1): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);1474 Bs3TestFailedF("Mismatch (%s,#1): expected %.*Rhxs, got %.*Rhxs\n", pWorker->pszDesc, cbIdtr, pbExpected, cbIdtr, abBuf); 1512 1475 g_usBs3TestStep++; 1513 1476 … … 1529 1492 Bs3TestFailedF("Not all bytes touched: cbIdtr=%u bFiller=%#x abBuf=%.*Rhxs\n", cbIdtr, bFiller, cbBuf, pbBuf); 1530 1493 if (Bs3MemCmp(abBuf, pbExpected, cbIdtr) != 0) 1531 Bs3TestFailedF("Mismatch ( #2): expected %.*Rhxs, got %.*Rhxs\n", cbIdtr, pbExpected, cbIdtr, abBuf);1494 Bs3TestFailedF("Mismatch (%s,#2): expected %.*Rhxs, got %.*Rhxs\n", pWorker->pszDesc, cbIdtr, pbExpected, cbIdtr, abBuf); 1532 1495 g_usBs3TestStep++; 1533 1496 … … 2022 1985 2023 1986 2024 # define bs3CpuBasic2_sidt_sgdt_Common BS3_CMN_NM(bs3CpuBasic2_sidt_sgdt_Common) 2025 BS3_DECL_NEAR(void) bs3CpuBasic2_sidt_sgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers, 2026 uint8_t const *pbExpected) 1987 static void bs3CpuBasic2_sidt_sgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers, 1988 uint8_t const *pbExpected) 2027 1989 { 2028 1990 unsigned idx; … … 2046 2008 } 2047 2009 } 2010 2048 2011 2049 2012 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(uint8_t bMode) … … 2092 2055 * If paged mode, try push the GDT way up. 2093 2056 */ 2057 Bs3MemZero(&Expected, sizeof(Expected)); 2058 ASMGetGDTR(&Expected.Gdtr); 2094 2059 if (BS3_MODE_IS_PAGED(bMode)) 2095 2060 { … … 2103 2068 Bs3Lgdt_Gdt.uAddr = uNew; 2104 2069 Bs3UtilSetFullGdtr(Bs3Lgdt_Gdt.cb, uNew); 2070 ASMGetGDTR(&Expected.Gdtr); 2071 if (BS3_MODE_IS_64BIT_SYS(bMode) && ARCH_BITS != 64) 2072 *(uint32_t *)&Expected.ab[6] = (uint32_t)(uNew >> 32); 2105 2073 } 2106 2074 } … … 2109 2077 * Pass to common worker which is only compiled once per mode. 2110 2078 */ 2111 Bs3MemZero(&Expected, sizeof(Expected));2112 ASMGetGDTR(&Expected.Gdtr);2113 2079 bs3CpuBasic2_sidt_sgdt_Common(bMode, g_aSgdtWorkers, RT_ELEMENTS(g_aSgdtWorkers), Expected.ab); 2114 2080 … … 2142 2108 * mind, i.e. not assuming the test bitcount is the same as the current. 2143 2109 */ 2144 # define bs3CpuBasic2_lidt_lgdt_One BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_One) 2145 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing, 2146 uint8_t const *pbRestore, size_t cbRestore, uint8_t const *pbExpected) 2110 static void bs3CpuBasic2_lidt_lgdt_One(BS3CB2SIDTSGDT const BS3_FAR *pWorker, uint8_t bTestMode, uint8_t bRing, 2111 uint8_t const *pbRestore, size_t cbRestore, uint8_t const *pbExpected) 2147 2112 { 2148 2113 static const struct … … 2804 2769 2805 2770 2806 # define bs3CpuBasic2_lidt_lgdt_Common BS3_CMN_NM(bs3CpuBasic2_lidt_lgdt_Common) 2807 BS3_DECL_NEAR(void) bs3CpuBasic2_lidt_lgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers, 2808 void const *pvRestore, size_t cbRestore, uint8_t const *pbExpected) 2771 static void bs3CpuBasic2_lidt_lgdt_Common(uint8_t bTestMode, BS3CB2SIDTSGDT const BS3_FAR *paWorkers, unsigned cWorkers, 2772 void const *pvRestore, size_t cbRestore, uint8_t const *pbExpected) 2809 2773 { 2810 2774 unsigned idx; … … 2904 2868 return 0; 2905 2869 } 2906 #endif /* TMPL_BITS == 16 */ 2907 2908 2909 # if ARCH_BITS != 64 2910 2911 /** 2912 * Worker for bs3CpuBasic2_TssGateEsp that tests the INT 80 from outer rings. 2913 */ 2914 # define bs3CpuBasic2_TssGateEsp_AltStackOuterRing BS3_CMN_NM(bs3CpuBasic2_TssGateEsp_AltStackOuterRing) 2915 BS3_DECL_NEAR(void) bs3CpuBasic2_TssGateEsp_AltStackOuterRing(PCBS3REGCTX pCtx, uint8_t bRing, uint8_t *pbAltStack, 2916 size_t cbAltStack, bool f16BitStack, bool f16BitTss, 2917 bool f16BitHandler, unsigned uLine) 2918 { 2919 uint8_t const cbIretFrame = f16BitHandler ? 5*2 : 5*4; 2920 BS3REGCTX Ctx2; 2921 BS3TRAPFRAME TrapCtx; 2922 uint8_t *pbTmp; 2923 g_usBs3TestStep = uLine; 2924 2925 Bs3MemCpy(&Ctx2, pCtx, sizeof(Ctx2)); 2926 Bs3RegCtxConvertToRingX(&Ctx2, bRing); 2927 2928 if (pbAltStack) 2929 { 2930 Ctx2.rsp.u = Bs3SelPtrToFlat(pbAltStack + 0x1980); 2931 Bs3MemZero(pbAltStack, cbAltStack); 2932 } 2933 2934 Bs3TrapSetJmpAndRestore(&Ctx2, &TrapCtx); 2935 2936 if (!f16BitStack && f16BitTss) 2937 Ctx2.rsp.u &= UINT16_MAX; 2938 2939 bs3CpuBasic2_CompareIntCtx1(&TrapCtx, &Ctx2, 0x80 /*bXcpt*/); 2940 CHECK_MEMBER("bCpl", "%u", TrapCtx.Ctx.bCpl, bRing); 2941 CHECK_MEMBER("cbIretFrame", "%#x", TrapCtx.cbIretFrame, cbIretFrame); 2942 2943 if (pbAltStack) 2944 { 2945 uint64_t uExpectedRsp = (f16BitTss ? Bs3Tss16.sp0 : Bs3Tss32.esp0) - cbIretFrame; 2946 if (f16BitStack) 2947 { 2948 uExpectedRsp &= UINT16_MAX; 2949 uExpectedRsp |= Ctx2.rsp.u & ~(uint64_t)UINT16_MAX; 2950 } 2951 if ( TrapCtx.uHandlerRsp != uExpectedRsp 2952 || TrapCtx.uHandlerSs != (f16BitTss ? Bs3Tss16.ss0 : Bs3Tss32.ss0)) 2953 bs3CpuBasic2_FailedF("handler SS:ESP=%04x:%08RX64, expected %04x:%08RX16", 2954 TrapCtx.uHandlerSs, TrapCtx.uHandlerRsp, Bs3Tss16.ss0, uExpectedRsp); 2955 2956 pbTmp = (uint8_t *)ASMMemFirstNonZero(pbAltStack, cbAltStack); 2957 if ((f16BitStack || TrapCtx.uHandlerRsp <= UINT16_MAX) && pbTmp != NULL) 2958 bs3CpuBasic2_FailedF("someone touched the alt stack (%p) with SS:ESP=%04x:%#RX32: %p=%02x", 2959 pbAltStack, Ctx2.ss, Ctx2.rsp.u32, pbTmp, *pbTmp); 2960 else if (!f16BitStack && TrapCtx.uHandlerRsp > UINT16_MAX && pbTmp == NULL) 2961 bs3CpuBasic2_FailedF("the alt stack (%p) was not used SS:ESP=%04x:%#RX32\n", pbAltStack, Ctx2.ss, Ctx2.rsp.u32); 2962 } 2963 } 2964 2965 # define bs3CpuBasic2_TssGateEspCommon BS3_CMN_NM(bs3CpuBasic2_TssGateEspCommon) 2966 BS3_DECL_NEAR(void) bs3CpuBasic2_TssGateEspCommon(bool const g_f16BitSys, PX86DESC const paIdt, unsigned const cIdteShift) 2967 { 2968 BS3TRAPFRAME TrapCtx; 2969 BS3REGCTX Ctx; 2970 BS3REGCTX Ctx2; 2971 # if TMPL_BITS == 16 2972 uint8_t *pbTmp; 2973 # endif 2974 2975 /* make sure they're allocated */ 2976 Bs3MemZero(&Ctx, sizeof(Ctx)); 2977 Bs3MemZero(&Ctx2, sizeof(Ctx2)); 2978 Bs3MemZero(&TrapCtx, sizeof(TrapCtx)); 2979 2980 Bs3RegCtxSave(&Ctx); 2981 Ctx.rsp.u -= 0x80; 2982 Ctx.rip.u = (uintptr_t)BS3_FP_OFF(&bs3CpuBasic2_Int80); 2983 # if TMPL_BITS == 32 2984 g_uBs3TrapEipHint = Ctx.rip.u32; 2985 # endif 2986 2987 /* 2988 * We'll be using IDT entry 80 and 81 here. The first one will be 2989 * accessible from all DPLs, the latter not. So, start with setting 2990 * the DPLs. 2991 */ 2992 paIdt[0x80 << cIdteShift].Gate.u2Dpl = 3; 2993 paIdt[0x81 << cIdteShift].Gate.u2Dpl = 0; 2994 2995 /* 2996 * Check that the basic stuff works first. 2997 */ 2998 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 2999 g_usBs3TestStep = __LINE__; 3000 bs3CpuBasic2_CompareIntCtx1(&TrapCtx, &Ctx, 0x80 /*bXcpt*/); 3001 3002 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 1, NULL, 0, g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__); 3003 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 2, NULL, 0, g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__); 3004 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 3, NULL, 0, g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__); 3005 3006 /* 3007 * Check that the upper part of ESP is preserved when doing . 3008 */ 3009 if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 3010 { 3011 size_t const cbAltStack = _8K; 3012 uint8_t *pbAltStack = Bs3MemAllocZ(BS3MEMKIND_TILED, cbAltStack); 3013 if (pbAltStack) 3014 { 3015 /* same ring */ 3016 g_usBs3TestStep = __LINE__; 3017 Bs3MemCpy(&Ctx2, &Ctx, sizeof(Ctx2)); 3018 Ctx2.rsp.u = Bs3SelPtrToFlat(pbAltStack + 0x1980); 3019 if (Bs3TrapSetJmp(&TrapCtx)) 3020 Bs3RegCtxRestore(&Ctx2, 0); /* (does not return) */ 3021 bs3CpuBasic2_CompareIntCtx1(&TrapCtx, &Ctx2, 0x80 /*bXcpt*/); 3022 # if TMPL_BITS == 16 3023 if ((pbTmp = (uint8_t *)ASMMemFirstNonZero(pbAltStack, cbAltStack)) != NULL) 3024 bs3CpuBasic2_FailedF("someone touched the alt stack (%p) with SS:ESP=%04x:%#RX32: %p=%02x\n", 3025 pbAltStack, Ctx2.ss, Ctx2.rsp.u32, pbTmp, *pbTmp); 3026 # else 3027 if (ASMMemIsZero(pbAltStack, cbAltStack)) 3028 bs3CpuBasic2_FailedF("alt stack wasn't used despite SS:ESP=%04x:%#RX32\n", Ctx2.ss, Ctx2.rsp.u32); 3029 # endif 3030 3031 /* Different rings (load SS0:SP0 from TSS). */ 3032 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 1, pbAltStack, cbAltStack, 3033 g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__); 3034 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 2, pbAltStack, cbAltStack, 3035 g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__); 3036 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 3, pbAltStack, cbAltStack, 3037 g_f16BitSys, g_f16BitSys, g_f16BitSys, __LINE__); 3038 3039 /* Different rings but switch the SS bitness in the TSS. */ 3040 if (g_f16BitSys) 3041 { 3042 Bs3Tss16.ss0 = BS3_SEL_R0_SS32; 3043 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 1, pbAltStack, cbAltStack, 3044 false, g_f16BitSys, g_f16BitSys, __LINE__); 3045 Bs3Tss16.ss0 = BS3_SEL_R0_SS16; 3046 } 3047 else 3048 { 3049 Bs3Tss32.ss0 = BS3_SEL_R0_SS16; 3050 bs3CpuBasic2_TssGateEsp_AltStackOuterRing(&Ctx, 1, pbAltStack, cbAltStack, 3051 true, g_f16BitSys, g_f16BitSys, __LINE__); 3052 Bs3Tss32.ss0 = BS3_SEL_R0_SS32; 3053 } 3054 3055 Bs3MemFree(pbAltStack, cbAltStack); 3056 } 3057 else 3058 Bs3TestPrintf("%s: Skipping ESP check, alloc failed\n", g_pszTestMode); 3059 } 3060 else 3061 Bs3TestPrintf("%s: Skipping ESP check, CPU too old\n", g_pszTestMode); 3062 } 3063 3064 # endif /* ARCH_BITS != 64 */ 3065 #endif /* BS3_INSTANTIATING_CMN */ 3066 3067 3068 /* 3069 * Mode specific code. 3070 * Mode specific code. 3071 * Mode specific code. 3072 */ 3073 #ifdef BS3_INSTANTIATING_MODE 3074 3075 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_TssGateEsp)(uint8_t bMode) 3076 { 3077 uint8_t bRet = 0; 3078 3079 g_pszTestMode = TMPL_NM(g_szBs3ModeName); 3080 g_bTestMode = bMode; 3081 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(TMPL_MODE); 3082 3083 # if TMPL_MODE == BS3_MODE_PE16 \ 3084 || TMPL_MODE == BS3_MODE_PE16_32 \ 3085 || TMPL_MODE == BS3_MODE_PP16 \ 3086 || TMPL_MODE == BS3_MODE_PP16_32 \ 3087 || TMPL_MODE == BS3_MODE_PAE16 \ 3088 || TMPL_MODE == BS3_MODE_PAE16_32 \ 3089 || TMPL_MODE == BS3_MODE_PE32 3090 bs3CpuBasic2_TssGateEspCommon(BS3_MODE_IS_16BIT_SYS(TMPL_MODE), 3091 (PX86DESC)MyBs3Idt, 3092 BS3_MODE_IS_64BIT_SYS(TMPL_MODE) ? 1 : 0); 3093 # else 3094 bRet = BS3TESTDOMODE_SKIPPED; 3095 # endif 3096 3097 /* 3098 * Re-initialize the IDT. 3099 */ 3100 Bs3TrapInit(); 3101 return bRet; 3102 } 3103 3104 3105 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_RaiseXcpt1)(uint8_t bMode) 3106 { 3107 g_pszTestMode = TMPL_NM(g_szBs3ModeName); 3108 g_bTestMode = bMode; 3109 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(TMPL_MODE); 3110 3111 # if !BS3_MODE_IS_RM_OR_V86(TMPL_MODE) 3112 3113 /* 3114 * Pass to common worker which is only compiled once per mode. 3115 */ 3116 bs3CpuBasic2_RaiseXcpt1Common(MY_SYS_SEL_R0_CS, 3117 MY_SYS_SEL_R0_CS_CNF, 3118 MY_SYS_SEL_R0_SS, 3119 (PX86DESC)MyBs3Idt, 3120 BS3_MODE_IS_64BIT_SYS(TMPL_MODE) ? 1 : 0); 3121 3122 /* 3123 * Re-initialize the IDT. 3124 */ 3125 Bs3TrapInit(); 3126 return 0; 3127 # elif TMPL_MODE == BS3_MODE_RM 3128 3129 /* 3130 * Check 3131 */ 3132 /** @todo check */ 3133 return BS3TESTDOMODE_SKIPPED; 3134 3135 # else 3136 return BS3TESTDOMODE_SKIPPED; 3137 # endif 3138 } 3139 3140 3141 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_iret)(uint8_t bMode) 3142 { 3143 g_pszTestMode = TMPL_NM(g_szBs3ModeName); 3144 g_bTestMode = bMode; 3145 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(TMPL_MODE); 3146 3147 Bs3PrintStrN(RT_STR_TUPLE("Hello world!\n")); 3148 # if !BS3_MODE_IS_V86(TMPL_MODE) 3149 Bs3TestPrintf(RT_STR_TUPLE("Hi there!\n")); 3150 # endif 3151 return BS3TESTDOMODE_SKIPPED; 3152 } 3153 3154 3155 # if 0 3156 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sidt)(uint8_t bMode) 3157 { 3158 BS3_ASSERT(bMode == TMPL_MODE); 3159 return BS3_CMN_FAR_NM(bs3CpuBasic2_sidt)(bMode); 3160 } 3161 3162 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_sgdt)(uint8_t bMode) 3163 { 3164 BS3_ASSERT(bMode == TMPL_MODE); 3165 return BS3_CMN_FAR_NM(bs3CpuBasic2_sgdt)(bMode); 3166 } 3167 3168 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lidt)(uint8_t bMode) 3169 { 3170 BS3_ASSERT(bMode == TMPL_MODE); 3171 return BS3_CMN_FAR_NM(bs3CpuBasic2_lidt)(bMode); 3172 } 3173 3174 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_lgdt)(uint8_t bMode) 3175 { 3176 BS3_ASSERT(bMode == TMPL_MODE); 3177 return BS3_CMN_FAR_NM(bs3CpuBasic2_lgdt)(bMode); 3178 } 3179 # endif 3180 3181 #endif /* BS3_INSTANTIATING_MODE */ 3182 2870 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c
r60749 r60750 38 38 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_TssGateEsp); 39 39 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_RaiseXcpt1); 40 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_iret);41 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sidt);42 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_sgdt);43 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lidt);44 BS3TESTMODE_PROTOTYPES_MODE(bs3CpuBasic2_lgdt);45 40 46 41 FNBS3TESTDOMODE bs3CpuBasic2_sidt_f16; … … 54 49 * Global Variables * 55 50 *********************************************************************************************************************************/ 56 #if 057 51 static const BS3TESTMODEENTRY g_aModeTest[] = 58 52 { 59 #if 0 60 BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp), 53 //BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp), 61 54 BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1), 62 // BS3TESTMODEENTRY_MODE("sidt", bs3CpuBasic2_sidt),63 // BS3TESTMODEENTRY_MODE("sgdt", bs3CpuBasic2_sgdt),64 // BS3TESTMODEENTRY_MODE("lidt", bs3CpuBasic2_lidt),65 // BS3TESTMODEENTRY_MODE("lgdt", bs3CpuBasic2_lgdt),66 #endif67 // BS3TESTMODEENTRY_MODE("iret", bs3CpuBasic2_iret),68 55 }; 69 #endif70 56 71 57 static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] = 72 58 { 73 59 //{ "iret", bs3CpuBasic2_iret_f16, 0 }, 60 { "sidt", bs3CpuBasic2_sidt_f16, 0 }, 61 { "sgdt", bs3CpuBasic2_sgdt_f16, 0 }, 62 { "lidt", bs3CpuBasic2_lidt_f16, 0 }, 74 63 { "lgdt", bs3CpuBasic2_lgdt_f16, 0 }, 75 64 }; … … 82 71 Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected); 83 72 84 //Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest));73 Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest)); 85 74 Bs3TestDoModesByOne_rm(g_aModeByOneTests, RT_ELEMENTS(g_aModeByOneTests), 0); 86 75 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-TestDoModesByOneHlp.asm
r60749 r60750 141 141 142 142 .return: 143 hlt144 143 ; Switch back to 64-bit mode. 145 144 extern _Bs3SwitchTo64Bit_c16
Note:
See TracChangeset
for help on using the changeset viewer.