VirtualBox

Ignore:
Timestamp:
May 2, 2016 12:04:01 AM (9 years ago)
Author:
vboxsync
Message:

bs3kit: update / iret

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  
    8181
    8282
     83BS3_PROC_BEGIN _bs3CpuBasic2_iret
     84        iret
     85BS3_PROC_END   _bs3CpuBasic2_iret
     86AssertCompile(_bs3CpuBasic2_iret_EndProc - _bs3CpuBasic2_iret == 1)
     87
     88
     89BS3_PROC_BEGIN _bs3CpuBasic2_iret_opsize
     90        iretd
     91BS3_PROC_END   _bs3CpuBasic2_iret_opsize
     92AssertCompile(_bs3CpuBasic2_iret_opsize_EndProc - _bs3CpuBasic2_iret_opsize == 2)
     93
     94
     95BS3_PROC_BEGIN _bs3CpuBasic2_iret_rexw
     96        BS3_SET_BITS 64
     97        iretq
     98        BS3_SET_BITS 16
     99BS3_PROC_END   _bs3CpuBasic2_iret_rexw
     100AssertCompile(_bs3CpuBasic2_iret_rexw_EndProc - _bs3CpuBasic2_iret_rexw == 2)
     101
     102
    83103;
    84104; Instantiate code templates.
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.c

    r60750 r60774  
    13761376    Bs3RegCtxSave(&Ctx);
    13771377    Ctx.rsp.u -= 0x80;
    1378     Ctx.rip.u  = (uintptr_t)BS3_FP_OFF(&bs3CpuBasic2_Int80);
     1378
     1379    Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, bs3CpuBasic2_Int80);
    13791380#  if TMPL_BITS == 32
    13801381    g_uBs3TrapEipHint = Ctx.rip.u32;
     
    15341535}
    15351536
    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 # endif
    1547     return BS3TESTDOMODE_SKIPPED;
    1548 }
    1549 
    15501537#endif /* BS3_INSTANTIATING_MODE */
    15511538
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-x0.c

    r60750 r60774  
    8080extern FNBS3FAR     bs3CpuBasic2_Int82;
    8181extern FNBS3FAR     bs3CpuBasic2_Int83;
     82
    8283extern FNBS3FAR     bs3CpuBasic2_ud2;
    8384#define             g_bs3CpuBasic2_ud2_FlatAddr BS3_DATA_NM(g_bs3CpuBasic2_ud2_FlatAddr)
    8485extern uint32_t     g_bs3CpuBasic2_ud2_FlatAddr;
     86
     87extern FNBS3FAR     bs3CpuBasic2_iret;
     88extern FNBS3FAR     bs3CpuBasic2_iret_opsize;
     89extern FNBS3FAR     bs3CpuBasic2_iret_rexw;
    8590
    8691extern FNBS3FAR     bs3CpuBasic2_sidt_bx_ud2_c16;
     
    142147*   Global Variables                                                                                                             *
    143148*********************************************************************************************************************************/
    144 #define                     g_pszTestMode   BS3_CMN_NM(g_pszTestMode)
    145149static const char BS3_FAR  *g_pszTestMode = (const char *)1;
    146 #define                     g_bTestMode     BS3_CMN_NM(g_bTestMode)
    147150static uint8_t              g_bTestMode = 1;
    148 #define                     g_f16BitSys     BS3_CMN_NM(g_f16BitSys)
    149151static bool                 g_f16BitSys = 1;
    150152
     
    281283#endif
    282284
     285
     286/**
     287 * Sets globals according to the mode.
     288 *
     289 * @param   bTestMode   The test mode.
     290 */
     291static 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}
    283298
    284299
     
    20182033    } Expected;
    20192034
    2020     g_pszTestMode = Bs3GetModeName(bMode);
    2021     g_bTestMode   = bMode;
    2022     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
    2023 
     2035    bs3CpuBasic2_SetGlobals(bMode);
    20242036
    20252037    /*
     
    20482060    } Expected;
    20492061
    2050     g_pszTestMode = Bs3GetModeName(bMode);
    2051     g_bTestMode   = bMode;
    2052     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
     2062    bs3CpuBasic2_SetGlobals(bMode);
    20532063
    20542064    /*
     
    28082818    } Expected;
    28092819
    2810     g_pszTestMode = Bs3GetModeName(bMode);
    2811     g_bTestMode   = bMode;
    2812     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
     2820    bs3CpuBasic2_SetGlobals(bMode);
    28132821
    28142822    /*
     
    28472855    } Expected;
    28482856
    2849     g_pszTestMode = Bs3GetModeName(bMode);
    2850     g_bTestMode   = bMode;
    2851     g_f16BitSys   = BS3_MODE_IS_16BIT_SYS(bMode);
     2857    bs3CpuBasic2_SetGlobals(bMode);
    28522858
    28532859    /*
     
    28692875}
    28702876
     2877typedef 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;
     2884typedef IRETBUF BS3_FAR *PIRETBUF;
     2885
     2886
     2887static 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
     2916uint32_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
     2926static 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
     3156BS3_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  
    5151static const BS3TESTMODEENTRY g_aModeTest[] =
    5252{
    53     //BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp),
     53    BS3TESTMODEENTRY_MODE("tss / gate / esp", bs3CpuBasic2_TssGateEsp),
    5454    BS3TESTMODEENTRY_MODE("raise xcpt #1", bs3CpuBasic2_RaiseXcpt1),
    5555};
     
    5757static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] =
    5858{
    59     //{ "iret", bs3CpuBasic2_iret_f16, 0 },
     59    { "iret", bs3CpuBasic2_iret_f16, 0 },
     60#if 0
    6061    { "sidt", bs3CpuBasic2_sidt_f16, 0 },
    6162    { "sgdt", bs3CpuBasic2_sgdt_f16, 0 },
    6263    { "lidt", bs3CpuBasic2_lidt_f16, 0 },
    6364    { "lgdt", bs3CpuBasic2_lgdt_f16, 0 },
     65#endif
    6466};
    6567
     
    7173    Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
    7274
    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));
    7477    Bs3TestDoModesByOne_rm(g_aModeByOneTests, RT_ELEMENTS(g_aModeByOneTests), 0);
    7578
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk

    r60749 r60774  
    9898       bs3-cmn-RegCtxSetGrpSegFromCurPtr.c \
    9999       bs3-cmn-RegCtxSetGrpSegFromFlat.c \
     100       bs3-cmn-RegCtxSetRipCsFromCurPtr.c \
     101       bs3-cmn-RegCtxSetRipCsFromFlat.c \
    100102       bs3-cmn-RegCtxSetRipCsFromLnkPtr.c \
    101103       bs3-cmn-SelFar32ToFlat32.c \
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxRestore.asm

    r60749 r60774  
    350350        ; 64-bit returns are simple because ss:rsp are always restored.
    351351        ;
     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
    352364        movzx   eax, word [xBX + BS3REGCTX.ss]
    353365        push    rax
     
    358370        push    qword [xBX + BS3REGCTX.rip]
    359371
     372.iretq_restore_regs_and_iret:
    360373        mov     es,  [xBX + BS3REGCTX.es]
    361374        mov     fs,  [xBX + BS3REGCTX.fs]
     
    379392        iretq
    380393
     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
    381444%else
    382445        ;
     
    417480        mov     esi, [xBX + BS3REGCTX.rsi]
    418481 %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).
    419483        mov     edi, [xBX + BS3REGCTX.rsp]
    420484        mov     di, sp
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-RegCtxSetRipCsFromFlat.c

    r60739 r60774  
    11/* $Id$ */
    22/** @file
    3  * BS3Kit - Bs3RegCtxSetRipCsFromLnkPtr
     3 * BS3Kit - Bs3RegCtxSetRipCsFromFlat
    44 */
    55
     
    3131
    3232
    33 #undef Bs3RegCtxSetRipCsFromLnkPtr
    34 BS3_CMN_DEF(void, Bs3RegCtxSetRipCsFromLnkPtr,(PBS3REGCTX pRegCtx, FPFNBS3FAR pfnCode))
     33#undef Bs3RegCtxSetRipCsFromFlat
     34BS3_CMN_DEF(void, Bs3RegCtxSetRipCsFromFlat,(PBS3REGCTX pRegCtx, RTCCUINTXREG uFlatCode))
    3535{
    3636    if (BS3_MODE_IS_16BIT_CODE(pRegCtx->bMode))
    3737    {
    38 #if ARCH_BITS == 16
    39         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         else
    43             pRegCtx->cs = Bs3SelRealModeCodeToProtMode(BS3_FP_SEG(pfnCode));
    44 #else
    4538        uint32_t uFar1616;
    4639        if (BS3_MODE_IS_RM_OR_V86(pRegCtx->bMode))
    47             uFar1616 = Bs3SelFlatCodeToRealMode((uint32_t)(uintptr_t)pfnCode);
     40            uFar1616 = Bs3SelFlatCodeToRealMode(uFlatCode);
    4841        else
    49             uFar1616 = Bs3SelFlatCodeToProtFar16((uint32_t)(uintptr_t)pfnCode);
     42            uFar1616 = Bs3SelFlatCodeToProtFar16(uFlatCode);
    5043        pRegCtx->rip.u = uFar1616 & UINT16_MAX;
    5144        pRegCtx->cs    = uFar1616 >> 16;
    52 #endif
    5345    }
    5446    else
    5547    {
    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;
    6149        if (BS3_MODE_IS_32BIT_CODE(pRegCtx->bMode))
    6250            pRegCtx->cs = BS3_SEL_R0_CS32;
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-StrFormatV.c

    r60751 r60774  
    422422            {
    423423                State.cchWidth *= 10;
    424                 State.cchWidth  = ch - '0';
     424                State.cchWidth += ch - '0';
    425425                ch = *pszFormat++;
    426426            } while (RT_C_IS_DIGIT(ch));
     
    451451                {
    452452                    State.cchPrecision *= 10;
    453                     State.cchPrecision  = ch - '0';
     453                    State.cchPrecision += ch - '0';
    454454                    ch = *pszFormat++;
    455455                } while (RT_C_IS_DIGIT(ch));
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-autostubs.kmk

    r60749 r60774  
    7878$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3RegCtxSetGrpSegFromCurPtr)
    7979$(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)
    8082$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3RegCtxSetRipCsFromLnkPtr)
    8183$(call BS3KIT_FN_GEN_CMN_NEARSTUB,bs3kit-common-16,Bs3SlabInit)
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-define.h

    r60749 r60774  
    7575#define Bs3RegCtxSetGrpSegFromCurPtr BS3_CMN_MANGLER(Bs3RegCtxSetGrpSegFromCurPtr)
    7676#define Bs3RegCtxSetGrpSegFromFlat BS3_CMN_MANGLER(Bs3RegCtxSetGrpSegFromFlat)
     77#define Bs3RegCtxSetRipCsFromCurPtr BS3_CMN_MANGLER(Bs3RegCtxSetRipCsFromCurPtr)
     78#define Bs3RegCtxSetRipCsFromFlat BS3_CMN_MANGLER(Bs3RegCtxSetRipCsFromFlat)
    7779#define Bs3RegCtxSetRipCsFromLnkPtr BS3_CMN_MANGLER(Bs3RegCtxSetRipCsFromLnkPtr)
    7880#define Bs3SelFar32ToFlat32 BS3_CMN_MANGLER(Bs3SelFar32ToFlat32)
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit-mangling-code-undef.h

    r60749 r60774  
    7575#undef Bs3RegCtxSetGrpSegFromCurPtr
    7676#undef Bs3RegCtxSetGrpSegFromFlat
     77#undef Bs3RegCtxSetRipCsFromCurPtr
     78#undef Bs3RegCtxSetRipCsFromFlat
    7779#undef Bs3RegCtxSetRipCsFromLnkPtr
    7880#undef Bs3SelFar32ToFlat32
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h

    r60749 r60774  
    24452445
    24462446/**
     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 */
     2453BS3_CMN_PROTO_STUB(void, Bs3RegCtxSetRipCsFromFlat,(PBS3REGCTX pRegCtx, RTCCUINTXREG uFlatCode));
     2454
     2455/**
    24472456 * Sets CS:RIP to point at the same piece of code as @a pfnCode.
    24482457 *
     
    24552464 *                      as fixed up by the linker (real mode selector).  This
    24562465 *                      address is converted to match the mode of the context.
     2466 * @sa      Bs3RegCtxSetRipCsFromCurPtr, Bs3RegCtxSetRipCsFromFlat
    24572467 */
    24582468BS3_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 */
     2477BS3_CMN_PROTO_STUB(void, Bs3RegCtxSetRipCsFromCurPtr,(PBS3REGCTX pRegCtx, FPFNBS3FAR pfnCode));
    24592478
    24602479
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette