VirtualBox

Changeset 97496 in vbox


Ignore:
Timestamp:
Nov 10, 2022 2:53:55 PM (2 years ago)
Author:
vboxsync
Message:

ValKit/bs3-cpu-basic-2: Added some tests of far jumps. bugref:9898

Location:
trunk/src/VBox/ValidationKit/bootsectors
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.mac

    r97489 r97496  
    500500
    501501;*********************************************************************************************************************************
    502 ;*  JMP Tests (simple ones).                                                                                                     *
     502;*  Non-far JMP & CALL Tests (simple ones).                                                                                      *
    503503;*********************************************************************************************************************************
    504504
     
    948948
    949949
     950
     951;*********************************************************************************************************************************
     952;*  FAR JMP & FAR CALL Tests                                                                                                     *
     953;*********************************************************************************************************************************
     954
     955  %if TMPL_BITS == 16
     956BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_rm__ud2
     957BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_rm__ud2, BS3_PBC_NEAR
     958        db      0eah
     959        dw      .again wrt CGROUP16
     960        dw      BS3_SEL_TEXT16
     961.post_jmp:
     962        times 2 int3
     963.again: ud2
     964        int3
     965        jmp     .again
     966BS3_PROC_END_CMN   bs3CpuBasic2_jmpf_ptr_rm__ud2
     967  %endif
     968
     969  %if TMPL_BITS != 64
     970
     971BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_same_r0__ud2
     972BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_same_r0__ud2, BS3_PBC_NEAR
     973        db      0eah
     974  %if TMPL_BITS == 16
     975        dw      .again wrt CGROUP16
     976        dw      BS3_SEL_R0_CS16
     977  %else
     978        dd      .again wrt FLAT
     979        dw      BS3_SEL_R0_CS32
     980  %endif
     981.post_jmp:
     982        times 7 int3
     983.again: ud2
     984        int3
     985        jmp     .again
     986BS3_PROC_END_CMN   bs3CpuBasic2_jmpf_ptr_same_r0__ud2
     987
     988BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_same_r1__ud2
     989BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_same_r1__ud2, BS3_PBC_NEAR
     990        db      0eah                    ; inter privilege jmp -> #GP(dst-cs)
     991  %if TMPL_BITS == 16
     992        dw      .again wrt CGROUP16
     993        dw      BS3_SEL_R1_CS16 | 1
     994  %else
     995        dd      .again wrt FLAT
     996        dw      BS3_SEL_R1_CS32 | 1
     997  %endif
     998.again: ud2
     999        jmp     .again
     1000BS3_PROC_END_CMN   bs3CpuBasic2_jmpf_ptr_same_r1__ud2
     1001
     1002BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_same_r2__ud2
     1003BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_same_r2__ud2, BS3_PBC_NEAR
     1004        db      0eah                    ; inter privilege jmp -> #GP(dst-cs)
     1005  %if TMPL_BITS == 16
     1006        dw      .again wrt CGROUP16
     1007        dw      BS3_SEL_R2_CS16 | 2
     1008  %else
     1009        dd      .again wrt FLAT
     1010        dw      BS3_SEL_R2_CS32 | 2
     1011  %endif
     1012.again: ud2
     1013        jmp     .again
     1014BS3_PROC_END_CMN   bs3CpuBasic2_jmpf_ptr_same_r2__ud2
     1015
     1016BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_same_r3__ud2
     1017BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_same_r3__ud2, BS3_PBC_NEAR
     1018        db      0eah                    ; inter privilege jmp -> #GP(dst-cs)
     1019  %if TMPL_BITS == 16
     1020        dw      .again wrt CGROUP16
     1021        dw      BS3_SEL_R3_CS16 | 3
     1022  %else
     1023        dd      .again wrt FLAT
     1024        dw      BS3_SEL_R3_CS32 | 3
     1025  %endif
     1026.again: ud2
     1027        jmp     .again
     1028BS3_PROC_END_CMN   bs3CpuBasic2_jmpf_ptr_same_r3__ud2
     1029
     1030BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2
     1031BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2, BS3_PBC_NEAR
     1032        db      066h, 0eah
     1033  %if TMPL_BITS == 32
     1034        dw      .again wrt CGROUP16
     1035        dw      BS3_SEL_R0_CS16
     1036  %else
     1037        dd      .again wrt FLAT
     1038        dw      BS3_SEL_R0_CS32
     1039  %endif
     1040        times 4 int3
     1041.again: ud2
     1042        jmp     .again
     1043BS3_PROC_END_CMN   bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2
     1044
     1045; Do a jmp to BS3_SEL_R0_CS64.  Except for when we're in long mode, this will
     1046; result in a 16-bit CS with zero base and 4G limit.
     1047BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2
     1048BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2, BS3_PBC_NEAR
     1049  %if TMPL_BITS == 16
     1050        db      066h
     1051  %endif
     1052        db      0eah
     1053        dd      .jmp_target wrt FLAT
     1054        dw      BS3_SEL_R0_CS64
     1055        times 8 int3
     1056.jmp_target:
     1057        salc                            ; #UD in 64-bit mode
     1058.again: ud2
     1059        jmp     .again
     1060BS3_PROC_END_CMN   bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2
     1061
     1062; Variation of the previous with a CS16 copy that has the L bit set, emulating
     1063; pre-AMD64 software using the L bit for other stuff.  (Don't run in long mode
     1064; w/o copying the 3 bytes to the 0xxxxh memory range.)
     1065BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2
     1066BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2, BS3_PBC_NEAR
     1067  %if TMPL_BITS != 16
     1068        db      066h
     1069  %endif
     1070        db      0eah
     1071        dw      .jmp_target wrt CGROUP16
     1072        dw      BS3_SEL_SPARE_00        ; ASSUMES this is set up as CGROUP16 but with L=1.
     1073        times 3 int3
     1074.jmp_target:
     1075        salc                            ; #UD in 64-bit mode
     1076.again: ud2
     1077        jmp     .again
     1078BS3_PROC_END_CMN   bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2
     1079
     1080 %endif ; TMPL_BITS != 64
     1081
    9501082%endif ; BS3_INSTANTIATING_CMN
    9511083
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-x0.c

    r97489 r97496  
    600600 * Compares \#DB trap.
    601601 */
    602 static void bs3CpuBasic2_CompareDbCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx)
    603 {
     602static void bs3CpuBasic2_CompareDbCtx(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pStartCtx, uint32_t fDr6Expect)
     603{
     604    uint32_t const fDr6 = Bs3RegGetDr6();
     605    fDr6Expect |= X86_DR6_RA1_MASK;
     606    CHECK_MEMBER("dr6", "%#08RX32", fDr6, fDr6Expect);
     607
    604608    bs3CpuBasic2_CompareCpuTrapCtx(pTrapCtx, pStartCtx, 0 /*always zero*/, X86_XCPT_DB, false /*f486ResumeFlagHint?*/, 0 /*cbIpAdjust*/);
    605609}
    606610
     611
     612/**
     613 * Checks that DR6 has the initial value, i.e. is unchanged when other exception
     614 * was raised before a \#DB could occur.
     615 */
     616static void bs3CpuBasic2_CheckDr6InitVal(void)
     617{
     618    uint32_t const fDr6       = Bs3RegGetDr6();
     619    uint32_t const fDr6Expect = X86_DR6_INIT_VAL;
     620    CHECK_MEMBER("dr6", "%#08RX32", fDr6, fDr6Expect);
     621}
    607622
    608623#if 0 /* convert me */
     
    36323647
    36333648/*********************************************************************************************************************************
    3634 *   JMP & CALL Tests                                                                                                             *
     3649*   Non-far JMP & CALL Tests                                                                                                     *
    36353650*********************************************************************************************************************************/
    36363651#define PROTO_ALL(a_Template) \
     
    36903705
    36913706/**
    3692  * Entrypoint for JMP tests.
     3707 * Entrypoint for non-far JMP & CALL tests.
    36933708 *
    36943709 * @returns 0 or BS3TESTDOMODE_SKIPPED.
     
    36983713 *          with control registers and such.
    36993714 */
    3700 BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_jmp_rel)(uint8_t bMode)
     3715BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_jmp_call)(uint8_t bMode)
    37013716{
    37023717    BS3TRAPFRAME        TrapCtx;
     
    38233838            /* Again single stepping: */
    38243839            //Bs3TestPrintf("stepping...\n");
     3840            Bs3RegSetDr6(0);
    38253841            Ctx.rflags.u16        |= X86_EFL_TF;
    38263842            CtxExpected.rflags.u16 = Ctx.rflags.u16;
    38273843            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    38283844            if (s_aTests[iTest].iWrap == 0 || !s_aTests[iTest].fOpSizePfx)
    3829             {
    3830                 /** @todo check DR6.BS. */
    3831                 bs3CpuBasic2_CompareDbCtx(&TrapCtx, &CtxExpected);
    3832             }
     3845                bs3CpuBasic2_CompareDbCtx(&TrapCtx, &CtxExpected, X86_DR6_BS);
    38333846            else
     3847            {
    38343848                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &CtxExpected, 0);
     3849                bs3CpuBasic2_CheckDr6InitVal();
     3850            }
    38353851            Ctx.rflags.u16        &= ~X86_EFL_TF;
    38363852            CtxExpected.rflags.u16 = Ctx.rflags.u16;
     
    40324048                /* Again single stepping: */
    40334049                //Bs3TestPrintf("stepping...\n");
     4050                Bs3RegSetDr6(0);
    40344051                Ctx.rflags.u16        |= X86_EFL_TF;
    40354052                CtxExpected.rflags.u16 = Ctx.rflags.u16;
    40364053                Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    4037                 /** @todo check DR6.BS. */
    4038                 bs3CpuBasic2_CompareDbCtx(&TrapCtx, &CtxExpected);
     4054                bs3CpuBasic2_CompareDbCtx(&TrapCtx, &CtxExpected, X86_DR6_BS);
    40394055                Ctx.rflags.u16        &= ~X86_EFL_TF;
    40404056                CtxExpected.rflags.u16 = Ctx.rflags.u16;
     
    40524068}
    40534069
     4070
     4071/*********************************************************************************************************************************
     4072*   FAR JMP & FAR CALL Tests                                                                                                     *
     4073*********************************************************************************************************************************/
     4074#define PROTO_ALL(a_Template) \
     4075    FNBS3FAR a_Template ## _c16, \
     4076             a_Template ## _c32, \
     4077             a_Template ## _c64
     4078FNBS3FAR  bs3CpuBasic2_jmpf_ptr_rm__ud2_c16;
     4079PROTO_ALL(bs3CpuBasic2_jmpf_ptr_same_r0__ud2);
     4080PROTO_ALL(bs3CpuBasic2_jmpf_ptr_same_r1__ud2);
     4081PROTO_ALL(bs3CpuBasic2_jmpf_ptr_same_r2__ud2);
     4082PROTO_ALL(bs3CpuBasic2_jmpf_ptr_same_r3__ud2);
     4083PROTO_ALL(bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2);
     4084PROTO_ALL(bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2);
     4085PROTO_ALL(bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2);
     4086#undef PROTO_ALL
     4087
     4088
     4089
     4090/**
     4091 * Entrypoint for FAR JMP & FAR CALL tests.
     4092 *
     4093 * @returns 0 or BS3TESTDOMODE_SKIPPED.
     4094 * @param   bMode       The CPU mode we're testing.
     4095 *
     4096 * @note    When testing v8086 code, we'll be running in v8086 mode. So, careful
     4097 *          with control registers and such.
     4098 */
     4099BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuBasic2_far_jmp_call)(uint8_t bMode)
     4100{
     4101    BS3TRAPFRAME        TrapCtx;
     4102    BS3REGCTX           Ctx;
     4103    BS3REGCTX           CtxExpected;
     4104    unsigned            iTest;
     4105
     4106    /* make sure they're allocated  */
     4107    Bs3MemZero(&Ctx, sizeof(Ctx));
     4108    Bs3MemZero(&CtxExpected, sizeof(Ctx));
     4109    Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
     4110
     4111    bs3CpuBasic2_SetGlobals(bMode);
     4112
     4113    /*
     4114     * Create a context.
     4115     */
     4116    Bs3RegCtxSaveEx(&Ctx, bMode, 768);
     4117    Bs3MemCpy(&CtxExpected, &Ctx, sizeof(CtxExpected));
     4118
     4119    if (Ctx.rax.u8 == 0 || Ctx.rax.u8 == 0xff) /* for salc & the 64-bit detection */
     4120        CtxExpected.rax.u8 = Ctx.rax.u8 = 0x42;
     4121
     4122    /*
     4123     * Set up spare selectors.
     4124     */
     4125    Bs3GdteSpare00 = Bs3Gdte_CODE16;
     4126    Bs3GdteSpare00.Gen.u1Long = 1;
     4127
     4128    /*
     4129     * 16-bit tests.
     4130     */
     4131    if (BS3_MODE_IS_16BIT_CODE(bMode))
     4132    {
     4133        static struct
     4134        {
     4135            bool        fRmOrV86;
     4136            bool        fCall;
     4137            uint16_t    uDstSel;
     4138            uint8_t     uDstBits;
     4139            FPFNBS3FAR  pfnTest;
     4140        }
     4141        const s_aTests[] =
     4142        {
     4143            {  true, false, BS3_SEL_TEXT16,         16, bs3CpuBasic2_jmpf_ptr_rm__ud2_c16, },
     4144            { false, false, BS3_SEL_R0_CS16,        16, bs3CpuBasic2_jmpf_ptr_same_r0__ud2_c16, },
     4145            { false, false, BS3_SEL_R1_CS16 | 1,    16, bs3CpuBasic2_jmpf_ptr_same_r1__ud2_c16, },
     4146            { false, false, BS3_SEL_R2_CS16 | 2,    16, bs3CpuBasic2_jmpf_ptr_same_r2__ud2_c16, },
     4147            { false, false, BS3_SEL_R3_CS16 | 3,    16, bs3CpuBasic2_jmpf_ptr_same_r3__ud2_c16, },
     4148            { false, false, BS3_SEL_R0_CS32,        32, bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2_c16, },
     4149            { false, false, BS3_SEL_R0_CS64,        64, bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2_c16, },  /* 16-bit CS, except in LM. */
     4150            { false, false, BS3_SEL_SPARE_00,       64, bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2_c16, }, /* 16-bit CS, except in LM. */
     4151        };
     4152        bool const fRmOrV86 = BS3_MODE_IS_RM_OR_V86(bMode);
     4153
     4154        for (iTest = 0; iTest < RT_ELEMENTS(s_aTests); iTest++)
     4155            if (   s_aTests[iTest].fRmOrV86 == fRmOrV86
     4156                && (s_aTests[iTest].uDstSel != BS3_SEL_SPARE_00 || !BS3_MODE_IS_64BIT_SYS(bMode))) /* skip it in LM16 for now*/
     4157            {
     4158                uint64_t const         uSavedRsp = Ctx.rsp.u;
     4159                bool const             fGp       = !s_aTests[iTest].fCall && (s_aTests[iTest].uDstSel & X86_SEL_RPL) != 0;
     4160                uint8_t const BS3_FAR *fpbCode;
     4161
     4162                Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, s_aTests[iTest].pfnTest);
     4163                fpbCode = (uint8_t const BS3_FAR *)BS3_FP_MAKE(Ctx.cs, Ctx.rip.u16);
     4164                CtxExpected.rip.u = Ctx.rip.u + (int64_t)(int8_t)fpbCode[-1];
     4165                if (   s_aTests[iTest].uDstBits == 32
     4166                    || (   s_aTests[iTest].uDstBits == 64
     4167                        && !BS3_MODE_IS_16BIT_SYS(bMode)
     4168                        && s_aTests[iTest].uDstSel != BS3_SEL_SPARE_00))
     4169                    CtxExpected.rip.u += BS3_ADDR_BS3TEXT16;
     4170                CtxExpected.cs    = s_aTests[iTest].uDstSel;
     4171                if (fGp)
     4172                {
     4173                    CtxExpected.rip.u = Ctx.rip.u;
     4174                    CtxExpected.cs    = Ctx.cs;
     4175                }
     4176                g_uBs3TrapEipHint = CtxExpected.rip.u32;
     4177                CtxExpected.rsp.u = Ctx.rsp.u;
     4178                if (s_aTests[iTest].fCall && !fGp)
     4179                    CtxExpected.rsp.u -= /*s_aTests[iTest].fOpSizePfx ? 8 :*/ 4;
     4180                if (s_aTests[iTest].uDstBits == 64 && !fGp)
     4181                {
     4182                    if (BS3_MODE_IS_64BIT_SYS(bMode))
     4183                        CtxExpected.rip.u -= 1;
     4184                    else
     4185                        CtxExpected.rax.u8 = CtxExpected.rflags.u & X86_EFL_CF ? 0xff : 0x00;
     4186                }
     4187                //Bs3TestPrintf("cs:rip=%04RX16:%04RX64 -> %04RX16:%04RX64\n", Ctx.cs, Ctx.rip.u, CtxExpected.cs, CtxExpected.rip.u);
     4188                Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     4189                if (!fGp)
     4190                    bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxExpected);
     4191                else
     4192                    bs3CpuBasic2_CompareGpCtx(&TrapCtx, &CtxExpected, s_aTests[iTest].uDstSel & X86_TRAP_ERR_SEL_MASK);
     4193                Ctx.rsp.u = uSavedRsp;
     4194                g_usBs3TestStep++;
     4195
     4196                /* Again single stepping: */
     4197                //Bs3TestPrintf("stepping...\n");
     4198                Bs3RegSetDr6(X86_DR6_INIT_VAL);
     4199                Ctx.rflags.u16        |= X86_EFL_TF;
     4200                CtxExpected.rflags.u16 = Ctx.rflags.u16;
     4201                CtxExpected.rax.u      = Ctx.rax.u;
     4202                if (s_aTests[iTest].uDstBits == 64 && !fGp && !BS3_MODE_IS_64BIT_SYS(bMode))
     4203                    CtxExpected.rip.u -= 1;
     4204                Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     4205                if (!fGp)
     4206                    bs3CpuBasic2_CompareDbCtx(&TrapCtx, &CtxExpected, X86_DR6_BS);
     4207                else
     4208                {
     4209                    bs3CpuBasic2_CompareGpCtx(&TrapCtx, &CtxExpected, s_aTests[iTest].uDstSel & X86_TRAP_ERR_SEL_MASK);
     4210                    bs3CpuBasic2_CheckDr6InitVal();
     4211                }
     4212                Ctx.rflags.u16        &= ~X86_EFL_TF;
     4213                CtxExpected.rflags.u16 = Ctx.rflags.u16;
     4214                Ctx.rsp.u              = uSavedRsp;
     4215                g_usBs3TestStep++;
     4216            }
     4217    }
     4218    /*
     4219     * 32-bit tests.
     4220     */
     4221    else if (BS3_MODE_IS_32BIT_CODE(bMode))
     4222    {
     4223        static struct
     4224        {
     4225            bool        fCall;
     4226            uint16_t    uDstSel;
     4227            uint8_t     uDstBits;
     4228            FPFNBS3FAR  pfnTest;
     4229        }
     4230        const s_aTests[] =
     4231        {
     4232            { false, BS3_SEL_R0_CS32,        32, bs3CpuBasic2_jmpf_ptr_same_r0__ud2_c32, },
     4233            { false, BS3_SEL_R1_CS32 | 1,    32, bs3CpuBasic2_jmpf_ptr_same_r1__ud2_c32, },
     4234            { false, BS3_SEL_R2_CS32 | 2,    32, bs3CpuBasic2_jmpf_ptr_same_r2__ud2_c32, },
     4235            { false, BS3_SEL_R3_CS32 | 3,    32, bs3CpuBasic2_jmpf_ptr_same_r3__ud2_c32, },
     4236            { false, BS3_SEL_R0_CS16,        16, bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2_c32, },
     4237            { false, BS3_SEL_R0_CS64,        64, bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2_c32, },  /* 16-bit CS, except in LM. */
     4238            { false, BS3_SEL_SPARE_00,       64, bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2_c32, }, /* 16-bit CS, except in LM. */
     4239        };
     4240
     4241        for (iTest = 0; iTest < RT_ELEMENTS(s_aTests); iTest++)
     4242            if (s_aTests[iTest].uDstSel != BS3_SEL_SPARE_00 || !BS3_MODE_IS_64BIT_SYS(bMode)) /* skip it in LM32 for now*/
     4243            {
     4244                uint64_t const         uSavedRsp = Ctx.rsp.u;
     4245                bool const             fGp       = !s_aTests[iTest].fCall && (s_aTests[iTest].uDstSel & X86_SEL_RPL) != 0;
     4246                uint8_t const BS3_FAR *fpbCode   = Bs3SelLnkPtrToCurPtr(s_aTests[iTest].pfnTest);
     4247
     4248                Ctx.rip.u = Bs3SelLnkPtrToFlat(s_aTests[iTest].pfnTest);
     4249                CtxExpected.rip.u = Ctx.rip.u + (int64_t)(int8_t)fpbCode[-1];
     4250                if (   s_aTests[iTest].uDstBits == 16
     4251                    || (   s_aTests[iTest].uDstBits == 64
     4252                        && (   BS3_MODE_IS_16BIT_SYS(bMode))
     4253                            || s_aTests[iTest].uDstSel == BS3_SEL_SPARE_00))
     4254                    CtxExpected.rip.u -= BS3_ADDR_BS3TEXT16;
     4255                CtxExpected.cs    = s_aTests[iTest].uDstSel;
     4256                if (fGp)
     4257                {
     4258                    CtxExpected.rip.u = Ctx.rip.u;
     4259                    CtxExpected.cs    = Ctx.cs;
     4260                }
     4261                g_uBs3TrapEipHint = CtxExpected.rip.u32;
     4262                CtxExpected.rsp.u = Ctx.rsp.u;
     4263                if (s_aTests[iTest].fCall && !fGp)
     4264                    CtxExpected.rsp.u -= /*s_aTests[iTest].fOpSizePfx ? 4 :*/ 8;
     4265                if (s_aTests[iTest].uDstBits == 64 && !fGp)
     4266                {
     4267                    if (BS3_MODE_IS_64BIT_SYS(bMode))
     4268                        CtxExpected.rip.u -= 1;
     4269                    else
     4270                        CtxExpected.rax.u8 = CtxExpected.rflags.u & X86_EFL_CF ? 0xff : 0x00;
     4271                }
     4272                //Bs3TestPrintf("cs:rip=%04RX16:%04RX64 -> %04RX16:%04RX64\n", Ctx.cs, Ctx.rip.u, CtxExpected.cs, CtxExpected.rip.u);
     4273                Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     4274                if (!fGp)
     4275                    bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxExpected);
     4276                else
     4277                    bs3CpuBasic2_CompareGpCtx(&TrapCtx, &CtxExpected, s_aTests[iTest].uDstSel & X86_TRAP_ERR_SEL_MASK);
     4278                Ctx.rsp.u = uSavedRsp;
     4279                g_usBs3TestStep++;
     4280
     4281                /* Again single stepping: */
     4282                //Bs3TestPrintf("stepping...\n");
     4283                Bs3RegSetDr6(X86_DR6_INIT_VAL);
     4284                Ctx.rflags.u16        |= X86_EFL_TF;
     4285                CtxExpected.rflags.u16 = Ctx.rflags.u16;
     4286                CtxExpected.rax.u      = Ctx.rax.u;
     4287                if (s_aTests[iTest].uDstBits == 64 && !fGp && !BS3_MODE_IS_64BIT_SYS(bMode))
     4288                    CtxExpected.rip.u -= 1;
     4289                Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     4290                if (!fGp)
     4291                    bs3CpuBasic2_CompareDbCtx(&TrapCtx, &CtxExpected, X86_DR6_BS);
     4292                else
     4293                {
     4294                    bs3CpuBasic2_CompareGpCtx(&TrapCtx, &CtxExpected, s_aTests[iTest].uDstSel & X86_TRAP_ERR_SEL_MASK);
     4295                    bs3CpuBasic2_CheckDr6InitVal();
     4296                }
     4297                Ctx.rflags.u16        &= ~X86_EFL_TF;
     4298                CtxExpected.rflags.u16 = Ctx.rflags.u16;
     4299                Ctx.rsp.u              = uSavedRsp;
     4300                g_usBs3TestStep++;
     4301            }
     4302    }
     4303    /*
     4304     * 64-bit tests.
     4305     */
     4306    else if (BS3_MODE_IS_64BIT_CODE(bMode))
     4307    {
     4308        static struct
     4309        {
     4310            bool        fInvalid;
     4311            bool        fCall;
     4312            uint16_t    uDstSel;
     4313            uint8_t     uDstBits;
     4314            FPFNBS3FAR  pfnTest;
     4315        }
     4316        const s_aTests[] =
     4317        {
     4318            /* invalid opcodes: */
     4319            {  true, false, BS3_SEL_R0_CS32,        64, bs3CpuBasic2_jmpf_ptr_same_r0__ud2_c32, },
     4320            {  true, false, BS3_SEL_R1_CS32 | 1,    64, bs3CpuBasic2_jmpf_ptr_same_r1__ud2_c32, },
     4321            {  true, false, BS3_SEL_R2_CS32 | 2,    64, bs3CpuBasic2_jmpf_ptr_same_r2__ud2_c32, },
     4322            {  true, false, BS3_SEL_R3_CS32 | 3,    64, bs3CpuBasic2_jmpf_ptr_same_r3__ud2_c32, },
     4323            {  true, false, BS3_SEL_R0_CS16,        64, bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2_c32, },
     4324            {  true, false, BS3_SEL_R0_CS64,        64, bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2_c32, },
     4325            {  true, false, BS3_SEL_SPARE_00,       64, bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2_c32, },
     4326        };
     4327
     4328        for (iTest = 0; iTest < RT_ELEMENTS(s_aTests); iTest++)
     4329        {
     4330            uint64_t const         uSavedRsp = Ctx.rsp.u;
     4331            bool const             fUd       = s_aTests[iTest].fInvalid;
     4332            bool const             fGp       = !s_aTests[iTest].fCall && (s_aTests[iTest].uDstSel & X86_SEL_RPL) != 0;
     4333            uint8_t const BS3_FAR *fpbCode   = Bs3SelLnkPtrToCurPtr(s_aTests[iTest].pfnTest);
     4334
     4335            Ctx.rip.u = Bs3SelLnkPtrToFlat(s_aTests[iTest].pfnTest);
     4336            CtxExpected.rip.u = Ctx.rip.u + (int64_t)(int8_t)fpbCode[-1];
     4337            CtxExpected.cs    = s_aTests[iTest].uDstSel;
     4338            if (fGp || fUd)
     4339            {
     4340                CtxExpected.rip.u = Ctx.rip.u;
     4341                CtxExpected.cs    = Ctx.cs;
     4342            }
     4343            g_uBs3TrapEipHint = CtxExpected.rip.u32;
     4344            CtxExpected.rsp.u = Ctx.rsp.u;
     4345            if (s_aTests[iTest].fCall && !fGp && !fUd)
     4346                CtxExpected.rsp.u -= /*s_aTests[iTest].fOpSizePfx ? 4 :*/ 8;
     4347            //Bs3TestPrintf("cs:rip=%04RX16:%04RX64 -> %04RX16:%04RX64\n", Ctx.cs, Ctx.rip.u, CtxExpected.cs, CtxExpected.rip.u);
     4348            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     4349            if (!fGp || fUd)
     4350                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxExpected);
     4351            else
     4352                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &CtxExpected, s_aTests[iTest].uDstSel & X86_TRAP_ERR_SEL_MASK);
     4353            Ctx.rsp.u = uSavedRsp;
     4354            g_usBs3TestStep++;
     4355
     4356            /* Again single stepping: */
     4357            //Bs3TestPrintf("stepping...\n");
     4358            Bs3RegSetDr6(X86_DR6_INIT_VAL);
     4359            Ctx.rflags.u16        |= X86_EFL_TF;
     4360            CtxExpected.rflags.u16 = Ctx.rflags.u16;
     4361            CtxExpected.rax.u      = Ctx.rax.u;
     4362            Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     4363            if (fUd)
     4364                bs3CpuBasic2_CompareUdCtx(&TrapCtx, &CtxExpected);
     4365            else if (!fGp)
     4366                bs3CpuBasic2_CompareDbCtx(&TrapCtx, &CtxExpected, X86_DR6_BS);
     4367            else
     4368            {
     4369                bs3CpuBasic2_CompareGpCtx(&TrapCtx, &CtxExpected, s_aTests[iTest].uDstSel & X86_TRAP_ERR_SEL_MASK);
     4370                bs3CpuBasic2_CheckDr6InitVal();
     4371            }
     4372            Ctx.rflags.u16        &= ~X86_EFL_TF;
     4373            CtxExpected.rflags.u16 = Ctx.rflags.u16;
     4374            Ctx.rsp.u              = uSavedRsp;
     4375            g_usBs3TestStep++;
     4376        }
     4377    }
     4378    else
     4379        Bs3TestFailed("wtf?");
     4380
     4381    return 0;
     4382}
     4383
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2.c

    r97451 r97496  
    5555FNBS3TESTDOMODE             bs3CpuBasic2_lgdt_f16;
    5656FNBS3TESTDOMODE             bs3CpuBasic2_iret_f16;
    57 FNBS3TESTDOMODE             bs3CpuBasic2_jmp_rel_f16;
     57FNBS3TESTDOMODE             bs3CpuBasic2_jmp_call_f16;
     58FNBS3TESTDOMODE             bs3CpuBasic2_far_jmp_call_f16;
    5859
    5960BS3_DECL_CALLBACK(void)     bs3CpuBasic2_Do32BitTests_pe32();
     
    7677#if 1
    7778    //{ "iret", bs3CpuBasic2_iret_f16, 0 },
    78     { "jmp jb / jv / ind",  bs3CpuBasic2_jmp_rel_f16, 0 },
     79    //{ "jmp+call jb / jv / ind",  bs3CpuBasic2_jmp_call_f16, 0 },
     80    { "far jmp+call",  bs3CpuBasic2_far_jmp_call_f16, 0 },
    7981#endif
    8082#if 0
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