]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/EbcDxe/EbcInt.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcInt.c
index 9357dcd26e936200720f8a4169dea3d82ae6b66d..d2254c2765b6b9a642a9f4eb2e1a5fe2b7eb215c 100644 (file)
@@ -3,19 +3,14 @@
   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 - 2010, 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
-\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 - 2011, 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
 // We'll keep track of all thunks we create in a linked list. Each\r
@@ -25,15 +20,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 typedef struct _EBC_THUNK_LIST EBC_THUNK_LIST;\r
 struct _EBC_THUNK_LIST {\r
-  VOID            *ThunkBuffer;\r
-  EBC_THUNK_LIST  *Next;\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
+  EBC_IMAGE_LIST    *Next;\r
+  EFI_HANDLE        ImageHandle;\r
+  EBC_THUNK_LIST    *ThunkList;\r
 };\r
 \r
 /**\r
@@ -53,8 +48,8 @@ struct _EBC_IMAGE_LIST {
 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
@@ -79,10 +74,10 @@ EbcUnloadImage (
 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
@@ -99,8 +94,8 @@ EbcCreateThunk (
 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
@@ -131,8 +126,8 @@ InitializeEbcCallback (
 VOID\r
 EFIAPI\r
 CommonEbcExceptionHandler (\r
-  IN EFI_EXCEPTION_TYPE   InterruptType,\r
-  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  IN EFI_EXCEPTION_TYPE  InterruptType,\r
+  IN EFI_SYSTEM_CONTEXT  SystemContext\r
   );\r
 \r
 /**\r
@@ -146,8 +141,8 @@ CommonEbcExceptionHandler (
 VOID\r
 EFIAPI\r
 EbcPeriodicNotifyFunction (\r
-  IN EFI_EVENT     Event,\r
-  IN VOID          *Context\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
   );\r
 \r
 /**\r
@@ -163,13 +158,14 @@ EbcPeriodicNotifyFunction (
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugPeriodic (\r
-  IN VM_CONTEXT *VmPtr\r
+  IN VM_CONTEXT  *VmPtr\r
   );\r
 \r
 //\r
 // These two functions and the  GUID are used to produce an EBC test protocol.\r
 // This functionality is definitely not required for execution.\r
 //\r
+\r
 /**\r
   Produces an EBC VM test protocol that can be used for regression tests.\r
 \r
@@ -181,7 +177,7 @@ EbcDebugPeriodic (
 **/\r
 EFI_STATUS\r
 InitEbcVmTestProtocol (\r
-  IN EFI_HANDLE     *IHandle\r
+  IN EFI_HANDLE  *IHandle\r
   );\r
 \r
 /**\r
@@ -191,6 +187,7 @@ InitEbcVmTestProtocol (
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 EbcVmTestUnsupported (\r
   VOID\r
   );\r
@@ -208,8 +205,8 @@ EbcVmTestUnsupported (
 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
@@ -226,8 +223,8 @@ EbcRegisterICacheFlush (
 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
@@ -312,10 +309,10 @@ EbcDebugRegisterExceptionCallback (
 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
@@ -324,30 +321,152 @@ EbcDebugInvalidateInstructionCache (
 // also be global since the execution of an EBC image does not provide\r
 // a This pointer.\r
 //\r
-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
-EBC_ICACHE_FLUSH       mEbcICacheFlush;\r
+EBC_ICACHE_FLUSH  mEbcICacheFlush;\r
 \r
 //\r
 // These get set via calls by the debug agent\r
 //\r
-EFI_PERIODIC_CALLBACK  mDebugPeriodicCallback = NULL;\r
-EFI_EXCEPTION_CALLBACK mDebugExceptionCallback[MAX_EBC_EXCEPTION + 1] = {NULL};\r
-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
-VOID                   *mStackBuffer[MAX_STACK_NUM];\r
-EFI_HANDLE             mStackBufferIndex[MAX_STACK_NUM];\r
-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
-EFI_EVENT              mEbcPeriodicEvent;\r
-VM_CONTEXT             *mVmPtr = NULL;\r
+EFI_EVENT   mEbcPeriodicEvent;\r
+VM_CONTEXT  *mVmPtr = NULL;\r
+\r
+/**\r
+  Check whether the emulator supports executing a certain PE/COFF image\r
+\r
+  @param[in] This         This pointer for EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL\r
+                          structure\r
+  @param[in] ImageType    Whether the image is an application, a boot time\r
+                          driver or a runtime driver.\r
+  @param[in] DevicePath   Path to device where the image originated\r
+                          (e.g., a PCI option ROM)\r
 \r
+  @retval TRUE            The image is supported by the emulator\r
+  @retval FALSE           The image is not supported by the emulator.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+EbcIsImageSupported (\r
+  IN  EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL  *This,\r
+  IN  UINT16                                ImageType,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL              *DevicePath   OPTIONAL\r
+  )\r
+{\r
+  if ((ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) &&\r
+      (ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER))\r
+  {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Register a supported PE/COFF image with the emulator. After this call\r
+  completes successfully, the PE/COFF image may be started as usual, and\r
+  it is the responsibility of the emulator implementation that any branch\r
+  into the code section of the image (including returns from functions called\r
+  from the foreign code) is executed as if it were running on the machine\r
+  type it was built for.\r
+\r
+  @param[in]      This          This pointer for\r
+                                EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL structure\r
+  @param[in]      ImageBase     The base address in memory of the PE/COFF image\r
+  @param[in]      ImageSize     The size in memory of the PE/COFF image\r
+  @param[in,out]  EntryPoint    The entry point of the PE/COFF image. Passed by\r
+                                reference so that the emulator may modify it.\r
+\r
+  @retval EFI_SUCCESS           The image was registered with the emulator and\r
+                                can be started as usual.\r
+  @retval other                 The image could not be registered.\r
+\r
+  If the PE/COFF machine type or image type are not supported by the emulator,\r
+  then ASSERT().\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EbcRegisterImage (\r
+  IN      EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL  *This,\r
+  IN      EFI_PHYSICAL_ADDRESS                  ImageBase,\r
+  IN      UINT64                                ImageSize,\r
+  IN  OUT EFI_IMAGE_ENTRY_POINT                 *EntryPoint\r
+  )\r
+{\r
+  DEBUG_CODE_BEGIN ();\r
+  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;\r
+  EFI_STATUS                    Status;\r
+\r
+  ZeroMem (&ImageContext, sizeof (ImageContext));\r
+\r
+  ImageContext.Handle    = (VOID *)(UINTN)ImageBase;\r
+  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
+\r
+  Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  ASSERT (ImageContext.Machine == EFI_IMAGE_MACHINE_EBC);\r
+  ASSERT (\r
+    ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ||\r
+    ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER\r
+    );\r
+  DEBUG_CODE_END ();\r
+\r
+  EbcRegisterICacheFlush (\r
+    NULL,\r
+    (EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange\r
+    );\r
+\r
+  return EbcCreateThunk (\r
+           NULL,\r
+           (VOID *)(UINTN)ImageBase,\r
+           (VOID *)(UINTN)*EntryPoint,\r
+           (VOID **)EntryPoint\r
+           );\r
+}\r
+\r
+/**\r
+  Unregister a PE/COFF image that has been registered with the emulator.\r
+  This should be done before the image is unloaded from memory.\r
+\r
+  @param[in] This         This pointer for EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL\r
+                          structure\r
+  @param[in] ImageBase    The base address in memory of the PE/COFF image\r
+\r
+  @retval EFI_SUCCESS     The image was unregistered with the emulator.\r
+  @retval other           Image could not be unloaded.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EbcUnregisterImage (\r
+  IN  EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL  *This,\r
+  IN  EFI_PHYSICAL_ADDRESS                  ImageBase\r
+  )\r
+{\r
+  return EbcUnloadImage (NULL, (VOID *)(UINTN)ImageBase);\r
+}\r
+\r
+STATIC EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL  mPeCoffEmuProtocol = {\r
+  EbcIsImageSupported,\r
+  EbcRegisterImage,\r
+  EbcUnregisterImage,\r
+  EDKII_PECOFF_IMAGE_EMULATOR_VERSION,\r
+  EFI_IMAGE_MACHINE_EBC\r
+};\r
 \r
 /**\r
   Initializes the VM EFI interface.  Allocates memory for the VM interface\r
@@ -362,8 +481,8 @@ VM_CONTEXT             *mVmPtr = NULL;
 EFI_STATUS\r
 EFIAPI\r
 InitializeEbcDriver (\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
   EFI_EBC_PROTOCOL            *EbcProtocol;\r
@@ -387,24 +506,24 @@ InitializeEbcDriver (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  EbcProtocol->CreateThunk          = EbcCreateThunk;\r
-  EbcProtocol->UnloadImage          = EbcUnloadImage;\r
-  EbcProtocol->RegisterICacheFlush  = EbcRegisterICacheFlush;\r
-  EbcProtocol->GetVersion           = EbcGetVersion;\r
-  mEbcICacheFlush                   = NULL;\r
+  EbcProtocol->CreateThunk         = EbcCreateThunk;\r
+  EbcProtocol->UnloadImage         = EbcUnloadImage;\r
+  EbcProtocol->RegisterICacheFlush = EbcRegisterICacheFlush;\r
+  EbcProtocol->GetVersion          = EbcGetVersion;\r
+  mEbcICacheFlush                  = NULL;\r
 \r
   //\r
   // Find any already-installed EBC protocols and uninstall them\r
   //\r
-  Installed     = FALSE;\r
-  HandleBuffer  = NULL;\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  &gEfiEbcProtocolGuid,\r
-                  NULL,\r
-                  &NumHandles,\r
-                  &HandleBuffer\r
-                  );\r
+  Installed    = FALSE;\r
+  HandleBuffer = NULL;\r
+  Status       = gBS->LocateHandleBuffer (\r
+                        ByProtocol,\r
+                        &gEfiEbcProtocolGuid,\r
+                        NULL,\r
+                        &NumHandles,\r
+                        &HandleBuffer\r
+                        );\r
   if (Status == EFI_SUCCESS) {\r
     //\r
     // Loop through the handles\r
@@ -413,15 +532,16 @@ InitializeEbcDriver (
       Status = gBS->HandleProtocol (\r
                       HandleBuffer[Index],\r
                       &gEfiEbcProtocolGuid,\r
-                      (VOID **) &OldEbcProtocol\r
+                      (VOID **)&OldEbcProtocol\r
                       );\r
       if (Status == EFI_SUCCESS) {\r
         if (gBS->ReinstallProtocolInterface (\r
-                  HandleBuffer[Index],\r
-                  &gEfiEbcProtocolGuid,\r
-                  OldEbcProtocol,\r
-                  EbcProtocol\r
-                  ) == EFI_SUCCESS) {\r
+                   HandleBuffer[Index],\r
+                   &gEfiEbcProtocolGuid,\r
+                   OldEbcProtocol,\r
+                   EbcProtocol\r
+                   ) == EFI_SUCCESS)\r
+        {\r
           Installed = TRUE;\r
         }\r
       }\r
@@ -432,15 +552,18 @@ InitializeEbcDriver (
     FreePool (HandleBuffer);\r
     HandleBuffer = NULL;\r
   }\r
+\r
   //\r
   // Add the protocol so someone can locate us if we haven't already.\r
   //\r
   if (!Installed) {\r
-    Status = gBS->InstallProtocolInterface (\r
+    Status = gBS->InstallMultipleProtocolInterfaces (\r
                     &ImageHandle,\r
                     &gEfiEbcProtocolGuid,\r
-                    EFI_NATIVE_INTERFACE,\r
-                    EbcProtocol\r
+                    EbcProtocol,\r
+                    &gEdkiiPeCoffImageEmulatorProtocolGuid,\r
+                    &mPeCoffEmuProtocol,\r
+                    NULL\r
                     );\r
     if (EFI_ERROR (Status)) {\r
       FreePool (EbcProtocol);\r
@@ -448,8 +571,8 @@ InitializeEbcDriver (
     }\r
   }\r
 \r
-  Status = InitEBCStack();\r
-  if (EFI_ERROR(Status)) {\r
+  Status = InitEBCStack ();\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -462,11 +585,11 @@ InitializeEbcDriver (
     goto ErrorExit;\r
   }\r
 \r
-  EbcDebugProtocol->Isa                         = IsaEbc;\r
-  EbcDebugProtocol->GetMaximumProcessorIndex    = EbcDebugGetMaximumProcessorIndex;\r
-  EbcDebugProtocol->RegisterPeriodicCallback    = EbcDebugRegisterPeriodicCallback;\r
-  EbcDebugProtocol->RegisterExceptionCallback   = EbcDebugRegisterExceptionCallback;\r
-  EbcDebugProtocol->InvalidateInstructionCache  = EbcDebugInvalidateInstructionCache;\r
+  EbcDebugProtocol->Isa                        = IsaEbc;\r
+  EbcDebugProtocol->GetMaximumProcessorIndex   = EbcDebugGetMaximumProcessorIndex;\r
+  EbcDebugProtocol->RegisterPeriodicCallback   = EbcDebugRegisterPeriodicCallback;\r
+  EbcDebugProtocol->RegisterExceptionCallback  = EbcDebugRegisterExceptionCallback;\r
+  EbcDebugProtocol->InvalidateInstructionCache = EbcDebugInvalidateInstructionCache;\r
 \r
   //\r
   // Add the protocol so the debug agent can find us\r
@@ -484,6 +607,7 @@ InitializeEbcDriver (
     FreePool (EbcDebugProtocol);\r
     goto ErrorExit;\r
   }\r
+\r
   //\r
   // Install EbcDebugSupport Protocol Successfully\r
   // Now we need to initialize the Ebc default Callback\r
@@ -494,21 +618,23 @@ InitializeEbcDriver (
   // Produce a VM test interface protocol. Not required for execution.\r
   //\r
   DEBUG_CODE_BEGIN ();\r
-    InitEbcVmTestProtocol (&ImageHandle);\r
+  InitEbcVmTestProtocol (&ImageHandle);\r
   DEBUG_CODE_END ();\r
 \r
+  EbcDebuggerHookInit (ImageHandle, EbcDebugProtocol);\r
+\r
   return EFI_SUCCESS;\r
 \r
 ErrorExit:\r
-  FreeEBCStack();\r
-  HandleBuffer  = NULL;\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  &gEfiEbcProtocolGuid,\r
-                  NULL,\r
-                  &NumHandles,\r
-                  &HandleBuffer\r
-                  );\r
+  FreeEBCStack ();\r
+  HandleBuffer = NULL;\r
+  Status       = gBS->LocateHandleBuffer (\r
+                        ByProtocol,\r
+                        &gEfiEbcProtocolGuid,\r
+                        NULL,\r
+                        &NumHandles,\r
+                        &HandleBuffer\r
+                        );\r
   if (Status == EFI_SUCCESS) {\r
     //\r
     // Loop through the handles\r
@@ -517,7 +643,7 @@ ErrorExit:
       Status = gBS->HandleProtocol (\r
                       HandleBuffer[Index],\r
                       &gEfiEbcProtocolGuid,\r
-                      (VOID **) &OldEbcProtocol\r
+                      (VOID **)&OldEbcProtocol\r
                       );\r
       if (Status == EFI_SUCCESS) {\r
         gBS->UninstallProtocolInterface (\r
@@ -539,7 +665,6 @@ ErrorExit:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This is the top-level routine plugged into the EBC protocol. Since thunks\r
   are very processor-specific, from here we dispatch directly to the very\r
@@ -562,24 +687,23 @@ ErrorExit:
 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
   EFI_STATUS  Status;\r
 \r
   Status = EbcCreateThunks (\r
-            ImageHandle,\r
-            EbcEntryPoint,\r
-            Thunk,\r
-            FLAG_THUNK_ENTRY_POINT\r
-            );\r
+             ImageHandle,\r
+             EbcEntryPoint,\r
+             Thunk,\r
+             FLAG_THUNK_ENTRY_POINT\r
+             );\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This EBC debugger protocol service is called by the debug agent\r
 \r
@@ -594,15 +718,14 @@ EbcCreateThunk (
 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
   *MaxProcessorIndex = 0;\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   This protocol service is called by the debug agent to register a function\r
   for us to call on a periodic basis.\r
@@ -635,6 +758,7 @@ EbcDebugRegisterPeriodicCallback (
   if ((mDebugPeriodicCallback == NULL) && (PeriodicCallback == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   if ((mDebugPeriodicCallback != NULL) && (PeriodicCallback != NULL)) {\r
     return EFI_ALREADY_STARTED;\r
   }\r
@@ -643,7 +767,6 @@ EbcDebugRegisterPeriodicCallback (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   This protocol service is called by the debug agent to register a function\r
   for us to call when we detect an exception.\r
@@ -681,17 +804,19 @@ EbcDebugRegisterExceptionCallback (
   if ((ExceptionType < 0) || (ExceptionType > MAX_EBC_EXCEPTION)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   if ((mDebugExceptionCallback[ExceptionType] == NULL) && (ExceptionCallback == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   if ((mDebugExceptionCallback[ExceptionType] != NULL) && (ExceptionCallback != NULL)) {\r
     return EFI_ALREADY_STARTED;\r
   }\r
+\r
   mDebugExceptionCallback[ExceptionType] = ExceptionCallback;\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   This EBC debugger protocol service is called by the debug agent.  Required\r
   for DebugSupport compliance but is only stubbed out for EBC.\r
@@ -711,16 +836,15 @@ EbcDebugRegisterExceptionCallback (
 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
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   The VM interpreter calls this function when an exception is detected.\r
 \r
@@ -734,9 +858,9 @@ EbcDebugInvalidateInstructionCache (
 **/\r
 EFI_STATUS\r
 EbcDebugSignalException (\r
-  IN EFI_EXCEPTION_TYPE                   ExceptionType,\r
-  IN EXCEPTION_FLAGS                      ExceptionFlags,\r
-  IN VM_CONTEXT                           *VmPtr\r
+  IN EFI_EXCEPTION_TYPE  ExceptionType,\r
+  IN EXCEPTION_FLAGS     ExceptionFlags,\r
+  IN VM_CONTEXT          *VmPtr\r
   )\r
 {\r
   EFI_SYSTEM_CONTEXT_EBC  EbcContext;\r
@@ -747,7 +871,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
@@ -763,43 +887,41 @@ EbcDebugSignalException (
   // status code via the status code API\r
   //\r
   if (mDebugExceptionCallback[ExceptionType] != NULL) {\r
-\r
     //\r
     // Initialize the context structure\r
     //\r
-    EbcContext.R0                   = VmPtr->Gpr[0];\r
-    EbcContext.R1                   = VmPtr->Gpr[1];\r
-    EbcContext.R2                   = VmPtr->Gpr[2];\r
-    EbcContext.R3                   = VmPtr->Gpr[3];\r
-    EbcContext.R4                   = VmPtr->Gpr[4];\r
-    EbcContext.R5                   = VmPtr->Gpr[5];\r
-    EbcContext.R6                   = VmPtr->Gpr[6];\r
-    EbcContext.R7                   = VmPtr->Gpr[7];\r
-    EbcContext.Ip                   = (UINT64)(UINTN)VmPtr->Ip;\r
-    EbcContext.Flags                = VmPtr->Flags;\r
-    EbcContext.ControlFlags         = 0;\r
-    SystemContext.SystemContextEbc  = &EbcContext;\r
-\r
-    mDebugExceptionCallback[ExceptionType] (ExceptionType, SystemContext);\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
+    SystemContext.SystemContextEbc = &EbcContext;\r
+\r
+    mDebugExceptionCallback[ExceptionType](ExceptionType, SystemContext);\r
     //\r
     // Restore the context structure and continue to execute\r
     //\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
+    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
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   To install default Callback function for the VM interpreter.\r
 \r
@@ -816,8 +938,8 @@ InitializeEbcCallback (
   IN EFI_DEBUG_SUPPORT_PROTOCOL  *This\r
   )\r
 {\r
-  INTN       Index;\r
-  EFI_STATUS Status;\r
+  INTN        Index;\r
+  EFI_STATUS  Status;\r
 \r
   //\r
   // For ExceptionCallback\r
@@ -841,7 +963,7 @@ InitializeEbcCallback (
                   &mVmPtr,\r
                   &mEbcPeriodicEvent\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
@@ -850,14 +972,13 @@ InitializeEbcCallback (
                   TimerPeriodic,\r
                   EBC_VM_PERIODIC_CALLBACK_RATE\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   The default Exception Callback for the VM interpreter.\r
   In this function, we report status code, and print debug information\r
@@ -870,19 +991,71 @@ InitializeEbcCallback (
 VOID\r
 EFIAPI\r
 CommonEbcExceptionHandler (\r
-  IN EFI_EXCEPTION_TYPE   InterruptType,\r
-  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  IN EFI_EXCEPTION_TYPE  InterruptType,\r
+  IN EFI_SYSTEM_CONTEXT  SystemContext\r
   )\r
 {\r
+  //\r
+  // We print debug information to let user know what happen.\r
+  //\r
+  DEBUG ((\r
+    DEBUG_ERROR,\r
+    "EBC Interrupter Version - 0x%016lx\n",\r
+    (UINT64)(((VM_MAJOR_VERSION & 0xFFFF) << 16) | ((VM_MINOR_VERSION & 0xFFFF)))\r
+    ));\r
+  DEBUG ((\r
+    DEBUG_ERROR,\r
+    "Exception Type - 0x%016lx\n",\r
+    (UINT64)(UINTN)InterruptType\r
+    ));\r
+  DEBUG ((\r
+    DEBUG_ERROR,\r
+    "  R0 - 0x%016lx, R1 - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->R0,\r
+    SystemContext.SystemContextEbc->R1\r
+    ));\r
+  DEBUG ((\r
+    DEBUG_ERROR,\r
+    "  R2 - 0x%016lx, R3 - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->R2,\r
+    SystemContext.SystemContextEbc->R3\r
+    ));\r
+  DEBUG ((\r
+    DEBUG_ERROR,\r
+    "  R4 - 0x%016lx, R5 - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->R4,\r
+    SystemContext.SystemContextEbc->R5\r
+    ));\r
+  DEBUG ((\r
+    DEBUG_ERROR,\r
+    "  R6 - 0x%016lx, R7 - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->R6,\r
+    SystemContext.SystemContextEbc->R7\r
+    ));\r
+  DEBUG ((\r
+    DEBUG_ERROR,\r
+    "  Flags - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->Flags\r
+    ));\r
+  DEBUG ((\r
+    DEBUG_ERROR,\r
+    "  ControlFlags - 0x%016lx\n",\r
+    SystemContext.SystemContextEbc->ControlFlags\r
+    ));\r
+  DEBUG ((\r
+    DEBUG_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
+  return;\r
 }\r
 \r
-\r
 /**\r
   The periodic callback function for EBC VM interpreter, which is used\r
   to support the EFI debug support protocol.\r
@@ -894,11 +1067,11 @@ CommonEbcExceptionHandler (
 VOID\r
 EFIAPI\r
 EbcPeriodicNotifyFunction (\r
-  IN EFI_EVENT     Event,\r
-  IN VOID          *Context\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
   )\r
 {\r
-  VM_CONTEXT *VmPtr;\r
+  VM_CONTEXT  *VmPtr;\r
 \r
   VmPtr = *(VM_CONTEXT **)Context;\r
 \r
@@ -906,10 +1079,9 @@ EbcPeriodicNotifyFunction (
     EbcDebugPeriodic (VmPtr);\r
   }\r
 \r
-  return ;\r
+  return;\r
 }\r
 \r
-\r
 /**\r
   The VM interpreter calls this function on a periodic basis to support\r
   the EFI debug support protocol.\r
@@ -923,54 +1095,52 @@ EbcPeriodicNotifyFunction (
 EFI_STATUS\r
 EFIAPI\r
 EbcDebugPeriodic (\r
-  IN VM_CONTEXT *VmPtr\r
+  IN VM_CONTEXT  *VmPtr\r
   )\r
 {\r
-  EFI_SYSTEM_CONTEXT_EBC   EbcContext;\r
-  EFI_SYSTEM_CONTEXT       SystemContext;\r
+  EFI_SYSTEM_CONTEXT_EBC  EbcContext;\r
+  EFI_SYSTEM_CONTEXT      SystemContext;\r
 \r
   //\r
   // If someone's registered for periodic callbacks, then call them.\r
   //\r
   if (mDebugPeriodicCallback != NULL) {\r
-\r
     //\r
     // Initialize the context structure\r
     //\r
-    EbcContext.R0                   = VmPtr->Gpr[0];\r
-    EbcContext.R1                   = VmPtr->Gpr[1];\r
-    EbcContext.R2                   = VmPtr->Gpr[2];\r
-    EbcContext.R3                   = VmPtr->Gpr[3];\r
-    EbcContext.R4                   = VmPtr->Gpr[4];\r
-    EbcContext.R5                   = VmPtr->Gpr[5];\r
-    EbcContext.R6                   = VmPtr->Gpr[6];\r
-    EbcContext.R7                   = VmPtr->Gpr[7];\r
-    EbcContext.Ip                   = (UINT64)(UINTN)VmPtr->Ip;\r
-    EbcContext.Flags                = VmPtr->Flags;\r
-    EbcContext.ControlFlags         = 0;\r
-    SystemContext.SystemContextEbc  = &EbcContext;\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
+    SystemContext.SystemContextEbc = &EbcContext;\r
 \r
     mDebugPeriodicCallback (SystemContext);\r
 \r
     //\r
     // Restore the context structure and continue to execute\r
     //\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
+    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
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   This routine is called by the core when an image is being unloaded from\r
   memory. Basically we now have the opportunity to do any necessary cleanup.\r
@@ -988,24 +1158,26 @@ EbcDebugPeriodic (
 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
   EBC_THUNK_LIST  *ThunkList;\r
   EBC_THUNK_LIST  *NextThunkList;\r
   EBC_IMAGE_LIST  *ImageList;\r
   EBC_IMAGE_LIST  *PrevImageList;\r
+\r
   //\r
   // First go through our list of known image handles and see if we've already\r
   // created an image list element for this image handle.\r
   //\r
-  ReturnEBCStackByHandle(ImageHandle);\r
+  ReturnEBCStackByHandle (ImageHandle);\r
   PrevImageList = NULL;\r
   for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {\r
     if (ImageList->ImageHandle == ImageHandle) {\r
       break;\r
     }\r
+\r
     //\r
     // Save the previous so we can connect the lists when we remove this one\r
     //\r
@@ -1015,6 +1187,7 @@ EbcUnloadImage (
   if (ImageList == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
+\r
   //\r
   // Free up all the thunk buffers and thunks list elements for this image\r
   // handle.\r
@@ -1026,6 +1199,7 @@ EbcUnloadImage (
     FreePool (ThunkList);\r
     ThunkList = NextThunkList;\r
   }\r
+\r
   //\r
   // Now remove this image list element from the chain\r
   //\r
@@ -1037,14 +1211,17 @@ EbcUnloadImage (
   } else {\r
     PrevImageList->Next = ImageList->Next;\r
   }\r
+\r
   //\r
   // Now free up the image list element\r
   //\r
   FreePool (ImageList);\r
+\r
+  EbcDebuggerHookEbcUnloadImage (ImageHandle);\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Add a thunk to our list of thunks for a given image handle.\r
   Also flush the instruction cache since we've written thunk code\r
@@ -1060,9 +1237,9 @@ EbcUnloadImage (
 **/\r
 EFI_STATUS\r
 EbcAddImageThunk (\r
-  IN EFI_HANDLE      ImageHandle,\r
-  IN VOID            *ThunkBuffer,\r
-  IN UINT32          ThunkSize\r
+  IN EFI_HANDLE  ImageHandle,\r
+  IN VOID        *ThunkBuffer,\r
+  IN UINT32      ThunkSize\r
   )\r
 {\r
   EBC_THUNK_LIST  *ThunkList;\r
@@ -1073,11 +1250,12 @@ EbcAddImageThunk (
   // It so far so good, then flush the instruction cache\r
   //\r
   if (mEbcICacheFlush != NULL) {\r
-    Status = mEbcICacheFlush ((EFI_PHYSICAL_ADDRESS) (UINTN) ThunkBuffer, ThunkSize);\r
+    Status = mEbcICacheFlush ((EFI_PHYSICAL_ADDRESS)(UINTN)ThunkBuffer, ThunkSize);\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
   }\r
+\r
   //\r
   // Go through our list of known image handles and see if we've already\r
   // created a image list element for this image handle.\r
@@ -1098,11 +1276,12 @@ EbcAddImageThunk (
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    ImageList->ThunkList    = NULL;\r
-    ImageList->ImageHandle  = ImageHandle;\r
-    ImageList->Next         = mEbcImageList;\r
-    mEbcImageList           = ImageList;\r
+    ImageList->ThunkList   = NULL;\r
+    ImageList->ImageHandle = ImageHandle;\r
+    ImageList->Next        = mEbcImageList;\r
+    mEbcImageList          = ImageList;\r
   }\r
+\r
   //\r
   // Ok, now create a new thunk element to add to the list\r
   //\r
@@ -1111,12 +1290,13 @@ EbcAddImageThunk (
   if (ThunkList == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+\r
   //\r
   // Add it to the head of the list\r
   //\r
-  ThunkList->Next         = ImageList->ThunkList;\r
-  ThunkList->ThunkBuffer  = ThunkBuffer;\r
-  ImageList->ThunkList    = ThunkList;\r
+  ThunkList->Next        = ImageList->ThunkList;\r
+  ThunkList->ThunkBuffer = ThunkBuffer;\r
+  ImageList->ThunkList   = ThunkList;\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1133,8 +1313,8 @@ EbcAddImageThunk (
 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
   mEbcICacheFlush = Flush;\r
@@ -1155,8 +1335,8 @@ EbcRegisterICacheFlush (
 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
   if (Version == NULL) {\r
@@ -1181,25 +1361,28 @@ EbcGetVersion (
 \r
 **/\r
 EFI_STATUS\r
-GetEBCStack(\r
-  IN  EFI_HANDLE Handle,\r
-  OUT VOID       **StackBuffer,\r
-  OUT UINTN      *BufferIndex\r
+GetEBCStack (\r
+  IN  EFI_HANDLE  Handle,\r
+  OUT VOID        **StackBuffer,\r
+  OUT UINTN       *BufferIndex\r
   )\r
 {\r
-  UINTN   Index;\r
-  EFI_TPL OldTpl;\r
-  OldTpl = gBS->RaiseTPL(TPL_HIGH_LEVEL);\r
-  for (Index = 0; Index < mStackNum; Index ++) {\r
+  UINTN    Index;\r
+  EFI_TPL  OldTpl;\r
+\r
+  OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+  for (Index = 0; Index < mStackNum; Index++) {\r
     if (mStackBufferIndex[Index] == NULL) {\r
       mStackBufferIndex[Index] = Handle;\r
       break;\r
     }\r
   }\r
-  gBS->RestoreTPL(OldTpl);\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
   if (Index == mStackNum) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+\r
   *BufferIndex = Index;\r
   *StackBuffer = mStackBuffer[Index];\r
   return EFI_SUCCESS;\r
@@ -1214,8 +1397,8 @@ GetEBCStack(
 \r
 **/\r
 EFI_STATUS\r
-ReturnEBCStack(\r
-  IN UINTN Index\r
+ReturnEBCStack (\r
+  IN UINTN  Index\r
   )\r
 {\r
   mStackBufferIndex[Index] = NULL;\r
@@ -1231,19 +1414,22 @@ ReturnEBCStack(
 \r
 **/\r
 EFI_STATUS\r
-ReturnEBCStackByHandle(\r
-  IN EFI_HANDLE Handle\r
+ReturnEBCStackByHandle (\r
+  IN EFI_HANDLE  Handle\r
   )\r
 {\r
-  UINTN Index;\r
-  for (Index = 0; Index < mStackNum; Index ++) {\r
+  UINTN  Index;\r
+\r
+  for (Index = 0; Index < mStackNum; Index++) {\r
     if (mStackBufferIndex[Index] == Handle) {\r
       break;\r
     }\r
   }\r
+\r
   if (Index == mStackNum) {\r
     return EFI_NOT_FOUND;\r
   }\r
+\r
   mStackBufferIndex[Index] = NULL;\r
   return EFI_SUCCESS;\r
 }\r
@@ -1260,20 +1446,21 @@ InitEBCStack (
   VOID\r
   )\r
 {\r
-  for (mStackNum = 0; mStackNum < MAX_STACK_NUM; mStackNum ++) {\r
-    mStackBuffer[mStackNum] = AllocatePool(STACK_POOL_SIZE);\r
+  for (mStackNum = 0; mStackNum < MAX_STACK_NUM; mStackNum++) {\r
+    mStackBuffer[mStackNum]      = AllocatePool (STACK_POOL_SIZE);\r
     mStackBufferIndex[mStackNum] = NULL;\r
     if (mStackBuffer[mStackNum] == NULL) {\r
       break;\r
     }\r
   }\r
+\r
   if (mStackNum == 0) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Free all EBC stacks allocated before.\r
 \r
@@ -1281,14 +1468,16 @@ InitEBCStack (
 \r
 **/\r
 EFI_STATUS\r
-FreeEBCStack(\r
+FreeEBCStack (\r
   VOID\r
   )\r
 {\r
-  UINTN Index;\r
-  for (Index = 0; Index < mStackNum; Index ++) {\r
-    FreePool(mStackBuffer[Index]);\r
+  UINTN  Index;\r
+\r
+  for (Index = 0; Index < mStackNum; Index++) {\r
+    FreePool (mStackBuffer[Index]);\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1303,12 +1492,12 @@ FreeEBCStack(
 **/\r
 EFI_STATUS\r
 InitEbcVmTestProtocol (\r
-  IN EFI_HANDLE     *IHandle\r
+  IN EFI_HANDLE  *IHandle\r
   )\r
 {\r
-  EFI_HANDLE Handle;\r
-  EFI_STATUS Status;\r
-  EFI_EBC_VM_TEST_PROTOCOL *EbcVmTestProtocol;\r
+  EFI_HANDLE                Handle;\r
+  EFI_STATUS                Status;\r
+  EFI_EBC_VM_TEST_PROTOCOL  *EbcVmTestProtocol;\r
 \r
   //\r
   // Allocate memory for the protocol, then fill in the fields\r
@@ -1317,25 +1506,26 @@ InitEbcVmTestProtocol (
   if (EbcVmTestProtocol == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  EbcVmTestProtocol->Execute      = (EBC_VM_TEST_EXECUTE) EbcExecuteInstructions;\r
+\r
+  EbcVmTestProtocol->Execute = (EBC_VM_TEST_EXECUTE)EbcExecuteInstructions;\r
 \r
   DEBUG_CODE_BEGIN ();\r
-    EbcVmTestProtocol->Assemble     = (EBC_VM_TEST_ASM) EbcVmTestUnsupported;\r
-    EbcVmTestProtocol->Disassemble  = (EBC_VM_TEST_DASM) EbcVmTestUnsupported;\r
+  EbcVmTestProtocol->Assemble    = (EBC_VM_TEST_ASM)EbcVmTestUnsupported;\r
+  EbcVmTestProtocol->Disassemble = (EBC_VM_TEST_DASM)EbcVmTestUnsupported;\r
   DEBUG_CODE_END ();\r
 \r
   //\r
   // Publish the protocol\r
   //\r
-  Handle  = NULL;\r
-  Status  = gBS->InstallProtocolInterface (&Handle, &mEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);\r
+  Handle = NULL;\r
+  Status = gBS->InstallProtocolInterface (&Handle, &gEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);\r
   if (EFI_ERROR (Status)) {\r
     FreePool (EbcVmTestProtocol);\r
   }\r
+\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Returns the EFI_UNSUPPORTED Status.\r
 \r
@@ -1343,6 +1533,7 @@ InitEbcVmTestProtocol (
 \r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 EbcVmTestUnsupported (\r
   VOID\r
   )\r
@@ -1350,3 +1541,27 @@ 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
+\r
+  return Buffer;\r
+}\r