Changeset 65555 in vbox
- Timestamp:
- Jan 31, 2017 5:22:08 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 113202
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-decoding-1.c32
r65528 r65555 937 937 938 938 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 */ 947 static 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 } 939 1093 940 1094 … … 944 1098 Bs3TestPrintf("g_uBs3CpuDetected=%#x\n", g_uBs3CpuDetected); 945 1099 946 //DecodeEdgeTest(); 1100 Bs3TestSub("MOVBE vs CRC32"); 1101 DecodeMovbeVsCrc32(); 947 1102 948 1103 #if 1 … … 955 1110 #endif 956 1111 1112 #if 1 1113 Bs3TestSub("misc"); 1114 DecodeEdgeTest(); 1115 #endif 1116 957 1117 Bs3TestTerm(); 958 1118 }
Note:
See TracChangeset
for help on using the changeset viewer.