VirtualBox

Changeset 65555 in vbox


Ignore:
Timestamp:
Jan 31, 2017 5:22:08 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
113202
Message:

bs3-cpu-decoding-1: Testcase for MOVBE & CRC32 encoding (the 066h prefix question).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-decoding-1.c32

    r65528 r65555  
    937937
    938938
     939/**
     940 * Checks various prefix encodings with the MOVBE and CRC32
     941 * instructions to try figure out how they are decoded.
     942 *
     943 * The issue here is that both MOVBE and CRC32 are sensitive to
     944 * the operand size prefix, which helps us identify .
     945 *
     946 */
     947static void DecodeMovbeVsCrc32(void)
     948{
     949    uint8_t BS3_FAR *pbPages;
     950
     951    /* Check that the instructions are supported. */
     952    if (   !(g_uBs3CpuDetected & BS3CPU_F_CPUID)
     953        || (ASMCpuId_ECX(1) & (X86_CPUID_FEATURE_ECX_MOVBE | X86_CPUID_FEATURE_ECX_SSE4_2))
     954           !=                 (X86_CPUID_FEATURE_ECX_MOVBE | X86_CPUID_FEATURE_ECX_SSE4_2) )
     955    {
     956        Bs3TestSkipped("not supported");
     957        return;
     958    }
     959
     960    /* Setup a guarded page. */
     961    pbPages = Bs3MemGuardedTestPageAlloc(BS3MEMKIND_FLAT32);
     962    if (pbPages)
     963    {
     964        unsigned        iTest;
     965        BS3REGCTX       Ctx;
     966        BS3TRAPFRAME    TrapFrame;
     967        BS3REGCTX       ExpectCtxMovbe_m32_eax; /*       0f 38 f1 /r */
     968        BS3REGCTX       ExpectCtxMovbe_m16_ax;  /*    66 0f 38 f1 /r */
     969        BS3REGCTX       ExpectCtxCrc32_eax_m32; /*    f2 0f 38 f1 /r */
     970        BS3REGCTX       ExpectCtxCrc32_eax_m16; /* 66 f2 0f 38 f1 /r */
     971        BS3REGCTX       ExpectCtxUd;
     972        PBS3REGCTX      apExpectCtxs[5];
     973        static const struct
     974        {
     975            uint32_t    u32Stored;
     976            uint8_t     iExpectCtx;
     977            uint8_t     bXcpt;
     978            uint8_t     cbOpcodes;
     979            uint8_t     abOpcodes[18];
     980        } s_aTests[] =
     981        {
     982#define BECRC_EAX           UINT32_C(0x11223344)
     983#define BECRC_MEM_ORG       UINT32_C(0x55667788)
     984#define BECRC_MEM_BE16      UINT32_C(0x55664433)
     985#define BECRC_MEM_BE32      UINT32_C(0x44332211)
     986
     987            /* base forms. */
     988            { BECRC_MEM_BE32, 0, X86_XCPT_PF, 4, {             0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     989            { BECRC_MEM_BE16, 1, X86_XCPT_PF, 5, {       P_OZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     990            { BECRC_MEM_ORG,  2, X86_XCPT_PF, 5, {       P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     991            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 6, { P_OZ, P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     992            { BECRC_MEM_ORG,  4, X86_XCPT_UD, 5, {       P_RN, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } }, /* undefined F3 (P_RN) */
     993            { BECRC_MEM_ORG,  4, X86_XCPT_UD, 6, { P_OZ, P_RN, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } }, /* undefined F3 (P_RN) */
     994
     995            /* CRC32 eax, [word ebx]: Simple variations showing it doesn't matter where the prefixes are placed. */
     996            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 6, { P_RZ, P_OZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     997            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 7, { P_RZ, P_OZ, P_ES, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     998            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_RZ, P_SS, P_OZ, P_ES, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     999            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_RZ, P_SS, P_ES, P_OZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1000            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_SS, P_RZ, P_ES, P_OZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1001            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_SS, P_ES, P_RZ, P_OZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1002            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_SS, P_ES, P_OZ, P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1003            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_SS, P_OZ, P_ES, P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1004            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_OZ, P_SS, P_ES, P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1005
     1006            /* CRC32 eax, [word ebx]: Throw the F3h prefix into the mix.  The last of F3 and F2 wins on Skylake. */
     1007            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 7, { P_RN, P_OZ, P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1008            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 7, { P_OZ, P_RN, P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1009            { BECRC_MEM_ORG,  4, X86_XCPT_UD, 7, { P_OZ, P_RZ, P_RN, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1010            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_OZ, P_RZ, P_RN, P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1011            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_RZ, P_RN, P_OZ, P_RZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1012            { BECRC_MEM_ORG,  3, X86_XCPT_PF, 8, { P_RZ, P_RN, P_RZ, P_OZ, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1013
     1014            { BECRC_MEM_ORG,  4, X86_XCPT_UD, 7, { P_OZ, P_RZ, P_RN, 0x0f, 0x38, 0xf1, RM_EAX_DEREF_EBX } },
     1015        };
     1016
     1017        apExpectCtxs[0] = &ExpectCtxMovbe_m32_eax;
     1018        apExpectCtxs[1] = &ExpectCtxMovbe_m16_ax;
     1019        apExpectCtxs[2] = &ExpectCtxCrc32_eax_m32;
     1020        apExpectCtxs[3] = &ExpectCtxCrc32_eax_m16;
     1021        apExpectCtxs[4] = &ExpectCtxUd;
     1022
     1023        Bs3MemZero(&Ctx, sizeof(Ctx));
     1024        Bs3MemZero(&ExpectCtxMovbe_m32_eax, sizeof(ExpectCtxMovbe_m32_eax));
     1025        Bs3MemZero(&ExpectCtxMovbe_m16_ax, sizeof(ExpectCtxMovbe_m16_ax));
     1026        Bs3MemZero(&ExpectCtxCrc32_eax_m32, sizeof(ExpectCtxCrc32_eax_m32));
     1027        Bs3MemZero(&ExpectCtxCrc32_eax_m16, sizeof(ExpectCtxCrc32_eax_m16));
     1028        Bs3MemZero(&ExpectCtxUd, sizeof(ExpectCtxUd));
     1029        Bs3MemZero(&TrapFrame, sizeof(TrapFrame));
     1030
     1031        /* Create a test context. */
     1032        Bs3RegCtxSaveEx(&Ctx, BS3_MODE_CODE_32, 512);
     1033        Ctx.rax.u = BECRC_EAX;
     1034        Ctx.rbx.u = (uintptr_t)pbPages;
     1035
     1036        /* Create expected result contexts. */
     1037        Bs3MemCpy(&ExpectCtxMovbe_m32_eax, &Ctx, sizeof(ExpectCtxMovbe_m32_eax));
     1038        ExpectCtxMovbe_m32_eax.rflags.u32 |= X86_EFL_RF;
     1039        ExpectCtxMovbe_m32_eax.rip.u = (uintptr_t)&pbPages[X86_PAGE_SIZE];
     1040        ExpectCtxMovbe_m32_eax.cr2.u = (uintptr_t)&pbPages[X86_PAGE_SIZE];
     1041
     1042        Bs3MemCpy(&ExpectCtxMovbe_m16_ax, &ExpectCtxMovbe_m32_eax, sizeof(ExpectCtxMovbe_m16_ax));
     1043
     1044        Bs3MemCpy(&ExpectCtxCrc32_eax_m32, &Ctx, sizeof(ExpectCtxCrc32_eax_m32));
     1045        ExpectCtxCrc32_eax_m32.rflags.u32 |= X86_EFL_RF;
     1046        ExpectCtxCrc32_eax_m32.rip.u = (uintptr_t)&pbPages[X86_PAGE_SIZE];
     1047        ExpectCtxCrc32_eax_m32.cr2.u = (uintptr_t)&pbPages[X86_PAGE_SIZE];
     1048        ExpectCtxCrc32_eax_m32.rax.u32 = 0x1aa7cd75;
     1049        Bs3MemCpy(&ExpectCtxCrc32_eax_m16, &ExpectCtxCrc32_eax_m32, sizeof(ExpectCtxCrc32_eax_m16));
     1050        ExpectCtxCrc32_eax_m16.rax.u32 = 0x51ab0518;
     1051
     1052        Bs3MemCpy(&ExpectCtxUd, &Ctx, sizeof(ExpectCtxUd));
     1053        ExpectCtxUd.rflags.u32 |= X86_EFL_RF;
     1054
     1055        /* Loop thru the tests. */
     1056        g_usBs3TestStep = 0;
     1057        for (iTest = 0; iTest < RT_ELEMENTS(s_aTests); iTest++)
     1058        {
     1059            unsigned const   cbOpcodes = s_aTests[iTest].cbOpcodes;
     1060            uint8_t BS3_FAR *pbRip     = &pbPages[X86_PAGE_SIZE - cbOpcodes];
     1061
     1062            Bs3MemCpy(pbRip, s_aTests[iTest].abOpcodes, cbOpcodes);
     1063            Bs3RegCtxSetRipCsFromFlat(&Ctx, (uintptr_t)pbRip);
     1064            *(uint32_t *)pbPages = BECRC_MEM_ORG;
     1065
     1066#if 1
     1067            Bs3TestPrintf("iTest=%d pbRip=%p cbOpcodes=%d: %.*Rhxs\n",
     1068                          iTest, pbRip, cbOpcodes, cbOpcodes, s_aTests[iTest].abOpcodes);
     1069            //Bs3RegCtxPrint(&Ctx);
     1070#endif
     1071            Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame);
     1072            if (s_aTests[iTest].bXcpt == X86_XCPT_UD)
     1073                ExpectCtxUd.rip = Ctx.rip;
     1074            if (   !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, apExpectCtxs[s_aTests[iTest].iExpectCtx],
     1075                                         0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 0 /*fExtraEfl*/, "mode", iTest)
     1076                || TrapFrame.bXcpt      != s_aTests[iTest].bXcpt
     1077                || *(uint32_t *)pbPages != s_aTests[iTest].u32Stored)
     1078            {
     1079                Bs3TestFailedF("iTest=%d cbOpcodes=%d: %.*Rhxs\n", iTest, cbOpcodes, cbOpcodes, s_aTests[iTest].abOpcodes);
     1080                if (TrapFrame.bXcpt != s_aTests[iTest].bXcpt)
     1081                    Bs3TestFailedF("Expected bXcpt=%#x, got %#x\n", s_aTests[iTest].bXcpt, TrapFrame.bXcpt);
     1082                if (*(uint32_t *)pbPages != s_aTests[iTest].u32Stored)
     1083                    Bs3TestFailedF("Expected %#RX32 stored at %p, found: %RX32\n",
     1084                                   s_aTests[iTest].u32Stored, pbPages, *(uint32_t *)pbPages);
     1085            }
     1086        }
     1087
     1088        Bs3MemGuardedTestPageFree(pbPages);
     1089    }
     1090    else
     1091        Bs3TestFailed("Failed to allocate two pages!\n");
     1092}
    9391093
    9401094
     
    9441098    Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected);
    9451099
    946     //DecodeEdgeTest();
     1100    Bs3TestSub("MOVBE vs CRC32");
     1101    DecodeMovbeVsCrc32();
    9471102
    9481103#if 1
     
    9551110#endif
    9561111
     1112#if 1
     1113    Bs3TestSub("misc");
     1114    DecodeEdgeTest();
     1115#endif
     1116
    9571117    Bs3TestTerm();
    9581118}
Note: See TracChangeset for help on using the changeset viewer.

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