Add doxygen style comments for functions in EBC module.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5194 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qhuang8 2008-05-13 08:46:12 +00:00
parent 335b890e40
commit 8e3bc754c5
8 changed files with 2211 additions and 477 deletions

File diff suppressed because it is too large Load Diff

View File

@ -227,6 +227,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define OPCODE_MOVIN 0x38 #define OPCODE_MOVIN 0x38
#define OPCODE_MOVREL 0x39 #define OPCODE_MOVREL 0x39
/**
Execute an EBC image from an entry point or from a published protocol.
@param VmPtr A pointer to a VM context.
@retval EFI_UNSUPPORTED At least one of the opcodes is not supported.
@retval EFI_SUCCESS All of the instructions are executed successfully.
**/
EFI_STATUS EFI_STATUS
EbcExecute ( EbcExecute (
IN VM_CONTEXT *VmPtr IN VM_CONTEXT *VmPtr
@ -235,12 +244,41 @@ EbcExecute (
/**
Returns the version of the EBC virtual machine.
@return The 64-bit version of EBC virtual machine.
**/
UINT64 UINT64
GetVmVersion ( GetVmVersion (
VOID VOID
) )
; ;
/**
Writes UINTN data to memory address.
This routine is called by the EBC data
movement instructions that write to memory. Since these writes
may be to the stack, which looks like (high address on top) this,
[EBC entry point arguments]
[VM stack]
[EBC stack]
we need to detect all attempts to write to the EBC entry point argument
stack area and adjust the address (which will initially point into the
VM stack) to point into the EBC entry point arguments.
@param VmPtr A pointer to a VM context.
@param Addr Adddress to write to.
@param Data Value to write to Addr.
@retval EFI_SUCCESS The instruction is executed successfully.
@retval Other Some error occurs when writing data to the address.
**/
EFI_STATUS EFI_STATUS
VmWriteMemN ( VmWriteMemN (
IN VM_CONTEXT *VmPtr, IN VM_CONTEXT *VmPtr,
@ -249,6 +287,29 @@ VmWriteMemN (
) )
; ;
/**
Writes 64-bit data to memory address.
This routine is called by the EBC data
movement instructions that write to memory. Since these writes
may be to the stack, which looks like (high address on top) this,
[EBC entry point arguments]
[VM stack]
[EBC stack]
we need to detect all attempts to write to the EBC entry point argument
stack area and adjust the address (which will initially point into the
VM stack) to point into the EBC entry point arguments.
@param VmPtr A pointer to a VM context.
@param Addr Adddress to write to.
@param Data Value to write to Addr.
@retval EFI_SUCCESS The instruction is executed successfully.
@retval Other Some error occurs when writing data to the address.
**/
EFI_STATUS EFI_STATUS
VmWriteMem64 ( VmWriteMem64 (
IN VM_CONTEXT *VmPtr, IN VM_CONTEXT *VmPtr,
@ -305,6 +366,20 @@ struct _EFI_EBC_VM_TEST_PROTOCOL {
EBC_VM_TEST_DASM Disassemble; EBC_VM_TEST_DASM Disassemble;
}; };
/**
Given a pointer to a new VM context, execute one or more instructions. This
function is only used for test purposes via the EBC VM test protocol.
@param This A pointer to the EFI_EBC_VM_TEST_PROTOCOL structure.
@param VmPtr A pointer to a VM context.
@param InstructionCount A pointer to a UINTN value holding the number of
instructions to execute. If it holds value of 0,
then the instruction to be executed is 1.
@retval EFI_UNSUPPORTED At least one of the opcodes is not supported.
@retval EFI_SUCCESS All of the instructions are executed successfully.
**/
EFI_STATUS EFI_STATUS
EbcExecuteInstructions ( EbcExecuteInstructions (
IN EFI_EBC_VM_TEST_PROTOCOL *This, IN EFI_EBC_VM_TEST_PROTOCOL *This,

View File

@ -1,9 +1,9 @@
/** @file /** @file
Top level module for the EBC virtual machine implementation. Top level module for the EBC virtual machine implementation.
Provides auxilliary support routines for the VM. That is, routines Provides auxiliary support routines for the VM. That is, routines
that are not particularly related to VM execution of EBC instructions. that are not particularly related to VM execution of EBC instructions.
Copyright (c) 2006, Intel Corporation Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -34,6 +34,20 @@ typedef struct _EBC_IMAGE_LIST {
EBC_THUNK_LIST *ThunkList; EBC_THUNK_LIST *ThunkList;
} EBC_IMAGE_LIST; } EBC_IMAGE_LIST;
/**
This routine is called by the core when an image is being unloaded from
memory. Basically we now have the opportunity to do any necessary cleanup.
Typically this will include freeing any memory allocated for thunk-creation.
@param This A pointer to the EFI_EBC_PROTOCOL instance.
@param ImageHandle Handle of image for which the thunk is being
created.
@retval EFI_INVALID_PARAMETER The ImageHandle passed in was not found in the
internal list of EBC image handles.
@retval EFI_SUCCESS The function completed successfully.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -42,6 +56,25 @@ EbcUnloadImage (
IN EFI_HANDLE ImageHandle IN EFI_HANDLE ImageHandle
); );
/**
This is the top-level routine plugged into the EBC protocol. Since thunks
are very processor-specific, from here we dispatch directly to the very
processor-specific routine EbcCreateThunks().
@param This A pointer to the EFI_EBC_PROTOCOL instance.
@param ImageHandle Handle of image for which the thunk is being
created. The EBC interpreter may use this to
keep track of any resource allocations
performed in loading and executing the image.
@param EbcEntryPoint Address of the actual EBC entry point or
protocol service the thunk should call.
@param Thunk Returned pointer to a thunk created.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Image entry point is not 2-byte aligned.
@retval EFI_OUT_OF_RESOURCES Memory could not be allocated for the thunk.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -52,6 +85,17 @@ EbcCreateThunk (
OUT VOID **Thunk OUT VOID **Thunk
); );
/**
Called to get the version of the interpreter.
@param This A pointer to the EFI_EBC_PROTOCOL instance.
@param Version Pointer to where to store the returned version
of the interpreter.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Version pointer is NULL.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -60,6 +104,16 @@ EbcGetVersion (
IN OUT UINT64 *Version IN OUT UINT64 *Version
); );
/**
To install default Callback function for the VM interpreter.
@param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
instance.
@retval EFI_SUCCESS The function completed successfully.
@retval Others Some error occurs when creating periodic event.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -67,6 +121,15 @@ InitializeEbcCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This IN EFI_DEBUG_SUPPORT_PROTOCOL *This
); );
/**
The default Exception Callback for the VM interpreter.
In this function, we report status code, and print debug information
about EBC_CONTEXT, then dead loop.
@param InterruptType Interrupt type.
@param SystemContext EBC system context.
**/
STATIC STATIC
VOID VOID
EFIAPI EFIAPI
@ -75,6 +138,14 @@ CommonEbcExceptionHandler (
IN EFI_SYSTEM_CONTEXT SystemContext IN EFI_SYSTEM_CONTEXT SystemContext
); );
/**
The periodic callback function for EBC VM interpreter, which is used
to support the EFI debug support protocol.
@param Event The Periodic Callback Event.
@param Context It should be the address of VM_CONTEXT pointer.
**/
STATIC STATIC
VOID VOID
EFIAPI EFIAPI
@ -83,6 +154,16 @@ EbcPeriodicNotifyFunction (
IN VOID *Context IN VOID *Context
); );
/**
The VM interpreter calls this function on a periodic basis to support
the EFI debug support protocol.
@param VmPtr Pointer to a VM context for passing info to the
debugger.
@retval EFI_SUCCESS The function completed successfully.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -94,18 +175,43 @@ EbcDebugPeriodic (
// These two functions and the GUID are used to produce an EBC test protocol. // These two functions and the GUID are used to produce an EBC test protocol.
// This functionality is definitely not required for execution. // This functionality is definitely not required for execution.
// //
/**
Produces an EBC VM test protocol that can be used for regression tests.
@param IHandle Handle on which to install the protocol.
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
@retval EFI_SUCCESS The function completed successfully.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
InitEbcVmTestProtocol ( InitEbcVmTestProtocol (
IN EFI_HANDLE *Handle IN EFI_HANDLE *Handle
); );
/**
Returns the EFI_UNSUPPORTED Status.
@return EFI_UNSUPPORTED This function always return EFI_UNSUPPORTED status.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EbcVmTestUnsupported ( EbcVmTestUnsupported (
VOID VOID
); );
/**
Registers a callback function that the EBC interpreter calls to flush the
processor instruction cache following creation of thunks.
@param This A pointer to the EFI_EBC_PROTOCOL instance.
@param Flush Pointer to a function of type EBC_ICACH_FLUSH.
@retval EFI_SUCCESS The function completed successfully.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -114,6 +220,17 @@ EbcRegisterICacheFlush (
IN EBC_ICACHE_FLUSH Flush IN EBC_ICACHE_FLUSH Flush
); );
/**
This EBC debugger protocol service is called by the debug agent
@param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
instance.
@param MaxProcessorIndex Pointer to a caller-allocated UINTN in which the
maximum supported processor index is returned.
@retval EFI_SUCCESS The function completed successfully.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -122,6 +239,27 @@ EbcDebugGetMaximumProcessorIndex (
OUT UINTN *MaxProcessorIndex OUT UINTN *MaxProcessorIndex
); );
/**
This protocol service is called by the debug agent to register a function
for us to call on a periodic basis.
@param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
instance.
@param ProcessorIndex Specifies which processor the callback function
applies to.
@param PeriodicCallback A pointer to a function of type
PERIODIC_CALLBACK that is the main periodic
entry point of the debug agent. It receives as a
parameter a pointer to the full context of the
interrupted execution thread.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a
callback function was previously registered.
@retval EFI_INVALID_PARAMETER Null PeriodicCallback parameter when no
callback function was previously registered.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -131,6 +269,31 @@ EbcDebugRegisterPeriodicCallback (
IN EFI_PERIODIC_CALLBACK PeriodicCallback IN EFI_PERIODIC_CALLBACK PeriodicCallback
); );
/**
This protocol service is called by the debug agent to register a function
for us to call when we detect an exception.
@param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
instance.
@param ProcessorIndex Specifies which processor the callback function
applies to.
@param ExceptionCallback A pointer to a function of type
EXCEPTION_CALLBACK that is called when the
processor exception specified by ExceptionType
occurs. Passing NULL unregisters any previously
registered function associated with
ExceptionType.
@param ExceptionType Specifies which processor exception to hook.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_ALREADY_STARTED Non-NULL ExceptionCallback parameter when a
callback function was previously registered.
@retval EFI_INVALID_PARAMETER ExceptionType parameter is negative or exceeds
MAX_EBC_EXCEPTION.
@retval EFI_INVALID_PARAMETER Null ExceptionCallback parameter when no
callback function was previously registered.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -141,6 +304,22 @@ EbcDebugRegisterExceptionCallback (
IN EFI_EXCEPTION_TYPE ExceptionType IN EFI_EXCEPTION_TYPE ExceptionType
); );
/**
This EBC debugger protocol service is called by the debug agent. Required
for DebugSupport compliance but is only stubbed out for EBC.
@param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
instance.
@param ProcessorIndex Specifies which processor the callback function
applies to.
@param Start StartSpecifies the physical base of the memory
range to be invalidated.
@param Length Specifies the minimum number of bytes in the
processor's instruction cache to invalidate.
@retval EFI_SUCCESS The function completed successfully.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -157,28 +336,28 @@ EbcDebugInvalidateInstructionCache (
// also be global since the execution of an EBC image does not provide // also be global since the execution of an EBC image does not provide
// a This pointer. // a This pointer.
// //
static EBC_IMAGE_LIST *mEbcImageList = NULL; STATIC EBC_IMAGE_LIST *mEbcImageList = NULL;
// //
// Callback function to flush the icache after thunk creation // Callback function to flush the icache after thunk creation
// //
static EBC_ICACHE_FLUSH mEbcICacheFlush; STATIC EBC_ICACHE_FLUSH mEbcICacheFlush;
// //
// These get set via calls by the debug agent // These get set via calls by the debug agent
// //
static EFI_PERIODIC_CALLBACK mDebugPeriodicCallback = NULL; STATIC EFI_PERIODIC_CALLBACK mDebugPeriodicCallback = NULL;
static EFI_EXCEPTION_CALLBACK mDebugExceptionCallback[MAX_EBC_EXCEPTION + 1] = {NULL}; STATIC EFI_EXCEPTION_CALLBACK mDebugExceptionCallback[MAX_EBC_EXCEPTION + 1] = {NULL};
static EFI_GUID mEfiEbcVmTestProtocolGuid = EFI_EBC_VM_TEST_PROTOCOL_GUID; STATIC EFI_GUID mEfiEbcVmTestProtocolGuid = EFI_EBC_VM_TEST_PROTOCOL_GUID;
static VOID* mStackBuffer[MAX_STACK_NUM]; STATIC VOID* mStackBuffer[MAX_STACK_NUM];
static EFI_HANDLE mStackBufferIndex[MAX_STACK_NUM]; STATIC EFI_HANDLE mStackBufferIndex[MAX_STACK_NUM];
static UINTN mStackNum = 0; STATIC UINTN mStackNum = 0;
// //
// Event for Periodic callback // Event for Periodic callback
// //
static EFI_EVENT mEbcPeriodicEvent; STATIC EFI_EVENT mEbcPeriodicEvent;
VM_CONTEXT *mVmPtr = NULL; VM_CONTEXT *mVmPtr = NULL;
@ -378,16 +557,18 @@ ErrorExit:
are very processor-specific, from here we dispatch directly to the very are very processor-specific, from here we dispatch directly to the very
processor-specific routine EbcCreateThunks(). processor-specific routine EbcCreateThunks().
@param This protocol instance pointer @param This A pointer to the EFI_EBC_PROTOCOL instance.
@param ImageHandle handle to the image. The EBC interpreter may use @param ImageHandle Handle of image for which the thunk is being
this to keep track of any resource allocations created. The EBC interpreter may use this to
performed in loading and executing the image. keep track of any resource allocations
@param EbcEntryPoint the entry point for the image (as defined in the performed in loading and executing the image.
file header) @param EbcEntryPoint Address of the actual EBC entry point or
@param Thunk pointer to thunk pointer where the address of the protocol service the thunk should call.
created thunk is returned. @param Thunk Returned pointer to a thunk created.
@return EFI_STATUS @retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Image entry point is not 2-byte aligned.
@retval EFI_OUT_OF_RESOURCES Memory could not be allocated for the thunk.
**/ **/
STATIC STATIC
@ -415,12 +596,12 @@ EbcCreateThunk (
/** /**
This EBC debugger protocol service is called by the debug agent This EBC debugger protocol service is called by the debug agent
@param This pointer to the caller's debug support protocol @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
interface instance.
@param MaxProcessorIndex pointer to a caller allocated UINTN in which the @param MaxProcessorIndex Pointer to a caller-allocated UINTN in which the
maximum processor index is returned. maximum supported processor index is returned.
@return Standard EFI_STATUS @retval EFI_SUCCESS The function completed successfully.
**/ **/
STATIC STATIC
@ -440,11 +621,21 @@ EbcDebugGetMaximumProcessorIndex (
This protocol service is called by the debug agent to register a function This protocol service is called by the debug agent to register a function
for us to call on a periodic basis. for us to call on a periodic basis.
@param This pointer to the caller's debug support protocol @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
interface instance.
@param PeriodicCallback pointer to the function to call periodically @param ProcessorIndex Specifies which processor the callback function
applies to.
@param PeriodicCallback A pointer to a function of type
PERIODIC_CALLBACK that is the main periodic
entry point of the debug agent. It receives as a
parameter a pointer to the full context of the
interrupted execution thread.
@return Always EFI_SUCCESS @retval EFI_SUCCESS The function completed successfully.
@retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a
callback function was previously registered.
@retval EFI_INVALID_PARAMETER Null PeriodicCallback parameter when no
callback function was previously registered.
**/ **/
STATIC STATIC
@ -472,11 +663,25 @@ EbcDebugRegisterPeriodicCallback (
This protocol service is called by the debug agent to register a function This protocol service is called by the debug agent to register a function
for us to call when we detect an exception. for us to call when we detect an exception.
@param This pointer to the caller's debug support protocol @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
interface instance.
@param ExceptionCallback pointer to the function to the exception @param ProcessorIndex Specifies which processor the callback function
applies to.
@param ExceptionCallback A pointer to a function of type
EXCEPTION_CALLBACK that is called when the
processor exception specified by ExceptionType
occurs. Passing NULL unregisters any previously
registered function associated with
ExceptionType.
@param ExceptionType Specifies which processor exception to hook.
@return Always EFI_SUCCESS @retval EFI_SUCCESS The function completed successfully.
@retval EFI_ALREADY_STARTED Non-NULL ExceptionCallback parameter when a
callback function was previously registered.
@retval EFI_INVALID_PARAMETER ExceptionType parameter is negative or exceeds
MAX_EBC_EXCEPTION.
@retval EFI_INVALID_PARAMETER Null ExceptionCallback parameter when no
callback function was previously registered.
**/ **/
STATIC STATIC
@ -507,8 +712,16 @@ EbcDebugRegisterExceptionCallback (
This EBC debugger protocol service is called by the debug agent. Required This EBC debugger protocol service is called by the debug agent. Required
for DebugSupport compliance but is only stubbed out for EBC. for DebugSupport compliance but is only stubbed out for EBC.
@param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
instance.
@param ProcessorIndex Specifies which processor the callback function
applies to.
@param Start StartSpecifies the physical base of the memory
range to be invalidated.
@param Length Specifies the minimum number of bytes in the
processor's instruction cache to invalidate.
@return EFI_SUCCESS @retval EFI_SUCCESS The function completed successfully.
**/ **/
STATIC STATIC
@ -528,10 +741,12 @@ EbcDebugInvalidateInstructionCache (
/** /**
The VM interpreter calls this function when an exception is detected. The VM interpreter calls this function when an exception is detected.
@param VmPtr pointer to a VM context for passing info to the @param ExceptionType Specifies the processor exception detected.
@param ExceptionFlags Specifies the exception context.
@param VmPtr Pointer to a VM context for passing info to the
EFI debugger. EFI debugger.
@return EFI_SUCCESS if it returns at all @retval EFI_SUCCESS This function completed successfully.
**/ **/
EFI_STATUS EFI_STATUS
@ -605,13 +820,16 @@ EbcDebugSignalException (
/** /**
To install default Callback function for the VM interpreter. To install default Callback function for the VM interpreter.
@param This pointer to the instance of DebugSupport protocol @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
instance.
@return None @retval EFI_SUCCESS The function completed successfully.
@retval Others Some error occurs when creating periodic event.
**/ **/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI
InitializeEbcCallback ( InitializeEbcCallback (
IN EFI_DEBUG_SUPPORT_PROTOCOL *This IN EFI_DEBUG_SUPPORT_PROTOCOL *This
) )
@ -666,11 +884,10 @@ InitializeEbcCallback (
@param InterruptType Interrupt type. @param InterruptType Interrupt type.
@param SystemContext EBC system context. @param SystemContext EBC system context.
@return None
**/ **/
STATIC STATIC
VOID VOID
EFIAPI
CommonEbcExceptionHandler ( CommonEbcExceptionHandler (
IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_EXCEPTION_TYPE InterruptType,
IN EFI_SYSTEM_CONTEXT SystemContext IN EFI_SYSTEM_CONTEXT SystemContext
@ -692,8 +909,6 @@ CommonEbcExceptionHandler (
@param Event The Periodic Callback Event. @param Event The Periodic Callback Event.
@param Context It should be the address of VM_CONTEXT pointer. @param Context It should be the address of VM_CONTEXT pointer.
@return None.
**/ **/
STATIC STATIC
VOID VOID
@ -719,14 +934,15 @@ EbcPeriodicNotifyFunction (
The VM interpreter calls this function on a periodic basis to support The VM interpreter calls this function on a periodic basis to support
the EFI debug support protocol. the EFI debug support protocol.
@param VmPtr pointer to a VM context for passing info to the @param VmPtr Pointer to a VM context for passing info to the
debugger. debugger.
@return Standard EFI status. @retval EFI_SUCCESS The function completed successfully.
**/ **/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI
EbcDebugPeriodic ( EbcDebugPeriodic (
IN VM_CONTEXT *VmPtr IN VM_CONTEXT *VmPtr
) )
@ -781,12 +997,13 @@ EbcDebugPeriodic (
memory. Basically we now have the opportunity to do any necessary cleanup. memory. Basically we now have the opportunity to do any necessary cleanup.
Typically this will include freeing any memory allocated for thunk-creation. Typically this will include freeing any memory allocated for thunk-creation.
@param This protocol instance pointer @param This A pointer to the EFI_EBC_PROTOCOL instance.
@param ImageHandle handle to the image being unloaded. @param ImageHandle Handle of image for which the thunk is being
created.
@retval EFI_INVALID_PARAMETER the ImageHandle passed in was not found in the @retval EFI_INVALID_PARAMETER The ImageHandle passed in was not found in the
internal list of EBC image handles. internal list of EBC image handles.
@retval EFI_STATUS completed successfully @retval EFI_SUCCESS The function completed successfully.
**/ **/
STATIC STATIC
@ -855,12 +1072,12 @@ EbcUnloadImage (
Also flush the instruction cache since we've written thunk code Also flush the instruction cache since we've written thunk code
to memory that will be executed eventually. to memory that will be executed eventually.
@param ImageHandle the image handle to which the thunk is tied @param ImageHandle The image handle to which the thunk is tied.
@param ThunkBuffer the buffer we've created/allocated @param ThunkBuffer The buffer that has been created/allocated.
@param ThunkSize the size of the thunk memory allocated @param ThunkSize The size of the thunk memory allocated.
@retval EFI_OUT_OF_RESOURCES memory allocation failed @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
@retval EFI_SUCCESS successful completion @retval EFI_SUCCESS The function completed successfully.
**/ **/
EFI_STATUS EFI_STATUS
@ -925,6 +1142,16 @@ EbcAddImageThunk (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Registers a callback function that the EBC interpreter calls to flush the
processor instruction cache following creation of thunks.
@param This A pointer to the EFI_EBC_PROTOCOL instance.
@param Flush Pointer to a function of type EBC_ICACH_FLUSH.
@retval EFI_SUCCESS The function completed successfully.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -937,6 +1164,17 @@ EbcRegisterICacheFlush (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Called to get the version of the interpreter.
@param This A pointer to the EFI_EBC_PROTOCOL instance.
@param Version Pointer to where to store the returned version
of the interpreter.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_INVALID_PARAMETER Version pointer is NULL.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
@ -953,11 +1191,24 @@ EbcGetVersion (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Returns the stack index and buffer assosicated with the Handle parameter.
@param Handle The EFI handle as the index to the EBC stack.
@param StackBuffer A pointer to hold the returned stack buffer.
@param BufferIndex A pointer to hold the returned stack index.
@retval EFI_OUT_OF_RESOURCES The Handle parameter does not correspond to any
existing EBC stack.
@retval EFI_SUCCESS The stack index and buffer were found and
returned to the caller.
**/
EFI_STATUS EFI_STATUS
GetEBCStack( GetEBCStack(
EFI_HANDLE Handle, IN EFI_HANDLE Handle,
VOID **StackBuffer, OUT VOID **StackBuffer,
UINTN *BufferIndex OUT UINTN *BufferIndex
) )
{ {
UINTN Index; UINTN Index;
@ -978,18 +1229,34 @@ GetEBCStack(
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Returns from the EBC stack by stack Index.
@param Index Specifies which EBC stack to return from.
@retval EFI_SUCCESS The function completed successfully.
**/
EFI_STATUS EFI_STATUS
ReturnEBCStack( ReturnEBCStack(
UINTN Index IN UINTN Index
) )
{ {
mStackBufferIndex[Index] =NULL; mStackBufferIndex[Index] = NULL;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Returns from the EBC stack associated with the Handle parameter.
@param Handle Specifies the EFI handle to find the EBC stack with.
@retval EFI_SUCCESS The function completed successfully.
**/
EFI_STATUS EFI_STATUS
ReturnEBCStackByHandle( ReturnEBCStackByHandle(
EFI_HANDLE Handle IN EFI_HANDLE Handle
) )
{ {
UINTN Index; UINTN Index;
@ -1005,6 +1272,13 @@ ReturnEBCStackByHandle(
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Allocates memory to hold all the EBC stacks.
@retval EFI_SUCCESS The EBC stacks were allocated successfully.
@retval EFI_OUT_OF_RESOURCES Not enough memory available for EBC stacks.
**/
EFI_STATUS EFI_STATUS
InitEBCStack ( InitEBCStack (
VOID VOID
@ -1023,6 +1297,13 @@ InitEBCStack (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
Free all EBC stacks allocated before.
@retval EFI_SUCCESS All the EBC stacks were freed.
**/
EFI_STATUS EFI_STATUS
FreeEBCStack( FreeEBCStack(
VOID VOID
@ -1036,12 +1317,12 @@ FreeEBCStack(
} }
/** /**
Produce an EBC VM test protocol that can be used for regression tests. Produces an EBC VM test protocol that can be used for regression tests.
@param IHandle handle on which to install the protocol. @param IHandle Handle on which to install the protocol.
@retval EFI_OUT_OF_RESOURCES memory allocation failed @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
@retval EFI_SUCCESS successful completion @retval EFI_SUCCESS The function completed successfully.
**/ **/
STATIC STATIC
@ -1078,9 +1359,19 @@ InitEbcVmTestProtocol (
} }
return Status; return Status;
} }
/**
Returns the EFI_UNSUPPORTED Status.
@return EFI_UNSUPPORTED This function always return EFI_UNSUPPORTED status.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
EbcVmTestUnsupported () EbcVmTestUnsupported (
VOID
)
{ {
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }

View File

@ -79,6 +79,23 @@ extern VM_CONTEXT *mVmPtr;
// //
#define VM_STACK_KEY_VALUE 0xDEADBEEF #define VM_STACK_KEY_VALUE 0xDEADBEEF
/**
Create thunks for an EBC image entry point, or an EBC protocol service.
@param ImageHandle Image handle for the EBC image. If not null, then
we're creating a thunk for an image entry point.
@param EbcEntryPoint Address of the EBC code that the thunk is to call
@param Thunk Returned thunk we create here
@param Flags Flags indicating options for creating the thunk
@retval EFI_SUCCESS The thunk was created successfully.
@retval EFI_INVALID_PARAMETER The parameter of EbcEntryPoint is not 16-bit
aligned.
@retval EFI_OUT_OF_RESOURCES There is not enough memory to created the EBC
Thunk.
@retval EFI_BUFFER_TOO_SMALL EBC_THUNK_SIZE is not larger enough.
**/
EFI_STATUS EFI_STATUS
EbcCreateThunks ( EbcCreateThunks (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
@ -88,6 +105,19 @@ EbcCreateThunks (
) )
; ;
/**
Add a thunk to our list of thunks for a given image handle.
Also flush the instruction cache since we've written thunk code
to memory that will be executed eventually.
@param ImageHandle The image handle to which the thunk is tied.
@param ThunkBuffer The buffer that has been created/allocated.
@param ThunkSize The size of the thunk memory allocated.
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
@retval EFI_SUCCESS The function completed successfully.
**/
EFI_STATUS EFI_STATUS
EbcAddImageThunk ( EbcAddImageThunk (
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle,
@ -100,6 +130,17 @@ EbcAddImageThunk (
// The interpreter calls these when an exception is detected, // The interpreter calls these when an exception is detected,
// or as a periodic callback. // or as a periodic callback.
// //
/**
The VM interpreter calls this function when an exception is detected.
@param ExceptionType Specifies the processor exception detected.
@param ExceptionFlags Specifies the exception context.
@param VmPtr Pointer to a VM context for passing info to the
EFI debugger.
@retval EFI_SUCCESS This function completed successfully.
**/
EFI_STATUS EFI_STATUS
EbcDebugSignalException ( EbcDebugSignalException (
IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_EXCEPTION_TYPE ExceptionType,
@ -117,28 +158,56 @@ EbcDebugSignalException (
#define STACK_POOL_SIZE (1024 * 1020) #define STACK_POOL_SIZE (1024 * 1020)
#define MAX_STACK_NUM 4 #define MAX_STACK_NUM 4
EFI_STATUS
EbcDebugSignalPeriodic (
IN VM_CONTEXT *VmPtr
)
;
// //
// External low level functions that are native-processor dependent // External low level functions that are native-processor dependent
// //
/**
The VM thunk code stuffs an EBC entry point into a processor
register. Since we can't use inline assembly to get it from
the interpreter C code, stuff it into the return value
register and return.
@return The contents of the register in which the entry point is passed.
**/
UINTN UINTN
EFIAPI
EbcLLGetEbcEntryPoint ( EbcLLGetEbcEntryPoint (
VOID VOID
) )
; ;
/**
Returns the caller's value of the stack pointer.
We adjust it by 4 here because when they called us, the return address
is put on the stack, thereby lowering it by 4 bytes.
@return The current value of the stack pointer for the caller.
**/
UINTN UINTN
EFIAPI
EbcLLGetStackPointer ( EbcLLGetStackPointer (
VOID VOID
) )
; ;
/**
This function is called to execute an EBC CALLEX instruction.
This instruction requires that we thunk out to external native
code. For x64, we switch stacks, copy the arguments to the stack
and jump to the specified function.
On return, we restore the stack pointer to its original location.
Destroys no working registers.
@param CallAddr The function address.
@param EbcSp The new EBC stack pointer.
@param FramePtr The frame pointer.
**/
VOID VOID
EFIAPI
EbcLLCALLEXNative ( EbcLLCALLEXNative (
IN UINTN CallAddr, IN UINTN CallAddr,
IN UINTN EbcSp, IN UINTN EbcSp,
@ -146,47 +215,114 @@ EbcLLCALLEXNative (
) )
; ;
/**
This function is called to execute an EBC CALLEX instruction.
The function check the callee's content to see whether it is common native
code or a thunk to another piece of EBC code.
If the callee is common native code, use EbcLLCAllEXASM to manipulate,
otherwise, set the VM->IP to target EBC code directly to avoid another VM
be startup which cost time and stack space.
@param VmPtr Pointer to a VM context.
@param FuncAddr Callee's address
@param NewStackPointer New stack pointer after the call
@param FramePtr New frame pointer after the call
@param Size The size of call instruction
**/
VOID VOID
EbcLLCALLEX ( EbcLLCALLEX (
IN VM_CONTEXT *VmPtr, IN VM_CONTEXT *VmPtr,
IN UINTN CallAddr, IN UINTN FuncAddr,
IN UINTN EbcSp, IN UINTN NewStackPointer,
IN VOID *FramePtr, IN VOID *FramePtr,
IN UINT8 Size IN UINT8 Size
) )
; ;
/**
When EBC calls native, on return the VM has to stuff the return
value into a VM register. It's assumed here that the value is still
in the register, so simply return and the caller should get the
return result properly.
@return The unmodified value returned by the native code.
**/
INT64 INT64
EFIAPI
EbcLLGetReturnValue ( EbcLLGetReturnValue (
VOID VOID
) )
; ;
/**
Returns the stack index and buffer assosicated with the Handle parameter.
@param Handle The EFI handle as the index to the EBC stack.
@param StackBuffer A pointer to hold the returned stack buffer.
@param BufferIndex A pointer to hold the returned stack index.
@retval EFI_OUT_OF_RESOURCES The Handle parameter does not correspond to any
existing EBC stack.
@retval EFI_SUCCESS The stack index and buffer were found and
returned to the caller.
**/
EFI_STATUS EFI_STATUS
GetEBCStack( GetEBCStack(
EFI_HANDLE Handle, IN EFI_HANDLE Handle,
VOID **StackBuffer, OUT VOID **StackBuffer,
UINTN *BufferIndex OUT UINTN *BufferIndex
); );
/**
Returns from the EBC stack by stack Index.
@param Index Specifies which EBC stack to return from.
@retval EFI_SUCCESS The function completed successfully.
**/
EFI_STATUS EFI_STATUS
ReturnEBCStack( ReturnEBCStack(
UINTN Index IN UINTN Index
); );
/**
Allocates memory to hold all the EBC stacks.
@retval EFI_SUCCESS The EBC stacks were allocated successfully.
@retval EFI_OUT_OF_RESOURCES Not enough memory available for EBC stacks.
**/
EFI_STATUS EFI_STATUS
InitEBCStack ( InitEBCStack (
VOID VOID
); );
/**
Free all EBC stacks allocated before.
@retval EFI_SUCCESS All the EBC stacks were freed.
**/
EFI_STATUS EFI_STATUS
FreeEBCStack( FreeEBCStack(
VOID VOID
); );
/**
Returns from the EBC stack associated with the Handle parameter.
@param Handle Specifies the EFI handle to find the EBC stack with.
@retval EFI_SUCCESS The function completed successfully.
**/
EFI_STATUS EFI_STATUS
ReturnEBCStackByHandle( ReturnEBCStackByHandle(
EFI_HANDLE Handle IN EFI_HANDLE Handle
); );
// //
// Defines for a simple EBC debugger interface // Defines for a simple EBC debugger interface
@ -255,13 +391,6 @@ typedef struct {
#define EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('e', 'b', 'c', 'p') #define EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('e', 'b', 'c', 'p')
struct _EBC_PROTOCOL_PRIVATE_DATA {
UINT32 Signature;
EFI_EBC_PROTOCOL EbcProtocol;
UINTN StackBase;
UINTN StackTop;
UINTN StackSize;
} ;
#define EBC_PROTOCOL_PRIVATE_DATA_FROM_THIS(a) \ #define EBC_PROTOCOL_PRIVATE_DATA_FROM_THIS(a) \
CR(a, EBC_PROTOCOL_PRIVATE_DATA, EbcProtocol, EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE) CR(a, EBC_PROTOCOL_PRIVATE_DATA, EbcProtocol, EBC_PROTOCOL_PRIVATE_DATA_SIGNATURE)

View File

@ -36,13 +36,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
otherwise, set the VM->IP to target EBC code directly to avoid another VM otherwise, set the VM->IP to target EBC code directly to avoid another VM
be startup which cost time and stack space. be startup which cost time and stack space.
@parm VmPtr Pointer to a VM context. @param VmPtr Pointer to a VM context.
@parm FuncAddr Callee's address @param FuncAddr Callee's address
@parm NewStackPointer New stack pointer after the call @param NewStackPointer New stack pointer after the call
@parm FramePtr New frame pointer after the call @param FramePtr New frame pointer after the call
@parm Size The size of call instruction @param Size The size of call instruction
@return None.
**/ **/
VOID VOID
@ -137,9 +135,26 @@ Action:
in via a processor register, so we'll need to make a call to get the in via a processor register, so we'll need to make a call to get the
value. value.
None. Since we're called from a fixed up thunk (which we want to keep This is a thunk function. Microsoft x64 compiler only provide fast_call
small), our only so-called argument is the EBC entry point passed in calling convention, so the first four arguments are passed by rcx, rdx,
to us in a processor register. r8, and r9, while other arguments are passed in stack.
@param Arg1 The 1st argument.
@param Arg2 The 2nd argument.
@param Arg3 The 3rd argument.
@param Arg4 The 4th argument.
@param Arg5 The 5th argument.
@param Arg6 The 6th argument.
@param Arg7 The 7th argument.
@param Arg8 The 8th argument.
@param Arg9 The 9th argument.
@param Arg10 The 10th argument.
@param Arg11 The 11th argument.
@param Arg12 The 12th argument.
@param Arg13 The 13th argument.
@param Arg14 The 14th argument.
@param Arg15 The 15th argument.
@param Arg16 The 16th argument.
@return The value returned by the EBC application we're going to run. @return The value returned by the EBC application we're going to run.
@ -286,8 +301,9 @@ EbcInterpret (
in via a processor register, so we'll need to make a call to get the in via a processor register, so we'll need to make a call to get the
value. value.
@param ImageHandle image handle for the EBC application we're executing @param ImageHandle image handle for the EBC application we're executing
@param SystemTable standard system table passed into an driver's entry point @param SystemTable standard system table passed into an driver's entry
point
@return The value returned by the EBC application we're going to run. @return The value returned by the EBC application we're going to run.
@ -385,13 +401,20 @@ ExecuteEbcImageEntryPoint (
/** /**
Create an IA32 thunk for the given EBC entry point. Create thunks for an EBC image entry point, or an EBC protocol service.
@param ImageHandle Handle of image for which this thunk is being created @param ImageHandle Image handle for the EBC image. If not null, then
@param EbcEntryPoint Address of the EBC code that the thunk is to call we're creating a thunk for an image entry point.
@param Thunk Returned thunk we create here @param EbcEntryPoint Address of the EBC code that the thunk is to call
@param Thunk Returned thunk we create here
@param Flags Flags indicating options for creating the thunk
@return Standard EFI status. @retval EFI_SUCCESS The thunk was created successfully.
@retval EFI_INVALID_PARAMETER The parameter of EbcEntryPoint is not 16-bit
aligned.
@retval EFI_OUT_OF_RESOURCES There is not enough memory to created the EBC
Thunk.
@retval EFI_BUFFER_TOO_SMALL EBC_THUNK_SIZE is not larger enough.
**/ **/
EFI_STATUS EFI_STATUS
@ -404,7 +427,7 @@ EbcCreateThunks (
{ {
UINT8 *Ptr; UINT8 *Ptr;
UINT8 *ThunkBase; UINT8 *ThunkBase;
UINT32 I; UINT32 Index;
UINT32 Addr; UINT32 Addr;
INT32 Size; INT32 Size;
INT32 ThunkSize; INT32 ThunkSize;
@ -444,7 +467,7 @@ EbcCreateThunks (
Ptr++; Ptr++;
Size--; Size--;
Addr = (UINT32) 0xCA112EBC; Addr = (UINT32) 0xCA112EBC;
for (I = 0; I < sizeof (Addr); I++) { for (Index = 0; Index < sizeof (Addr); Index++) {
*Ptr = (UINT8) (UINTN) Addr; *Ptr = (UINT8) (UINTN) Addr;
Addr >>= 8; Addr >>= 8;
Ptr++; Ptr++;
@ -461,7 +484,7 @@ EbcCreateThunks (
Ptr++; Ptr++;
Size--; Size--;
Addr = (UINT32) EbcEntryPoint; Addr = (UINT32) EbcEntryPoint;
for (I = 0; I < sizeof (Addr); I++) { for (Index = 0; Index < sizeof (Addr); Index++) {
*Ptr = (UINT8) (UINTN) Addr; *Ptr = (UINT8) (UINTN) Addr;
Addr >>= 8; Addr >>= 8;
Ptr++; Ptr++;
@ -483,7 +506,7 @@ EbcCreateThunks (
*Ptr = 0xB9; *Ptr = 0xB9;
Ptr++; Ptr++;
Size--; Size--;
for (I = 0; I < sizeof (Addr); I++) { for (Index = 0; Index < sizeof (Addr); Index++) {
*Ptr = (UINT8) Addr; *Ptr = (UINT8) Addr;
Addr >>= 8; Addr >>= 8;
Ptr++; Ptr++;

View File

@ -17,6 +17,23 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "EbcExecute.h" #include "EbcExecute.h"
#include "EbcSupport.h" #include "EbcSupport.h"
/**
Given raw bytes of Itanium based code, format them into a bundle and
write them out.
@param MemPtr pointer to memory location to write the bundles
to.
@param Template 5-bit template.
@param Slot0 Instruction slot 0 data for the bundle.
@param Slot1 Instruction slot 1 data for the bundle.
@param Slot2 Instruction slot 2 data for the bundle.
@retval EFI_INVALID_PARAMETER Pointer is not aligned
@retval EFI_INVALID_PARAMETER No more than 5 bits in template
@retval EFI_INVALID_PARAMETER More than 41 bits used in code
@retval EFI_SUCCESS All data is written.
**/
STATIC STATIC
EFI_STATUS EFI_STATUS
WriteBundle ( WriteBundle (
@ -27,11 +44,18 @@ WriteBundle (
IN UINT64 Slot2 IN UINT64 Slot2
); );
/**
Pushes a 64 bit unsigned value to the VM stack.
@param VmPtr The pointer to current VM context.
@param Arg The value to be pushed.
**/
STATIC STATIC
VOID VOID
PushU64 ( PushU64 (
VM_CONTEXT *VmPtr, IN VM_CONTEXT *VmPtr,
UINT64 Arg IN UINT64 Arg
) )
{ {
// //
@ -42,6 +66,21 @@ PushU64 (
*(UINT64 *) VmPtr->R[0] = Arg; *(UINT64 *) VmPtr->R[0] = Arg;
} }
/**
Begin executing an EBC image. The address of the entry point is passed
in via a processor register, so we'll need to make a call to get the
value.
This is a thunk function. Microsoft x64 compiler only provide fast_call
calling convention, so the first four arguments are passed by rcx, rdx,
r8, and r9, while other arguments are passed in stack.
@param Arg1 The 1st argument.
@param ... The variable arguments list.
@return The value returned by the EBC application we're going to run.
**/
STATIC STATIC
UINT64 UINT64
EbcInterpret ( EbcInterpret (
@ -189,15 +228,13 @@ EbcInterpret (
/** /**
IPF implementation.
Begin executing an EBC image. The address of the entry point is passed Begin executing an EBC image. The address of the entry point is passed
in via a processor register, so we'll need to make a call to get the in via a processor register, so we'll need to make a call to get the
value. value.
@param ImageHandle image handle for the EBC application we're @param ImageHandle image handle for the EBC application we're executing
executing @param SystemTable standard system table passed into an driver's entry
@param SystemTable standard system table passed into an driver's point
entry point
@return The value returned by the EBC application we're going to run. @return The value returned by the EBC application we're going to run.
@ -312,13 +349,18 @@ ExecuteEbcImageEntryPoint (
/** /**
Create thunks for an EBC image entry point, or an EBC protocol service. Create thunks for an EBC image entry point, or an EBC protocol service.
@param ImageHandle Image handle for the EBC image. If not null, then @param ImageHandle Image handle for the EBC image. If not null, then
we're creating a thunk for an image entry point. we're creating a thunk for an image entry point.
@param EbcEntryPoint Address of the EBC code that the thunk is to call @param EbcEntryPoint Address of the EBC code that the thunk is to call
@param Thunk Returned thunk we create here @param Thunk Returned thunk we create here
@param Flags Flags indicating options for creating the thunk @param Flags Flags indicating options for creating the thunk
@return Standard EFI status. @retval EFI_SUCCESS The thunk was created successfully.
@retval EFI_INVALID_PARAMETER The parameter of EbcEntryPoint is not 16-bit
aligned.
@retval EFI_OUT_OF_RESOURCES There is not enough memory to created the EBC
Thunk.
@retval EFI_BUFFER_TOO_SMALL EBC_THUNK_SIZE is not larger enough.
**/ **/
EFI_STATUS EFI_STATUS
@ -334,11 +376,11 @@ EbcCreateThunks (
UINT64 Addr; UINT64 Addr;
UINT64 Code[3]; // Code in a bundle UINT64 Code[3]; // Code in a bundle
UINT64 RegNum; // register number for MOVL UINT64 RegNum; // register number for MOVL
UINT64 I; // bits of MOVL immediate data UINT64 BitI; // bits of MOVL immediate data
UINT64 Ic; // bits of MOVL immediate data UINT64 BitIc; // bits of MOVL immediate data
UINT64 Imm5c; // bits of MOVL immediate data UINT64 BitImm5c; // bits of MOVL immediate data
UINT64 Imm9d; // bits of MOVL immediate data UINT64 BitImm9d; // bits of MOVL immediate data
UINT64 Imm7b; // bits of MOVL immediate data UINT64 BitImm7b; // bits of MOVL immediate data
UINT64 Br; // branch register for loading and jumping UINT64 Br; // branch register for loading and jumping
UINT64 *Data64Ptr; UINT64 *Data64Ptr;
UINT32 ThunkSize; UINT32 ThunkSize;
@ -436,23 +478,23 @@ EbcCreateThunks (
// Extract bits from the address for insertion into the instruction // Extract bits from the address for insertion into the instruction
// i = Addr[63:63] // i = Addr[63:63]
// //
I = RShiftU64 (Addr, 63) & 0x01; BitI = RShiftU64 (Addr, 63) & 0x01;
// //
// ic = Addr[21:21] // ic = Addr[21:21]
// //
Ic = RShiftU64 (Addr, 21) & 0x01; BitIc = RShiftU64 (Addr, 21) & 0x01;
// //
// imm5c = Addr[20:16] for 5 bits // imm5c = Addr[20:16] for 5 bits
// //
Imm5c = RShiftU64 (Addr, 16) & 0x1F; BitImm5c = RShiftU64 (Addr, 16) & 0x1F;
// //
// imm9d = Addr[15:7] for 9 bits // imm9d = Addr[15:7] for 9 bits
// //
Imm9d = RShiftU64 (Addr, 7) & 0x1FF; BitImm9d = RShiftU64 (Addr, 7) & 0x1FF;
// //
// imm7b = Addr[6:0] for 7 bits // imm7b = Addr[6:0] for 7 bits
// //
Imm7b = Addr & 0x7F; BitImm7b = Addr & 0x7F;
// //
// The EBC entry point will be put into r8, so r8 can be used here // The EBC entry point will be put into r8, so r8 can be used here
@ -463,12 +505,12 @@ EbcCreateThunks (
// //
// Next is jumbled data, including opcode and rest of address // Next is jumbled data, including opcode and rest of address
// //
Code[2] = LShiftU64 (Imm7b, 13); Code[2] = LShiftU64 (BitImm7b, 13);
Code[2] = Code[2] | LShiftU64 (0x00, 20); // vc Code[2] = Code[2] | LShiftU64 (0x00, 20); // vc
Code[2] = Code[2] | LShiftU64 (Ic, 21); Code[2] = Code[2] | LShiftU64 (BitIc, 21);
Code[2] = Code[2] | LShiftU64 (Imm5c, 22); Code[2] = Code[2] | LShiftU64 (BitImm5c, 22);
Code[2] = Code[2] | LShiftU64 (Imm9d, 27); Code[2] = Code[2] | LShiftU64 (BitImm9d, 27);
Code[2] = Code[2] | LShiftU64 (I, 36); Code[2] = Code[2] | LShiftU64 (BitI, 36);
Code[2] = Code[2] | LShiftU64 ((UINT64)MOVL_OPCODE, 37); Code[2] = Code[2] | LShiftU64 ((UINT64)MOVL_OPCODE, 37);
Code[2] = Code[2] | LShiftU64 ((RegNum & 0x7F), 6); Code[2] = Code[2] | LShiftU64 ((RegNum & 0x7F), 6);
@ -501,23 +543,23 @@ EbcCreateThunks (
// Extract bits from the address for insertion into the instruction // Extract bits from the address for insertion into the instruction
// i = Addr[63:63] // i = Addr[63:63]
// //
I = RShiftU64 (Addr, 63) & 0x01; BitI = RShiftU64 (Addr, 63) & 0x01;
// //
// ic = Addr[21:21] // ic = Addr[21:21]
// //
Ic = RShiftU64 (Addr, 21) & 0x01; BitIc = RShiftU64 (Addr, 21) & 0x01;
// //
// imm5c = Addr[20:16] for 5 bits // imm5c = Addr[20:16] for 5 bits
// //
Imm5c = RShiftU64 (Addr, 16) & 0x1F; BitImm5c = RShiftU64 (Addr, 16) & 0x1F;
// //
// imm9d = Addr[15:7] for 9 bits // imm9d = Addr[15:7] for 9 bits
// //
Imm9d = RShiftU64 (Addr, 7) & 0x1FF; BitImm9d = RShiftU64 (Addr, 7) & 0x1FF;
// //
// imm7b = Addr[6:0] for 7 bits // imm7b = Addr[6:0] for 7 bits
// //
Imm7b = Addr & 0x7F; BitImm7b = Addr & 0x7F;
// //
// Put the EBC entry point in r8, which is the location of the return value // Put the EBC entry point in r8, which is the location of the return value
@ -528,12 +570,12 @@ EbcCreateThunks (
// //
// Next is jumbled data, including opcode and rest of address // Next is jumbled data, including opcode and rest of address
// //
Code[2] = LShiftU64 (Imm7b, 13); Code[2] = LShiftU64 (BitImm7b, 13);
Code[2] = Code[2] | LShiftU64 (0x00, 20); // vc Code[2] = Code[2] | LShiftU64 (0x00, 20); // vc
Code[2] = Code[2] | LShiftU64 (Ic, 21); Code[2] = Code[2] | LShiftU64 (BitIc, 21);
Code[2] = Code[2] | LShiftU64 (Imm5c, 22); Code[2] = Code[2] | LShiftU64 (BitImm5c, 22);
Code[2] = Code[2] | LShiftU64 (Imm9d, 27); Code[2] = Code[2] | LShiftU64 (BitImm9d, 27);
Code[2] = Code[2] | LShiftU64 (I, 36); Code[2] = Code[2] | LShiftU64 (BitI, 36);
Code[2] = Code[2] | LShiftU64 ((UINT64)MOVL_OPCODE, 37); Code[2] = Code[2] | LShiftU64 ((UINT64)MOVL_OPCODE, 37);
Code[2] = Code[2] | LShiftU64 ((RegNum & 0x7F), 6); Code[2] = Code[2] | LShiftU64 ((RegNum & 0x7F), 6);
@ -573,23 +615,23 @@ EbcCreateThunks (
// Extract bits from the address for insertion into the instruction // Extract bits from the address for insertion into the instruction
// i = Addr[63:63] // i = Addr[63:63]
// //
I = RShiftU64 (Addr, 63) & 0x01; BitI = RShiftU64 (Addr, 63) & 0x01;
// //
// ic = Addr[21:21] // ic = Addr[21:21]
// //
Ic = RShiftU64 (Addr, 21) & 0x01; BitIc = RShiftU64 (Addr, 21) & 0x01;
// //
// imm5c = Addr[20:16] for 5 bits // imm5c = Addr[20:16] for 5 bits
// //
Imm5c = RShiftU64 (Addr, 16) & 0x1F; BitImm5c = RShiftU64 (Addr, 16) & 0x1F;
// //
// imm9d = Addr[15:7] for 9 bits // imm9d = Addr[15:7] for 9 bits
// //
Imm9d = RShiftU64 (Addr, 7) & 0x1FF; BitImm9d = RShiftU64 (Addr, 7) & 0x1FF;
// //
// imm7b = Addr[6:0] for 7 bits // imm7b = Addr[6:0] for 7 bits
// //
Imm7b = Addr & 0x7F; BitImm7b = Addr & 0x7F;
// //
// Put it in r31, a scratch register // Put it in r31, a scratch register
@ -599,12 +641,12 @@ EbcCreateThunks (
// //
// Next is jumbled data, including opcode and rest of address // Next is jumbled data, including opcode and rest of address
// //
Code[2] = LShiftU64(Imm7b, 13); Code[2] = LShiftU64(BitImm7b, 13);
Code[2] = Code[2] | LShiftU64 (0x00, 20); // vc Code[2] = Code[2] | LShiftU64 (0x00, 20); // vc
Code[2] = Code[2] | LShiftU64 (Ic, 21); Code[2] = Code[2] | LShiftU64 (BitIc, 21);
Code[2] = Code[2] | LShiftU64 (Imm5c, 22); Code[2] = Code[2] | LShiftU64 (BitImm5c, 22);
Code[2] = Code[2] | LShiftU64 (Imm9d, 27); Code[2] = Code[2] | LShiftU64 (BitImm9d, 27);
Code[2] = Code[2] | LShiftU64 (I, 36); Code[2] = Code[2] | LShiftU64 (BitI, 36);
Code[2] = Code[2] | LShiftU64 ((UINT64)MOVL_OPCODE, 37); Code[2] = Code[2] | LShiftU64 ((UINT64)MOVL_OPCODE, 37);
Code[2] = Code[2] | LShiftU64 ((RegNum & 0x7F), 6); Code[2] = Code[2] | LShiftU64 ((RegNum & 0x7F), 6);
@ -667,13 +709,16 @@ EbcCreateThunks (
Given raw bytes of Itanium based code, format them into a bundle and Given raw bytes of Itanium based code, format them into a bundle and
write them out. write them out.
@param MemPtr pointer to memory location to write the bundles to @param MemPtr pointer to memory location to write the bundles
@param Template 5-bit template to.
@param Slot0-2 instruction slot data for the bundle @param Template 5-bit template.
@param Slot0 Instruction slot 0 data for the bundle.
@param Slot1 Instruction slot 1 data for the bundle.
@param Slot2 Instruction slot 2 data for the bundle.
@retval EFI_INVALID_PARAMETER Pointer is not aligned @retval EFI_INVALID_PARAMETER Pointer is not aligned
@retval No more than 5 bits in template @retval EFI_INVALID_PARAMETER No more than 5 bits in template
@retval More than 41 bits used in code @retval EFI_INVALID_PARAMETER More than 41 bits used in code
@retval EFI_SUCCESS All data is written. @retval EFI_SUCCESS All data is written.
**/ **/
@ -745,13 +790,11 @@ WriteBundle (
otherwise, set the VM->IP to target EBC code directly to avoid another VM otherwise, set the VM->IP to target EBC code directly to avoid another VM
be startup which cost time and stack space. be startup which cost time and stack space.
@param VmPtr Pointer to a VM context. @param VmPtr Pointer to a VM context.
@param FuncAddr Callee's address @param FuncAddr Callee's address
@param NewStackPointer New stack pointer after the call @param NewStackPointer New stack pointer after the call
@param FramePtr New frame pointer after the call @param FramePtr New frame pointer after the call
@param Size The size of call instruction @param Size The size of call instruction
@return None.
**/ **/
VOID VOID

View File

@ -38,10 +38,4 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// //
#define MOVL_OPCODE 0x06 #define MOVL_OPCODE 0x06
VOID
EbcAsmLLCALLEX (
IN UINTN CallAddr,
IN UINTN EbcSp
);
#endif #endif

View File

@ -27,28 +27,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define STACK_REMAIN_SIZE (1024 * 4) #define STACK_REMAIN_SIZE (1024 * 4)
/**
Pushes a 64 bit unsigned value to the VM stack.
@param VmPtr The pointer to current VM context.
@param Arg The value to be pushed.
**/
STATIC STATIC
VOID VOID
PushU64 ( PushU64 (
VM_CONTEXT *VmPtr, IN VM_CONTEXT *VmPtr,
UINT64 Arg IN UINT64 Arg
) )
/*++
Routine Description:
Push a 64 bit unsigned value to the VM stack.
Arguments:
VmPtr - The pointer to current VM context.
Arg - The value to be pushed
Returns:
VOID
--*/
{ {
// //
// Advance the VM stack down, and then copy the argument to the stack. // Advance the VM stack down, and then copy the argument to the stack.
@ -69,28 +61,45 @@ Returns:
calling convention, so the first four arguments are passed by rcx, rdx, calling convention, so the first four arguments are passed by rcx, rdx,
r8, and r9, while other arguments are passed in stack. r8, and r9, while other arguments are passed in stack.
@param Arg1 The 1st argument.
@param Arg2 The 2nd argument.
@param Arg3 The 3rd argument.
@param Arg4 The 4th argument.
@param Arg5 The 5th argument.
@param Arg6 The 6th argument.
@param Arg7 The 7th argument.
@param Arg8 The 8th argument.
@param Arg9 The 9th argument.
@param Arg10 The 10th argument.
@param Arg11 The 11th argument.
@param Arg12 The 12th argument.
@param Arg13 The 13th argument.
@param Arg14 The 14th argument.
@param Arg15 The 15th argument.
@param Arg16 The 16th argument.
@return The value returned by the EBC application we're going to run. @return The value returned by the EBC application we're going to run.
**/ **/
STATIC STATIC
UINT64 UINT64
EbcInterpret ( EbcInterpret (
UINTN Arg1, IN OUT UINTN Arg1,
UINTN Arg2, IN OUT UINTN Arg2,
UINTN Arg3, IN OUT UINTN Arg3,
UINTN Arg4, IN OUT UINTN Arg4,
UINTN Arg5, IN OUT UINTN Arg5,
UINTN Arg6, IN OUT UINTN Arg6,
UINTN Arg7, IN OUT UINTN Arg7,
UINTN Arg8, IN OUT UINTN Arg8,
UINTN Arg9, IN OUT UINTN Arg9,
UINTN Arg10, IN OUT UINTN Arg10,
UINTN Arg11, IN OUT UINTN Arg11,
UINTN Arg12, IN OUT UINTN Arg12,
UINTN Arg13, IN OUT UINTN Arg13,
UINTN Arg14, IN OUT UINTN Arg14,
UINTN Arg15, IN OUT UINTN Arg15,
UINTN Arg16 IN OUT UINTN Arg16
) )
{ {
// //
@ -328,13 +337,20 @@ ExecuteEbcImageEntryPoint (
/** /**
Create an IA32 thunk for the given EBC entry point. Create thunks for an EBC image entry point, or an EBC protocol service.
@param ImageHandle Handle of image for which this thunk is being created @param ImageHandle Image handle for the EBC image. If not null, then
@param EbcEntryPoint Address of the EBC code that the thunk is to call we're creating a thunk for an image entry point.
@param Thunk Returned thunk we create here @param EbcEntryPoint Address of the EBC code that the thunk is to call
@param Thunk Returned thunk we create here
@param Flags Flags indicating options for creating the thunk
@return Standard EFI status. @retval EFI_SUCCESS The thunk was created successfully.
@retval EFI_INVALID_PARAMETER The parameter of EbcEntryPoint is not 16-bit
aligned.
@retval EFI_OUT_OF_RESOURCES There is not enough memory to created the EBC
Thunk.
@retval EFI_BUFFER_TOO_SMALL EBC_THUNK_SIZE is not larger enough.
**/ **/
EFI_STATUS EFI_STATUS
@ -347,7 +363,7 @@ EbcCreateThunks (
{ {
UINT8 *Ptr; UINT8 *Ptr;
UINT8 *ThunkBase; UINT8 *ThunkBase;
UINT32 I; UINT32 Index;
UINT64 Addr; UINT64 Addr;
INT32 Size; INT32 Size;
INT32 ThunkSize; INT32 ThunkSize;
@ -390,7 +406,7 @@ EbcCreateThunks (
Ptr++; Ptr++;
Size--; Size--;
Addr = (UINT64) 0xCA112EBCCA112EBCULL; Addr = (UINT64) 0xCA112EBCCA112EBCULL;
for (I = 0; I < sizeof (Addr); I++) { for (Index = 0; Index < sizeof (Addr); Index++) {
*Ptr = (UINT8) (UINTN) Addr; *Ptr = (UINT8) (UINTN) Addr;
Addr >>= 8; Addr >>= 8;
Ptr++; Ptr++;
@ -410,7 +426,7 @@ EbcCreateThunks (
Ptr++; Ptr++;
Size--; Size--;
Addr = (UINT64) EbcEntryPoint; Addr = (UINT64) EbcEntryPoint;
for (I = 0; I < sizeof (Addr); I++) { for (Index = 0; Index < sizeof (Addr); Index++) {
*Ptr = (UINT8) (UINTN) Addr; *Ptr = (UINT8) (UINTN) Addr;
Addr >>= 8; Addr >>= 8;
Ptr++; Ptr++;
@ -438,7 +454,7 @@ EbcCreateThunks (
*Ptr = 0xBB; *Ptr = 0xBB;
Ptr++; Ptr++;
Size--; Size--;
for (I = 0; I < sizeof (Addr); I++) { for (Index = 0; Index < sizeof (Addr); Index++) {
*Ptr = (UINT8) Addr; *Ptr = (UINT8) Addr;
Addr >>= 8; Addr >>= 8;
Ptr++; Ptr++;
@ -487,8 +503,6 @@ EbcCreateThunks (
@param FramePtr New frame pointer after the call @param FramePtr New frame pointer after the call
@param Size The size of call instruction @param Size The size of call instruction
@return None.
**/ **/
VOID VOID
EbcLLCALLEX ( EbcLLCALLEX (