Changeset 103223 in vbox for trunk/src/VBox/ValidationKit/bootsectors
- Timestamp:
- Feb 6, 2024 10:59:03 AM (12 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-2-template.c
r103208 r103223 2975 2975 { 2976 2976 2977 BS3REGCTX Ctx; 2978 BS3REGCTX ExpectCtx; 2979 BS3TRAPFRAME TrapFrame; 2980 RTUINT64U au64[3]; 2981 PRTUINT64U pau64 = RT_ALIGN_PT(&au64[0], sizeof(RTUINT64U), PRTUINT64U); 2982 bool const fSupportCX8 = RT_BOOL(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_CX8); 2983 unsigned iFlags; 2984 unsigned offBuf; 2985 unsigned iMatch; 2986 unsigned iWorker; 2977 BS3REGCTX Ctx; 2978 BS3REGCTX ExpectCtx; 2979 BS3TRAPFRAME TrapFrame; 2980 RTUINT64U au64[3]; 2981 PRTUINT64U pau64 = RT_ALIGN_PT(&au64[0], sizeof(RTUINT64U), PRTUINT64U); 2982 bool const fSupportCX8 = RT_BOOL(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_CX8); 2983 const char BS3_FAR * const pszMode = Bs3GetModeName(bMode); 2984 uint8_t bRing = BS3_MODE_IS_V86(bMode) ? 3 : 0; 2985 unsigned iFlags; 2986 unsigned offBuf; 2987 unsigned iMatch; 2988 unsigned iWorker; 2987 2989 static struct 2988 2990 { … … 3020 3022 3021 3023 /* 3022 * One loop with the normal variant and one with the locked one 3024 * Run the tests in all rings since alignment issues may behave 3025 * differently in ring-3 compared to ring-0. 3023 3026 */ 3024 g_usBs3TestStep = 0; 3025 for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++) 3026 { 3027 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker); 3028 3027 for (;;) 3028 { 3029 3029 /* 3030 * One loop with al l status flags set, and one with them clear.3030 * One loop with alignment checks disabled and one with enabled. 3031 3031 */ 3032 Ctx.rflags.u16 |= X86_EFL_STATUS_BITS;3033 for (i Flags = 0; iFlags < 2; iFlags++)3032 unsigned iCfg; 3033 for (iCfg = 0; iCfg < 2; iCfg++) 3034 3034 { 3035 Bs3MemCpy(&ExpectCtx, &Ctx, sizeof(ExpectCtx)); 3036 3037 for (offBuf = 0; offBuf < sizeof(RTUINT64U); offBuf++) 3035 if (iCfg) 3038 3036 { 3037 Ctx.rflags.u32 |= X86_EFL_AC; 3038 Ctx.cr0.u32 |= X86_CR0_AM; 3039 } 3040 else 3041 { 3042 Ctx.rflags.u32 &= ~X86_EFL_AC; 3043 Ctx.cr0.u32 &= ~X86_CR0_AM; 3044 } 3045 3046 /* 3047 * One loop with the normal variant and one with the locked one 3048 */ 3049 g_usBs3TestStep = 0; 3050 for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++) 3051 { 3052 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker); 3053 3054 /* 3055 * One loop with all status flags set, and one with them clear. 3056 */ 3057 Ctx.rflags.u16 |= X86_EFL_STATUS_BITS; 3058 for (iFlags = 0; iFlags < 2; iFlags++) 3059 { 3060 Bs3MemCpy(&ExpectCtx, &Ctx, sizeof(ExpectCtx)); 3061 3062 for (offBuf = 0; offBuf < sizeof(RTUINT64U); offBuf++) 3063 { 3039 3064 # define CX8_OLD_LO UINT32_C(0xcc9c4bbd) 3040 3065 # define CX8_OLD_HI UINT32_C(0x749549ab) … … 3044 3069 # define CX8_STORE_HI UINT32_C(0xd1b54963) 3045 3070 3046 PRTUINT64U pBuf = (PRTUINT64U)&pau64->au8[offBuf]; 3047 3048 ExpectCtx.rax.u = Ctx.rax.u = CX8_MISMATCH_LO; 3049 ExpectCtx.rdx.u = Ctx.rdx.u = CX8_MISMATCH_HI; 3050 3051 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rdi, &Ctx.fs, pBuf); 3052 Bs3RegCtxSetGrpSegFromCurPtr(&ExpectCtx, &ExpectCtx.rdi, &ExpectCtx.fs, pBuf); 3053 3054 for (iMatch = 0; iMatch < 2; iMatch++) 3055 { 3056 uint8_t bExpectXcpt; 3057 pBuf->s.Lo = CX8_OLD_LO; 3058 pBuf->s.Hi = CX8_OLD_HI; 3059 3060 Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame); 3061 g_usBs3TestStep++; 3062 //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker); 3063 bExpectXcpt = X86_XCPT_DB; 3064 if (fSupportCX8) 3065 { 3066 ExpectCtx.rax.u = CX8_OLD_LO; 3067 ExpectCtx.rdx.u = CX8_OLD_HI; 3068 if (iMatch & 1) 3069 ExpectCtx.rflags.u32 = Ctx.rflags.u32 | X86_EFL_ZF; 3070 else 3071 ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF; 3072 ExpectCtx.rip.u = Ctx.rip.u + s_aWorkers[iWorker].offIcebp; 3073 3074 /** @todo r=aeichner RF (Resume Flag) gets always cleared on my i7-6700K. */ 3075 ExpectCtx.rflags.u32 &= ~X86_EFL_RF; 3071 PRTUINT64U pBuf = (PRTUINT64U)&pau64->au8[offBuf]; 3072 3073 ExpectCtx.rax.u = Ctx.rax.u = CX8_MISMATCH_LO; 3074 ExpectCtx.rdx.u = Ctx.rdx.u = CX8_MISMATCH_HI; 3075 3076 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rdi, &Ctx.fs, pBuf); 3077 Bs3RegCtxSetGrpSegFromCurPtr(&ExpectCtx, &ExpectCtx.rdi, &ExpectCtx.fs, pBuf); 3078 3079 for (iMatch = 0; iMatch < 2; iMatch++) 3080 { 3081 uint8_t bExpectXcpt; 3082 pBuf->s.Lo = CX8_OLD_LO; 3083 pBuf->s.Hi = CX8_OLD_HI; 3084 3085 Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame); 3086 g_usBs3TestStep++; 3087 //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker); 3088 bExpectXcpt = X86_XCPT_UD; 3089 if (fSupportCX8) 3090 { 3091 if ( offBuf 3092 && bRing == 3 3093 && bMode != BS3_MODE_RM 3094 && !BS3_MODE_IS_V86(bMode) 3095 && iCfg) 3096 { 3097 bExpectXcpt = X86_XCPT_AC; 3098 ExpectCtx.rflags.u32 = Ctx.rflags.u32; 3099 } 3100 else 3101 { 3102 bExpectXcpt = X86_XCPT_DB; 3103 3104 ExpectCtx.rax.u = CX8_OLD_LO; 3105 ExpectCtx.rdx.u = CX8_OLD_HI; 3106 3107 if (iMatch & 1) 3108 ExpectCtx.rflags.u32 = Ctx.rflags.u32 | X86_EFL_ZF; 3109 else 3110 ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF; 3111 } 3112 3113 /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on an i7-6700K. WEIRD! */ 3114 if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC)) 3115 { 3116 if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC) 3117 Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt); 3118 TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC; 3119 } 3120 } 3121 3122 if ( !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &ExpectCtx, bExpectXcpt == X86_XCPT_DB ? s_aWorkers[iWorker].offIcebp : 0, 0 /*cbSpAdjust*/, 3123 bExpectXcpt == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, pszMode, g_usBs3TestStep) 3124 || TrapFrame.bXcpt != bExpectXcpt) 3125 { 3126 if (TrapFrame.bXcpt != bExpectXcpt) 3127 Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd); 3128 Bs3TestFailedF("^^^ bRing=%u iCfg=%d iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n", 3129 bRing, iCfg, iWorker, iFlags, offBuf, iMatch); 3130 ASMHalt(); 3131 } 3132 3133 ExpectCtx.rax.u = Ctx.rax.u = CX8_OLD_LO; 3134 ExpectCtx.rdx.u = Ctx.rdx.u = CX8_OLD_HI; 3135 } 3076 3136 } 3077 if ( !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &ExpectCtx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 3078 0 /*fExtraEfl*/, "mode", 0 /*idTestStep*/) 3079 || TrapFrame.bXcpt != bExpectXcpt) 3080 { 3081 if (TrapFrame.bXcpt != bExpectXcpt) 3082 Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd); 3083 Bs3TestFailedF("^^^ iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n", iWorker, iFlags, offBuf, iMatch); 3084 ASMHalt(); 3085 } 3086 3087 ExpectCtx.rax.u = Ctx.rax.u = CX8_OLD_LO; 3088 ExpectCtx.rdx.u = Ctx.rdx.u = CX8_OLD_HI; 3137 Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS; 3089 3138 } 3090 3139 } 3091 Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS; 3092 } 3140 } /* for each test config. */ 3141 3142 /* 3143 * Next ring. 3144 */ 3145 bRing++; 3146 if (bRing > 3 || bMode == BS3_MODE_RM) 3147 break; 3148 Bs3RegCtxConvertToRingX(&Ctx, bRing); 3093 3149 } 3094 3150 … … 3105 3161 BS3_DECL_FAR(uint8_t) BS3_CMN_NM(bs3CpuInstr2_cmpxchg16b)(uint8_t bMode) 3106 3162 { 3107 BS3REGCTX Ctx; 3108 BS3REGCTX ExpectCtx; 3109 BS3TRAPFRAME TrapFrame; 3110 RTUINT128U au128[3]; 3111 PRTUINT128U pau128 = RT_ALIGN_PT(&au128[0], sizeof(RTUINT128U), PRTUINT128U); 3112 bool const fSupportCX16 = RT_BOOL(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16); 3113 unsigned iFlags; 3114 unsigned offBuf; 3115 unsigned iMatch; 3116 unsigned iWorker; 3163 BS3REGCTX Ctx; 3164 BS3REGCTX ExpectCtx; 3165 BS3TRAPFRAME TrapFrame; 3166 RTUINT128U au128[3]; 3167 PRTUINT128U pau128 = RT_ALIGN_PT(&au128[0], sizeof(RTUINT128U), PRTUINT128U); 3168 bool const fSupportCX16 = RT_BOOL(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16); 3169 const char BS3_FAR * const pszMode = Bs3GetModeName(bMode); 3170 uint8_t bRing = BS3_MODE_IS_V86(bMode) ? 3 : 0; 3171 unsigned iFlags; 3172 unsigned offBuf; 3173 unsigned iMatch; 3174 unsigned iWorker; 3117 3175 static struct 3118 3176 { … … 3145 3203 Bs3TestPrintf("Note! CMPXCHG16B is not supported by the CPU!\n"); 3146 3204 3205 3147 3206 /* 3148 * One loop with the normal variant and one with the locked one 3207 * Run the tests in all rings since alignment issues may behave 3208 * differently in ring-3 compared to ring-0. 3149 3209 */ 3150 g_usBs3TestStep = 0; 3151 for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++) 3152 { 3153 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker); 3154 3210 for (;;) 3211 { 3155 3212 /* 3156 * One loop with al l status flags set, and one with them clear.3213 * One loop with alignment checks disabled and one with enabled. 3157 3214 */ 3158 Ctx.rflags.u16 |= X86_EFL_STATUS_BITS;3159 for (i Flags = 0; iFlags < 2; iFlags++)3215 unsigned iCfg; 3216 for (iCfg = 0; iCfg < 2; iCfg++) 3160 3217 { 3161 Bs3MemCpy(&ExpectCtx, &Ctx, sizeof(ExpectCtx)); 3162 3163 for (offBuf = 0; offBuf < sizeof(RTUINT128U); offBuf++) 3218 if (iCfg) 3164 3219 { 3220 Ctx.rflags.u32 |= X86_EFL_AC; 3221 Ctx.cr0.u32 |= X86_CR0_AM; 3222 } 3223 else 3224 { 3225 Ctx.rflags.u32 &= ~X86_EFL_AC; 3226 Ctx.cr0.u32 &= ~X86_CR0_AM; 3227 } 3228 3229 /* 3230 * One loop with the normal variant and one with the locked one 3231 */ 3232 g_usBs3TestStep = 0; 3233 for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++) 3234 { 3235 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker); 3236 3237 /* 3238 * One loop with all status flags set, and one with them clear. 3239 */ 3240 Ctx.rflags.u16 |= X86_EFL_STATUS_BITS; 3241 for (iFlags = 0; iFlags < 2; iFlags++) 3242 { 3243 Bs3MemCpy(&ExpectCtx, &Ctx, sizeof(ExpectCtx)); 3244 3245 for (offBuf = 0; offBuf < sizeof(RTUINT128U); offBuf++) 3246 { 3165 3247 # define CX16_OLD_LO UINT64_C(0xabb6345dcc9c4bbd) 3166 3248 # define CX16_OLD_HI UINT64_C(0x7b06ea35749549ab) … … 3170 3252 # define CX16_STORE_HI UINT64_C(0x17ff434ed1b54963) 3171 3253 3172 PRTUINT128U pBuf = (PRTUINT128U)&pau128->au8[offBuf]; 3173 3174 ExpectCtx.rax.u = Ctx.rax.u = CX16_MISMATCH_LO; 3175 ExpectCtx.rdx.u = Ctx.rdx.u = CX16_MISMATCH_HI; 3176 for (iMatch = 0; iMatch < 2; iMatch++) 3177 { 3178 uint8_t bExpectXcpt; 3179 pBuf->s.Lo = CX16_OLD_LO; 3180 pBuf->s.Hi = CX16_OLD_HI; 3181 ExpectCtx.rdi.u = Ctx.rdi.u = (uintptr_t)pBuf; 3182 Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame); 3183 g_usBs3TestStep++; 3184 //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker); 3185 bExpectXcpt = X86_XCPT_UD; 3186 if (fSupportCX16) 3187 { 3188 if (offBuf & 15) 3254 PRTUINT128U pBuf = (PRTUINT128U)&pau128->au8[offBuf]; 3255 3256 ExpectCtx.rax.u = Ctx.rax.u = CX16_MISMATCH_LO; 3257 ExpectCtx.rdx.u = Ctx.rdx.u = CX16_MISMATCH_HI; 3258 for (iMatch = 0; iMatch < 2; iMatch++) 3189 3259 { 3190 bExpectXcpt = X86_XCPT_GP; 3191 ExpectCtx.rip.u = Ctx.rip.u; 3192 ExpectCtx.rflags.u32 = Ctx.rflags.u32; 3260 uint8_t bExpectXcpt; 3261 pBuf->s.Lo = CX16_OLD_LO; 3262 pBuf->s.Hi = CX16_OLD_HI; 3263 ExpectCtx.rdi.u = Ctx.rdi.u = (uintptr_t)pBuf; 3264 Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame); 3265 g_usBs3TestStep++; 3266 //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker); 3267 bExpectXcpt = X86_XCPT_UD; 3268 if (fSupportCX16) 3269 { 3270 if (offBuf & 15) 3271 { 3272 bExpectXcpt = X86_XCPT_GP; 3273 ExpectCtx.rip.u = Ctx.rip.u; 3274 ExpectCtx.rflags.u32 = Ctx.rflags.u32; 3275 } 3276 else 3277 { 3278 ExpectCtx.rax.u = CX16_OLD_LO; 3279 ExpectCtx.rdx.u = CX16_OLD_HI; 3280 if (iMatch & 1) 3281 ExpectCtx.rflags.u32 = Ctx.rflags.u32 | X86_EFL_ZF; 3282 else 3283 ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF; 3284 ExpectCtx.rip.u = Ctx.rip.u + s_aWorkers[iWorker].offUd2; 3285 } 3286 ExpectCtx.rflags.u32 |= X86_EFL_RF; 3287 } 3288 if ( !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &ExpectCtx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 3289 0 /*fExtraEfl*/, pszMode, 0 /*idTestStep*/) 3290 || TrapFrame.bXcpt != bExpectXcpt) 3291 { 3292 if (TrapFrame.bXcpt != bExpectXcpt) 3293 Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd); 3294 Bs3TestFailedF("^^^bRing=%d iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n", bRing, iWorker, iFlags, offBuf, iMatch); 3295 ASMHalt(); 3296 } 3297 3298 ExpectCtx.rax.u = Ctx.rax.u = CX16_OLD_LO; 3299 ExpectCtx.rdx.u = Ctx.rdx.u = CX16_OLD_HI; 3193 3300 } 3194 else3195 {3196 ExpectCtx.rax.u = CX16_OLD_LO;3197 ExpectCtx.rdx.u = CX16_OLD_HI;3198 if (iMatch & 1)3199 ExpectCtx.rflags.u32 = Ctx.rflags.u32 | X86_EFL_ZF;3200 else3201 ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF;3202 ExpectCtx.rip.u = Ctx.rip.u + s_aWorkers[iWorker].offUd2;3203 }3204 ExpectCtx.rflags.u32 |= X86_EFL_RF;3205 3301 } 3206 if ( !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &ExpectCtx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 3207 0 /*fExtraEfl*/, "lm64", 0 /*idTestStep*/) 3208 || TrapFrame.bXcpt != bExpectXcpt) 3209 { 3210 if (TrapFrame.bXcpt != bExpectXcpt) 3211 Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd); 3212 Bs3TestFailedF("^^^ iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n", iWorker, iFlags, offBuf, iMatch); 3213 ASMHalt(); 3214 } 3215 3216 ExpectCtx.rax.u = Ctx.rax.u = CX16_OLD_LO; 3217 ExpectCtx.rdx.u = Ctx.rdx.u = CX16_OLD_HI; 3302 Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS; 3218 3303 } 3219 3304 } 3220 Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS; 3221 } 3305 } /* for each test config. */ 3306 3307 /* 3308 * Next ring. 3309 */ 3310 bRing++; 3311 if (bRing > 3 || bMode == BS3_MODE_RM) 3312 break; 3313 Bs3RegCtxConvertToRingX(&Ctx, bRing); 3222 3314 } 3223 3315
Note:
See TracChangeset
for help on using the changeset viewer.