17#define DATA_SIZE_INVALID 0
34(*DATA_MANIP_EXEC_FUNCTION) (
445 IN BOOLEAN IsSignedOp
1250CONST DATA_MANIP_EXEC_FUNCTION mDataManipDispatchTable[] = {
1342CONST UINT8 mJMPLen[] = { 2, 2, 6, 10 };
1368 UINTN InstructionsLeft;
1369 UINTN SavedInstructionCount;
1373 if (*InstructionCount == 0) {
1374 InstructionsLeft = 1;
1376 InstructionsLeft = *InstructionCount;
1379 SavedInstructionCount = *InstructionCount;
1380 *InstructionCount = 0;
1387 while (InstructionsLeft != 0) {
1388 ExecFunc = (
UINTN)mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction;
1391 return EFI_UNSUPPORTED;
1393 mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction (VmPtr);
1394 *InstructionCount = *InstructionCount + 1;
1400 if (SavedInstructionCount != 0) {
1423 UINT8 StackCorrupted;
1428 EbcSimpleDebugger =
NULL;
1435 if (*VmPtr->StackMagicPtr != (
UINTN)VM_STACK_KEY_VALUE) {
1439 VmPtr->FramePtr = (VOID *)((UINT8 *)(
UINTN)VmPtr->Gpr[0] + 8);
1445 Status =
gBS->LocateProtocol (
1446 &gEfiEbcSimpleDebuggerProtocolGuid,
1448 (VOID **)&EbcSimpleDebugger
1450 if (EFI_ERROR (Status)) {
1451 EbcSimpleDebugger =
NULL;
1461 VmPtr->EntryPoint = (VOID *)VmPtr->Ip;
1467 VmPtr->StopFlags = 0;
1468 while ((VmPtr->StopFlags & STOPFLAG_APP_DONE) == 0) {
1473 if (EbcSimpleDebugger !=
NULL) {
1474 EbcSimpleDebugger->Debugger (EbcSimpleDebugger, VmPtr);
1483 ExecFunc = (
UINTN)mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction;
1486 Status = EFI_UNSUPPORTED;
1498 mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction (VmPtr);
1508 if (VMFLAG_ISSET (VmPtr, VMFLAGS_STEP)) {
1515 if ((StackCorrupted == 0) && (*VmPtr->StackMagicPtr != (
UINTN)VM_STACK_KEY_VALUE)) {
1520 if ((StackCorrupted == 0) && ((UINT64)VmPtr->Gpr[0] <= (UINT64)(
UINTN)VmPtr->StackTop)) {
1571 Opcode = GETOPCODE (VmPtr);
1572 OpcMasked = (UINT8)(Opcode & OPCODE_M_OPCODE);
1577 Operands = GETOPERANDS (VmPtr);
1591 if ((Opcode & (OPCODE_M_IMMED_OP1 | OPCODE_M_IMMED_OP2)) != 0) {
1595 if ((OpcMasked <= OPCODE_MOVQW) || (OpcMasked == OPCODE_MOVNW)) {
1600 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) {
1602 Index64Op1 = (INT64)Index16;
1603 Size +=
sizeof (UINT16);
1606 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) {
1608 Index64Op2 = (INT64)Index16;
1609 Size +=
sizeof (UINT16);
1611 }
else if ((OpcMasked <= OPCODE_MOVQD) || (OpcMasked == OPCODE_MOVND)) {
1615 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) {
1617 Index64Op1 = (INT64)Index32;
1618 Size +=
sizeof (UINT32);
1621 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) {
1623 Index64Op2 = (INT64)Index32;
1624 Size +=
sizeof (UINT32);
1626 }
else if (OpcMasked == OPCODE_MOVQQ) {
1630 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) {
1632 Size +=
sizeof (UINT64);
1635 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) {
1637 Size +=
sizeof (UINT64);
1645 EXCEPTION_FLAG_FATAL,
1648 return EFI_UNSUPPORTED;
1656 if ((OpcMasked == OPCODE_MOVBW) || (OpcMasked == OPCODE_MOVBD)) {
1657 MoveSize = DATA_SIZE_8;
1659 }
else if ((OpcMasked == OPCODE_MOVWW) || (OpcMasked == OPCODE_MOVWD)) {
1660 MoveSize = DATA_SIZE_16;
1662 }
else if ((OpcMasked == OPCODE_MOVDW) || (OpcMasked == OPCODE_MOVDD)) {
1663 MoveSize = DATA_SIZE_32;
1664 DataMask = 0xFFFFFFFF;
1665 }
else if ((OpcMasked == OPCODE_MOVQW) || (OpcMasked == OPCODE_MOVQD) || (OpcMasked == OPCODE_MOVQQ)) {
1666 MoveSize = DATA_SIZE_64;
1667 DataMask = (UINT64) ~0;
1668 }
else if ((OpcMasked == OPCODE_MOVNW) || (OpcMasked == OPCODE_MOVND)) {
1669 MoveSize = DATA_SIZE_N;
1670 DataMask = (UINT64) ~0 >> (64 - 8 *
sizeof (
UINTN));
1676 return EFI_UNSUPPORTED;
1682 if (OPERAND2_INDIRECT (Operands)) {
1686 Source = (
UINTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index64Op2);
1693 Data64 = (UINT64)(UINT8)
VmReadMem8 (VmPtr, Source);
1697 Data64 = (UINT64)(UINT16)
VmReadMem16 (VmPtr, Source);
1701 Data64 = (UINT64)(UINT32)
VmReadMem32 (VmPtr, Source);
1722 Data64 = (UINT64)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index64Op2);
1727 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) {
1741 if ((OPERAND2_REGNUM (Operands) == 0) &&
1742 (!OPERAND2_INDIRECT (Operands)) &&
1744 (OPERAND1_REGNUM (Operands) == 0) &&
1745 (OPERAND1_INDIRECT (Operands))
1756 if (OPERAND1_INDIRECT (Operands)) {
1760 Source = (
UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index64Op1);
1796 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) {
1799 EXCEPTION_FLAG_FATAL,
1802 return EFI_UNSUPPORTED;
1809 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Data64 & DataMask;
1834 VOID *EbcEntryPoint;
1836 UINT64 U64EbcEntryPoint;
1840 Operands = GETOPERANDS (VmPtr);
1866 VmPtr->StopFlags |= STOPFLAG_BREAKPOINT;
1871 EXCEPT_EBC_BREAKPOINT,
1872 EXCEPTION_FLAG_NONE,
1890 U64EbcEntryPoint = (UINT64)(VmPtr->Gpr[7] + Offset + 4);
1891 EbcEntryPoint = (VOID *)(
UINTN)U64EbcEntryPoint;
1896 Status =
EbcCreateThunks (VmPtr->ImageHandle, EbcEntryPoint, &Thunk, 0);
1897 if (EFI_ERROR (Status)) {
1911 VmPtr->CompilerVersion = (UINT32)VmPtr->Gpr[7];
1964 UINT8 ConditionFlag;
1971 Operand = GETOPERANDS (VmPtr);
1972 Opcode = GETOPCODE (VmPtr);
1978 Size = mJMPLen[(Opcode >> 6) & 0x03];
1984 CompareSet = (UINT8)(((Operand & JMP_M_CS) != 0) ? 1 : 0);
1985 ConditionFlag = (UINT8)VMFLAG_ISSET (VmPtr, VMFLAGS_CC);
1986 if ((Operand & CONDITION_M_CONDITIONAL) != 0) {
1987 if (CompareSet != ConditionFlag) {
1999 if ((Opcode & OPCODE_M_IMMDATA64) != 0) {
2004 if ((Opcode & OPCODE_M_IMMDATA) == 0) {
2007 EXCEPTION_FLAG_ERROR,
2010 return EFI_UNSUPPORTED;
2020 EXCEPT_EBC_ALIGNMENT_CHECK,
2021 EXCEPTION_FLAG_FATAL,
2025 return EFI_UNSUPPORTED;
2032 if ((Operand & JMP_M_RELATIVE) != 0) {
2033 VmPtr->Ip += (
UINTN)Data64 + Size;
2050 if ((Opcode & OPCODE_M_IMMDATA) != 0) {
2051 if (OPERAND1_INDIRECT (Operand)) {
2063 if (OPERAND1_REGNUM (Operand) == 0) {
2066 Data64 = (UINT64)OPERAND1_REGDATA (VmPtr, Operand);
2072 if (OPERAND1_INDIRECT (Operand)) {
2079 EXCEPT_EBC_ALIGNMENT_CHECK,
2080 EXCEPTION_FLAG_FATAL,
2084 return EFI_UNSUPPORTED;
2088 if ((Operand & JMP_M_RELATIVE) != 0) {
2089 VmPtr->Ip += (
UINTN)Addr + Size;
2091 VmPtr->Ip = (
VMIP)Addr;
2099 Addr = (
UINTN)(Data64 + Index32);
2102 EXCEPT_EBC_ALIGNMENT_CHECK,
2103 EXCEPTION_FLAG_FATAL,
2107 return EFI_UNSUPPORTED;
2111 if ((Operand & JMP_M_RELATIVE) != 0) {
2112 VmPtr->Ip += (
UINTN)Addr + Size;
2114 VmPtr->Ip = (
VMIP)Addr;
2140 UINT8 ConditionFlag;
2147 Opcode = GETOPCODE (VmPtr);
2148 CompareSet = (UINT8)(((Opcode & JMP_M_CS) != 0) ? 1 : 0);
2149 ConditionFlag = (UINT8)VMFLAG_ISSET (VmPtr, VMFLAGS_CC);
2154 if ((Opcode & CONDITION_M_CONDITIONAL) != 0) {
2155 if (CompareSet != ConditionFlag) {
2172 VmPtr->Ip += (Offset * 2) + 2;
2214 Opcode = GETOPCODE (VmPtr);
2215 Operands = GETOPERANDS (VmPtr);
2220 if ((Operands & MOVI_M_IMMDATA) != 0) {
2231 if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
2234 }
else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
2237 }
else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
2246 EXCEPTION_FLAG_FATAL,
2249 return EFI_UNSUPPORTED;
2255 if (!OPERAND1_INDIRECT (Operands)) {
2259 if ((Operands & MOVI_M_IMMDATA) != 0) {
2262 EXCEPTION_FLAG_FATAL,
2265 return EFI_UNSUPPORTED;
2271 if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH8) {
2272 Mask64 = 0x000000FF;
2273 }
else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH16) {
2274 Mask64 = 0x0000FFFF;
2275 }
else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH32) {
2276 Mask64 = 0x00000000FFFFFFFF;
2278 Mask64 = (UINT64) ~0;
2281 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = ImmData64 & Mask64;
2286 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;
2287 if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH8) {
2289 }
else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH16) {
2291 }
else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH32) {
2336 Opcode = GETOPCODE (VmPtr);
2337 Operands = GETOPERANDS (VmPtr);
2342 if ((Operands & MOVI_M_IMMDATA) != 0) {
2353 if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
2355 ImmedIndex64 = (INT64)ImmedIndex16;
2357 }
else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
2359 ImmedIndex64 = (INT64)ImmedIndex32;
2361 }
else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
2370 EXCEPTION_FLAG_FATAL,
2373 return EFI_UNSUPPORTED;
2379 if (!OPERAND1_INDIRECT (Operands)) {
2384 if ((Operands & MOVI_M_IMMDATA) != 0) {
2387 EXCEPTION_FLAG_FATAL,
2390 return EFI_UNSUPPORTED;
2393 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = ImmedIndex64;
2398 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;
2439 Opcode = GETOPCODE (VmPtr);
2440 Operands = GETOPERANDS (VmPtr);
2445 if ((Operands & MOVI_M_IMMDATA) != 0) {
2456 if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
2459 }
else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
2462 }
else if ((Opcode & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
2471 EXCEPTION_FLAG_FATAL,
2474 return EFI_UNSUPPORTED;
2480 Op2 = (UINT64)((INT64)((UINT64)(
UINTN)VmPtr->Ip) + (INT64)ImmData64 + Size);
2481 if (!OPERAND1_INDIRECT (Operands)) {
2485 if ((Operands & MOVI_M_IMMDATA) != 0) {
2488 EXCEPTION_FLAG_FATAL,
2491 return EFI_UNSUPPORTED;
2494 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (VM_REGISTER)Op2;
2501 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;
2546 Opcode = GETOPCODE (VmPtr);
2547 Operands = GETOPERANDS (VmPtr);
2549 Op1Index = Op2Index = 0;
2555 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) {
2556 if (OPERAND1_INDIRECT (Operands)) {
2564 EXCEPTION_FLAG_FATAL,
2567 return EFI_UNSUPPORTED;
2570 Size +=
sizeof (UINT16);
2573 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) {
2574 if (OPERAND2_INDIRECT (Operands)) {
2580 Size +=
sizeof (UINT16);
2586 Op2 = (UINT64)(INT64)(
INTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Op2Index);
2587 if (OPERAND2_INDIRECT (Operands)) {
2594 if (!OPERAND1_INDIRECT (Operands)) {
2595 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Op2;
2641 Opcode = GETOPCODE (VmPtr);
2642 Operands = GETOPERANDS (VmPtr);
2644 Op1Index = Op2Index = 0;
2650 if ((Opcode & OPCODE_M_IMMED_OP1) != 0) {
2651 if (OPERAND1_INDIRECT (Operands)) {
2659 EXCEPTION_FLAG_FATAL,
2662 return EFI_UNSUPPORTED;
2665 Size +=
sizeof (UINT32);
2668 if ((Opcode & OPCODE_M_IMMED_OP2) != 0) {
2669 if (OPERAND2_INDIRECT (Operands)) {
2675 Size +=
sizeof (UINT32);
2681 Op2 = (UINT64)(INT64)(
INTN)(INT64)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Op2Index);
2682 if (OPERAND2_INDIRECT (Operands)) {
2689 if (!OPERAND1_INDIRECT (Operands)) {
2690 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Op2;
2726 Opcode = GETOPCODE (VmPtr);
2727 Operands = GETOPERANDS (VmPtr);
2732 if ((Opcode & PUSHPOP_M_IMMDATA) != 0) {
2733 if (OPERAND1_INDIRECT (Operands)) {
2748 if (OPERAND1_INDIRECT (Operands)) {
2749 DataN =
VmReadMemN (VmPtr, (
UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16));
2751 DataN = (
UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16);
2757 VmPtr->Gpr[0] -=
sizeof (
UINTN);
2787 Opcode = GETOPCODE (VmPtr);
2788 Operands = GETOPERANDS (VmPtr);
2792 if ((Opcode & PUSHPOP_M_IMMDATA) != 0) {
2793 if (OPERAND1_INDIRECT (Operands)) {
2808 if ((Opcode & PUSHPOP_M_64) != 0) {
2809 if (OPERAND1_INDIRECT (Operands)) {
2810 Data64 =
VmReadMem64 (VmPtr, (
UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16));
2812 Data64 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;
2818 VmPtr->Gpr[0] -=
sizeof (UINT64);
2824 if (OPERAND1_INDIRECT (Operands)) {
2825 Data32 =
VmReadMem32 (VmPtr, (
UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16));
2827 Data32 = (UINT32)VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;
2833 VmPtr->Gpr[0] -=
sizeof (UINT32);
2864 Opcode = GETOPCODE (VmPtr);
2865 Operands = GETOPERANDS (VmPtr);
2869 if ((Opcode & PUSHPOP_M_IMMDATA) != 0) {
2870 if (OPERAND1_INDIRECT (Operands)) {
2886 VmPtr->Gpr[0] +=
sizeof (
UINTN);
2890 if (OPERAND1_INDIRECT (Operands)) {
2891 VmWriteMemN (VmPtr, (
UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), DataN);
2893 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (INT64)(UINT64)(
UINTN)(DataN + Index16);
2924 Opcode = GETOPCODE (VmPtr);
2925 Operands = GETOPERANDS (VmPtr);
2929 if ((Opcode & PUSHPOP_M_IMMDATA) != 0) {
2930 if (OPERAND1_INDIRECT (Operands)) {
2945 if ((Opcode & PUSHPOP_M_64) != 0) {
2950 VmPtr->Gpr[0] +=
sizeof (UINT64);
2954 if (OPERAND1_INDIRECT (Operands)) {
2955 VmWriteMem64 (VmPtr, (
UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), Data64);
2957 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Data64 + Index16;
2964 VmPtr->Gpr[0] +=
sizeof (UINT32);
2968 if (OPERAND1_INDIRECT (Operands)) {
2969 VmWriteMem32 (VmPtr, (
UINTN)(VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), Data32);
2971 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (INT64)Data32 + Index16;
3009 Opcode = GETOPCODE (VmPtr);
3010 Operands = GETOPERANDS (VmPtr);
3012 if ((Operands & OPERAND_M_NATIVE_CALL) != 0) {
3024 FramePtr = VmPtr->FramePtr;
3028 if ((Opcode & OPCODE_M_IMMDATA) != 0) {
3029 if ((Opcode & OPCODE_M_IMMDATA64) != 0) {
3036 if (OPERAND1_INDIRECT (Operands)) {
3052 if ((Operands & OPERAND_M_NATIVE_CALL) == 0) {
3055 VmPtr->FramePtr = (VOID *)(
UINTN)VmPtr->Gpr[0];
3063 if ((Opcode & OPCODE_M_IMMDATA64) != 0) {
3067 if ((Operands & OPERAND_M_NATIVE_CALL) == 0) {
3081 if (OPERAND1_REGNUM (Operands) != 0) {
3082 Immed64 = (UINT64)(
UINTN)VmPtr->Gpr[OPERAND1_REGNUM (Operands)];
3088 if (OPERAND1_INDIRECT (Operands)) {
3097 if ((Operands & OPERAND_M_NATIVE_CALL) == 0) {
3102 if ((Operands & OPERAND_M_RELATIVE_ADDR) != 0) {
3103 VmPtr->Ip += Immed64 + Size;
3111 if ((Operands & OPERAND_M_RELATIVE_ADDR) != 0) {
3114 if ((VmPtr->StopFlags & STOPFLAG_BREAK_ON_CALLEX) != 0) {
3123 if ((Operands & OPERAND_M_NATIVE_CALL) != 0) {
3154 if (VmPtr->StackRetAddr == (UINT64)VmPtr->Gpr[0]) {
3155 VmPtr->StopFlags |= STOPFLAG_APP_DONE;
3163 EXCEPT_EBC_ALIGNMENT_CHECK,
3164 EXCEPTION_FLAG_FATAL,
3211 Opcode = GETOPCODE (VmPtr);
3212 Operands = GETOPERANDS (VmPtr);
3216 Op1 = VmPtr->Gpr[OPERAND1_REGNUM (Operands)];
3220 if ((Opcode & OPCODE_M_IMMDATA) != 0) {
3221 if (OPERAND2_INDIRECT (Operands)) {
3236 if (OPERAND2_INDIRECT (Operands)) {
3237 if ((Opcode & OPCODE_M_64BIT) != 0) {
3238 Op2 = (INT64)
VmReadMem64 (VmPtr, (
UINTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16));
3243 Op2 = (INT64)(UINT64)((UINT32)
VmReadMem32 (VmPtr, (
UINTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16)));
3246 Op2 = VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16;
3253 if ((Opcode & OPCODE_M_64BIT) != 0) {
3257 switch (Opcode & OPCODE_M_OPCODE) {
3279 case OPCODE_CMPULTE:
3280 if ((UINT64)Op1 <= (UINT64)Op2) {
3286 case OPCODE_CMPUGTE:
3287 if ((UINT64)Op1 >= (UINT64)Op2) {
3300 switch (Opcode & OPCODE_M_OPCODE) {
3302 if ((INT32)Op1 == (INT32)Op2) {
3309 if ((INT32)Op1 <= (INT32)Op2) {
3316 if ((INT32)Op1 >= (INT32)Op2) {
3322 case OPCODE_CMPULTE:
3323 if ((UINT32)Op1 <= (UINT32)Op2) {
3329 case OPCODE_CMPUGTE:
3330 if ((UINT32)Op1 >= (UINT32)Op2) {
3345 VMFLAG_SET (VmPtr, VMFLAGS_CC);
3347 VMFLAG_CLEAR (VmPtr, (UINT64)VMFLAGS_CC);
3385 Opcode = GETOPCODE (VmPtr);
3386 Operands = GETOPERANDS (VmPtr);
3392 if ((Operands & OPERAND_M_CMPI_INDEX) != 0) {
3402 Op1 = (INT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)];
3403 if (OPERAND1_INDIRECT (Operands)) {
3407 if ((Opcode & OPCODE_M_CMPI64) != 0) {
3417 if ((Operands & OPERAND_M_CMPI_INDEX) != 0) {
3420 EXCEPTION_FLAG_ERROR,
3424 return EFI_UNSUPPORTED;
3431 if ((Opcode & OPCODE_M_CMPI32_DATA) != 0) {
3446 if ((Opcode & OPCODE_M_CMPI64) != 0) {
3450 switch (Opcode & OPCODE_M_OPCODE) {
3452 if (Op1 == (INT64)Op2) {
3458 case OPCODE_CMPILTE:
3459 if (Op1 <= (INT64)Op2) {
3465 case OPCODE_CMPIGTE:
3466 if (Op1 >= (INT64)Op2) {
3472 case OPCODE_CMPIULTE:
3473 if ((UINT64)Op1 <= (UINT64)((UINT32)Op2)) {
3479 case OPCODE_CMPIUGTE:
3480 if ((UINT64)Op1 >= (UINT64)((UINT32)Op2)) {
3493 switch (Opcode & OPCODE_M_OPCODE) {
3495 if ((INT32)Op1 == Op2) {
3501 case OPCODE_CMPILTE:
3502 if ((INT32)Op1 <= Op2) {
3508 case OPCODE_CMPIGTE:
3509 if ((INT32)Op1 >= Op2) {
3515 case OPCODE_CMPIULTE:
3516 if ((UINT32)Op1 <= (UINT32)Op2) {
3522 case OPCODE_CMPIUGTE:
3523 if ((UINT32)Op1 >= (UINT32)Op2) {
3538 VMFLAG_SET (VmPtr, VMFLAGS_CC);
3540 VMFLAG_CLEAR (VmPtr, (UINT64)VMFLAGS_CC);
3639 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {
3640 return (UINT64)((INT64)((INT64)Op1 - (INT64)Op2));
3642 return (UINT64)((INT64)((INT32)((INT32)Op1 - (INT32)Op2)));
3666 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {
3669 return (UINT64)((INT64)((INT32)((INT32)Op1 * (INT32)Op2)));
3693 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {
3696 return (UINT64)((UINT32)((UINT32)Op1 * (UINT32)Op2));
3727 EXCEPT_EBC_DIVIDE_ERROR,
3728 EXCEPTION_FLAG_FATAL,
3734 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {
3737 return (UINT64)((INT64)((INT32)Op1 / (INT32)Op2));
3769 EXCEPT_EBC_DIVIDE_ERROR,
3770 EXCEPTION_FLAG_FATAL,
3778 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {
3781 return (UINT64)((UINT32)Op1 / (UINT32)Op2);
3813 EXCEPT_EBC_DIVIDE_ERROR,
3814 EXCEPTION_FLAG_FATAL,
3851 EXCEPT_EBC_DIVIDE_ERROR,
3852 EXCEPTION_FLAG_FATAL,
3951 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {
3954 return (UINT64)((UINT32)((UINT32)Op1 << (UINT32)Op2));
3978 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {
3981 return (UINT64)((UINT32)Op1 >> (UINT32)Op2);
4005 if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {
4008 return (UINT64)((INT64)((INT32)Op1 >> (UINT32)Op2));
4040 Data64 = (INT64)Data8;
4042 return (UINT64)Data64;
4072 Data16 = (INT16)Op2;
4073 Data64 = (INT64)Data16;
4075 return (UINT64)Data64;
4114 Data32 = (INT32)Op2;
4115 Data64 = (INT64)Data32;
4117 return (UINT64)Data64;
4199 IN BOOLEAN IsSignedOp
4208 INTN DataManipDispatchTableIndex;
4213 Opcode = GETOPCODE (VmPtr);
4214 Operands = GETOPERANDS (VmPtr);
4219 if ((Opcode & DATAMANIP_M_IMMDATA) != 0) {
4223 if (OPERAND2_INDIRECT (Operands)) {
4238 Op2 = (UINT64)VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16;
4239 if (OPERAND2_INDIRECT (Operands)) {
4243 if ((Opcode & DATAMANIP_M_64) != 0) {
4256 if ((Opcode & DATAMANIP_M_64) == 0) {
4258 Op2 = (UINT64)(INT64)((INT32)Op2);
4260 Op2 = (UINT64)((UINT32)Op2);
4269 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)];
4270 if (OPERAND1_INDIRECT (Operands)) {
4271 if ((Opcode & DATAMANIP_M_64) != 0) {
4281 if ((Opcode & DATAMANIP_M_64) == 0) {
4283 Op1 = (UINT64)(INT64)((INT32)Op1);
4285 Op1 = (UINT64)((UINT32)Op1);
4293 DataManipDispatchTableIndex = (Opcode & OPCODE_M_OPCODE) - OPCODE_NOT;
4294 if ((DataManipDispatchTableIndex < 0) ||
4295 (DataManipDispatchTableIndex >=
ARRAY_SIZE (mDataManipDispatchTable)))
4299 EXCEPTION_FLAG_ERROR,
4306 return EFI_UNSUPPORTED;
4308 Op2 = mDataManipDispatchTable[DataManipDispatchTableIndex](VmPtr, Op1, Op2);
4314 if (OPERAND1_INDIRECT (Operands)) {
4315 Op1 = (UINT64)VmPtr->Gpr[OPERAND1_REGNUM (Operands)];
4316 if ((Opcode & DATAMANIP_M_64) != 0) {
4326 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Op2;
4327 if ((Opcode & DATAMANIP_M_64) == 0) {
4328 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] &= 0xFFFFFFFF;
4361 Operands = GETOPERANDS (VmPtr);
4366 switch (OPERAND1_REGNUM (Operands)) {
4375 VmPtr->Flags = (VmPtr->Flags &~VMFLAGS_ALL_VALID) | (VmPtr->Gpr[OPERAND2_REGNUM (Operands)] & VMFLAGS_ALL_VALID);
4381 EXCEPTION_FLAG_WARNING,
4385 return EFI_UNSUPPORTED;
4414 Operands = GETOPERANDS (VmPtr);
4419 switch (OPERAND2_REGNUM (Operands)) {
4427 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (UINT64)(VmPtr->Flags & VMFLAGS_ALL_VALID);
4434 VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (UINT64)(
UINTN)VmPtr->Ip + 2;
4440 EXCEPTION_FLAG_WARNING,
4444 return EFI_UNSUPPORTED;
4477 IN UINT32 CodeOffset
4495 NBits = (INT16)((Index & 0x7000) >> 12);
4505 Mask = (INT16)((INT16) ~0 << NBits);
4510 NaturalUnits = (INT16)(Index &~Mask);
4515 ConstUnits = (INT16)(((Index &~0xF000) & Mask) >> NBits);
4517 Offset = (INT16)(NaturalUnits *
sizeof (
UINTN) + ConstUnits);
4522 if ((Index & 0x8000) != 0) {
4528 Offset = (INT16)((INT32)Offset * -1);
4547 IN UINT32 CodeOffset
4562 NBits = (Index & 0x70000000) >> 28;
4572 Mask = (INT32) ~0 << NBits;
4577 NaturalUnits = Index &~Mask;
4582 ConstUnits = ((Index &~0xF0000000) & Mask) >> NBits;
4584 Offset = NaturalUnits *
sizeof (
UINTN) + ConstUnits;
4589 if ((Index & 0x80000000) != 0) {
4590 Offset = Offset * -1;
4609 IN UINT32 CodeOffset
4624 NBits =
RShiftU64 ((Index & 0x7000000000000000ULL), 60);
4639 NaturalUnits = Index &~Mask;
4644 ConstUnits =
ARShiftU64 (((Index &~0xF000000000000000ULL) & Mask), (
UINTN)NBits);
4646 Offset =
MultU64x64 ((UINT64)NaturalUnits,
sizeof (
UINTN)) + ConstUnits;
4651 if ((Index & 0x8000000000000000ULL) != 0) {
4692 *(UINT8 *)Addr = Data;
4737 *(UINT16 *)Addr = Data;
4799 *(UINT32 *)Addr = Data;
4861 *(UINT64 *)Addr = Data;
4926 *(
UINTN *)Addr = Data;
4928 for (Index = 0; Index <
sizeof (
UINTN) /
sizeof (UINT32); Index++) {
4930 Status =
VmWriteMem32 (VmPtr, Addr + Index *
sizeof (UINT32), (UINT32)Data);
4962 return *(INT8 *)(VmPtr->Ip + Offset);
4989 return *(INT16 *)(VmPtr->Ip + Offset);
4995 EXCEPT_EBC_ALIGNMENT_CHECK,
4996 EXCEPTION_FLAG_WARNING,
5004 return (INT16)(*(UINT8 *)(VmPtr->Ip + Offset) + (*(UINT8 *)(VmPtr->Ip + Offset + 1) << 8));
5033 return *(INT32 *)(VmPtr->Ip + Offset);
5040 Data |= (UINT32)(
VmReadCode16 (VmPtr, Offset + 2) << 16);
5072 return *(UINT64 *)(VmPtr->Ip + Offset);
5078 Ptr = (UINT8 *)&Data64;
5080 *(UINT32 *)Ptr = Data32;
5081 Ptr +=
sizeof (Data32);
5082 Data32 =
VmReadCode32 (VmPtr, Offset +
sizeof (UINT32));
5083 *(UINT32 *)Ptr = Data32;
5109 return *(UINT16 *)(VmPtr->Ip + Offset);
5115 EXCEPT_EBC_ALIGNMENT_CHECK,
5116 EXCEPTION_FLAG_WARNING,
5124 return (UINT16)(*(UINT8 *)(VmPtr->Ip + Offset) + (*(UINT8 *)(VmPtr->Ip + Offset + 1) << 8));
5151 return *(UINT32 *)(VmPtr->Ip + Offset);
5188 return *(UINT64 *)(VmPtr->Ip + Offset);
5194 Ptr = (UINT8 *)&Data64;
5196 *(UINT32 *)Ptr = Data32;
5197 Ptr +=
sizeof (Data32);
5198 Data32 =
VmReadCode32 (VmPtr, Offset +
sizeof (UINT32));
5199 *(UINT32 *)Ptr = Data32;
5225 return *(UINT8 *)Addr;
5251 return *(UINT16 *)Addr;
5257 return (UINT16)(*(UINT8 *)Addr + (*(UINT8 *)(Addr + 1) << 8));
5285 return *(UINT32 *)Addr;
5323 return *(UINT64 *)Addr;
5330 Data = (UINT64)
VmReadMem32 (VmPtr, Addr +
sizeof (UINT32));
5360 ASSERT (((Addr < VmPtr->LowStackTop) || (Addr > VmPtr->HighStackBottom)));
5380 volatile UINT32 Size;
5392 return *(
UINTN *)Addr;
5399 FromPtr = (UINT8 *)Addr;
5400 ToPtr = (UINT8 *)&Data;
5402 for (Size = 0; Size <
sizeof (Data); Size++) {
5422 return (UINT64)(((VM_MAJOR_VERSION & 0xFFFF) << 16) | ((VM_MINOR_VERSION & 0xFFFF)));
VOID EbcLLCALLEX(IN VM_CONTEXT *VmPtr, IN UINTN FuncAddr, IN UINTN NewStackPointer, IN VOID *FramePtr, IN UINT8 Size)
EFI_STATUS EbcCreateThunks(IN EFI_HANDLE ImageHandle, IN VOID *EbcEntryPoint, OUT VOID **Thunk, IN UINT32 Flags)
UINT64 EFIAPI MultU64x64(IN UINT64 Multiplicand, IN UINT64 Multiplier)
INT64 EFIAPI DivS64x64Remainder(IN INT64 Dividend, IN INT64 Divisor, OUT INT64 *Remainder OPTIONAL)
VOID EFIAPI MemoryFence(VOID)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI ARShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
INT64 EFIAPI MultS64x64(IN INT64 Multiplicand, IN INT64 Multiplier)
VOID EFIAPI CpuBreakpoint(VOID)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
EFI_STATUS EbcDebugSignalException(IN EFI_EXCEPTION_TYPE ExceptionType, IN EXCEPTION_FLAGS ExceptionFlags, IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecutePOPn(IN VM_CONTEXT *VmPtr)
UINT64 ExecuteDIV(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT64 ExecuteMULU(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
EFI_STATUS ExecuteMOVIn(IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecuteJMP8(IN VM_CONTEXT *VmPtr)
UINT64 ExecuteMODU(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT64 VmReadCode64(IN VM_CONTEXT *VmPtr, IN UINT32 Offset)
INT32 VmReadIndex32(IN VM_CONTEXT *VmPtr, IN UINT32 CodeOffset)
UINT64 ExecuteEXTNDD(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT16 VmReadMem16(IN VM_CONTEXT *VmPtr, IN UINTN Addr)
UINT64 ExecuteSHR(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT64 ExecuteXOR(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
INT64 VmReadIndex64(IN VM_CONTEXT *VmPtr, IN UINT32 CodeOffset)
EFI_STATUS ExecuteCMP(IN VM_CONTEXT *VmPtr)
UINT64 ExecuteADD(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT64 VmReadMem64(IN VM_CONTEXT *VmPtr, IN UINTN Addr)
INT8 VmReadImmed8(IN VM_CONTEXT *VmPtr, IN UINT32 Offset)
UINT64 ExecuteDIVU(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
EFI_STATUS ExecuteMOVsnw(IN VM_CONTEXT *VmPtr)
INT32 VmReadImmed32(IN VM_CONTEXT *VmPtr, IN UINT32 Offset)
EFI_STATUS ExecuteMOVsnd(IN VM_CONTEXT *VmPtr)
UINT16 VmReadCode16(IN VM_CONTEXT *VmPtr, IN UINT32 Offset)
EFI_STATUS ExecutePOP(IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecuteCMPI(IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecuteDataManip(IN VM_CONTEXT *VmPtr, IN BOOLEAN IsSignedOp)
EFI_STATUS VmWriteMem32(IN VM_CONTEXT *VmPtr, IN UINTN Addr, IN UINT32 Data)
EFI_STATUS EbcExecute(IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecuteCALL(IN VM_CONTEXT *VmPtr)
UINT64 ExecuteSUB(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT32 VmReadCode32(IN VM_CONTEXT *VmPtr, IN UINT32 Offset)
EFI_STATUS ExecutePUSHn(IN VM_CONTEXT *VmPtr)
UINT64 ExecuteOR(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT64 ExecuteASHR(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT64 ExecuteEXTNDB(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
EFI_STATUS ExecuteMOVI(IN VM_CONTEXT *VmPtr)
UINT64 ExecuteMUL(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
EFI_STATUS ExecuteSTORESP(IN VM_CONTEXT *VmPtr)
EFI_STATUS VmWriteMem16(IN VM_CONTEXT *VmPtr, IN UINTN Addr, IN UINT16 Data)
EFI_STATUS ExecuteRET(IN VM_CONTEXT *VmPtr)
INT16 VmReadIndex16(IN VM_CONTEXT *VmPtr, IN UINT32 CodeOffset)
INT16 VmReadImmed16(IN VM_CONTEXT *VmPtr, IN UINT32 Offset)
UINT64 ExecuteAND(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT64 ExecuteMOD(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINTN ConvertStackAddr(IN VM_CONTEXT *VmPtr, IN UINTN Addr)
UINT64 ExecuteNOT(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
UINT64 GetVmVersion(VOID)
INT64 VmReadImmed64(IN VM_CONTEXT *VmPtr, IN UINT32 Offset)
UINTN VmReadMemN(IN VM_CONTEXT *VmPtr, IN UINTN Addr)
UINT64 ExecuteSHL(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
EFI_STATUS VmWriteMemN(IN VM_CONTEXT *VmPtr, IN UINTN Addr, IN UINTN Data)
EFI_STATUS ExecuteBREAK(IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecutePUSH(IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecuteSignedDataManip(IN VM_CONTEXT *VmPtr)
UINT64 ExecuteEXTNDW(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
EFI_STATUS ExecuteMOVREL(IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecuteMOVxx(IN VM_CONTEXT *VmPtr)
EFI_STATUS ExecuteJMP(IN VM_CONTEXT *VmPtr)
UINT32 VmReadMem32(IN VM_CONTEXT *VmPtr, IN UINTN Addr)
EFI_STATUS EFIAPI EbcExecuteInstructions(IN EFI_EBC_VM_TEST_PROTOCOL *This, IN VM_CONTEXT *VmPtr, IN OUT UINTN *InstructionCount)
EFI_STATUS ExecuteUnsignedDataManip(IN VM_CONTEXT *VmPtr)
UINT8 VmReadMem8(IN VM_CONTEXT *VmPtr, IN UINTN Addr)
EFI_STATUS VmWriteMem8(IN VM_CONTEXT *VmPtr, IN UINTN Addr, IN UINT8 Data)
UINT64 ExecuteNEG(IN VM_CONTEXT *VmPtr, IN UINT64 Op1, IN UINT64 Op2)
EFI_STATUS VmWriteMem64(IN VM_CONTEXT *VmPtr, IN UINTN Addr, IN UINT64 Data)
EFI_STATUS ExecuteLOADSP(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookJMPStart(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookExecuteStart(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookCALLEnd(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookCALLStart(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookCALLEXStart(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookRETEnd(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookCALLEXEnd(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookJMPEnd(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookJMP8Start(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookExecuteEnd(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookRETStart(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookJMP8End(IN VM_CONTEXT *VmPtr)
#define ADDRESS_IS_ALIGNED(Address, Alignment)
#define ARRAY_SIZE(Array)
#define DEBUG_CODE_BEGIN()
#define EXCEPT_EBC_UNDEFINED
#define EXCEPT_EBC_BAD_BREAK
BREAK 0 or undefined BREAK.
#define EXCEPT_EBC_INVALID_OPCODE
Opcode out of range.
#define EXCEPT_EBC_INSTRUCTION_ENCODING
Malformed instruction.