]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/EbcDxe/EbcInt.c
MdeModulePkg: Remove X86 ASM and S files
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcInt.c
index f48176ef1bcc8fb9f0889d25f9b2782c29f70216..727ba8bcae44d65da091493ed05fcf0d37041a96 100644 (file)
@@ -3,8 +3,8 @@
   Provides auxiliary support routines for the VM. That is, routines\r
   that are not particularly related to VM execution of EBC instructions.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+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
@@ -16,6 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "EbcInt.h"\r
 #include "EbcExecute.h"\r
+#include "EbcDebuggerHook.h"\r
 \r
 //\r
 // We'll keep track of all thunks we create in a linked list. Each\r
@@ -23,16 +24,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 // image handles, with each having a linked list of thunks allocated\r
 // to that image handle.\r
 //\r
-typedef struct _EBC_THUNK_LIST {\r
-  VOID                    *ThunkBuffer;\r
-  struct _EBC_THUNK_LIST  *Next;\r
-} EBC_THUNK_LIST;\r
-\r
-typedef struct _EBC_IMAGE_LIST {\r
-  struct _EBC_IMAGE_LIST  *Next;\r
-  EFI_HANDLE              ImageHandle;\r
-  EBC_THUNK_LIST          *ThunkList;\r
-} EBC_IMAGE_LIST;\r
+typedef struct _EBC_THUNK_LIST EBC_THUNK_LIST;\r
+struct _EBC_THUNK_LIST {\r
+  VOID            *ThunkBuffer;\r
+  EBC_THUNK_LIST  *Next;\r
+};\r
+\r
+typedef struct _EBC_IMAGE_LIST EBC_IMAGE_LIST;\r
+struct _EBC_IMAGE_LIST {\r
+  EBC_IMAGE_LIST  *Next;\r
+  EFI_HANDLE      ImageHandle;\r
+  EBC_THUNK_LIST  *ThunkList;\r
+};\r
 \r
 /**\r
   This routine is called by the core when an image is being unloaded from\r
@@ -48,12 +51,11 @@ typedef struct _EBC_IMAGE_LIST {
   @retval EFI_SUCCESS           The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcUnloadImage (\r
-  IN EFI_EBC_PROTOCOL     *This,\r
-  IN EFI_HANDLE           ImageHandle\r
+  IN EFI_EBC_PROTOCOL   *This,\r
+  IN EFI_HANDLE         ImageHandle\r
   );\r
 \r
 /**\r
@@ -75,14 +77,13 @@ EbcUnloadImage (
   @retval EFI_OUT_OF_RESOURCES  Memory could not be allocated for the thunk.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcCreateThunk (\r
-  IN EFI_EBC_PROTOCOL     *This,\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN VOID                 *EbcEntryPoint,\r
-  OUT VOID                **Thunk\r
+  IN EFI_EBC_PROTOCOL   *This,\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN VOID               *EbcEntryPoint,\r
+  OUT VOID              **Thunk\r
   );\r
 \r
 /**\r
@@ -91,17 +92,16 @@ EbcCreateThunk (
   @param  This                  A pointer to the EFI_EBC_PROTOCOL instance.\r
   @param  Version               Pointer to where to store the returned version\r
                                 of the interpreter.\r
-   \r
+\r
   @retval EFI_SUCCESS           The function completed successfully.\r
   @retval EFI_INVALID_PARAMETER Version pointer is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcGetVersion (\r
-  IN EFI_EBC_PROTOCOL     *This,\r
-  IN OUT UINT64           *Version\r
+  IN EFI_EBC_PROTOCOL   *This,\r
+  IN OUT UINT64         *Version\r
   );\r
 \r
 /**\r
@@ -114,7 +114,6 @@ EbcGetVersion (
   @retval Others                Some error occurs when creating periodic event.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 InitializeEbcCallback (\r
@@ -130,7 +129,6 @@ InitializeEbcCallback (
   @param  SystemContext          EBC system context.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 EFIAPI\r
 CommonEbcExceptionHandler (\r
@@ -146,7 +144,6 @@ CommonEbcExceptionHandler (
   @param  Context                It should be the address of VM_CONTEXT pointer.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 EFIAPI\r
 EbcPeriodicNotifyFunction (\r
@@ -164,7 +161,6 @@ EbcPeriodicNotifyFunction (
   @retval EFI_SUCCESS            The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugPeriodic (\r
@@ -184,40 +180,38 @@ EbcDebugPeriodic (
   @retval EFI_SUCCESS            The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InitEbcVmTestProtocol (\r
-  IN EFI_HANDLE     *Handle\r
+  IN EFI_HANDLE     *IHandle\r
   );\r
 \r
 /**\r
   Returns the EFI_UNSUPPORTED Status.\r
-   \r
+\r
   @return EFI_UNSUPPORTED  This function always return EFI_UNSUPPORTED status.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
+EFIAPI\r
 EbcVmTestUnsupported (\r
   VOID\r
   );\r
 \r
 /**\r
   Registers a callback function that the EBC interpreter calls to flush the\r
-  processor instruction cache following creation of thunks. \r
+  processor instruction cache following creation of thunks.\r
 \r
   @param  This        A pointer to the EFI_EBC_PROTOCOL instance.\r
   @param  Flush       Pointer to a function of type EBC_ICACH_FLUSH.\r
-   \r
+\r
   @retval EFI_SUCCESS The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcRegisterICacheFlush (\r
-  IN EFI_EBC_PROTOCOL               *This,\r
-  IN EBC_ICACHE_FLUSH               Flush\r
+  IN EFI_EBC_PROTOCOL   *This,\r
+  IN EBC_ICACHE_FLUSH   Flush\r
   );\r
 \r
 /**\r
@@ -231,12 +225,11 @@ EbcRegisterICacheFlush (
   @retval EFI_SUCCESS           The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugGetMaximumProcessorIndex (\r
-  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,\r
-  OUT UINTN                         *MaxProcessorIndex\r
+  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,\r
+  OUT UINTN                              *MaxProcessorIndex\r
   );\r
 \r
 /**\r
@@ -260,13 +253,12 @@ EbcDebugGetMaximumProcessorIndex (
                                 callback function was previously registered.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugRegisterPeriodicCallback (\r
-  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,\r
-  IN UINTN                          ProcessorIndex,\r
-  IN EFI_PERIODIC_CALLBACK          PeriodicCallback\r
+  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,\r
+  IN UINTN                       ProcessorIndex,\r
+  IN EFI_PERIODIC_CALLBACK       PeriodicCallback\r
   );\r
 \r
 /**\r
@@ -294,14 +286,13 @@ EbcDebugRegisterPeriodicCallback (
                                 callback function was previously registered.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugRegisterExceptionCallback (\r
-  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,\r
-  IN UINTN                          ProcessorIndex,\r
-  IN EFI_EXCEPTION_CALLBACK         ExceptionCallback,\r
-  IN EFI_EXCEPTION_TYPE             ExceptionType\r
+  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,\r
+  IN UINTN                       ProcessorIndex,\r
+  IN EFI_EXCEPTION_CALLBACK      ExceptionCallback,\r
+  IN EFI_EXCEPTION_TYPE          ExceptionType\r
   );\r
 \r
 /**\r
@@ -315,19 +306,18 @@ EbcDebugRegisterExceptionCallback (
   @param  Start                 StartSpecifies the physical base of the memory\r
                                 range to be invalidated.\r
   @param  Length                Specifies the minimum number of bytes in the\r
-                                processor's instruction cache to invalidate. \r
+                                processor's instruction cache to invalidate.\r
 \r
   @retval EFI_SUCCESS           The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugInvalidateInstructionCache (\r
-  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,\r
-  IN UINTN                          ProcessorIndex,\r
-  IN VOID                           *Start,\r
-  IN UINT64                         Length\r
+  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,\r
+  IN UINTN                               ProcessorIndex,\r
+  IN VOID                                *Start,\r
+  IN UINT64                              Length\r
   );\r
 \r
 //\r
@@ -336,29 +326,28 @@ EbcDebugInvalidateInstructionCache (
 // also be global since the execution of an EBC image does not provide\r
 // a This pointer.\r
 //\r
-STATIC EBC_IMAGE_LIST         *mEbcImageList = NULL;\r
+EBC_IMAGE_LIST         *mEbcImageList = NULL;\r
 \r
 //\r
 // Callback function to flush the icache after thunk creation\r
 //\r
-STATIC EBC_ICACHE_FLUSH       mEbcICacheFlush;\r
+EBC_ICACHE_FLUSH       mEbcICacheFlush;\r
 \r
 //\r
 // These get set via calls by the debug agent\r
 //\r
-STATIC EFI_PERIODIC_CALLBACK  mDebugPeriodicCallback                            = NULL;\r
-STATIC EFI_EXCEPTION_CALLBACK mDebugExceptionCallback[MAX_EBC_EXCEPTION + 1] = {NULL};\r
-STATIC EFI_GUID               mEfiEbcVmTestProtocolGuid = EFI_EBC_VM_TEST_PROTOCOL_GUID;\r
+EFI_PERIODIC_CALLBACK  mDebugPeriodicCallback = NULL;\r
+EFI_EXCEPTION_CALLBACK mDebugExceptionCallback[MAX_EBC_EXCEPTION + 1] = {NULL};\r
 \r
-STATIC VOID*      mStackBuffer[MAX_STACK_NUM];\r
-STATIC EFI_HANDLE mStackBufferIndex[MAX_STACK_NUM];\r
-STATIC UINTN      mStackNum = 0;\r
+VOID                   *mStackBuffer[MAX_STACK_NUM];\r
+EFI_HANDLE             mStackBufferIndex[MAX_STACK_NUM];\r
+UINTN                  mStackNum = 0;\r
 \r
 //\r
 // Event for Periodic callback\r
 //\r
-STATIC EFI_EVENT              mEbcPeriodicEvent;\r
-VM_CONTEXT                    *mVmPtr = NULL;\r
+EFI_EVENT              mEbcPeriodicEvent;\r
+VM_CONTEXT             *mVmPtr = NULL;\r
 \r
 \r
 /**\r
@@ -509,6 +498,8 @@ InitializeEbcDriver (
     InitEbcVmTestProtocol (&ImageHandle);\r
   DEBUG_CODE_END ();\r
 \r
+  EbcDebuggerHookInit (ImageHandle, EbcDebugProtocol);\r
+\r
   return EFI_SUCCESS;\r
 \r
 ErrorExit:\r
@@ -571,7 +562,6 @@ ErrorExit:
   @retval EFI_OUT_OF_RESOURCES  Memory could not be allocated for the thunk.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcCreateThunk (\r
@@ -604,7 +594,6 @@ EbcCreateThunk (
   @retval EFI_SUCCESS           The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugGetMaximumProcessorIndex (\r
@@ -638,7 +627,6 @@ EbcDebugGetMaximumProcessorIndex (
                                 callback function was previously registered.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugRegisterPeriodicCallback (\r
@@ -684,7 +672,6 @@ EbcDebugRegisterPeriodicCallback (
                                 callback function was previously registered.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugRegisterExceptionCallback (\r
@@ -719,12 +706,11 @@ EbcDebugRegisterExceptionCallback (
   @param  Start                 StartSpecifies the physical base of the memory\r
                                 range to be invalidated.\r
   @param  Length                Specifies the minimum number of bytes in the\r
-                                processor's instruction cache to invalidate. \r
+                                processor's instruction cache to invalidate.\r
 \r
   @retval EFI_SUCCESS           The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugInvalidateInstructionCache (\r
@@ -742,7 +728,7 @@ EbcDebugInvalidateInstructionCache (
   The VM interpreter calls this function when an exception is detected.\r
 \r
   @param  ExceptionType          Specifies the processor exception detected.\r
-  @param  ExceptionFlags         Specifies the exception context. \r
+  @param  ExceptionFlags         Specifies the exception context.\r
   @param  VmPtr                  Pointer to a VM context for passing info to the\r
                                  EFI debugger.\r
 \r
@@ -764,7 +750,7 @@ EbcDebugSignalException (
   // Save the exception in the context passed in\r
   //\r
   VmPtr->ExceptionFlags |= ExceptionFlags;\r
-  VmPtr->LastException = ExceptionType;\r
+  VmPtr->LastException = (UINTN) ExceptionType;\r
   //\r
   // If it's a fatal exception, then flag it in the VM context in case an\r
   // attached debugger tries to return from it.\r
@@ -784,14 +770,14 @@ EbcDebugSignalException (
     //\r
     // Initialize the context structure\r
     //\r
-    EbcContext.R0                   = VmPtr->R[0];\r
-    EbcContext.R1                   = VmPtr->R[1];\r
-    EbcContext.R2                   = VmPtr->R[2];\r
-    EbcContext.R3                   = VmPtr->R[3];\r
-    EbcContext.R4                   = VmPtr->R[4];\r
-    EbcContext.R5                   = VmPtr->R[5];\r
-    EbcContext.R6                   = VmPtr->R[6];\r
-    EbcContext.R7                   = VmPtr->R[7];\r
+    EbcContext.R0                   = (UINT64) VmPtr->Gpr[0];\r
+    EbcContext.R1                   = (UINT64) VmPtr->Gpr[1];\r
+    EbcContext.R2                   = (UINT64) VmPtr->Gpr[2];\r
+    EbcContext.R3                   = (UINT64) VmPtr->Gpr[3];\r
+    EbcContext.R4                   = (UINT64) VmPtr->Gpr[4];\r
+    EbcContext.R5                   = (UINT64) VmPtr->Gpr[5];\r
+    EbcContext.R6                   = (UINT64) VmPtr->Gpr[6];\r
+    EbcContext.R7                   = (UINT64) VmPtr->Gpr[7];\r
     EbcContext.Ip                   = (UINT64)(UINTN)VmPtr->Ip;\r
     EbcContext.Flags                = VmPtr->Flags;\r
     EbcContext.ControlFlags         = 0;\r
@@ -801,14 +787,14 @@ EbcDebugSignalException (
     //\r
     // Restore the context structure and continue to execute\r
     //\r
-    VmPtr->R[0]  = EbcContext.R0;\r
-    VmPtr->R[1]  = EbcContext.R1;\r
-    VmPtr->R[2]  = EbcContext.R2;\r
-    VmPtr->R[3]  = EbcContext.R3;\r
-    VmPtr->R[4]  = EbcContext.R4;\r
-    VmPtr->R[5]  = EbcContext.R5;\r
-    VmPtr->R[6]  = EbcContext.R6;\r
-    VmPtr->R[7]  = EbcContext.R7;\r
+    VmPtr->Gpr[0]  = EbcContext.R0;\r
+    VmPtr->Gpr[1]  = EbcContext.R1;\r
+    VmPtr->Gpr[2]  = EbcContext.R2;\r
+    VmPtr->Gpr[3]  = EbcContext.R3;\r
+    VmPtr->Gpr[4]  = EbcContext.R4;\r
+    VmPtr->Gpr[5]  = EbcContext.R5;\r
+    VmPtr->Gpr[6]  = EbcContext.R6;\r
+    VmPtr->Gpr[7]  = EbcContext.R7;\r
     VmPtr->Ip    = (VMIP)(UINTN)EbcContext.Ip;\r
     VmPtr->Flags = EbcContext.Flags;\r
   }\r
@@ -827,7 +813,6 @@ EbcDebugSignalException (
   @retval Others                Some error occurs when creating periodic event.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 InitializeEbcCallback (\r
@@ -885,7 +870,6 @@ InitializeEbcCallback (
   @param  SystemContext          EBC system context.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 EFIAPI\r
 CommonEbcExceptionHandler (\r
@@ -893,10 +877,63 @@ CommonEbcExceptionHandler (
   IN EFI_SYSTEM_CONTEXT   SystemContext\r
   )\r
 {\r
+  //\r
+  // We print debug information to let user know what happen.\r
+  //\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "EBC Interrupter Version - 0x%016lx\n",\r
+    (UINT64) (((VM_MAJOR_VERSION & 0xFFFF) << 16) | ((VM_MINOR_VERSION & 0xFFFF)))\r
+    ));\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "Exception Type - 0x%016lx\n",\r
+    (UINT64)(UINTN)InterruptType\r
+    ));\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "  R0 - 0x%016lx, R1 - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->R0,\r
+    SystemContext.SystemContextEbc->R1\r
+    ));\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "  R2 - 0x%016lx, R3 - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->R2,\r
+    SystemContext.SystemContextEbc->R3\r
+    ));\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "  R4 - 0x%016lx, R5 - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->R4,\r
+    SystemContext.SystemContextEbc->R5\r
+    ));\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "  R6 - 0x%016lx, R7 - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->R6,\r
+    SystemContext.SystemContextEbc->R7\r
+    ));\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "  Flags - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->Flags\r
+    ));\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "  ControlFlags - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->ControlFlags\r
+    ));\r
+  DEBUG ((\r
+    EFI_D_ERROR,\r
+    "  Ip - 0x%016lx\n\n",\r
+    SystemContext.SystemContextEbc->Ip\r
+    ));\r
+\r
   //\r
   // We deadloop here to make it easy to debug this issue.\r
   //\r
-  ASSERT (FALSE);\r
+  CpuDeadLoop ();\r
 \r
   return ;\r
 }\r
@@ -910,7 +947,6 @@ CommonEbcExceptionHandler (
   @param  Context                It should be the address of VM_CONTEXT pointer.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 EFIAPI\r
 EbcPeriodicNotifyFunction (\r
@@ -940,7 +976,6 @@ EbcPeriodicNotifyFunction (
   @retval EFI_SUCCESS            The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugPeriodic (\r
@@ -958,14 +993,14 @@ EbcDebugPeriodic (
     //\r
     // Initialize the context structure\r
     //\r
-    EbcContext.R0                   = VmPtr->R[0];\r
-    EbcContext.R1                   = VmPtr->R[1];\r
-    EbcContext.R2                   = VmPtr->R[2];\r
-    EbcContext.R3                   = VmPtr->R[3];\r
-    EbcContext.R4                   = VmPtr->R[4];\r
-    EbcContext.R5                   = VmPtr->R[5];\r
-    EbcContext.R6                   = VmPtr->R[6];\r
-    EbcContext.R7                   = VmPtr->R[7];\r
+    EbcContext.R0                   = (UINT64) VmPtr->Gpr[0];\r
+    EbcContext.R1                   = (UINT64) VmPtr->Gpr[1];\r
+    EbcContext.R2                   = (UINT64) VmPtr->Gpr[2];\r
+    EbcContext.R3                   = (UINT64) VmPtr->Gpr[3];\r
+    EbcContext.R4                   = (UINT64) VmPtr->Gpr[4];\r
+    EbcContext.R5                   = (UINT64) VmPtr->Gpr[5];\r
+    EbcContext.R6                   = (UINT64) VmPtr->Gpr[6];\r
+    EbcContext.R7                   = (UINT64) VmPtr->Gpr[7];\r
     EbcContext.Ip                   = (UINT64)(UINTN)VmPtr->Ip;\r
     EbcContext.Flags                = VmPtr->Flags;\r
     EbcContext.ControlFlags         = 0;\r
@@ -976,14 +1011,14 @@ EbcDebugPeriodic (
     //\r
     // Restore the context structure and continue to execute\r
     //\r
-    VmPtr->R[0]  = EbcContext.R0;\r
-    VmPtr->R[1]  = EbcContext.R1;\r
-    VmPtr->R[2]  = EbcContext.R2;\r
-    VmPtr->R[3]  = EbcContext.R3;\r
-    VmPtr->R[4]  = EbcContext.R4;\r
-    VmPtr->R[5]  = EbcContext.R5;\r
-    VmPtr->R[6]  = EbcContext.R6;\r
-    VmPtr->R[7]  = EbcContext.R7;\r
+    VmPtr->Gpr[0]  = EbcContext.R0;\r
+    VmPtr->Gpr[1]  = EbcContext.R1;\r
+    VmPtr->Gpr[2]  = EbcContext.R2;\r
+    VmPtr->Gpr[3]  = EbcContext.R3;\r
+    VmPtr->Gpr[4]  = EbcContext.R4;\r
+    VmPtr->Gpr[5]  = EbcContext.R5;\r
+    VmPtr->Gpr[6]  = EbcContext.R6;\r
+    VmPtr->Gpr[7]  = EbcContext.R7;\r
     VmPtr->Ip    = (VMIP)(UINTN)EbcContext.Ip;\r
     VmPtr->Flags = EbcContext.Flags;\r
   }\r
@@ -1006,7 +1041,6 @@ EbcDebugPeriodic (
   @retval EFI_SUCCESS           The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcUnloadImage (\r
@@ -1063,6 +1097,9 @@ EbcUnloadImage (
   // Now free up the image list element\r
   //\r
   FreePool (ImageList);\r
+\r
+  EbcDebuggerHookEbcUnloadImage (ImageHandle);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1144,15 +1181,14 @@ EbcAddImageThunk (
 \r
 /**\r
   Registers a callback function that the EBC interpreter calls to flush the\r
-  processor instruction cache following creation of thunks. \r
+  processor instruction cache following creation of thunks.\r
 \r
   @param  This        A pointer to the EFI_EBC_PROTOCOL instance.\r
   @param  Flush       Pointer to a function of type EBC_ICACH_FLUSH.\r
-   \r
+\r
   @retval EFI_SUCCESS The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcRegisterICacheFlush (\r
@@ -1170,12 +1206,11 @@ EbcRegisterICacheFlush (
   @param  This                  A pointer to the EFI_EBC_PROTOCOL instance.\r
   @param  Version               Pointer to where to store the returned version\r
                                 of the interpreter.\r
-   \r
+\r
   @retval EFI_SUCCESS           The function completed successfully.\r
   @retval EFI_INVALID_PARAMETER Version pointer is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EbcGetVersion (\r
@@ -1194,10 +1229,10 @@ EbcGetVersion (
 /**\r
   Returns the stack index and buffer assosicated with the Handle parameter.\r
 \r
-  @param  Handle                The EFI handle as the index to the EBC stack. \r
+  @param  Handle                The EFI handle as the index to the EBC stack.\r
   @param  StackBuffer           A pointer to hold the returned stack buffer.\r
   @param  BufferIndex           A pointer to hold the returned stack index.\r
-   \r
+\r
   @retval EFI_OUT_OF_RESOURCES  The Handle parameter does not correspond to any\r
                                 existing EBC stack.\r
   @retval EFI_SUCCESS           The stack index and buffer were found and\r
@@ -1230,10 +1265,10 @@ GetEBCStack(
 }\r
 \r
 /**\r
-  Returns from the EBC stack by stack Index. \r
-   \r
+  Returns from the EBC stack by stack Index.\r
+\r
   @param  Index        Specifies which EBC stack to return from.\r
-   \r
+\r
   @retval EFI_SUCCESS  The function completed successfully.\r
 \r
 **/\r
@@ -1247,10 +1282,10 @@ ReturnEBCStack(
 }\r
 \r
 /**\r
-  Returns from the EBC stack associated with the Handle parameter. \r
-   \r
+  Returns from the EBC stack associated with the Handle parameter.\r
+\r
   @param  Handle      Specifies the EFI handle to find the EBC stack with.\r
-   \r
+\r
   @retval EFI_SUCCESS The function completed successfully.\r
 \r
 **/\r
@@ -1275,7 +1310,7 @@ ReturnEBCStackByHandle(
 /**\r
   Allocates memory to hold all the EBC stacks.\r
 \r
-  @retval EFI_SUCCESS          The EBC stacks were allocated successfully. \r
+  @retval EFI_SUCCESS          The EBC stacks were allocated successfully.\r
   @retval EFI_OUT_OF_RESOURCES Not enough memory available for EBC stacks.\r
 \r
 **/\r
@@ -1325,7 +1360,6 @@ FreeEBCStack(
   @retval EFI_SUCCESS            The function completed successfully.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 InitEbcVmTestProtocol (\r
   IN EFI_HANDLE     *IHandle\r
@@ -1353,7 +1387,7 @@ InitEbcVmTestProtocol (
   // Publish the protocol\r
   //\r
   Handle  = NULL;\r
-  Status  = gBS->InstallProtocolInterface (&Handle, &mEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);\r
+  Status  = gBS->InstallProtocolInterface (&Handle, &gEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);\r
   if (EFI_ERROR (Status)) {\r
     FreePool (EbcVmTestProtocol);\r
   }\r
@@ -1363,12 +1397,12 @@ InitEbcVmTestProtocol (
 \r
 /**\r
   Returns the EFI_UNSUPPORTED Status.\r
-   \r
+\r
   @return EFI_UNSUPPORTED  This function always return EFI_UNSUPPORTED status.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
+EFIAPI\r
 EbcVmTestUnsupported (\r
   VOID\r
   )\r
@@ -1376,3 +1410,26 @@ EbcVmTestUnsupported (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
+/**\r
+  Allocates a buffer of type EfiBootServicesCode.\r
+\r
+  @param  AllocationSize        The number of bytes to allocate.\r
+\r
+  @return A pointer to the allocated buffer or NULL if allocation fails.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+EbcAllocatePoolForThunk (\r
+  IN UINTN  AllocationSize\r
+  )\r
+{\r
+  VOID        *Buffer;\r
+  EFI_STATUS  Status;\r
+\r
+  Status = gBS->AllocatePool (EfiBootServicesCode, AllocationSize, &Buffer);\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+  return Buffer;\r
+}\r