Changeset 60774 in vbox for trunk/src/VBox/ValidationKit/bootsectors
- Timestamp:
- May 2, 2016 12:04:01 AM (9 years ago)
- Location:
- trunk/src/VBox/ValidationKit/bootsectors
- Files:
-
- 1 added
- 11 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-asm.asm
r60676 r60774 81 81 82 82 83 BS3_PROC_BEGIN _bs3CpuBasic2_iret 84 iret 85 BS3_PROC_END _bs3CpuBasic2_iret 86 AssertCompile(_bs3CpuBasic2_iret_EndProc - _bs3CpuBasic2_iret == 1) 87 88 89 BS3_PROC_BEGIN _bs3CpuBasic2_iret_opsize 90 iretd 91 BS3_PROC_END _bs3CpuBasic2_iret_opsize 92 AssertCompile(_bs3CpuBasic2_iret_opsize_EndProc - _bs3CpuBasic2_iret_opsize == 2) 93 94 95 BS3_PROC_BEGIN _bs3CpuBasic2_iret_rexw 96 BS3_SET_BITS 64 97 iretq 98 BS3_SET_BITS 16 99 BS3_PROC_END _bs3CpuBasic2_iret_rexw 100 AssertCompile(_bs3CpuBasic2_iret_rexw_EndProc - _bs3CpuBasic2_iret_rexw == 2) 101 102 83 103 ; 84 104 ; Instantiate code templates. -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c
r60750 r60774 1376 1376 Bs3RegCtxSave(&Ctx); 1377 1377 Ctx.rsp.u -= 0x80; 1378 Ctx.rip.u = (uintptr_t)BS3_FP_OFF(&bs3CpuBasic2_Int80); 1378 1379 Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, bs3CpuBasic2_Int80); 1379 1380 # if TMPL_BITS == 32 1380 1381 g_uBs3TrapEipHint = Ctx.rip.u32; … … 1534 1535 } 1535 1536 1536 1537 BS3_DECL_FAR(uint8_t) TMPL_NM(bs3CpuBasic2_iret)(uint8_t bMode)1538 {1539 g_pszTestMode = TMPL_NM(g_szBs3ModeName);1540 g_bTestMode = bMode;1541 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(TMPL_MODE);1542 1543 Bs3PrintStrN(RT_STR_TUPLE("Hello world!\n"));1544 # if !BS3_MODE_IS_V86(TMPL_MODE)1545 Bs3TestPrintf(RT_STR_TUPLE("Hi there!\n"));1546 # endif1547 return BS3TESTDOMODE_SKIPPED;1548 }1549 1550 1537 #endif /* BS3_INSTANTIATING_MODE */ 1551 1538 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-x0.c
r60750 r60774 80 80 extern FNBS3FAR bs3CpuBasic2_Int82; 81 81 extern FNBS3FAR bs3CpuBasic2_Int83; 82 82 83 extern FNBS3FAR bs3CpuBasic2_ud2; 83 84 #define g_bs3CpuBasic2_ud2_FlatAddr BS3_DATA_NM(g_bs3CpuBasic2_ud2_FlatAddr) 84 85 extern uint32_t g_bs3CpuBasic2_ud2_FlatAddr; 86 87 extern FNBS3FAR bs3CpuBasic2_iret; 88 extern FNBS3FAR bs3CpuBasic2_iret_opsize; 89 extern FNBS3FAR bs3CpuBasic2_iret_rexw; 85 90 86 91 extern FNBS3FAR bs3CpuBasic2_sidt_bx_ud2_c16; … … 142 147 * Global Variables * 143 148 *********************************************************************************************************************************/ 144 #define g_pszTestMode BS3_CMN_NM(g_pszTestMode)145 149 static const char BS3_FAR *g_pszTestMode = (const char *)1; 146 #define g_bTestMode BS3_CMN_NM(g_bTestMode)147 150 static uint8_t g_bTestMode = 1; 148 #define g_f16BitSys BS3_CMN_NM(g_f16BitSys)149 151 static bool g_f16BitSys = 1; 150 152 … … 281 283 #endif 282 284 285 286 /** 287 * Sets globals according to the mode. 288 * 289 * @param bTestMode The test mode. 290 */ 291 static void bs3CpuBasic2_SetGlobals(uint8_t bTestMode) 292 { 293 g_bTestMode = bTestMode; 294 g_pszTestMode = Bs3GetModeName(bTestMode); 295 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bTestMode); 296 g_usBs3TestStep = 0; 297 } 283 298 284 299 … … 2018 2033 } Expected; 2019 2034 2020 g_pszTestMode = Bs3GetModeName(bMode); 2021 g_bTestMode = bMode; 2022 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bMode); 2023 2035 bs3CpuBasic2_SetGlobals(bMode); 2024 2036 2025 2037 /* … … 2048 2060 } Expected; 2049 2061 2050 g_pszTestMode = Bs3GetModeName(bMode); 2051 g_bTestMode = bMode; 2052 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bMode); 2062 bs3CpuBasic2_SetGlobals(bMode); 2053 2063 2054 2064 /* … … 2808 2818 } Expected; 2809 2819 2810 g_pszTestMode = Bs3GetModeName(bMode); 2811 g_bTestMode = bMode; 2812 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bMode); 2820 bs3CpuBasic2_SetGlobals(bMode); 2813 2821 2814 2822 /* … … 2847 2855 } Expected; 2848 2856 2849 g_pszTestMode = Bs3GetModeName(bMode); 2850 g_bTestMode = bMode; 2851 g_f16BitSys = BS3_MODE_IS_16BIT_SYS(bMode); 2857 bs3CpuBasic2_SetGlobals(bMode); 2852 2858 2853 2859 /* … … 2869 2875 } 2870 2876 2877 typedef union IRETBUF 2878 { 2879 uint64_t au64[6]; /* max req is 5 */ 2880 uint32_t au32[12]; /* max req is 9 */ 2881 uint16_t au16[24]; /* max req is 5 */ 2882 uint8_t ab[48]; 2883 } IRETBUF; 2884 typedef IRETBUF BS3_FAR *PIRETBUF; 2885 2886 2887 static void iretbuf_SetupFrame(PIRETBUF pIretBuf, unsigned const cbPop, 2888 uint16_t uCS, uint64_t uPC, uint32_t fEfl, uint16_t uSS, uint64_t uSP) 2889 { 2890 if (cbPop == 2) 2891 { 2892 pIretBuf->au16[0] = (uint16_t)uPC; 2893 pIretBuf->au16[1] = uCS; 2894 pIretBuf->au16[2] = (uint16_t)fEfl; 2895 pIretBuf->au16[3] = (uint16_t)uSP; 2896 pIretBuf->au16[4] = uSS; 2897 } 2898 else if (cbPop != 8) 2899 { 2900 pIretBuf->au32[0] = (uint32_t)uPC; 2901 pIretBuf->au16[1*2] = uCS; 2902 pIretBuf->au32[2] = (uint32_t)fEfl; 2903 pIretBuf->au32[3] = (uint32_t)uSP; 2904 pIretBuf->au16[4*2] = uSS; 2905 } 2906 else 2907 { 2908 pIretBuf->au64[0] = uPC; 2909 pIretBuf->au16[1*4] = uCS; 2910 pIretBuf->au64[2] = fEfl; 2911 pIretBuf->au64[3] = uSP; 2912 pIretBuf->au16[4*4] = uSS; 2913 } 2914 } 2915 2916 uint32_t ASMGetESP(void); 2917 #pragma aux ASMGetESP = \ 2918 ".386" \ 2919 "mov ax, sp" \ 2920 "mov edx, esp" \ 2921 "shr edx, 16" \ 2922 value [ax dx] \ 2923 modify exact [ax dx]; 2924 2925 2926 static void bs3CpuBasic2_iret_Worker(uint8_t bTestMode, FPFNBS3FAR pfnIret, unsigned const cbPop, 2927 PIRETBUF pIretBuf, const char BS3_FAR *pszDesc) 2928 { 2929 BS3TRAPFRAME TrapCtx; 2930 BS3REGCTX Ctx; 2931 BS3REGCTX CtxUdExpected; 2932 BS3REGCTX TmpCtx; 2933 BS3REGCTX TmpCtxExpected; 2934 uint8_t abLowUd[8]; 2935 uint8_t abLowIret[8]; 2936 FPFNBS3FAR pfnUdLow = (FPFNBS3FAR)abLowUd; 2937 FPFNBS3FAR pfnIretLow = (FPFNBS3FAR)abLowIret; 2938 unsigned const cbSameCplFrame = BS3_MODE_IS_64BIT_CODE(bTestMode) ? 5*cbPop : 3*cbPop; 2939 bool const fUseLowCode = cbPop == 2 && !BS3_MODE_IS_16BIT_CODE(bTestMode); 2940 int iRingDst; 2941 int iRingSrc; 2942 uint16_t uDplSs; 2943 uint16_t uRplCs; 2944 uint16_t uRplSs; 2945 // int i; 2946 uint8_t BS3_FAR *pbTest; 2947 2948 NOREF(abLowUd); 2949 #define IRETBUF_SET_SEL(a_idx, a_uValue) \ 2950 do { *(uint16_t)&pIretBuf->ab[a_idx * cbPop] = (a_uValue); } while (0) 2951 #define IRETBUF_SET_REG(a_idx, a_uValue) \ 2952 do { uint8_t const BS3_FAR *pbTmp = &pIretBuf->ab[a_idx * cbPop]; \ 2953 if (cbPop == 2) *(uint16_t)pbTmp = (uint16_t)(a_uValue); \ 2954 else if (cbPop != 8) *(uint32_t)pbTmp = (uint32_t)(a_uValue); \ 2955 else *(uint64_t)pbTmp = (a_uValue); \ 2956 } while (0) 2957 2958 /* make sure they're allocated */ 2959 Bs3MemZero(&Ctx, sizeof(Ctx)); 2960 Bs3MemZero(&CtxUdExpected, sizeof(CtxUdExpected)); 2961 Bs3MemZero(&TmpCtx, sizeof(TmpCtx)); 2962 Bs3MemZero(&TmpCtxExpected, sizeof(TmpCtxExpected)); 2963 Bs3MemZero(&TrapCtx, sizeof(TrapCtx)); 2964 2965 /* 2966 * When dealing with 16-bit irets in 32-bit or 64-bit mode, we must have 2967 * copies of both iret and ud in the first 64KB of memory. The stack is 2968 * below 64KB, so we'll just copy the instructions onto the stack. 2969 */ 2970 Bs3MemCpy(abLowUd, bs3CpuBasic2_ud2, 4); 2971 Bs3MemCpy(abLowIret, pfnIret, 4); 2972 2973 /* 2974 * Create a context (stack is irrelevant, we'll mainly be using pIretBuf). 2975 * - Point the context at our iret instruction. 2976 * - Point SS:xSP at pIretBuf. 2977 */ 2978 Bs3RegCtxSaveEx(&Ctx, bTestMode, 0); 2979 if (!fUseLowCode) 2980 Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, pfnIret); 2981 else 2982 Bs3RegCtxSetRipCsFromCurPtr(&Ctx, pfnIretLow); 2983 if (BS3_MODE_IS_16BIT_SYS(bTestMode)) 2984 g_uBs3TrapEipHint = Ctx.rip.u32; 2985 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rsp, &Ctx.ss, pIretBuf); 2986 2987 /* 2988 * The first success (UD) context keeps the same code bit-count as the iret. 2989 */ 2990 Bs3MemCpy(&CtxUdExpected, &Ctx, sizeof(Ctx)); 2991 if (!fUseLowCode) 2992 Bs3RegCtxSetRipCsFromLnkPtr(&CtxUdExpected, bs3CpuBasic2_ud2); 2993 else 2994 Bs3RegCtxSetRipCsFromCurPtr(&CtxUdExpected, pfnUdLow); 2995 CtxUdExpected.rsp.u += cbSameCplFrame; 2996 2997 /* 2998 * Check that it works at all. 2999 */ 3000 iretbuf_SetupFrame(pIretBuf, cbPop, CtxUdExpected.cs, CtxUdExpected.rip.u, 3001 CtxUdExpected.rflags.u32, CtxUdExpected.ss, CtxUdExpected.rsp.u); 3002 3003 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 3004 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 3005 g_usBs3TestStep++; 3006 3007 if (!BS3_MODE_IS_RM_OR_V86(bTestMode)) 3008 { 3009 /* Selectors are modified when switching rings, so we need to know 3010 what we're dealing with there. */ 3011 if ( !BS3_SEL_IS_IN_R0_RANGE(Ctx.cs) || !BS3_SEL_IS_IN_R0_RANGE(Ctx.ss) 3012 || !BS3_SEL_IS_IN_R0_RANGE(Ctx.ds) || !BS3_SEL_IS_IN_R0_RANGE(Ctx.es)) 3013 Bs3TestFailedF("Expected R0 CS, SS, DS and ES; not %#x, %#x, %#x and %#x\n", Ctx.cs, Ctx.ss, Ctx.ds, Ctx.es); 3014 if (Ctx.fs || Ctx.gs) 3015 Bs3TestFailed("Expected R0 FS and GS to be 0!\n"); 3016 3017 /* 3018 * Test returning to outer rings if protected mode. 3019 */ 3020 Bs3MemCpy(&TmpCtx, &Ctx, sizeof(TmpCtx)); 3021 Bs3MemCpy(&TmpCtxExpected, &CtxUdExpected, sizeof(TmpCtxExpected)); 3022 for (iRingDst = 3; iRingDst >= 0; iRingDst--) 3023 { 3024 Bs3RegCtxConvertToRingX(&TmpCtxExpected, iRingDst); 3025 TmpCtxExpected.ds = iRingDst ? 0 : TmpCtx.ds; 3026 TmpCtx.es = TmpCtxExpected.es; 3027 iretbuf_SetupFrame(pIretBuf, cbPop, TmpCtxExpected.cs, TmpCtxExpected.rip.u, 3028 TmpCtxExpected.rflags.u32, TmpCtxExpected.ss, TmpCtxExpected.rsp.u); 3029 Bs3TrapSetJmpAndRestore(&TmpCtx, &TrapCtx); 3030 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &TmpCtxExpected); 3031 g_usBs3TestStep++; 3032 } 3033 3034 /* 3035 * Check CS.RPL and SS.RPL. 3036 */ 3037 for (iRingDst = 3; iRingDst >= 0; iRingDst--) 3038 { 3039 uint16_t const uDstSsR0 = (CtxUdExpected.ss & BS3_SEL_RING_SUB_MASK) + BS3_SEL_R0_FIRST; 3040 Bs3MemCpy(&TmpCtxExpected, &CtxUdExpected, sizeof(TmpCtxExpected)); 3041 Bs3RegCtxConvertToRingX(&TmpCtxExpected, iRingDst); 3042 for (iRingSrc = 3; iRingSrc >= 0; iRingSrc--) 3043 { 3044 Bs3MemCpy(&TmpCtx, &Ctx, sizeof(TmpCtx)); 3045 Bs3RegCtxConvertToRingX(&TmpCtx, iRingSrc); 3046 TmpCtx.es = TmpCtxExpected.es; 3047 TmpCtxExpected.ds = iRingDst != iRingSrc ? 0 : TmpCtx.ds; 3048 for (uRplCs = 0; uRplCs <= 3; uRplCs++) 3049 { 3050 uint16_t const uSrcEs = TmpCtx.es; 3051 uint16_t const uDstCs = (TmpCtxExpected.cs & X86_SEL_MASK_OFF_RPL) | uRplCs; 3052 //Bs3TestPrintf("dst=%d src=%d rpl=%d\n", iRingDst, iRingSrc, uRplCs); 3053 3054 /* CS.RPL */ 3055 iretbuf_SetupFrame(pIretBuf, cbPop, uDstCs, TmpCtxExpected.rip.u, TmpCtxExpected.rflags.u32, 3056 TmpCtxExpected.ss, TmpCtxExpected.rsp.u); 3057 Bs3TrapSetJmpAndRestore(&TmpCtx, &TrapCtx); 3058 if (uRplCs == iRingDst && iRingDst >= iRingSrc) 3059 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &TmpCtxExpected); 3060 else 3061 { 3062 if (iRingDst < iRingSrc) 3063 TmpCtx.es = 0; 3064 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &TmpCtx, uDstCs & X86_SEL_MASK_OFF_RPL); 3065 TmpCtx.es = uSrcEs; 3066 } 3067 g_usBs3TestStep++; 3068 3069 /* SS.RPL */ 3070 if (iRingDst != iRingSrc || BS3_MODE_IS_64BIT_CODE(bTestMode)) 3071 { 3072 uint16_t uSavedDstSs = TmpCtxExpected.ss; 3073 for (uRplSs = 0; uRplSs <= 3; uRplSs++) 3074 { 3075 /* SS.DPL (iRingDst == CS.DPL) */ 3076 for (uDplSs = 0; uDplSs <= 3; uDplSs++) 3077 { 3078 uint16_t const uDstSs = ((uDplSs << BS3_SEL_RING_SHIFT) | uRplSs) + uDstSsR0; 3079 //Bs3TestPrintf("dst=%d src=%d rplCS=%d rplSS=%d dplSS=%d dst %04x:%08RX64 %08RX32 %04x:%08RX64\n", 3080 // iRingDst, iRingSrc, uRplCs, uRplSs, uDplSs, uDstCs, TmpCtxExpected.rip.u, 3081 // TmpCtxExpected.rflags.u32, uDstSs, TmpCtxExpected.rsp.u); 3082 3083 iretbuf_SetupFrame(pIretBuf, cbPop, uDstCs, TmpCtxExpected.rip.u, 3084 TmpCtxExpected.rflags.u32, uDstSs, TmpCtxExpected.rsp.u); 3085 Bs3TrapSetJmpAndRestore(&TmpCtx, &TrapCtx); 3086 if (uRplCs != iRingDst || iRingDst < iRingSrc) 3087 { 3088 if (iRingDst < iRingSrc) 3089 TmpCtx.es = 0; 3090 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &TmpCtx, uDstCs & X86_SEL_MASK_OFF_RPL); 3091 } 3092 else if (uRplSs != iRingDst || uDplSs != iRingDst) 3093 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &TmpCtx, uDstSs & X86_SEL_MASK_OFF_RPL); 3094 else 3095 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &TmpCtxExpected); 3096 TmpCtx.es = uSrcEs; 3097 g_usBs3TestStep++; 3098 } 3099 } 3100 3101 TmpCtxExpected.ss = uSavedDstSs; 3102 } 3103 } 3104 } 3105 } 3106 } 3107 3108 /* 3109 * Special 64-bit checks. 3110 */ 3111 if (BS3_MODE_IS_64BIT_CODE(bTestMode)) 3112 { 3113 /* The VM flag is completely ignored. */ 3114 iretbuf_SetupFrame(pIretBuf, cbPop, CtxUdExpected.cs, CtxUdExpected.rip.u, 3115 CtxUdExpected.rflags.u32 | X86_EFL_VM, CtxUdExpected.ss, CtxUdExpected.rsp.u); 3116 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 3117 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 3118 g_usBs3TestStep++; 3119 3120 /* The NT flag can be loaded just fine. */ 3121 CtxUdExpected.rflags.u32 |= X86_EFL_NT; 3122 iretbuf_SetupFrame(pIretBuf, cbPop, CtxUdExpected.cs, CtxUdExpected.rip.u, 3123 CtxUdExpected.rflags.u32, CtxUdExpected.ss, CtxUdExpected.rsp.u); 3124 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 3125 bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxUdExpected); 3126 CtxUdExpected.rflags.u32 &= ~X86_EFL_NT; 3127 g_usBs3TestStep++; 3128 3129 /* However, we'll #GP(0) if it's already set (in RFLAGS) when executing IRET. */ 3130 Ctx.rflags.u32 |= X86_EFL_NT; 3131 iretbuf_SetupFrame(pIretBuf, cbPop, CtxUdExpected.cs, CtxUdExpected.rip.u, 3132 CtxUdExpected.rflags.u32, CtxUdExpected.ss, CtxUdExpected.rsp.u); 3133 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 3134 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 3135 g_usBs3TestStep++; 3136 3137 /* The NT flag #GP(0) should trump all other exceptions - pit it against #PF. */ 3138 pbTest = (uint8_t BS3_FAR *)Bs3MemGuardedTestPageAlloc(BS3MEMKIND_TILED); 3139 if (pbTest != NULL) 3140 { 3141 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rsp, &Ctx.ss, &pbTest[X86_PAGE_SIZE]); 3142 iretbuf_SetupFrame(pIretBuf, cbPop, CtxUdExpected.cs, CtxUdExpected.rip.u, 3143 CtxUdExpected.rflags.u32, CtxUdExpected.ss, CtxUdExpected.rsp.u); 3144 Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx); 3145 bs3CpuBasic2_CompareGpCtx(&TrapCtx, &Ctx, 0); 3146 g_usBs3TestStep++; 3147 3148 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rsp, &Ctx.ss, pIretBuf); 3149 Bs3MemGuardedTestPageFree(pbTest); 3150 } 3151 Ctx.rflags.u32 &= ~X86_EFL_NT; 3152 } 3153 } 3154 3155 3156 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_iret)(uint8_t bMode) 3157 { 3158 struct 3159 { 3160 uint8_t abExtraStack[4096]; /**< we've got ~30KB of stack, so 4KB for the trap handlers++ is not a problem. */ 3161 IRETBUF IRetBuf; 3162 uint8_t abGuard[32]; 3163 } uBuf; 3164 size_t cbUnused; 3165 //if (bMode != BS3_MODE_LM64) return BS3TESTDOMODE_SKIPPED; 3166 3167 bs3CpuBasic2_SetGlobals(bMode); 3168 3169 /* 3170 * Primary instruction form. 3171 */ 3172 Bs3MemSet(&uBuf, 0xaa, sizeof(uBuf)); 3173 Bs3MemSet(uBuf.abGuard, 0x88, sizeof(uBuf.abGuard)); 3174 if (BS3_MODE_IS_16BIT_CODE(bMode)) 3175 bs3CpuBasic2_iret_Worker(bMode, bs3CpuBasic2_iret, 2, &uBuf.IRetBuf, "iret"); 3176 else if (BS3_MODE_IS_32BIT_CODE(bMode)) 3177 bs3CpuBasic2_iret_Worker(bMode, bs3CpuBasic2_iret, 4, &uBuf.IRetBuf, "iretd"); 3178 else 3179 bs3CpuBasic2_iret_Worker(bMode, bs3CpuBasic2_iret_rexw, 8, &uBuf.IRetBuf, "o64 iret"); 3180 3181 BS3_ASSERT(ASMMemIsAllU8(uBuf.abGuard, sizeof(uBuf.abGuard), 0x88)); 3182 cbUnused = (uintptr_t)ASMMemFirstMismatchingU8(uBuf.abExtraStack, sizeof(uBuf.abExtraStack) + sizeof(uBuf.IRetBuf), 0xaa) 3183 - (uintptr_t)uBuf.abExtraStack; 3184 if (cbUnused < 2048) 3185 Bs3TestFailedF("cbUnused=%u #%u\n", cbUnused, 1); 3186 3187 /* 3188 * Secondary variation: opsize prefixed. 3189 */ 3190 Bs3MemSet(&uBuf, 0xaa, sizeof(uBuf)); 3191 Bs3MemSet(uBuf.abGuard, 0x88, sizeof(uBuf.abGuard)); 3192 if (BS3_MODE_IS_16BIT_CODE(bMode) && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 3193 bs3CpuBasic2_iret_Worker(bMode, bs3CpuBasic2_iret_opsize, 4, &uBuf.IRetBuf, "o32 iret"); 3194 else if (BS3_MODE_IS_32BIT_CODE(bMode)) 3195 bs3CpuBasic2_iret_Worker(bMode, bs3CpuBasic2_iret_opsize, 2, &uBuf.IRetBuf, "o16 iret"); 3196 else if (BS3_MODE_IS_64BIT_CODE(bMode)) 3197 bs3CpuBasic2_iret_Worker(bMode, bs3CpuBasic2_iret, 4, &uBuf.IRetBuf, "iretd"); 3198 BS3_ASSERT(ASMMemIsAllU8(uBuf.abGuard, sizeof(uBuf.abGuard), 0x88)); 3199 cbUnused = (uintptr_t)ASMMemFirstMismatchingU8(uBuf.abExtraStack, sizeof(uBuf.abExtraStack) + sizeof(uBuf.IRetBuf), 0xaa) 3200 - (uintptr_t)uBuf.abExtraStack; 3201 if (cbUnused < 2048) 3202 Bs3TestFailedF("cbUnused=%u #%u\n", cbUnused, 2); 3203 3204 /* 3205 * Third variation: 16-bit in 64-bit mode (truely unlikely) 3206 */ 3207 if (BS3_MODE_IS_64BIT_CODE(bMode)) 3208 { 3209 Bs3MemSet(&uBuf, 0xaa, sizeof(uBuf)); 3210 Bs3MemSet(uBuf.abGuard, 0x88, sizeof(uBuf.abGuard)); 3211 bs3CpuBasic2_iret_Worker(bMode, bs3CpuBasic2_iret_opsize, 2, &uBuf.IRetBuf, "o16 iret"); 3212 BS3_ASSERT(ASMMemIsAllU8(uBuf.abGuard, sizeof(uBuf.abGuard), 0x88)); 3213 cbUnused = (uintptr_t)ASMMemFirstMismatchingU8(uBuf.abExtraStack, sizeof(uBuf.abExtraStack) + sizeof(uBuf.IRetBuf), 0xaa) 3214 - (uintptr_t)uBuf.abExtraStack; 3215 if (cbUnused < 2048) 3216 Bs3TestFailedF("cbUnused=%u #%u\n", cbUnused, 3); 3217 } 3218 3219 return 0; 3220 } 3221 -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c
r60750 r60774 51 51 static const BS3TESTMODEENTRY g_aModeTest[] = 52 52 { 53 //BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp),53 BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp), 54 54 BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1), 55 55 }; … … 57 57 static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] = 58 58 { 59 //{ "iret", bs3CpuBasic2_iret_f16, 0 }, 59 { "iret", bs3CpuBasic2_iret_f16, 0 }, 60 #if 0 60 61 { "sidt", bs3CpuBasic2_sidt_f16, 0 }, 61 62 { "sgdt", bs3CpuBasic2_sgdt_f16, 0 }, 62 63 { "lidt", bs3CpuBasic2_lidt_f16, 0 }, 63 64 { "lgdt", bs3CpuBasic2_lgdt_f16, 0 }, 65 #endif 64 66 }; 65 67 … … 71 73 Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected); 72 74 73 Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest)); 75 NOREF(g_aModeTest); NOREF(g_aModeByOneTests); /* for when commenting out bits */ 76 //Bs3TestDoModes_rm(g_aModeTest, RT_ELEMENTS(g_aModeTest)); 74 77 Bs3TestDoModesByOne_rm(g_aModeByOneTests, RT_ELEMENTS(g_aModeByOneTests), 0); 75 78 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk
r60749 r60774 98 98 bs3-cmn-RegCtxSetGrpSegFromCurPtr.c \ 99 99 bs3-cmn-RegCtxSetGrpSegFromFlat.c \ 100 bs3-cmn-RegCtxSetRipCsFromCurPtr.c \ 101 bs3-cmn-RegCtxSetRipCsFromFlat.c \ 100 102 bs3-cmn-RegCtxSetRipCsFromLnkPtr.c \ 101 103 bs3-cmn-SelFar32ToFlat32.c \ -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm
r60749 r60774 350 350 ; 64-bit returns are simple because ss:rsp are always restored. 351 351 ; 352 ; A small complication here when returning to a 16-bit stack (only 353 ; applicable to 16-bit and 32-bit code), iret doesn't touch the high 354 ; ESP bits and we can easily later end up with trap handlers 355 ; accessing memory never intended as stack. 356 ; 357 mov rcx, qword [xBX + BS3REGCTX.rsp] ; (also 1st param for conv call below) 358 cmp rcx, 0ffffh 359 ja .iretq_maybe_annoying_16bit_stack 360 cmp rsp, 0ffffh 361 ja .iretq_maybe_annoying_16bit_stack 362 .iretq_ok: 363 352 364 movzx eax, word [xBX + BS3REGCTX.ss] 353 365 push rax … … 358 370 push qword [xBX + BS3REGCTX.rip] 359 371 372 .iretq_restore_regs_and_iret: 360 373 mov es, [xBX + BS3REGCTX.es] 361 374 mov fs, [xBX + BS3REGCTX.fs] … … 379 392 iretq 380 393 394 .iretq_maybe_annoying_16bit_stack: 395 movzx edx, word [xBX + BS3REGCTX.ss] ; (also 2nd param for conv call below) 396 lar eax, dx 397 jnz .iretq_ok 398 test eax, X86LAR_F_D | X86LAR_F_L 399 jnz .iretq_ok ; Returning to a big of long SS needs not extra work. 400 401 lar eax, word [xBX + BS3REGCTX.cs] 402 jnz .iretq_ok 403 test eax, X86LAR_F_L 404 jnz .iretq_ok ; It doesn't matter when returning to 64-bit code. 405 406 ; Convert ss:sp to a flat address. 407 BS3_EXTERN_CMN Bs3SelFar32ToFlat32NoClobber 408 call Bs3SelFar32ToFlat32NoClobber 409 mov rdi, rax 410 411 ; 2nd return frame (32-bit, same CPL). 412 mov eax, [xBX + BS3REGCTX.rflags] 413 mov [rdi - 4], eax 414 movzx eax, word [xBX + BS3REGCTX.cs] 415 mov [rdi - 8], eax 416 mov eax, [xBX + BS3REGCTX.rip] 417 mov [rdi - 12], eax 418 mov ecx, [xBX + BS3REGCTX.rsp] 419 sub cx, 12 420 mov [rdi - 16], ecx 421 422 ; 1st return frame. 423 movzx eax, word [xBX + BS3REGCTX.ss] 424 push rax ; new 16-bit SS 425 sub cx, 4 426 push rcx ; new esp 427 mov rax, [xBX + BS3REGCTX.rflags] 428 and rax, ~(X86_EFL_NT | X86_EFL_TF) 429 push rax ; rflags 430 AssertCompile(BS3_SEL_RING_SHIFT == 8) 431 mov eax, BS3_SEL_R0_CS32 432 add ah, [xBX + BS3REGCTX.bCpl] 433 or al, [xBX + BS3REGCTX.bCpl] 434 push rax ; 32-bit CS 435 push .iretq_pop_real_esp_and_iret_again wrt FLAT 436 jmp .iretq_restore_regs_and_iret 437 438 BS3_SET_BITS 32 439 .iretq_pop_real_esp_and_iret_again: 440 pop esp 441 iretd 442 BS3_SET_BITS 64 443 381 444 %else 382 445 ; … … 417 480 mov esi, [xBX + BS3REGCTX.rsi] 418 481 %if TMPL_BITS == 16 ; if SS is 16-bit, we will not be able to restore the high word. 482 ;; @todo 16-bit stack will also mess us up in 32-bit code, so this needs fixing (see 64-bit above). 419 483 mov edi, [xBX + BS3REGCTX.rsp] 420 484 mov di, sp -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSetRipCsFromFlat.c
r60739 r60774 1 1 /* $Id$ */ 2 2 /** @file 3 * BS3Kit - Bs3RegCtxSetRipCsFrom LnkPtr3 * BS3Kit - Bs3RegCtxSetRipCsFromFlat 4 4 */ 5 5 … … 31 31 32 32 33 #undef Bs3RegCtxSetRipCsFrom LnkPtr34 BS3_CMN_DEF(void, Bs3RegCtxSetRipCsFrom LnkPtr,(PBS3REGCTX pRegCtx, FPFNBS3FAR pfnCode))33 #undef Bs3RegCtxSetRipCsFromFlat 34 BS3_CMN_DEF(void, Bs3RegCtxSetRipCsFromFlat,(PBS3REGCTX pRegCtx, RTCCUINTXREG uFlatCode)) 35 35 { 36 36 if (BS3_MODE_IS_16BIT_CODE(pRegCtx->bMode)) 37 37 { 38 #if ARCH_BITS == 1639 pRegCtx->rip.u = BS3_FP_OFF(pfnCode);40 if (BS3_MODE_IS_RM_OR_V86(pRegCtx->bMode))41 pRegCtx->cs = BS3_FP_SEG(pfnCode);42 else43 pRegCtx->cs = Bs3SelRealModeCodeToProtMode(BS3_FP_SEG(pfnCode));44 #else45 38 uint32_t uFar1616; 46 39 if (BS3_MODE_IS_RM_OR_V86(pRegCtx->bMode)) 47 uFar1616 = Bs3SelFlatCodeToRealMode( (uint32_t)(uintptr_t)pfnCode);40 uFar1616 = Bs3SelFlatCodeToRealMode(uFlatCode); 48 41 else 49 uFar1616 = Bs3SelFlatCodeToProtFar16( (uint32_t)(uintptr_t)pfnCode);42 uFar1616 = Bs3SelFlatCodeToProtFar16(uFlatCode); 50 43 pRegCtx->rip.u = uFar1616 & UINT16_MAX; 51 44 pRegCtx->cs = uFar1616 >> 16; 52 #endif53 45 } 54 46 else 55 47 { 56 #if ARCH_BITS == 16 57 pRegCtx->rip.u = Bs3SelRealModeCodeToFlat(pfnCode); 58 #else 59 pRegCtx->rip.u = (uintptr_t)pfnCode; 60 #endif 48 pRegCtx->rip.u = uFlatCode; 61 49 if (BS3_MODE_IS_32BIT_CODE(pRegCtx->bMode)) 62 50 pRegCtx->cs = BS3_SEL_R0_CS32; -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-StrFormatV.c
r60751 r60774 422 422 { 423 423 State.cchWidth *= 10; 424 State.cchWidth 424 State.cchWidth += ch - '0'; 425 425 ch = *pszFormat++; 426 426 } while (RT_C_IS_DIGIT(ch)); … … 451 451 { 452 452 State.cchPrecision *= 10; 453 State.cchPrecision 453 State.cchPrecision += ch - '0'; 454 454 ch = *pszFormat++; 455 455 } while (RT_C_IS_DIGIT(ch)); -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk
r60749 r60774 78 78 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3RegCtxSetGrpSegFromCurPtr) 79 79 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3RegCtxSetGrpSegFromFlat) 80 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3RegCtxSetRipCsFromCurPtr) 81 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3RegCtxSetRipCsFromFlat) 80 82 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3RegCtxSetRipCsFromLnkPtr) 81 83 $(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabInit) -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h
r60749 r60774 75 75 #define Bs3RegCtxSetGrpSegFromCurPtr BS3_CMN_MANGLER(Bs3RegCtxSetGrpSegFromCurPtr) 76 76 #define Bs3RegCtxSetGrpSegFromFlat BS3_CMN_MANGLER(Bs3RegCtxSetGrpSegFromFlat) 77 #define Bs3RegCtxSetRipCsFromCurPtr BS3_CMN_MANGLER(Bs3RegCtxSetRipCsFromCurPtr) 78 #define Bs3RegCtxSetRipCsFromFlat BS3_CMN_MANGLER(Bs3RegCtxSetRipCsFromFlat) 77 79 #define Bs3RegCtxSetRipCsFromLnkPtr BS3_CMN_MANGLER(Bs3RegCtxSetRipCsFromLnkPtr) 78 80 #define Bs3SelFar32ToFlat32 BS3_CMN_MANGLER(Bs3SelFar32ToFlat32) -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h
r60749 r60774 75 75 #undef Bs3RegCtxSetGrpSegFromCurPtr 76 76 #undef Bs3RegCtxSetGrpSegFromFlat 77 #undef Bs3RegCtxSetRipCsFromCurPtr 78 #undef Bs3RegCtxSetRipCsFromFlat 77 79 #undef Bs3RegCtxSetRipCsFromLnkPtr 78 80 #undef Bs3SelFar32ToFlat32 -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h
r60749 r60774 2445 2445 2446 2446 /** 2447 * Sets CS:RIP to point at the same piece of code as @a uFlatCode. 2448 * 2449 * @param pRegCtx The register context. 2450 * @param uFlatCode Flat code pointer 2451 * @sa Bs3RegCtxSetRipCsFromLnkPtr, Bs3RegCtxSetRipCsFromCurPtr 2452 */ 2453 BS3_CMN_PROTO_STUB(void, Bs3RegCtxSetRipCsFromFlat,(PBS3REGCTX pRegCtx, RTCCUINTXREG uFlatCode)); 2454 2455 /** 2447 2456 * Sets CS:RIP to point at the same piece of code as @a pfnCode. 2448 2457 * … … 2455 2464 * as fixed up by the linker (real mode selector). This 2456 2465 * address is converted to match the mode of the context. 2466 * @sa Bs3RegCtxSetRipCsFromCurPtr, Bs3RegCtxSetRipCsFromFlat 2457 2467 */ 2458 2468 BS3_CMN_PROTO_STUB(void, Bs3RegCtxSetRipCsFromLnkPtr,(PBS3REGCTX pRegCtx, FPFNBS3FAR pfnCode)); 2469 2470 /** 2471 * Sets CS:RIP to point at the same piece of code as @a pfnCode. 2472 * 2473 * @param pRegCtx The register context. 2474 * @param pfnCode Pointer to the code. Current mode pointer. 2475 * @sa Bs3RegCtxSetRipCsFromLnkPtr, Bs3RegCtxSetRipCsFromFlat 2476 */ 2477 BS3_CMN_PROTO_STUB(void, Bs3RegCtxSetRipCsFromCurPtr,(PBS3REGCTX pRegCtx, FPFNBS3FAR pfnCode)); 2459 2478 2460 2479
Note:
See TracChangeset
for help on using the changeset viewer.