/** @file\r
Contains code that implements the virtual machine.\r
\r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "EbcInt.h"\r
#include "EbcExecute.h"\r
+#include "EbcDebuggerHook.h"\r
\r
\r
//\r
@param VmPtr A pointer to VM context.\r
@param Addr The memory address.\r
\r
- @return The 8-bit value from the memory adress.\r
+ @return The 8-bit value from the memory address.\r
\r
**/\r
UINT8\r
@param VmPtr A pointer to VM context.\r
@param Addr The memory address.\r
\r
- @return The 16-bit value from the memory adress.\r
+ @return The 16-bit value from the memory address.\r
\r
**/\r
UINT16\r
@param VmPtr A pointer to VM context.\r
@param Addr The memory address.\r
\r
- @return The 32-bit value from the memory adress.\r
+ @return The 32-bit value from the memory address.\r
\r
**/\r
UINT32\r
@param VmPtr A pointer to VM context.\r
@param Addr The memory address.\r
\r
- @return The 64-bit value from the memory adress.\r
+ @return The 64-bit value from the memory address.\r
\r
**/\r
UINT64\r
VM stack) to point into the EBC entry point arguments.\r
\r
@param VmPtr A pointer to a VM context.\r
- @param Addr Adddress to write to.\r
+ @param Addr Address to write to.\r
@param Data Value to write to Addr.\r
\r
@retval EFI_SUCCESS The instruction is executed successfully.\r
VM stack) to point into the EBC entry point arguments.\r
\r
@param VmPtr A pointer to a VM context.\r
- @param Addr Adddress to write to.\r
+ @param Addr Address to write to.\r
@param Data Value to write to Addr.\r
\r
@retval EFI_SUCCESS The instruction is executed successfully.\r
VM stack) to point into the EBC entry point arguments.\r
\r
@param VmPtr A pointer to a VM context.\r
- @param Addr Adddress to write to.\r
+ @param Addr Address to write to.\r
@param Data Value to write to Addr.\r
\r
@retval EFI_SUCCESS The instruction is executed successfully.\r
);\r
\r
/**\r
- Reads 16-bit unsinged data from the code stream.\r
+ Reads 16-bit unsigned data from the code stream.\r
\r
This routine provides the ability to read raw unsigned data from the code\r
stream.\r
);\r
\r
/**\r
- Reads 32-bit unsinged data from the code stream.\r
+ Reads 32-bit unsigned data from the code stream.\r
\r
This routine provides the ability to read raw unsigned data from the code\r
stream.\r
);\r
\r
/**\r
- Reads 64-bit unsinged data from the code stream.\r
+ Reads 64-bit unsigned data from the code stream.\r
\r
This routine provides the ability to read raw unsigned data from the code\r
stream.\r
{ ExecutePOPn }, // opcode 0x36\r
{ ExecuteMOVI }, // opcode 0x37 - mov immediate data\r
{ ExecuteMOVIn }, // opcode 0x38 - mov immediate natural\r
- { ExecuteMOVREL } // opcode 0x39 - move data relative to PC\r
+ { ExecuteMOVREL }, // opcode 0x39 - move data relative to PC\r
+ { NULL }, // opcode 0x3a\r
+ { NULL }, // opcode 0x3b\r
+ { NULL }, // opcode 0x3c\r
+ { NULL }, // opcode 0x3d\r
+ { NULL }, // opcode 0x3e\r
+ { NULL } // opcode 0x3f\r
};\r
\r
//\r
//\r
CONST UINT8 mJMPLen[] = { 2, 2, 6, 10 };\r
\r
-//\r
-// Simple Debugger Protocol GUID\r
-//\r
-EFI_GUID mEbcSimpleDebuggerProtocolGuid = EFI_EBC_SIMPLE_DEBUGGER_PROTOCOL_GUID;\r
-\r
-\r
/**\r
Given a pointer to a new VM context, execute one or more instructions. This\r
function is only used for test purposes via the EBC VM test protocol.\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
EbcExecuteInstructions (\r
IN EFI_EBC_VM_TEST_PROTOCOL *This,\r
IN VM_CONTEXT *VmPtr,\r
// call it if it's not null.\r
//\r
while (InstructionsLeft != 0) {\r
- ExecFunc = (UINTN) mVmOpcodeTable[(*VmPtr->Ip & 0x3F)].ExecuteFunction;\r
+ ExecFunc = (UINTN) mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction;\r
if (ExecFunc == (UINTN) NULL) {\r
EbcDebugSignalException (EXCEPT_EBC_INVALID_OPCODE, EXCEPTION_FLAG_FATAL, VmPtr);\r
return EFI_UNSUPPORTED;\r
} else {\r
- mVmOpcodeTable[(*VmPtr->Ip & 0x3F)].ExecuteFunction (VmPtr);\r
+ mVmOpcodeTable[(*VmPtr->Ip & OPCODE_M_OPCODE)].ExecuteFunction (VmPtr);\r
*InstructionCount = *InstructionCount + 1;\r
}\r
\r
StackCorrupted = 1;\r
}\r
\r
- VmPtr->FramePtr = (VOID *) ((UINT8 *) (UINTN) VmPtr->R[0] + 8);\r
+ VmPtr->FramePtr = (VOID *) ((UINT8 *) (UINTN) VmPtr->Gpr[0] + 8);\r
\r
//\r
// Try to get the debug support for EBC\r
//\r
DEBUG_CODE_BEGIN ();\r
Status = gBS->LocateProtocol (\r
- &mEbcSimpleDebuggerProtocolGuid,\r
+ &gEfiEbcSimpleDebuggerProtocolGuid,\r
NULL,\r
(VOID **) &EbcSimpleDebugger\r
);\r
}\r
DEBUG_CODE_END ();\r
\r
- //\r
- // Verify the opcode is in range. Otherwise generate an exception.\r
- //\r
- if ((*VmPtr->Ip & OPCODE_M_OPCODE) >= (sizeof (mVmOpcodeTable) / sizeof (mVmOpcodeTable[0]))) {\r
- EbcDebugSignalException (EXCEPT_EBC_INVALID_OPCODE, EXCEPTION_FLAG_FATAL, VmPtr);\r
- Status = EFI_UNSUPPORTED;\r
- goto Done;\r
- }\r
//\r
// Use the opcode bits to index into the opcode dispatch table. If the\r
// function pointer is null then generate an exception.\r
Status = EFI_UNSUPPORTED;\r
goto Done;\r
}\r
+\r
+ EbcDebuggerHookExecuteStart (VmPtr);\r
+\r
//\r
// The EBC VM is a strongly ordered processor, so perform a fence operation before\r
// and after each instruction is executed.\r
\r
MemoryFence ();\r
\r
+ EbcDebuggerHookExecuteEnd (VmPtr);\r
+\r
//\r
// If the step flag is set, signal an exception and continue. We don't\r
// clear it here. Assuming the debugger is responsible for clearing it.\r
EbcDebugSignalException (EXCEPT_EBC_STACK_FAULT, EXCEPTION_FLAG_FATAL, VmPtr);\r
StackCorrupted = 1;\r
}\r
- if ((StackCorrupted == 0) && ((UINT64)VmPtr->R[0] <= (UINT64)(UINTN) VmPtr->StackTop)) {\r
+ if ((StackCorrupted == 0) && ((UINT64)VmPtr->Gpr[0] <= (UINT64)(UINTN) VmPtr->StackTop)) {\r
EbcDebugSignalException (EXCEPT_EBC_STACK_FAULT, EXCEPTION_FLAG_FATAL, VmPtr);\r
StackCorrupted = 1;\r
}\r
//\r
// Indirect form @R2. Compute address of operand2\r
//\r
- Source = (UINTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Index64Op2);\r
+ Source = (UINTN) (VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index64Op2);\r
//\r
// Now get the data from the source. Always 0-extend and let the compiler\r
// sign-extend where required.\r
//\r
// Not indirect source: MOVxx {@}Rx, Ry [Index]\r
//\r
- Data64 = VmPtr->R[OPERAND2_REGNUM (Operands)] + Index64Op2;\r
+ Data64 = (UINT64) (VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index64Op2);\r
//\r
// Did Operand2 have an index? If so, treat as two signed values since\r
// indexes are signed values.\r
//\r
// Reuse the Source variable to now be dest.\r
//\r
- Source = (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index64Op1);\r
+ Source = (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index64Op1);\r
//\r
// Do the write based on the size\r
//\r
// Direct storage in register. Clear unused bits and store back to\r
// register.\r
//\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = Data64 & DataMask;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Data64 & DataMask;\r
}\r
//\r
// Advance the instruction pointer\r
IN VM_CONTEXT *VmPtr\r
)\r
{\r
+ EFI_STATUS Status;\r
UINT8 Operands;\r
VOID *EbcEntryPoint;\r
VOID *Thunk;\r
UINT64 U64EbcEntryPoint;\r
INT32 Offset;\r
\r
+ Thunk = NULL;\r
Operands = GETOPERANDS (VmPtr);\r
switch (Operands) {\r
//\r
// 16-8 = Major version\r
// 7-0 = Minor version\r
//\r
- VmPtr->R[7] = GetVmVersion ();\r
+ VmPtr->Gpr[7] = GetVmVersion ();\r
break;\r
\r
//\r
// After we're done, *(UINT64 *)R7 will be the address of the new thunk.\r
//\r
case 5:\r
- Offset = (INT32) VmReadMem32 (VmPtr, (UINTN) VmPtr->R[7]);\r
- U64EbcEntryPoint = (UINT64) (VmPtr->R[7] + Offset + 4);\r
+ Offset = (INT32) VmReadMem32 (VmPtr, (UINTN) VmPtr->Gpr[7]);\r
+ U64EbcEntryPoint = (UINT64) (VmPtr->Gpr[7] + Offset + 4);\r
EbcEntryPoint = (VOID *) (UINTN) U64EbcEntryPoint;\r
\r
//\r
// Now create a new thunk\r
//\r
- EbcCreateThunks (VmPtr->ImageHandle, EbcEntryPoint, &Thunk, 0);\r
+ Status = EbcCreateThunks (VmPtr->ImageHandle, EbcEntryPoint, &Thunk, 0);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
//\r
// Finally replace the EBC entry point memory with the thunk address\r
//\r
- VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[7], (UINT64) (UINTN) Thunk);\r
+ VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[7], (UINT64) (UINTN) Thunk);\r
break;\r
\r
//\r
// Compiler setting version per value in R7\r
//\r
case 6:\r
- VmPtr->CompilerVersion = (UINT32) VmPtr->R[7];\r
+ VmPtr->CompilerVersion = (UINT32) VmPtr->Gpr[7];\r
//\r
// Check compiler version against VM version?\r
//\r
ConditionFlag = (UINT8) VMFLAG_ISSET (VmPtr, VMFLAGS_CC);\r
if ((Operand & CONDITION_M_CONDITIONAL) != 0) {\r
if (CompareSet != ConditionFlag) {\r
+ EbcDebuggerHookJMPStart (VmPtr);\r
VmPtr->Ip += Size;\r
+ EbcDebuggerHookJMPEnd (VmPtr);\r
return EFI_SUCCESS;\r
}\r
}\r
// 64-bit immediate data is full address. Read the immediate data,\r
// check for alignment, and jump absolute.\r
//\r
- Data64 = VmReadImmed64 (VmPtr, 2);\r
+ Data64 = (UINT64) VmReadImmed64 (VmPtr, 2);\r
if (!IS_ALIGNED ((UINTN) Data64, sizeof (UINT16))) {\r
EbcDebugSignalException (\r
EXCEPT_EBC_ALIGNMENT_CHECK,\r
//\r
// Take jump -- relative or absolute\r
//\r
+ EbcDebuggerHookJMPStart (VmPtr);\r
if ((Operand & JMP_M_RELATIVE) != 0) {\r
VmPtr->Ip += (UINTN) Data64 + Size;\r
} else {\r
VmPtr->Ip = (VMIP) (UINTN) Data64;\r
}\r
+ EbcDebuggerHookJMPEnd (VmPtr);\r
\r
return EFI_SUCCESS;\r
}\r
if (OPERAND1_REGNUM (Operand) == 0) {\r
Data64 = 0;\r
} else {\r
- Data64 = OPERAND1_REGDATA (VmPtr, Operand);\r
+ Data64 = (UINT64) OPERAND1_REGDATA (VmPtr, Operand);\r
}\r
//\r
// Decode the forms\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ EbcDebuggerHookJMPStart (VmPtr);\r
if ((Operand & JMP_M_RELATIVE) != 0) {\r
VmPtr->Ip += (UINTN) Addr + Size;\r
} else {\r
VmPtr->Ip = (VMIP) Addr;\r
}\r
+ EbcDebuggerHookJMPEnd (VmPtr);\r
+\r
} else {\r
//\r
// Form: JMP32 Rx {Immed32}\r
return EFI_UNSUPPORTED;\r
}\r
\r
+ EbcDebuggerHookJMPStart (VmPtr);\r
if ((Operand & JMP_M_RELATIVE) != 0) {\r
VmPtr->Ip += (UINTN) Addr + Size;\r
} else {\r
VmPtr->Ip = (VMIP) Addr;\r
}\r
+ EbcDebuggerHookJMPEnd (VmPtr);\r
+\r
}\r
\r
return EFI_SUCCESS;\r
//\r
if ((Opcode & CONDITION_M_CONDITIONAL) != 0) {\r
if (CompareSet != ConditionFlag) {\r
+ EbcDebuggerHookJMP8Start (VmPtr);\r
VmPtr->Ip += 2;\r
+ EbcDebuggerHookJMP8End (VmPtr);\r
return EFI_SUCCESS;\r
}\r
}\r
//\r
// Want to check for offset == -2 and then raise an exception?\r
//\r
+ EbcDebuggerHookJMP8Start (VmPtr);\r
VmPtr->Ip += (Offset * 2) + 2;\r
+ EbcDebuggerHookJMP8End (VmPtr);\r
return EFI_SUCCESS;\r
}\r
\r
Mask64 = (UINT64)~0;\r
}\r
\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = ImmData64 & Mask64;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = ImmData64 & Mask64;\r
} else {\r
//\r
// Get the address then write back based on size of the move\r
//\r
- Op1 = (UINT64) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;\r
+ Op1 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;\r
if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH8) {\r
VmWriteMem8 (VmPtr, (UINTN) Op1, (UINT8) ImmData64);\r
} else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH16) {\r
} else if ((Operands & MOVI_M_MOVEWIDTH) == MOVI_MOVEWIDTH32) {\r
VmWriteMem32 (VmPtr, (UINTN) Op1, (UINT32) ImmData64);\r
} else {\r
- VmWriteMem64 (VmPtr, (UINTN) Op1, ImmData64);\r
+ VmWriteMem64 (VmPtr, (UINTN) Op1, (UINT64) ImmData64);\r
}\r
}\r
//\r
return EFI_UNSUPPORTED;\r
}\r
\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = ImmedIndex64;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = ImmedIndex64;\r
} else {\r
//\r
// Get the address\r
//\r
- Op1 = (UINT64) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;\r
- VmWriteMemN (VmPtr, (UINTN) Op1, (INTN) ImmedIndex64);\r
+ Op1 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;\r
+ VmWriteMemN (VmPtr, (UINTN) Op1, (UINTN)(INTN) ImmedIndex64);\r
}\r
//\r
// Advance the instruction pointer\r
return EFI_UNSUPPORTED;\r
}\r
\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = (VM_REGISTER) Op2;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (VM_REGISTER) Op2;\r
} else {\r
//\r
// Get the address = [Rx] + Index16\r
// Write back the result. Always a natural size write, since\r
// we're talking addresses here.\r
//\r
- Op1 = (UINT64) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;\r
+ Op1 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;\r
VmWriteMemN (VmPtr, (UINTN) Op1, (UINTN) Op2);\r
}\r
//\r
//\r
// Get the data from the source.\r
//\r
- Op2 = (INT64) ((INTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Op2Index));\r
+ Op2 = (UINT64)(INT64)(INTN)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Op2Index);\r
if (OPERAND2_INDIRECT (Operands)) {\r
- Op2 = (INT64) (INTN) VmReadMemN (VmPtr, (UINTN) Op2);\r
+ Op2 = (UINT64)(INT64)(INTN)VmReadMemN (VmPtr, (UINTN) Op2);\r
}\r
//\r
// Now write back the result.\r
//\r
if (!OPERAND1_INDIRECT (Operands)) {\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = Op2;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Op2;\r
} else {\r
- VmWriteMemN (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN) Op2);\r
+ VmWriteMemN (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN) Op2);\r
}\r
//\r
// Advance the instruction pointer\r
//\r
// Get the data from the source.\r
//\r
- Op2 = (INT64) ((INTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Op2Index));\r
+ Op2 = (UINT64)(INT64)(INTN)(INT64)(VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Op2Index);\r
if (OPERAND2_INDIRECT (Operands)) {\r
- Op2 = (INT64) (INTN) VmReadMemN (VmPtr, (UINTN) Op2);\r
+ Op2 = (UINT64)(INT64)(INTN)(INT64)VmReadMemN (VmPtr, (UINTN) Op2);\r
}\r
//\r
// Now write back the result.\r
//\r
if (!OPERAND1_INDIRECT (Operands)) {\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = Op2;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Op2;\r
} else {\r
- VmWriteMemN (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN) Op2);\r
+ VmWriteMemN (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Op1Index), (UINTN) Op2);\r
}\r
//\r
// Advance the instruction pointer\r
// Get the data to push\r
//\r
if (OPERAND1_INDIRECT (Operands)) {\r
- DataN = VmReadMemN (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16));\r
+ DataN = VmReadMemN (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16));\r
} else {\r
- DataN = (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16);\r
+ DataN = (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16);\r
}\r
//\r
// Adjust the stack down.\r
//\r
- VmPtr->R[0] -= sizeof (UINTN);\r
- VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], DataN);\r
+ VmPtr->Gpr[0] -= sizeof (UINTN);\r
+ VmWriteMemN (VmPtr, (UINTN) VmPtr->Gpr[0], DataN);\r
return EFI_SUCCESS;\r
}\r
\r
//\r
if ((Opcode & PUSHPOP_M_64) != 0) {\r
if (OPERAND1_INDIRECT (Operands)) {\r
- Data64 = VmReadMem64 (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16));\r
+ Data64 = VmReadMem64 (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16));\r
} else {\r
- Data64 = (UINT64) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;\r
+ Data64 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;\r
}\r
//\r
// Adjust the stack down, then write back the data\r
//\r
- VmPtr->R[0] -= sizeof (UINT64);\r
- VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], Data64);\r
+ VmPtr->Gpr[0] -= sizeof (UINT64);\r
+ VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[0], Data64);\r
} else {\r
//\r
// 32-bit data\r
//\r
if (OPERAND1_INDIRECT (Operands)) {\r
- Data32 = VmReadMem32 (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16));\r
+ Data32 = VmReadMem32 (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16));\r
} else {\r
- Data32 = (UINT32) VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16;\r
+ Data32 = (UINT32) VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16;\r
}\r
//\r
// Adjust the stack down and write the data\r
//\r
- VmPtr->R[0] -= sizeof (UINT32);\r
- VmWriteMem32 (VmPtr, (UINTN) VmPtr->R[0], Data32);\r
+ VmPtr->Gpr[0] -= sizeof (UINT32);\r
+ VmWriteMem32 (VmPtr, (UINTN) VmPtr->Gpr[0], Data32);\r
}\r
\r
return EFI_SUCCESS;\r
//\r
// Read the data off the stack, then adjust the stack pointer\r
//\r
- DataN = VmReadMemN (VmPtr, (UINTN) VmPtr->R[0]);\r
- VmPtr->R[0] += sizeof (UINTN);\r
+ DataN = VmReadMemN (VmPtr, (UINTN) VmPtr->Gpr[0]);\r
+ VmPtr->Gpr[0] += sizeof (UINTN);\r
//\r
// Do the write-back\r
//\r
if (OPERAND1_INDIRECT (Operands)) {\r
- VmWriteMemN (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16), DataN);\r
+ VmWriteMemN (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), DataN);\r
} else {\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = (INT64) (UINT64) ((UINTN) DataN + Index16);\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (INT64) (UINT64) (UINTN) (DataN + Index16);\r
}\r
\r
return EFI_SUCCESS;\r
//\r
// Read the data off the stack, then adjust the stack pointer\r
//\r
- Data64 = VmReadMem64 (VmPtr, (UINTN) VmPtr->R[0]);\r
- VmPtr->R[0] += sizeof (UINT64);\r
+ Data64 = VmReadMem64 (VmPtr, (UINTN) VmPtr->Gpr[0]);\r
+ VmPtr->Gpr[0] += sizeof (UINT64);\r
//\r
// Do the write-back\r
//\r
if (OPERAND1_INDIRECT (Operands)) {\r
- VmWriteMem64 (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16), Data64);\r
+ VmWriteMem64 (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), Data64);\r
} else {\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = Data64 + Index16;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Data64 + Index16;\r
}\r
} else {\r
//\r
// 32-bit pop. Read it off the stack and adjust the stack pointer\r
//\r
- Data32 = (INT32) VmReadMem32 (VmPtr, (UINTN) VmPtr->R[0]);\r
- VmPtr->R[0] += sizeof (UINT32);\r
+ Data32 = (INT32) VmReadMem32 (VmPtr, (UINTN) VmPtr->Gpr[0]);\r
+ VmPtr->Gpr[0] += sizeof (UINT32);\r
//\r
// Do the write-back\r
//\r
if (OPERAND1_INDIRECT (Operands)) {\r
- VmWriteMem32 (VmPtr, (UINTN) (VmPtr->R[OPERAND1_REGNUM (Operands)] + Index16), Data32);\r
+ VmWriteMem32 (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND1_REGNUM (Operands)] + Index16), Data32);\r
} else {\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = (INT64) Data32 + Index16;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (INT64) Data32 + Index16;\r
}\r
}\r
\r
//\r
Opcode = GETOPCODE (VmPtr);\r
Operands = GETOPERANDS (VmPtr);\r
+\r
+ if ((Operands & OPERAND_M_NATIVE_CALL) != 0) {\r
+ EbcDebuggerHookCALLEXStart (VmPtr);\r
+ } else {\r
+ EbcDebuggerHookCALLStart (VmPtr);\r
+ }\r
+\r
//\r
// Assign these as well to avoid compiler warnings\r
//\r
// put our return address and frame pointer on the VM stack.\r
//\r
if ((Operands & OPERAND_M_NATIVE_CALL) == 0) {\r
- VmPtr->R[0] -= 8;\r
- VmWriteMemN (VmPtr, (UINTN) VmPtr->R[0], (UINTN) FramePtr);\r
- VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->R[0];\r
- VmPtr->R[0] -= 8;\r
- VmWriteMem64 (VmPtr, (UINTN) VmPtr->R[0], (UINT64) (UINTN) (VmPtr->Ip + Size));\r
+ VmPtr->Gpr[0] -= 8;\r
+ VmWriteMemN (VmPtr, (UINTN) VmPtr->Gpr[0], (UINTN) FramePtr);\r
+ VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->Gpr[0];\r
+ VmPtr->Gpr[0] -= 8;\r
+ VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[0], (UINT64) (UINTN) (VmPtr->Ip + Size));\r
}\r
//\r
// If 64-bit data, then absolute jump only\r
//\r
// Call external function, get the return value, and advance the IP\r
//\r
- EbcLLCALLEX (VmPtr, (UINTN) Immed64, (UINTN) VmPtr->R[0], FramePtr, Size);\r
+ EbcLLCALLEX (VmPtr, (UINTN) Immed64, (UINTN) VmPtr->Gpr[0], FramePtr, Size);\r
}\r
} else {\r
//\r
// Compiler should take care of upper bits if 32-bit machine.\r
//\r
if (OPERAND1_REGNUM (Operands) != 0) {\r
- Immed64 = (UINT64) (UINTN) VmPtr->R[OPERAND1_REGNUM (Operands)];\r
+ Immed64 = (UINT64) (UINTN) VmPtr->Gpr[OPERAND1_REGNUM (Operands)];\r
}\r
//\r
// Get final address\r
// Native call. Relative or absolute?\r
//\r
if ((Operands & OPERAND_M_RELATIVE_ADDR) != 0) {\r
- EbcLLCALLEX (VmPtr, (UINTN) (Immed64 + VmPtr->Ip + Size), (UINTN) VmPtr->R[0], FramePtr, Size);\r
+ EbcLLCALLEX (VmPtr, (UINTN) (Immed64 + VmPtr->Ip + Size), (UINTN) VmPtr->Gpr[0], FramePtr, Size);\r
} else {\r
if ((VmPtr->StopFlags & STOPFLAG_BREAK_ON_CALLEX) != 0) {\r
CpuBreakpoint ();\r
}\r
\r
- EbcLLCALLEX (VmPtr, (UINTN) Immed64, (UINTN) VmPtr->R[0], FramePtr, Size);\r
+ EbcLLCALLEX (VmPtr, (UINTN) Immed64, (UINTN) VmPtr->Gpr[0], FramePtr, Size);\r
}\r
}\r
}\r
\r
+ if ((Operands & OPERAND_M_NATIVE_CALL) != 0) {\r
+ EbcDebuggerHookCALLEXEnd (VmPtr);\r
+ } else {\r
+ EbcDebuggerHookCALLEnd (VmPtr);\r
+ }\r
+\r
return EFI_SUCCESS;\r
}\r
\r
IN VM_CONTEXT *VmPtr\r
)\r
{\r
+\r
+ EbcDebuggerHookRETStart (VmPtr);\r
+\r
//\r
// If we're at the top of the stack, then simply set the done\r
// flag and return\r
//\r
- if (VmPtr->StackRetAddr == (UINT64) VmPtr->R[0]) {\r
+ if (VmPtr->StackRetAddr == (UINT64) VmPtr->Gpr[0]) {\r
VmPtr->StopFlags |= STOPFLAG_APP_DONE;\r
} else {\r
//\r
// Pull the return address off the VM app's stack and set the IP\r
// to it\r
//\r
- if (!IS_ALIGNED ((UINTN) VmPtr->R[0], sizeof (UINT16))) {\r
+ if (!IS_ALIGNED ((UINTN) VmPtr->Gpr[0], sizeof (UINT16))) {\r
EbcDebugSignalException (\r
EXCEPT_EBC_ALIGNMENT_CHECK,\r
EXCEPTION_FLAG_FATAL,\r
//\r
// Restore the IP and frame pointer from the stack\r
//\r
- VmPtr->Ip = (VMIP) (UINTN) VmReadMem64 (VmPtr, (UINTN) VmPtr->R[0]);\r
- VmPtr->R[0] += 8;\r
- VmPtr->FramePtr = (VOID *) VmReadMemN (VmPtr, (UINTN) VmPtr->R[0]);\r
- VmPtr->R[0] += 8;\r
+ VmPtr->Ip = (VMIP) (UINTN) VmReadMem64 (VmPtr, (UINTN) VmPtr->Gpr[0]);\r
+ VmPtr->Gpr[0] += 8;\r
+ VmPtr->FramePtr = (VOID *) VmReadMemN (VmPtr, (UINTN) VmPtr->Gpr[0]);\r
+ VmPtr->Gpr[0] += 8;\r
}\r
\r
+\r
+ EbcDebuggerHookRETEnd (VmPtr);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
//\r
// Get the register data we're going to compare to\r
//\r
- Op1 = VmPtr->R[OPERAND1_REGNUM (Operands)];\r
+ Op1 = VmPtr->Gpr[OPERAND1_REGNUM (Operands)];\r
//\r
// Get immediate data\r
//\r
//\r
if (OPERAND2_INDIRECT (Operands)) {\r
if ((Opcode & OPCODE_M_64BIT) != 0) {\r
- Op2 = (INT64) VmReadMem64 (VmPtr, (UINTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Index16));\r
+ Op2 = (INT64) VmReadMem64 (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16));\r
} else {\r
//\r
// 32-bit operations. 0-extend the values for all cases.\r
//\r
- Op2 = (INT64) (UINT64) ((UINT32) VmReadMem32 (VmPtr, (UINTN) (VmPtr->R[OPERAND2_REGNUM (Operands)] + Index16)));\r
+ Op2 = (INT64) (UINT64) ((UINT32) VmReadMem32 (VmPtr, (UINTN) (VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16)));\r
}\r
} else {\r
- Op2 = VmPtr->R[OPERAND2_REGNUM (Operands)] + Index16;\r
+ Op2 = VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16;\r
}\r
//\r
// Now do the compare\r
if (Flag != 0) {\r
VMFLAG_SET (VmPtr, VMFLAGS_CC);\r
} else {\r
- VMFLAG_CLEAR (VmPtr, VMFLAGS_CC);\r
+ VMFLAG_CLEAR (VmPtr, (UINT64)VMFLAGS_CC);\r
}\r
//\r
// Advance the IP\r
//\r
// Get operand1 data we're going to compare to\r
//\r
- Op1 = (INT64) VmPtr->R[OPERAND1_REGNUM (Operands)];\r
+ Op1 = (INT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)];\r
if (OPERAND1_INDIRECT (Operands)) {\r
//\r
// Indirect operand1. Fetch 32 or 64-bit value based on compare size.\r
if (Flag != 0) {\r
VMFLAG_SET (VmPtr, VMFLAGS_CC);\r
} else {\r
- VMFLAG_CLEAR (VmPtr, VMFLAGS_CC);\r
+ VMFLAG_CLEAR (VmPtr, (UINT64)VMFLAGS_CC);\r
}\r
//\r
// Advance the IP\r
if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {\r
return (UINT64) ((INT64) ((INT64) Op1 - (INT64) Op2));\r
} else {\r
- return (UINT64) ((INT64) ((INT32) Op1 - (INT32) Op2));\r
+ return (UINT64) ((INT64) ((INT32) ((INT32) Op1 - (INT32) Op2)));\r
}\r
}\r
\r
if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {\r
return MultS64x64 ((INT64)Op1, (INT64)Op2);\r
} else {\r
- return (UINT64) ((INT64) ((INT32) Op1 * (INT32) Op2));\r
+ return (UINT64) ((INT64) ((INT32) ((INT32) Op1 * (INT32) Op2)));\r
}\r
}\r
\r
if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {\r
return MultU64x64 (Op1, Op2);\r
} else {\r
- return (UINT64) ((UINT32) Op1 * (UINT32) Op2);\r
+ return (UINT64) ((UINT32) ((UINT32) Op1 * (UINT32) Op2));\r
}\r
}\r
\r
// Get the destination register\r
//\r
if ((*VmPtr->Ip & DATAMANIP_M_64) != 0) {\r
- return (UINT64) (DivU64x64Remainder ((INT64)Op1, (INT64)Op2, &Remainder));\r
+ return (UINT64) (DivU64x64Remainder (Op1, Op2, &Remainder));\r
} else {\r
return (UINT64) ((UINT32) Op1 / (UINT32) Op2);\r
}\r
UINT8 Size;\r
UINT64 Op1;\r
UINT64 Op2;\r
+ INTN DataManipDispatchTableIndex;\r
\r
//\r
// Get opcode and operands\r
//\r
// Now get operand2 (source). It's of format {@}R2 {Index16|Immed16}\r
//\r
- Op2 = (UINT64) VmPtr->R[OPERAND2_REGNUM (Operands)] + Index16;\r
+ Op2 = (UINT64) VmPtr->Gpr[OPERAND2_REGNUM (Operands)] + Index16;\r
if (OPERAND2_INDIRECT (Operands)) {\r
//\r
// Indirect form: @R2 Index16. Fetch as 32- or 64-bit data\r
// Get operand1 (destination and sometimes also an actual operand)\r
// of form {@}R1\r
//\r
- Op1 = VmPtr->R[OPERAND1_REGNUM (Operands)];\r
+ Op1 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)];\r
if (OPERAND1_INDIRECT (Operands)) {\r
if ((Opcode & DATAMANIP_M_64) != 0) {\r
Op1 = VmReadMem64 (VmPtr, (UINTN) Op1);\r
//\r
// Dispatch to the computation function\r
//\r
- if (((Opcode & OPCODE_M_OPCODE) - OPCODE_NOT) >=\r
- (sizeof (mDataManipDispatchTable) / sizeof (mDataManipDispatchTable[0]))\r
- ) {\r
+ DataManipDispatchTableIndex = (Opcode & OPCODE_M_OPCODE) - OPCODE_NOT;\r
+ if ((DataManipDispatchTableIndex < 0) ||\r
+ (DataManipDispatchTableIndex >= ARRAY_SIZE (mDataManipDispatchTable))) {\r
EbcDebugSignalException (\r
EXCEPT_EBC_INVALID_OPCODE,\r
EXCEPTION_FLAG_ERROR,\r
VmPtr->Ip += Size;\r
return EFI_UNSUPPORTED;\r
} else {\r
- Op2 = mDataManipDispatchTable[(Opcode & OPCODE_M_OPCODE) - OPCODE_NOT](VmPtr, Op1, Op2);\r
+ Op2 = mDataManipDispatchTable[DataManipDispatchTableIndex](VmPtr, Op1, Op2);\r
}\r
//\r
// Write back the result.\r
//\r
if (OPERAND1_INDIRECT (Operands)) {\r
- Op1 = VmPtr->R[OPERAND1_REGNUM (Operands)];\r
+ Op1 = (UINT64) VmPtr->Gpr[OPERAND1_REGNUM (Operands)];\r
if ((Opcode & DATAMANIP_M_64) != 0) {\r
VmWriteMem64 (VmPtr, (UINTN) Op1, Op2);\r
} else {\r
// Storage back to a register. Write back, clearing upper bits (as per\r
// the specification) if 32-bit operation.\r
//\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = Op2;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = Op2;\r
if ((Opcode & DATAMANIP_M_64) == 0) {\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] &= 0xFFFFFFFF;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] &= 0xFFFFFFFF;\r
}\r
}\r
//\r
// Spec states that this instruction will not modify reserved bits in\r
// the flags register.\r
//\r
- VmPtr->Flags = (VmPtr->Flags &~VMFLAGS_ALL_VALID) | (VmPtr->R[OPERAND2_REGNUM (Operands)] & VMFLAGS_ALL_VALID);\r
+ VmPtr->Flags = (VmPtr->Flags &~VMFLAGS_ALL_VALID) | (VmPtr->Gpr[OPERAND2_REGNUM (Operands)] & VMFLAGS_ALL_VALID);\r
break;\r
\r
default:\r
//\r
// Retrieve the value in the flags register, then clear reserved bits\r
//\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = (UINT64) (VmPtr->Flags & VMFLAGS_ALL_VALID);\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (UINT64) (VmPtr->Flags & VMFLAGS_ALL_VALID);\r
break;\r
\r
//\r
// Get IP -- address of following instruction\r
//\r
case 1:\r
- VmPtr->R[OPERAND1_REGNUM (Operands)] = (UINT64) (UINTN) VmPtr->Ip + 2;\r
+ VmPtr->Gpr[OPERAND1_REGNUM (Operands)] = (UINT64) (UINTN) VmPtr->Ip + 2;\r
break;\r
\r
default:\r
//\r
ConstUnits = ARShiftU64 (((Index &~0xF000000000000000ULL) & Mask), (UINTN)NBits);\r
\r
- Offset = MultU64x64 (NaturalUnits, sizeof (UINTN)) + ConstUnits;\r
+ Offset = MultU64x64 ((UINT64) NaturalUnits, sizeof (UINTN)) + ConstUnits;\r
\r
//\r
// Now set the sign\r
VM stack) to point into the EBC entry point arguments.\r
\r
@param VmPtr A pointer to a VM context.\r
- @param Addr Adddress to write to.\r
+ @param Addr Address to write to.\r
@param Data Value to write to Addr.\r
\r
@retval EFI_SUCCESS The instruction is executed successfully.\r
VM stack) to point into the EBC entry point arguments.\r
\r
@param VmPtr A pointer to a VM context.\r
- @param Addr Adddress to write to.\r
+ @param Addr Address to write to.\r
@param Data Value to write to Addr.\r
\r
@retval EFI_SUCCESS The instruction is executed successfully.\r
VM stack) to point into the EBC entry point arguments.\r
\r
@param VmPtr A pointer to a VM context.\r
- @param Addr Adddress to write to.\r
+ @param Addr Address to write to.\r
@param Data Value to write to Addr.\r
\r
@retval EFI_SUCCESS The instruction is executed successfully.\r
VM stack) to point into the EBC entry point arguments.\r
\r
@param VmPtr A pointer to a VM context.\r
- @param Addr Adddress to write to.\r
+ @param Addr Address to write to.\r
@param Data Value to write to Addr.\r
\r
@retval EFI_SUCCESS The instruction is executed successfully.\r
)\r
{\r
EFI_STATUS Status;\r
- UINT32 Data32;\r
\r
//\r
// Convert the address if it's in the stack gap\r
}\r
\r
MemoryFence ();\r
- Data32 = (UINT32) (((UINT32 *) &Data)[1]);\r
- if ((Status = VmWriteMem32 (VmPtr, Addr + sizeof (UINT32), Data32)) != EFI_SUCCESS) {\r
+ if ((Status = VmWriteMem32 (VmPtr, Addr + sizeof (UINT32), (UINT32) RShiftU64(Data, 32))) != EFI_SUCCESS) {\r
return Status;\r
}\r
\r
VM stack) to point into the EBC entry point arguments.\r
\r
@param VmPtr A pointer to a VM context.\r
- @param Addr Adddress to write to.\r
+ @param Addr Address to write to.\r
@param Data Value to write to Addr.\r
\r
@retval EFI_SUCCESS The instruction is executed successfully.\r
\r
\r
/**\r
- Reads 16-bit unsinged data from the code stream.\r
+ Reads 16-bit unsigned data from the code stream.\r
\r
This routine provides the ability to read raw unsigned data from the code\r
stream.\r
\r
\r
/**\r
- Reads 32-bit unsinged data from the code stream.\r
+ Reads 32-bit unsigned data from the code stream.\r
\r
This routine provides the ability to read raw unsigned data from the code\r
stream.\r
\r
\r
/**\r
- Reads 64-bit unsinged data from the code stream.\r
+ Reads 64-bit unsigned data from the code stream.\r
\r
This routine provides the ability to read raw unsigned data from the code\r
stream.\r
@param VmPtr A pointer to VM context.\r
@param Addr The memory address.\r
\r
- @return The 8-bit value from the memory adress.\r
+ @return The 8-bit value from the memory address.\r
\r
**/\r
UINT8\r
@param VmPtr A pointer to VM context.\r
@param Addr The memory address.\r
\r
- @return The 16-bit value from the memory adress.\r
+ @return The 16-bit value from the memory address.\r
\r
**/\r
UINT16\r
@param VmPtr A pointer to VM context.\r
@param Addr The memory address.\r
\r
- @return The 32-bit value from the memory adress.\r
+ @return The 32-bit value from the memory address.\r
\r
**/\r
UINT32\r
@param VmPtr A pointer to VM context.\r
@param Addr The memory address.\r
\r
- @return The 64-bit value from the memory adress.\r
+ @return The 64-bit value from the memory address.\r
\r
**/\r
UINT64\r
//\r
// Return unaligned data. Assume little endian.\r
//\r
- Data = (UINT64) VmReadMem32 (VmPtr, Addr);\r
- Data32 = VmReadMem32 (VmPtr, Addr + sizeof (UINT32));\r
- *(UINT32 *) ((UINT32 *) &Data + 1) = Data32;\r
+ Data32 = VmReadMem32 (VmPtr, Addr);\r
+ Data = (UINT64) VmReadMem32 (VmPtr, Addr + sizeof (UINT32));\r
+ Data = LShiftU64 (Data, 32) | Data32;\r
return Data;\r
}\r
\r