- Timestamp:
- Jan 6, 2024 1:43:05 AM (16 months ago)
- svn:sync-xref-src-repo-rev:
- 160959
- Location:
- trunk/src/VBox/ValidationKit/bootsectors
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-template.mac
r98103 r102778 162 162 163 163 164 ; 165 ; PUSH / POP. 166 ; 167 168 BS3_PROC_BEGIN_CMN bs3CpuWeird1_Push_xSP_Ud2, BS3_PBC_NEAR 169 push xSP 170 .ud2_again: 171 ud2 172 jmp .ud2_again 173 AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Push_xSP_Ud2) == 1) 174 BS3_PROC_END_CMN bs3CpuWeird1_Push_xSP_Ud2 175 176 BS3_PROC_BEGIN_CMN bs3CpuWeird1_Pop_xSP_Ud2, BS3_PBC_NEAR 177 pop xSP 178 .ud2_again: 179 ud2 180 jmp .ud2_again 181 AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Pop_xSP_Ud2) == 1) 182 BS3_PROC_END_CMN bs3CpuWeird1_Pop_xSP_Ud2 183 184 185 BS3_PROC_BEGIN_CMN bs3CpuWeird1_Push_opsize_xSP_Ud2, BS3_PBC_NEAR 186 db 066h 187 push xSP 188 .ud2_again: 189 ud2 190 jmp .ud2_again 191 AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Push_opsize_xSP_Ud2) == 2) 192 BS3_PROC_END_CMN bs3CpuWeird1_Push_opsize_xSP_Ud2 193 194 BS3_PROC_BEGIN_CMN bs3CpuWeird1_Pop_opsize_xSP_Ud2, BS3_PBC_NEAR 195 db 066h 196 pop xSP 197 .ud2_again: 198 ud2 199 jmp .ud2_again 200 AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Pop_opsize_xSP_Ud2) == 2) 201 BS3_PROC_END_CMN bs3CpuWeird1_Pop_opsize_xSP_Ud2 202 203 204 BS3_PROC_BEGIN_CMN bs3CpuWeird1_Push_opsize_xBX_Ud2, BS3_PBC_NEAR 205 db 066h 206 push xBX 207 .ud2_again: 208 ud2 209 jmp .ud2_again 210 AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Push_opsize_xBX_Ud2) == 2) 211 BS3_PROC_END_CMN bs3CpuWeird1_Push_opsize_xBX_Ud2 212 213 BS3_PROC_BEGIN_CMN bs3CpuWeird1_Pop_opsize_xBX_Ud2, BS3_PBC_NEAR 214 db 066h 215 pop xBX 216 .ud2_again: 217 ud2 218 jmp .ud2_again 219 AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Pop_opsize_xBX_Ud2) == 2) 220 BS3_PROC_END_CMN bs3CpuWeird1_Pop_opsize_xBX_Ud2 221 222 164 223 %endif ; BS3_INSTANTIATING_CMN 165 224 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-x0.c
r98103 r102778 1085 1085 } 1086 1086 1087 1088 /********************************************************************************************************************************* 1089 * PUSH / POP * 1090 *********************************************************************************************************************************/ 1091 #define PROTO_ALL(a_Template) \ 1092 FNBS3FAR a_Template ## _c16, \ 1093 a_Template ## _c32, \ 1094 a_Template ## _c64 1095 PROTO_ALL(bs3CpuWeird1_Push_xSP_Ud2); 1096 PROTO_ALL(bs3CpuWeird1_Push_opsize_xSP_Ud2); 1097 PROTO_ALL(bs3CpuWeird1_Push_opsize_xBX_Ud2); 1098 PROTO_ALL(bs3CpuWeird1_Pop_xSP_Ud2); 1099 PROTO_ALL(bs3CpuWeird1_Pop_opsize_xSP_Ud2); 1100 PROTO_ALL(bs3CpuWeird1_Pop_opsize_xBX_Ud2); 1101 #undef PROTO_ALL 1102 1103 1104 /** 1105 * Compares push/pop result. 1106 */ 1107 static uint8_t bs3CpuWeird1_ComparePushPop(PCBS3TRAPFRAME pTrapCtx, PCBS3TRAPFRAME pTrapExpect) 1108 { 1109 uint16_t const cErrorsBefore = Bs3TestSubErrorCount(); 1110 CHECK_MEMBER("bXcpt", "%#04x", pTrapCtx->bXcpt, pTrapExpect->bXcpt); 1111 CHECK_MEMBER("bErrCd", "%#06RX64", pTrapCtx->uErrCd, pTrapExpect->uErrCd); 1112 Bs3TestCheckRegCtxEx(&pTrapCtx->Ctx, &pTrapExpect->Ctx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 0 /*fExtraEfl*/, 1113 g_pszTestMode, g_usBs3TestStep); 1114 if (Bs3TestSubErrorCount() != cErrorsBefore) 1115 { 1116 Bs3TrapPrintFrame(pTrapCtx); 1117 Bs3TestPrintf("CS=%04RX16 SS:ESP=%04RX16:%08RX64 EFL=%RX64 cbIret=%#x\n", 1118 pTrapCtx->uHandlerCs, pTrapCtx->uHandlerSs, pTrapCtx->uHandlerRsp, 1119 pTrapCtx->fHandlerRfl, pTrapCtx->cbIretFrame); 1120 #if 0 1121 Bs3TestPrintf("Halting in ComparePushPop: bXcpt=%#x\n", pTrapCtx->bXcpt); 1122 ASMHalt(); 1123 #endif 1124 return 1; 1125 } 1126 return 0; 1127 } 1128 1129 1130 /** Initialize the stack around the CS:RSP with fixed values. */ 1131 static void bs3CpuWeird1_PushPopInitStack(BS3PTRUNION PtrStack) 1132 { 1133 PtrStack.pu16[-8] = UINT16_C(0x1e0f); 1134 PtrStack.pu16[-7] = UINT16_C(0x3c2d); 1135 PtrStack.pu16[-6] = UINT16_C(0x5a4b); 1136 PtrStack.pu16[-5] = UINT16_C(0x7869); 1137 PtrStack.pu16[-4] = UINT16_C(0x9687); 1138 PtrStack.pu16[-3] = UINT16_C(0xb4a5); 1139 PtrStack.pu16[-2] = UINT16_C(0xd2c3); 1140 PtrStack.pu16[-1] = UINT16_C(0xf0e1); 1141 PtrStack.pu16[0] = UINT16_C(0xfdec); 1142 PtrStack.pu16[1] = UINT16_C(0xdbca); 1143 PtrStack.pu16[2] = UINT16_C(0xb9a8); 1144 PtrStack.pu16[3] = UINT16_C(0x9786); 1145 PtrStack.pu16[4] = UINT16_C(0x7564); 1146 PtrStack.pu16[5] = UINT16_C(0x5342); 1147 PtrStack.pu16[6] = UINT16_C(0x3120); 1148 } 1149 1150 1151 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuWeird1_PushPop)(uint8_t bTestMode) 1152 { 1153 static struct 1154 { 1155 FPFNBS3FAR pfnStart; 1156 uint8_t cBits; 1157 bool fPush; /**< true if push, false if pop. */ 1158 int8_t cbAdjSp; /**< The SP adjustment value. */ 1159 uint8_t idxReg; /**< The X86_GREG_xXX value of the register in question. */ 1160 uint8_t offUd2; /**< The UD2 offset into the code. */ 1161 } s_aTests[] = 1162 { 1163 { bs3CpuWeird1_Push_opsize_xBX_Ud2_c16, 16, true, -4, X86_GREG_xBX, 2 }, 1164 { bs3CpuWeird1_Pop_opsize_xBX_Ud2_c16, 16, false, +4, X86_GREG_xBX, 2 }, 1165 { bs3CpuWeird1_Push_xSP_Ud2_c16, 16, true, -2, X86_GREG_xSP, 1 }, 1166 { bs3CpuWeird1_Push_opsize_xSP_Ud2_c16, 16, true, -4, X86_GREG_xSP, 2 }, 1167 { bs3CpuWeird1_Pop_xSP_Ud2_c16, 16, false, +2, X86_GREG_xSP, 1 }, 1168 { bs3CpuWeird1_Pop_opsize_xSP_Ud2_c16, 16, false, +4, X86_GREG_xSP, 2 }, 1169 1170 { bs3CpuWeird1_Push_opsize_xBX_Ud2_c32, 32, true, -2, X86_GREG_xBX, 2 }, 1171 { bs3CpuWeird1_Pop_opsize_xBX_Ud2_c32, 32, false, +2, X86_GREG_xBX, 2 }, 1172 { bs3CpuWeird1_Push_xSP_Ud2_c32, 32, true, -4, X86_GREG_xSP, 1 }, 1173 { bs3CpuWeird1_Push_opsize_xSP_Ud2_c32, 32, true, -2, X86_GREG_xSP, 2 }, 1174 { bs3CpuWeird1_Pop_xSP_Ud2_c32, 32, false, +4, X86_GREG_xSP, 1 }, 1175 { bs3CpuWeird1_Pop_opsize_xSP_Ud2_c32, 32, false, +2, X86_GREG_xSP, 2 }, 1176 1177 { bs3CpuWeird1_Push_opsize_xBX_Ud2_c64, 64, true, -2, X86_GREG_xBX, 2 }, 1178 { bs3CpuWeird1_Pop_opsize_xBX_Ud2_c64, 64, false, +2, X86_GREG_xBX, 2 }, 1179 { bs3CpuWeird1_Push_xSP_Ud2_c64, 64, true, -8, X86_GREG_xSP, 1 }, 1180 { bs3CpuWeird1_Push_opsize_xSP_Ud2_c64, 64, true, -2, X86_GREG_xSP, 2 }, 1181 { bs3CpuWeird1_Pop_xSP_Ud2_c64, 64, false, +8, X86_GREG_xSP, 1 }, 1182 { bs3CpuWeird1_Pop_opsize_xSP_Ud2_c64, 64, false, +2, X86_GREG_xSP, 2 }, 1183 }; 1184 BS3TRAPFRAME TrapCtx; 1185 BS3TRAPFRAME TrapExpect; 1186 BS3REGCTX Ctx; 1187 uint8_t const cTestBits = BS3_MODE_IS_16BIT_CODE(bTestMode) ? 16 1188 : BS3_MODE_IS_32BIT_CODE(bTestMode) ? 32 : 64; 1189 uint8_t BS3_FAR *pbAltStack = NULL; 1190 BS3PTRUNION PtrStack; 1191 unsigned i; 1192 1193 /* make sure they're allocated */ 1194 Bs3MemZero(&Ctx, sizeof(Ctx)); 1195 Bs3MemZero(&TrapCtx, sizeof(TrapCtx)); 1196 Bs3MemZero(&TrapExpect, sizeof(TrapExpect)); 1197 1198 bs3CpuWeird1_SetGlobals(bTestMode); 1199 1200 /* Construct a basic context. */ 1201 Bs3RegCtxSaveEx(&Ctx, bTestMode, 1024); 1202 Ctx.rflags.u32 &= ~X86_EFL_RF; 1203 if (BS3_MODE_IS_64BIT_CODE(bTestMode)) 1204 { 1205 Ctx.rbx.au32[1] ^= UINT32_C(0x12305c78); 1206 Ctx.rcx.au32[1] ^= UINT32_C(0x33447799); 1207 Ctx.rax.au32[1] ^= UINT32_C(0x9983658a); 1208 Ctx.r11.au32[1] ^= UINT32_C(0xbbeeffdd); 1209 Ctx.r12.au32[1] ^= UINT32_C(0x87272728); 1210 } 1211 1212 /* ring-3 if possible, since that'll enable automatic stack switching. */ 1213 if (!BS3_MODE_IS_RM_OR_V86(bTestMode)) 1214 Bs3RegCtxConvertToRingX(&Ctx, 3); 1215 1216 /* Make PtrStack == SS:xSP from Ctx. */ 1217 PtrStack.pv = Bs3RegCtxGetRspSsAsCurPtr(&Ctx); 1218 1219 #if 1 1220 /* Use our own stack so we can observe the effect of ESP/RSP rolling across 1221 a 64KB boundrary when just popping SP. */ 1222 if (!BS3_MODE_IS_16BIT_CODE(bTestMode)) /** @todo extend this to 16-bit code as well (except RM ofc). */ 1223 { 1224 uint32_t uFlatNextSeg; 1225 pbAltStack = (uint8_t BS3_FAR *)Bs3SlabAllocEx(&g_Bs3Mem4KUpperTiled.Core, 17 /*cPages*/, 0 /*fFlags*/); 1226 if (!pbAltStack) 1227 { 1228 Bs3TestFailed("Failed to allocate 68K for alternative stack!"); 1229 return 1; 1230 } 1231 1232 /* Modify RSP to be one byte under the 64KB boundrary. */ 1233 uFlatNextSeg = (Bs3SelPtrToFlat(pbAltStack) + _64K) & ~UINT32_C(0xffff); 1234 Ctx.rsp.u = uFlatNextSeg - 1; 1235 //Bs3TestPrintf("uFlatNextSeg=%RX32 rsp=%RX64 ss=%RX16\n", uFlatNextSeg, Ctx.rsp.u, Ctx.ss); 1236 1237 /* Modify the PtrStack accordingly, using a spare selector for addressing it. */ 1238 Bs3SelSetup16BitData(&Bs3GdteSpare00, uFlatNextSeg - _4K); 1239 PtrStack.pv = BS3_FP_MAKE(BS3_SEL_SPARE_00 | 3, _4K - 1); 1240 } 1241 #endif 1242 1243 /* 1244 * Iterate the test snippets and run those relevant to the test context. 1245 */ 1246 for (i = 0; i < RT_ELEMENTS(s_aTests); i++) 1247 { 1248 if (s_aTests[i].cBits == cTestBits) 1249 { 1250 PBS3REG const pReg = &(&Ctx.rax)[s_aTests[i].idxReg]; 1251 unsigned iRep; /**< This is to trigger native recompilation. */ 1252 BS3REG SavedReg; 1253 BS3REG SavedRsp; 1254 1255 /* Save context stuff we may change: */ 1256 SavedReg.u = pReg->u; 1257 SavedRsp.u = Ctx.rsp.u; 1258 1259 /* Setup the test context. */ 1260 Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, s_aTests[i].pfnStart); 1261 if (BS3_MODE_IS_16BIT_SYS(bTestMode)) 1262 g_uBs3TrapEipHint = Ctx.rip.u32; 1263 1264 if (BS3_MODE_IS_16BIT_CODE(bTestMode)) 1265 Ctx.rsp.u32 |= UINT32_C(0x34560000); /* This part should be ignored, as the stack is also 16-bit. */ 1266 1267 /* The basic expected trap context. */ 1268 TrapExpect.bXcpt = X86_XCPT_UD; 1269 Bs3MemCpy(&TrapExpect.Ctx, &Ctx, sizeof(TrapExpect.Ctx)); 1270 TrapExpect.Ctx.rsp.u += s_aTests[i].cbAdjSp; 1271 TrapExpect.Ctx.rip.u += s_aTests[i].offUd2; 1272 if (!BS3_MODE_IS_16BIT_SYS(bTestMode)) 1273 TrapExpect.Ctx.rflags.u32 |= X86_EFL_RF; 1274 1275 g_usBs3TestStep = i; 1276 1277 if (s_aTests[i].cbAdjSp < 0) 1278 { 1279 /* 1280 * PUSH 1281 */ 1282 RTUINT64U u64ExpectPushed; 1283 BS3PTRUNION PtrStack2; 1284 PtrStack2.pb = PtrStack.pb + s_aTests[i].cbAdjSp; 1285 1286 bs3CpuWeird1_PushPopInitStack(PtrStack); 1287 u64ExpectPushed.u = *PtrStack2.pu64; 1288 switch (s_aTests[i].cbAdjSp) 1289 { 1290 case -2: u64ExpectPushed.au16[0] = pReg->au16[0]; break; 1291 case -4: u64ExpectPushed.au32[0] = pReg->au32[0]; break; 1292 case -8: u64ExpectPushed.au64[0] = pReg->u; break; 1293 } 1294 1295 for (iRep = 0; iRep < 256; iRep++) 1296 { 1297 bs3CpuWeird1_PushPopInitStack(PtrStack); 1298 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 1299 if (bs3CpuWeird1_ComparePushPop(&TrapCtx, &TrapExpect)) 1300 break; 1301 if (*PtrStack2.pu64 != u64ExpectPushed.u) 1302 { 1303 Bs3TestFailedF("%u - Unexpected stack value after push: %RX64, expected %RX64", 1304 g_usBs3TestStep, *PtrStack2.pu64, u64ExpectPushed); 1305 break; 1306 } 1307 } 1308 } 1309 else 1310 { 1311 /* 1312 * POP. 1313 * 1314 * This is where it gets interesting. When popping a partial 1315 * SP and the upper part also changes, this is preserved. I.e. 1316 * the CPU first writes the updated RSP then the register or 1317 * register part that it popped. 1318 */ 1319 PBS3REG const pExpectReg = &(&TrapExpect.Ctx.rax)[s_aTests[i].idxReg]; 1320 RTUINT64U u64PopValue; 1321 1322 bs3CpuWeird1_PushPopInitStack(PtrStack); 1323 u64PopValue.u = *PtrStack.pu64; 1324 if (bTestMode != BS3_MODE_RM) 1325 { 1326 /* When in ring-3 we can put whatever we want on the stack, as the UD2 will cause a stack switch. */ 1327 switch (s_aTests[i].cbAdjSp) 1328 { 1329 case 2: u64PopValue.au16[0] = ~pReg->au16[0] ^ UINT16_C(0xf394); break; 1330 case 4: u64PopValue.au32[0] = ~pReg->au32[0] ^ UINT32_C(0x9e501ab3); break; 1331 case 8: u64PopValue.au64[0] = ~pReg->u ^ UINT64_C(0xbf5fedd520fe9a45); break; 1332 } 1333 } 1334 else 1335 { 1336 /* In real mode we have to be a little more careful. */ 1337 if (s_aTests[i].cbAdjSp == 2) 1338 u64PopValue.au16[0] = pReg->au16[0] - 382; 1339 else 1340 { 1341 u64PopValue.au16[0] = pReg->au16[0] - 258; 1342 u64PopValue.au16[1] = ~pReg->au16[1]; 1343 } 1344 } 1345 1346 switch (s_aTests[i].cbAdjSp) 1347 { 1348 case 2: 1349 pExpectReg->au16[0] = u64PopValue.au16[0]; 1350 break; 1351 case 4: 1352 pExpectReg->au32[0] = u64PopValue.au32[0]; 1353 pExpectReg->au32[1] = 0; 1354 break; 1355 case 8: 1356 pExpectReg->u = u64PopValue.u; 1357 break; 1358 } 1359 //Bs3TestPrintf("iTest=%u/%d: %RX64 -> %RX64\n", i, s_aTests[i].cbAdjSp, pReg->u, pExpectReg->u); 1360 1361 for (iRep = 0; iRep < 256; iRep++) 1362 { 1363 bs3CpuWeird1_PushPopInitStack(PtrStack); 1364 *PtrStack.pu64 = u64PopValue.u; 1365 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 1366 if (bs3CpuWeird1_ComparePushPop(&TrapCtx, &TrapExpect)) 1367 break; 1368 } 1369 } 1370 1371 /* Restore context (except cs:rsp): */ 1372 pReg->u = SavedReg.u; 1373 Ctx.rsp.u = SavedRsp.u; 1374 } 1375 } 1376 1377 if (pbAltStack) 1378 Bs3SlabFree(&g_Bs3Mem4KUpperTiled.Core, Bs3SelPtrToFlat(pbAltStack), 17); 1379 1380 return 0; 1381 } 1382 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1.c
r98103 r102778 48 48 FNBS3TESTDOMODE bs3CpuWeird1_DbgInhibitRingXfer_f16; 49 49 FNBS3TESTDOMODE bs3CpuWeird1_PcWrapping_f16; 50 FNBS3TESTDOMODE bs3CpuWeird1_PushPop_f16; 50 51 51 52 … … 55 56 static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] = 56 57 { 58 #if 1 /** @todo fails in native recompiler atm. */ /** @todo asserts in ring-0 on VT-x! */ 57 59 { "dbg+inhibit+ringxfer", bs3CpuWeird1_DbgInhibitRingXfer_f16, 0 }, 60 #endif 61 #if 1 /** @todo asserts in native recompiler debug builds, but seems to work otherwise. */ 58 62 { "pc wrapping", bs3CpuWeird1_PcWrapping_f16, 0 }, 63 #endif 64 { "push/pop", bs3CpuWeird1_PushPop_f16, 0 }, 59 65 }; 60 66
Note:
See TracChangeset
for help on using the changeset viewer.