Changeset 64776 in vbox for trunk/src/VBox/ValidationKit/bootsectors
- Timestamp:
- Dec 2, 2016 12:30:33 PM (8 years ago)
- Location:
- trunk/src/VBox/ValidationKit/bootsectors
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-pf.c32
r64752 r64776 30 30 *********************************************************************************************************************************/ 31 31 #include <bs3kit.h> 32 #include <iprt/asm-amd64-x86.h> 33 34 35 /********************************************************************************************************************************* 36 * Defined Constants And Macros * 37 *********************************************************************************************************************************/ 38 #define CHECK_MEMBER(a_pszMode, a_szName, a_szFmt, a_Actual, a_Expected) \ 39 do { \ 40 if ((a_Actual) == (a_Expected)) { /* likely */ } \ 41 else Bs3TestFailedF("%u - %s: " a_szName "=" a_szFmt " expected " a_szFmt, \ 42 g_usBs3TestStep, (a_pszMode), (a_Actual), (a_Expected)); \ 43 } while (0) 32 44 33 45 … … 43 55 uint8_t cbTmpl; 44 56 } FNBS3CPUBASIC2PFTSTCODE; 57 typedef FNBS3CPUBASIC2PFTSTCODE const *PCFNBS3CPUBASIC2PFTSTCODE; 45 58 46 59 typedef struct BS3CPUBASIC2PFTTSTCMNMODE 47 60 { 48 61 uint8_t bMode; 49 FNBS3CPUBASIC2PFTSTCODE ExecTmpl;50 62 FNBS3CPUBASIC2PFTSTCODE MovLoad; 51 63 FNBS3CPUBASIC2PFTSTCODE MovStore; … … 60 72 /** The mode we're currently testing. */ 61 73 uint8_t bMode; 74 /** The size of a natural access. */ 75 uint8_t cbAccess; 62 76 /** The common mode functions. */ 63 77 PCBS3CPUBASIC2PFTTSTCMNMODE pCmnMode; … … 80 94 /** Trap context frame. */ 81 95 BS3TRAPFRAME TrapCtx; 96 /** Expected result context. */ 97 BS3REGCTX ExpectCtx; 82 98 83 99 } BS3CPUBASIC2PFSTATE; … … 98 114 99 115 /* bs3-cpu-basic-2-template.mac: */ 100 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_RaisePF_ExecTmpl_c16;101 116 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ax_ds_bx__ud2_c16; 102 117 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ds_bx_ax__ud2_c16; … … 104 119 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c16; 105 120 106 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_RaisePF_ExecTmpl_c32;107 121 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ax_ds_bx__ud2_c32; 108 122 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ds_bx_ax__ud2_c32; … … 110 124 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2_c32; 111 125 112 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_RaisePF_ExecTmpl_c64;113 126 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ax_ds_bx__ud2_c64; 114 127 FNBS3CPUBASIC2PFSNIPPET bs3CpuBasic2_mov_ds_bx_ax__ud2_c64; … … 137 150 { 138 151 BS3_MODE_CODE_16, 139 { bs3CpuBasic2_RaisePF_ExecTmpl_c16, 0, 3 },140 152 { bs3CpuBasic2_mov_ax_ds_bx__ud2_c16, 2 }, 141 153 { bs3CpuBasic2_mov_ds_bx_ax__ud2_c16, 2 }, … … 145 157 { 146 158 BS3_MODE_CODE_32, 147 { bs3CpuBasic2_RaisePF_ExecTmpl_c32, 0, 3 },148 159 { bs3CpuBasic2_mov_ax_ds_bx__ud2_c32, 2 }, 149 160 { bs3CpuBasic2_mov_ds_bx_ax__ud2_c32, 2 }, … … 153 164 { 154 165 BS3_MODE_CODE_64, 155 { bs3CpuBasic2_RaisePF_ExecTmpl_c64, 0, 3 },156 166 { bs3CpuBasic2_mov_ax_ds_bx__ud2_c64, 2 + 1 }, 157 167 { bs3CpuBasic2_mov_ds_bx_ax__ud2_c64, 2 + 1 }, … … 161 171 { 162 172 BS3_MODE_CODE_V86, 163 { bs3CpuBasic2_RaisePF_ExecTmpl_c16, 0, 3 },164 173 { bs3CpuBasic2_mov_ax_ds_bx__ud2_c16, 2 }, 165 174 { bs3CpuBasic2_mov_ds_bx_ax__ud2_c16, 2 }, … … 170 179 171 180 172 static void bs3CpuBasic2Pf_DoExecSubTest(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t uXcpt, uint8_t uPfErrCd, 173 unsigned iRing) 181 /** 182 * Compares a CPU trap. 183 */ 184 static void bs3CpuBasic2Pf_CompareCtx(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pExpectCtx, int cbPcAdjust, 185 uint8_t bXcpt, unsigned uErrCd) 186 { 187 const char *pszHint = "xxxx"; 188 uint16_t const cErrorsBefore = Bs3TestSubErrorCount(); 189 uint32_t fExtraEfl; 190 191 CHECK_MEMBER(pszHint, "bXcpt", "%#04x", pThis->TrapCtx.bXcpt, bXcpt); 192 CHECK_MEMBER(pszHint, "uErrCd", "%#06RX16", (uint16_t)pThis->TrapCtx.uErrCd, (uint16_t)uErrCd); /* 486 only writes a word */ 193 194 fExtraEfl = X86_EFL_RF; 195 if (BS3_MODE_IS_16BIT_SYS(g_bBs3CurrentMode)) 196 fExtraEfl = 0; 197 else 198 fExtraEfl = X86_EFL_RF; 199 Bs3TestCheckRegCtxEx(&pThis->TrapCtx.Ctx, pExpectCtx, cbPcAdjust, 0 /*cbSpAdjust*/, fExtraEfl, pszHint, g_usBs3TestStep); 200 if (Bs3TestSubErrorCount() != cErrorsBefore) 201 { 202 Bs3TrapPrintFrame(&pThis->TrapCtx); 203 #if 1 204 Bs3TestPrintf("Halting: g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected); 205 Bs3TestPrintf("Halting: bXcpt=%#x uErrCd=%#x\n", bXcpt, uErrCd); 206 ASMHalt(); 207 #endif 208 } 209 } 210 211 212 /** 213 * Compares a CPU trap. 214 */ 215 static void bs3CpuBasic2Pf_CompareSimpleCtx(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pStartCtx, int offAddPC, 216 uint8_t bXcpt, unsigned uErrCd, uint64_t uCr2) 217 { 218 const char *pszHint = "xxxx"; 219 uint16_t const cErrorsBefore = Bs3TestSubErrorCount(); 220 uint64_t const uSavedCr2 = pStartCtx->cr2.u; 221 uint32_t fExtraEfl; 222 223 CHECK_MEMBER(pszHint, "bXcpt", "%#04x", pThis->TrapCtx.bXcpt, bXcpt); 224 CHECK_MEMBER(pszHint, "uErrCd", "%#06RX16", (uint16_t)pThis->TrapCtx.uErrCd, (uint16_t)uErrCd); /* 486 only writes a word */ 225 226 fExtraEfl = X86_EFL_RF; 227 if (BS3_MODE_IS_16BIT_SYS(g_bBs3CurrentMode)) 228 fExtraEfl = 0; 229 else 230 fExtraEfl = X86_EFL_RF; 231 pStartCtx->cr2.u = uCr2; 232 Bs3TestCheckRegCtxEx(&pThis->TrapCtx.Ctx, pStartCtx, offAddPC, 0 /*cbSpAdjust*/, fExtraEfl, pszHint, g_usBs3TestStep); 233 pStartCtx->cr2.u = uSavedCr2; 234 if (Bs3TestSubErrorCount() != cErrorsBefore) 235 { 236 Bs3TrapPrintFrame(&pThis->TrapCtx); 237 #if 1 238 Bs3TestPrintf("Halting: g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected); 239 Bs3TestPrintf("Halting: bXcpt=%#x uErrCd=%#x\n", bXcpt, uErrCd); 240 ASMHalt(); 241 #endif 242 } 243 } 244 245 246 /** 247 * Checks the trap context for a simple \#PF trap. 248 */ 249 static void bs3CpuBasic2Pf_CompareSimplePf(PBS3CPUBASIC2PFSTATE pThis, PCBS3REGCTX pStartCtx, int offAddPC, 250 unsigned uErrCd, uint64_t uCr2) 251 { 252 bs3CpuBasic2Pf_CompareSimpleCtx(pThis, (PBS3REGCTX)pStartCtx, offAddPC, X86_XCPT_PF, uErrCd, uCr2); 253 } 254 255 /** 256 * Checks the trap context for a simple \#UD trap. 257 */ 258 static void bs3CpuBasic2Pf_CompareSimpleUd(PBS3CPUBASIC2PFSTATE pThis, PCBS3REGCTX pStartCtx, int offAddPC) 259 { 260 bs3CpuBasic2Pf_CompareSimpleCtx(pThis, (PBS3REGCTX)pStartCtx, offAddPC, X86_XCPT_UD, 0, pStartCtx->cr2.u); 261 } 262 263 264 static void bs3CpuBasic2Pf_DoExec(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel) 174 265 { 175 266 uint8_t *pbOrgTest = pThis->pbOrgTest; 176 267 unsigned off; 177 for (off = X86_PAGE_SIZE - 2; off < X86_PAGE_SIZE + 2; off++) 178 { 268 269 for (off = X86_PAGE_SIZE - 4; off < X86_PAGE_SIZE + 2; off++) 270 { 271 /* Emit a little bit of code (using the original allocation mapping) and point pCtx to it. */ 179 272 pbOrgTest[off + 0] = X86_OP_PRF_SIZE_ADDR; 180 273 pbOrgTest[off + 1] = X86_OP_PRF_SIZE_OP; … … 190 283 break; 191 284 case BS3_MODE_CODE_16: 192 Bs3SelSetup16BitCode(&Bs3GdteSpare01, (uintptr_t)pThis->pbTest, iRing);285 Bs3SelSetup16BitCode(&Bs3GdteSpare01, (uintptr_t)pThis->pbTest, pCtx->bCpl); 193 286 pCtx->rip.u = off; 194 pCtx->cs = BS3_SEL_SPARE_01 ;287 pCtx->cs = BS3_SEL_SPARE_01 | pCtx->bCpl; 195 288 break; 196 289 case BS3_MODE_CODE_V86: … … 198 291 return; 199 292 } 293 //Bs3TestPrintf("cs:rip=%04x:%010RX64 iRing=%d\n", pCtx->cs, pCtx->rip.u, pCtx->bCpl); 200 294 201 295 Bs3TrapSetJmpAndRestore(pCtx, &pThis->TrapCtx); 202 //bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 203 204 } 296 //Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd); 297 if (bXcpt == X86_XCPT_PF) 298 { 299 unsigned offAddPC = !fPageLevel || off >= X86_PAGE_SIZE ? 0 : X86_PAGE_SIZE - off; 300 bs3CpuBasic2Pf_CompareSimplePf(pThis, pCtx, offAddPC, uPfErrCd, (uintptr_t)pThis->pbTest + offAddPC); 301 } 302 else 303 bs3CpuBasic2Pf_CompareSimpleUd(pThis, pCtx, 3); 304 305 } 306 } 307 308 309 static void bs3CpuBasic2Pf_SetCsEip(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, PCFNBS3CPUBASIC2PFTSTCODE pCode) 310 { 311 switch (pThis->bMode & BS3_MODE_CODE_MASK) 312 { 313 default: 314 pCtx->rip.u = (uintptr_t)pCode->pfn; 315 break; 316 317 case BS3_MODE_CODE_16: 318 { 319 uint32_t uFar16 = Bs3SelFlatCodeToProtFar16((uintptr_t)pCode->pfn); 320 pCtx->rip.u = (uint16_t)uFar16; 321 pCtx->cs = (uint16_t)(uFar16 >> 16) | pCtx->bCpl; 322 pCtx->cs += (uint16_t)pCtx->bCpl << BS3_SEL_RING_SHIFT; 323 break; 324 } 325 326 case BS3_MODE_CODE_V86: 327 { 328 uint32_t uFar16 = Bs3SelFlatCodeToRealMode((uintptr_t)pCode->pfn); 329 pCtx->rip.u = (uint16_t)uFar16; 330 pCtx->cs = (uint16_t)(uFar16 >> 16); 331 break; 332 } 333 } 334 } 335 336 337 /** 338 * Test a simple load instruction around the edges of page two. 339 * 340 * @param pThis The test stat data. 341 * @param pCtx The test context. 342 * @param bXcpt X86_XCPT_PF if this can cause \#PFs, otherwise 343 * X86_XCPT_UD. 344 * @param uPfErrCd The error code for \#PFs. 345 * @param fPageLevel Set if we're pushing PTE level bits. 346 */ 347 static void bs3CpuBasic2Pf_DoMovLoad(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, 348 bool fPageLevel) 349 { 350 static uint64_t const s_uValue = UINT64_C(0x7c4d0114428d); 351 uint64_t uExpectRax; 352 unsigned i; 353 354 /* 355 * Adjust the incoming context and calculate our expections. 356 */ 357 bs3CpuBasic2Pf_SetCsEip(pThis, pCtx, &pThis->pCmnMode->MovLoad); 358 Bs3MemCpy(&pThis->ExpectCtx, pCtx, sizeof(pThis->ExpectCtx)); 359 switch (pThis->bMode & BS3_MODE_CODE_MASK) 360 { 361 case BS3_MODE_CODE_16: 362 case BS3_MODE_CODE_V86: 363 uExpectRax = (uint16_t)s_uValue | (pCtx->rax.u & UINT64_C(0xffffffffffff0000)); 364 break; 365 case BS3_MODE_CODE_32: 366 uExpectRax = (uint32_t)s_uValue | (pCtx->rax.u & UINT64_C(0xffffffff00000000)); 367 break; 368 case BS3_MODE_CODE_64: 369 uExpectRax = s_uValue; 370 break; 371 } 372 if (uExpectRax == pCtx->rax.u) 373 pCtx->rax.u = ~pCtx->rax.u; 374 375 /* 376 * Make two approaches to the test page (the 2nd one): 377 * - i=0: Start on the 1st page and edge into the 2nd. 378 * - i=1: Start at the end of the 2nd page and edge off it and into the 3rd. 379 */ 380 for (i = 0; i < 2; i++) 381 { 382 unsigned off = X86_PAGE_SIZE * (i + 1) - pThis->cbAccess; 383 unsigned offEnd = X86_PAGE_SIZE * (i + 1) + (i == 0 ? 8 : 7); 384 for (; off < offEnd; off++) 385 { 386 *(uint64_t *)&pThis->pbOrgTest[off] = s_uValue; 387 if (BS3_MODE_IS_16BIT_CODE(pThis->bMode)) 388 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = off; 389 else 390 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = (uintptr_t)pThis->pbTest + off; 391 392 Bs3TrapSetJmpAndRestore(pCtx, &pThis->TrapCtx); 393 //Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd); 394 395 if ( bXcpt != X86_XCPT_PF 396 || (fPageLevel && off >= X86_PAGE_SIZE * 2) 397 || (fPageLevel && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 398 { 399 pThis->ExpectCtx.rax.u = uExpectRax; 400 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->MovLoad.offUd2, bXcpt, 0 /*uErrCd*/); 401 pThis->ExpectCtx.rax = pCtx->rax; 402 } 403 else 404 { 405 if (off < X86_PAGE_SIZE) 406 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + X86_PAGE_SIZE; 407 else 408 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + off; 409 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, 0 /*cbPcAdjust*/, bXcpt, uPfErrCd); 410 pThis->ExpectCtx.cr2 = pCtx->cr2; 411 } 412 } 413 } 414 } 415 416 417 /** 418 * Test a simple store instruction around the edges of page two. 419 * 420 * @param pThis The test stat data. 421 * @param pCtx The test context. 422 * @param bXcpt X86_XCPT_PF if this can cause \#PFs, otherwise 423 * X86_XCPT_UD. 424 * @param uPfErrCd The error code for \#PFs. 425 * @param fPageLevel Set if we're pushing PTE level bits. 426 */ 427 static void bs3CpuBasic2Pf_DoMovStore(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, 428 bool fPageLevel) 429 { 430 static uint64_t const s_uValue = UINT64_C(0x3af45ead86a34a26); 431 static uint64_t const s_uValueFlipped = UINT64_C(0xc50ba152795cb5d9); 432 uint64_t const uRaxSaved = pCtx->rax.u; 433 uint64_t uExpectStored; 434 unsigned i; 435 436 /* 437 * Adjust the incoming context and calculate our expections. 438 */ 439 bs3CpuBasic2Pf_SetCsEip(pThis, pCtx, &pThis->pCmnMode->MovStore); 440 if ((pThis->bMode & BS3_MODE_CODE_MASK) != BS3_MODE_CODE_64) 441 pCtx->rax.u = (uint32_t)s_uValue; /* leave the upper part zero */ 442 else 443 pCtx->rax.u = s_uValue; 444 445 Bs3MemCpy(&pThis->ExpectCtx, pCtx, sizeof(pThis->ExpectCtx)); 446 switch (pThis->bMode & BS3_MODE_CODE_MASK) 447 { 448 case BS3_MODE_CODE_16: 449 case BS3_MODE_CODE_V86: 450 uExpectStored = (uint16_t)s_uValue | (s_uValueFlipped & UINT64_C(0xffffffffffff0000)); 451 break; 452 case BS3_MODE_CODE_32: 453 uExpectStored = (uint32_t)s_uValue | (s_uValueFlipped & UINT64_C(0xffffffff00000000)); 454 break; 455 case BS3_MODE_CODE_64: 456 uExpectStored = s_uValue; 457 break; 458 } 459 460 /* 461 * Make two approaches to the test page (the 2nd one): 462 * - i=0: Start on the 1st page and edge into the 2nd. 463 * - i=1: Start at the end of the 2nd page and edge off it and into the 3rd. 464 */ 465 for (i = 0; i < 2; i++) 466 { 467 unsigned off = X86_PAGE_SIZE * (i + 1) - pThis->cbAccess; 468 unsigned offEnd = X86_PAGE_SIZE * (i + 1) + (i == 0 ? 8 : 7); 469 for (; off < offEnd; off++) 470 { 471 *(uint64_t *)&pThis->pbOrgTest[off] = s_uValueFlipped; 472 if (BS3_MODE_IS_16BIT_CODE(pThis->bMode)) 473 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = off; 474 else 475 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = (uintptr_t)pThis->pbTest + off; 476 477 Bs3TrapSetJmpAndRestore(pCtx, &pThis->TrapCtx); 478 //Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd); 479 480 if ( bXcpt != X86_XCPT_PF 481 || (fPageLevel && off >= X86_PAGE_SIZE * 2) 482 || (fPageLevel && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 483 { 484 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->MovStore.offUd2, bXcpt, 0 /*uErrCd*/); 485 if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored) 486 Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64", 487 g_usBs3TestStep, "xxxx", *(uint64_t *)&pThis->pbOrgTest[off], uExpectStored); 488 } 489 else 490 { 491 if (off < X86_PAGE_SIZE) 492 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + X86_PAGE_SIZE; 493 else 494 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + off; 495 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, 0 /*cbPcAdjust*/, bXcpt, uPfErrCd); 496 pThis->ExpectCtx.cr2 = pCtx->cr2; 497 if (*(uint64_t *)&pThis->pbOrgTest[off] != s_uValueFlipped) 498 Bs3TestFailedF("%u - %s: #PF'ed store modified memory: %#RX64, expected %#RX64", 499 g_usBs3TestStep, "xxxx", *(uint64_t *)&pThis->pbOrgTest[off], s_uValueFlipped); 500 501 } 502 } 503 } 504 505 pCtx->rax.u = uRaxSaved; 506 } 507 508 509 /** 510 * Test a xchg instruction around the edges of page two. 511 * 512 * @param pThis The test stat data. 513 * @param pCtx The test context. 514 * @param bXcpt X86_XCPT_PF if this can cause \#PFs, otherwise 515 * X86_XCPT_UD. 516 * @param uPfErrCd The error code for \#PFs. 517 * @param fPageLevel Set if we're pushing PTE level bits. 518 */ 519 static void bs3CpuBasic2Pf_DoXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, bool fPageLevel) 520 { 521 static uint64_t const s_uValue = UINT64_C(0xea58699648e2f32c); 522 static uint64_t const s_uValueFlipped = UINT64_C(0x15a79669b71d0cd3); 523 uint64_t const uRaxSaved = pCtx->rax.u; 524 uint64_t uRaxIn; 525 uint64_t uExpectedRax; 526 uint64_t uExpectStored; 527 unsigned i; 528 529 /* 530 * Adjust the incoming context and calculate our expections. 531 */ 532 bs3CpuBasic2Pf_SetCsEip(pThis, pCtx, &pThis->pCmnMode->Xchg); 533 if ((pThis->bMode & BS3_MODE_CODE_MASK) != BS3_MODE_CODE_64) 534 uRaxIn = (uint32_t)s_uValue; /* leave the upper part zero */ 535 else 536 uRaxIn = s_uValue; 537 538 Bs3MemCpy(&pThis->ExpectCtx, pCtx, sizeof(pThis->ExpectCtx)); 539 switch (pThis->bMode & BS3_MODE_CODE_MASK) 540 { 541 case BS3_MODE_CODE_16: 542 case BS3_MODE_CODE_V86: 543 uExpectedRax = (uint16_t)s_uValueFlipped | (uRaxIn & UINT64_C(0xffffffffffff0000)); 544 uExpectStored = (uint16_t)s_uValue | (s_uValueFlipped & UINT64_C(0xffffffffffff0000)); 545 break; 546 case BS3_MODE_CODE_32: 547 uExpectedRax = (uint32_t)s_uValueFlipped | (uRaxIn & UINT64_C(0xffffffff00000000)); 548 uExpectStored = (uint32_t)s_uValue | (s_uValueFlipped & UINT64_C(0xffffffff00000000)); 549 break; 550 case BS3_MODE_CODE_64: 551 uExpectedRax = s_uValueFlipped; 552 uExpectStored = s_uValue; 553 break; 554 } 555 556 /* 557 * Make two approaches to the test page (the 2nd one): 558 * - i=0: Start on the 1st page and edge into the 2nd. 559 * - i=1: Start at the end of the 2nd page and edge off it and into the 3rd. 560 */ 561 for (i = 0; i < 2; i++) 562 { 563 unsigned off = X86_PAGE_SIZE * (i + 1) - pThis->cbAccess; 564 unsigned offEnd = X86_PAGE_SIZE * (i + 1) + (i == 0 ? 8 : 7); 565 for (; off < offEnd; off++) 566 { 567 *(uint64_t *)&pThis->pbOrgTest[off] = s_uValueFlipped; 568 pCtx->rax.u = uRaxIn; 569 if (BS3_MODE_IS_16BIT_CODE(pThis->bMode)) 570 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = off; 571 else 572 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = (uintptr_t)pThis->pbTest + off; 573 574 Bs3TrapSetJmpAndRestore(pCtx, &pThis->TrapCtx); 575 //Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd); 576 577 if ( bXcpt != X86_XCPT_PF 578 || (fPageLevel && off >= X86_PAGE_SIZE * 2) 579 || (fPageLevel && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 580 { 581 pThis->ExpectCtx.rax.u = uExpectedRax; 582 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->Xchg.offUd2, bXcpt, 0 /*uErrCd*/); 583 if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored) 584 Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64", 585 g_usBs3TestStep, "xxxx", *(uint64_t *)&pThis->pbOrgTest[off], uExpectStored); 586 } 587 else 588 { 589 pThis->ExpectCtx.rax.u = uRaxIn; 590 if (off < X86_PAGE_SIZE) 591 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + X86_PAGE_SIZE; 592 else 593 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + off; 594 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, 0 /*cbPcAdjust*/, bXcpt, uPfErrCd); 595 pThis->ExpectCtx.cr2 = pCtx->cr2; 596 if (*(uint64_t *)&pThis->pbOrgTest[off] != s_uValueFlipped) 597 Bs3TestFailedF("%u - %s: #PF'ed store modified memory: %#RX64, expected %#RX64", 598 g_usBs3TestStep, "xxxx", *(uint64_t *)&pThis->pbOrgTest[off], s_uValueFlipped); 599 } 600 } 601 } 602 603 pCtx->rax.u = uRaxSaved; 604 } 605 606 607 /** 608 * Test a cmpxchg instruction around the edges of page two. 609 * 610 * @param pThis The test stat data. 611 * @param pCtx The test context. 612 * @param bXcpt X86_XCPT_PF if this can cause \#PFs, otherwise 613 * X86_XCPT_UD. 614 * @param uPfErrCd The error code for \#PFs. 615 * @param fPageLevel Set if we're pushing PTE level bits. 616 * @param fMissmatch Whether to fail and not store (@c true), or succeed 617 * and do the store. 618 */ 619 static void bs3CpuBasic2Pf_DoCmpXchg(PBS3CPUBASIC2PFSTATE pThis, PBS3REGCTX pCtx, uint8_t bXcpt, uint8_t uPfErrCd, 620 bool fPageLevel, bool fMissmatch) 621 { 622 static uint64_t const s_uValue = UINT64_C(0xea58699648e2f32c); 623 static uint64_t const s_uValueFlipped = UINT64_C(0x15a79669b71d0cd3); 624 static uint64_t const s_uValueOther = UINT64_C(0x2171239bcb044c81); 625 uint64_t const uRaxSaved = pCtx->rax.u; 626 uint64_t const uRcxSaved = pCtx->rcx.u; 627 uint64_t uRaxIn; 628 uint64_t uExpectedRax; 629 uint32_t uExpectedFlags; 630 uint64_t uExpectStored; 631 unsigned i; 632 633 /* 634 * Adjust the incoming context and calculate our expections. 635 * Hint: CMPXCHG [xBX],xCX ; xAX compare and update implicit, ZF set to !fMissmatch. 636 */ 637 bs3CpuBasic2Pf_SetCsEip(pThis, pCtx, &pThis->pCmnMode->CmpXchg); 638 if ((pThis->bMode & BS3_MODE_CODE_MASK) != BS3_MODE_CODE_64) 639 { 640 uRaxIn = (uint32_t)(fMissmatch ? s_uValueOther : s_uValueFlipped); /* leave the upper part zero */ 641 pCtx->rcx.u = (uint32_t)s_uValue; /* ditto */ 642 } 643 else 644 { 645 uRaxIn = fMissmatch ? s_uValueOther : s_uValueFlipped; 646 pCtx->rcx.u = s_uValue; 647 } 648 if (fMissmatch) 649 pCtx->rflags.u32 |= X86_EFL_ZF; 650 else 651 pCtx->rflags.u32 &= ~X86_EFL_ZF; 652 653 Bs3MemCpy(&pThis->ExpectCtx, pCtx, sizeof(pThis->ExpectCtx)); 654 uExpectedFlags = pCtx->rflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_OF | X86_EFL_ZF); 655 switch (pThis->bMode & BS3_MODE_CODE_MASK) 656 { 657 case BS3_MODE_CODE_16: 658 case BS3_MODE_CODE_V86: 659 uExpectedRax = (uint16_t)s_uValueFlipped | (uRaxIn & UINT64_C(0xffffffffffff0000)); 660 uExpectStored = (uint16_t)s_uValue | (s_uValueFlipped & UINT64_C(0xffffffffffff0000)); 661 uExpectedFlags |= !fMissmatch ? X86_EFL_ZF | X86_EFL_PF : X86_EFL_AF; 662 break; 663 case BS3_MODE_CODE_32: 664 uExpectedRax = (uint32_t)s_uValueFlipped | (uRaxIn & UINT64_C(0xffffffff00000000)); 665 uExpectStored = (uint32_t)s_uValue | (s_uValueFlipped & UINT64_C(0xffffffff00000000)); 666 uExpectedFlags |= !fMissmatch ? X86_EFL_ZF | X86_EFL_PF : X86_EFL_AF; 667 break; 668 case BS3_MODE_CODE_64: 669 uExpectedRax = s_uValueFlipped; 670 uExpectStored = s_uValue; 671 uExpectedFlags |= !fMissmatch ? X86_EFL_ZF | X86_EFL_PF : X86_EFL_AF; 672 break; 673 } 674 if (fMissmatch) 675 uExpectStored = s_uValueFlipped; 676 677 /* 678 * Make two approaches to the test page (the 2nd one): 679 * - i=0: Start on the 1st page and edge into the 2nd. 680 * - i=1: Start at the end of the 2nd page and edge off it and into the 3rd. 681 */ 682 for (i = 0; i < 2; i++) 683 { 684 unsigned off = X86_PAGE_SIZE * (i + 1) - pThis->cbAccess; 685 unsigned offEnd = X86_PAGE_SIZE * (i + 1) + (i == 0 ? 8 : 7); 686 for (; off < offEnd; off++) 687 { 688 *(uint64_t *)&pThis->pbOrgTest[off] = s_uValueFlipped; 689 pCtx->rax.u = uRaxIn; 690 if (BS3_MODE_IS_16BIT_CODE(pThis->bMode)) 691 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = off; 692 else 693 pThis->ExpectCtx.rbx.u = pCtx->rbx.u = (uintptr_t)pThis->pbTest + off; 694 695 Bs3TrapSetJmpAndRestore(pCtx, &pThis->TrapCtx); 696 //Bs3TestPrintf("off=%#06x bXcpt=%#x uErrCd=%#RX64\n", off, pThis->TrapCtx.bXcpt, pThis->TrapCtx.uErrCd); 697 698 if ( bXcpt != X86_XCPT_PF 699 || (fPageLevel && off >= X86_PAGE_SIZE * 2) 700 || (fPageLevel && off <= X86_PAGE_SIZE - pThis->cbAccess) ) 701 { 702 pThis->ExpectCtx.rax.u = uExpectedRax; 703 pThis->ExpectCtx.rflags.u32 = uExpectedFlags; 704 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, pThis->pCmnMode->CmpXchg.offUd2, bXcpt, 0 /*uErrCd*/); 705 if (*(uint64_t *)&pThis->pbOrgTest[off] != uExpectStored) 706 Bs3TestFailedF("%u - %s: Stored %#RX64, expected %#RX64", 707 g_usBs3TestStep, "xxxx", *(uint64_t *)&pThis->pbOrgTest[off], uExpectStored); 708 } 709 else 710 { 711 pThis->ExpectCtx.rax.u = uRaxIn; 712 pThis->ExpectCtx.rflags = pCtx->rflags; 713 if (off < X86_PAGE_SIZE) 714 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + X86_PAGE_SIZE; 715 else 716 pThis->ExpectCtx.cr2.u = (uintptr_t)pThis->pbTest + off; 717 bs3CpuBasic2Pf_CompareCtx(pThis, &pThis->ExpectCtx, 0 /*cbPcAdjust*/, bXcpt, uPfErrCd); 718 pThis->ExpectCtx.cr2 = pCtx->cr2; 719 if (*(uint64_t *)&pThis->pbOrgTest[off] != s_uValueFlipped) 720 Bs3TestFailedF("%u - %s: #PF'ed store modified memory: %#RX64, expected %#RX64", 721 g_usBs3TestStep, "xxxx", *(uint64_t *)&pThis->pbOrgTest[off], s_uValueFlipped); 722 } 723 } 724 } 725 726 pCtx->rax.u = uRaxSaved; 727 pCtx->rcx.u = uRcxSaved; 205 728 } 206 729 … … 219 742 BS3REGCTX aCtxts[4]; 220 743 744 /** @todo figure out V8086 testing. */ 745 if ((pThis->bMode & BS3_MODE_CODE_MASK) == BS3_MODE_CODE_V86) 746 return BS3TESTDOMODE_SKIPPED; 747 748 221 749 /* paranoia: Touch the various big stack structures to ensure the compiler has allocated stack for them. */ 222 750 for (iRing = 0; iRing < RT_ELEMENTS(aCtxts); iRing++) … … 247 775 } 248 776 249 250 /* 251 * Check basic operation. 777 /* 778 * Check basic operation: 252 779 */ 253 780 for (iRing = 0; iRing < 4; iRing++) 254 781 { 255 /* we can execute the test page. */ 256 bs3CpuBasic2Pf_DoExecSubTest(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, iRing); 257 } 258 259 782 /* 1. we can execute the test page. */ 783 bs3CpuBasic2Pf_DoExec(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 784 /* 2. we can read from the test page. */ 785 bs3CpuBasic2Pf_DoMovLoad(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 786 /* 3. we can write to the test page. */ 787 bs3CpuBasic2Pf_DoMovStore(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 788 /* 4. we can do locked read+write (a few variants). */ 789 bs3CpuBasic2Pf_DoXchg(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/); 790 bs3CpuBasic2Pf_DoCmpXchg(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/, false /*fMissmatch*/); 791 bs3CpuBasic2Pf_DoCmpXchg(pThis, &aCtxts[iRing], X86_XCPT_UD, UINT8_MAX, true /*fPageLevel*/, true /*fMissmatch*/); 792 } 793 794 /* 795 * Check the U bit on PTE level. 796 */ 260 797 261 798 … … 277 814 Bs3MemZero(&State, sizeof(State)); 278 815 State.bMode = bMode; 816 switch (bMode & BS3_MODE_CODE_MASK) 817 { 818 case BS3_MODE_CODE_16: State.cbAccess = sizeof(uint16_t); break; 819 case BS3_MODE_CODE_V86: State.cbAccess = sizeof(uint16_t); break; 820 case BS3_MODE_CODE_32: State.cbAccess = sizeof(uint32_t); break; 821 case BS3_MODE_CODE_64: State.cbAccess = sizeof(uint64_t); break; 822 } 279 823 State.pCmnMode = &g_aCmnModes[0]; 280 824 while (State.pCmnMode->bMode != (bMode & BS3_MODE_CODE_MASK)) -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.mac
r64752 r64776 321 321 ; 322 322 323 ; For testing exec access.324 BS3_PROC_BEGIN_CMN bs3CpuBasic2_RaisePF_ExecTmpl, BS3_PBC_NEAR325 .again: ud2326 jmp .again327 BS3_PROC_END_CMN bs3CpuBasic2_RaisePF_ExecTmpl328 329 330 323 ; For testing read access. 331 324 BS3_PROC_BEGIN_CMN bs3CpuBasic2_mov_ax_ds_bx__ud2, BS3_PBC_NEAR -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c
r64704 r64776 77 77 */ 78 78 NOREF(g_aModeTest); NOREF(g_aModeByOneTests); /* for when commenting out bits */ 79 #if 0 79 80 Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest)); 80 81 Bs3TestDoModesByOne_rm(g_aModeByOneTests, RT_ELEMENTS(g_aModeByOneTests), 0); 82 #endif 81 83 82 84 /* … … 86 88 87 89 Bs3TestTerm(); 88 for (;;) { ASMHalt(); }90 //for (;;) { ASMHalt(); } 89 91 } 90 92 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-PagingQueryAddressInfo.c
r64734 r64776 70 70 if (!pPgInfo->u.Pae.pPml4e->n.u1Present) 71 71 rc = VERR_PAGE_NOT_PRESENT; 72 else if ( pPgInfo->u.Pae.pPml4e->u<= uMaxAddr)72 else if ((pPgInfo->u.Pae.pPml4e->u & X86_PML4E_PG_MASK) <= uMaxAddr) 73 73 { 74 pPgInfo->u.Pae.pPdpe = (X86PDPE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPml4e->u & X86_P AGE_BASE_MASK);74 pPgInfo->u.Pae.pPdpe = (X86PDPE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPml4e->u & X86_PML4E_PG_MASK); 75 75 pPgInfo->u.Pae.pPdpe += (uFlat >> X86_PDPT_SHIFT) & X86_PDPT_MASK_AMD64; 76 76 if (!pPgInfo->u.Pae.pPdpe->n.u1Present) … … 96 96 /* Common code for the PD and PT levels. */ 97 97 if ( rc == VINF_TRY_AGAIN 98 && pPgInfo->u.Pae.pPdpe->u<= uMaxAddr)98 && (pPgInfo->u.Pae.pPdpe->u & X86_PDPE_PG_MASK) <= uMaxAddr) 99 99 { 100 100 rc = VERR_OUT_OF_RANGE; 101 pPgInfo->u.Pae.pPde = (X86PDEPAE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPdpe->u & X86_P AGE_BASE_MASK);101 pPgInfo->u.Pae.pPde = (X86PDEPAE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPdpe->u & X86_PDPE_PG_MASK); 102 102 pPgInfo->u.Pae.pPde += (uFlat >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK; 103 103 if (!pPgInfo->u.Pae.pPde->n.u1Present) … … 105 105 else if (pPgInfo->u.Pae.pPde->b.u1Size) 106 106 rc = VINF_SUCCESS; 107 else if ( pPgInfo->u.Pae.pPde->u<= uMaxAddr)107 else if ((pPgInfo->u.Pae.pPde->u & X86_PDE_PAE_PG_MASK) <= uMaxAddr) 108 108 { 109 pPgInfo->u.Pae.pPte = (X86PTEPAE BS3_FAR *)Bs3XptrFlatToCurrent( pPgInfo->u.Pae.pPde->u110 & X86_PAGE_BASE_MASK);109 pPgInfo->u.Pae.pPte = (X86PTEPAE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Pae.pPde->u & X86_PDE_PAE_PG_MASK); 110 rc = VINF_SUCCESS; 111 111 } 112 112 } … … 136 136 else if (pPgInfo->u.Legacy.pPde->u <= uMaxAddr) 137 137 { 138 pPgInfo->u.Legacy.pPte = (X86PTE BS3_FAR *)Bs3XptrFlatToCurrent( pPgInfo->u.Legacy.pPde->u 139 & X86_PAGE_BASE_MASK_32); 138 pPgInfo->u.Legacy.pPte = (X86PTE BS3_FAR *)Bs3XptrFlatToCurrent(pPgInfo->u.Legacy.pPde->u & X86_PDE_PG_MASK); 140 139 pPgInfo->u.Legacy.pPte += ((uint32_t)uFlat >> X86_PT_SHIFT) & X86_PT_MASK; 141 140 if (pPgInfo->u.Legacy.pPte->n.u1Present)
Note:
See TracChangeset
for help on using the changeset viewer.