]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Ebc/Dxe/EbcInt.c
Adjust directory structures.
[mirror_edk2.git] / MdeModulePkg / Universal / Ebc / Dxe / EbcInt.c
diff --git a/MdeModulePkg/Universal/Ebc/Dxe/EbcInt.c b/MdeModulePkg/Universal/Ebc/Dxe/EbcInt.c
deleted file mode 100644 (file)
index 2b647d9..0000000
+++ /dev/null
@@ -1,1172 +0,0 @@
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
-  EbcInt.c\r
-\r
-Abstract:\r
-\r
-  Top level module for the EBC virtual machine implementation.\r
-  Provides auxilliary support routines for the VM. That is, routines\r
-  that are not particularly related to VM execution of EBC instructions.\r
-\r
---*/\r
-\r
-#include "EbcInt.h"\r
-#include "EbcExecute.h"\r
-\r
-//\r
-// We'll keep track of all thunks we create in a linked list. Each\r
-// thunk is tied to an image handle, so we have a linked list of\r
-// 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
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcUnloadImage (\r
-  IN EFI_EBC_PROTOCOL     *This,\r
-  IN EFI_HANDLE           ImageHandle\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
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcGetVersion (\r
-  IN EFI_EBC_PROTOCOL     *This,\r
-  IN OUT UINT64           *Version\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeEbcCallback (\r
-  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This\r
-  );\r
-\r
-STATIC\r
-VOID\r
-EFIAPI\r
-CommonEbcExceptionHandler (\r
-  IN EFI_EXCEPTION_TYPE   InterruptType,\r
-  IN EFI_SYSTEM_CONTEXT   SystemContext\r
-  );\r
-\r
-STATIC\r
-VOID\r
-EFIAPI\r
-EbcPeriodicNotifyFunction (\r
-  IN EFI_EVENT     Event,\r
-  IN VOID          *Context\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcDebugPeriodic (\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
-STATIC\r
-EFI_STATUS\r
-InitEbcVmTestProtocol (\r
-  IN EFI_HANDLE     *Handle\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EbcVmTestUnsupported (\r
-  VOID\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcRegisterICacheFlush (\r
-  IN EFI_EBC_PROTOCOL               *This,\r
-  IN EBC_ICACHE_FLUSH               Flush\r
-  );\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcDebugGetMaximumProcessorIndex (\r
-  IN EFI_DEBUG_SUPPORT_PROTOCOL     *This,\r
-  OUT UINTN                         *MaxProcessorIndex\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
-  );\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
-  );\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
-  );\r
-\r
-//\r
-// We have one linked list of image handles for the whole world. Since\r
-// there should only be one interpreter, make them global. They must\r
-// 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
-\r
-//\r
-// Callback function to flush the icache after thunk creation\r
-//\r
-static 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
-\r
-static VOID*      mStackBuffer[MAX_STACK_NUM];\r
-static EFI_HANDLE mStackBufferIndex[MAX_STACK_NUM];\r
-static UINTN      mStackNum = 0;\r
-\r
-//\r
-// Event for Periodic callback\r
-//\r
-static EFI_EVENT              mEbcPeriodicEvent;\r
-VM_CONTEXT                    *mVmPtr = NULL;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeEbcDriver (\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Initializes the VM EFI interface.  Allocates memory for the VM interface\r
-  and registers the VM protocol.\r
-\r
-Arguments:\r
-\r
-  ImageHandle - EFI image handle.\r
-  SystemTable - Pointer to the EFI system table.\r
-\r
-Returns:\r
-  Standard EFI status code.\r
-\r
---*/\r
-{\r
-  EFI_EBC_PROTOCOL            *EbcProtocol;\r
-  EFI_EBC_PROTOCOL            *OldEbcProtocol;\r
-  EFI_STATUS                  Status;\r
-  EFI_DEBUG_SUPPORT_PROTOCOL  *EbcDebugProtocol;\r
-  EFI_HANDLE                  *HandleBuffer;\r
-  UINTN                       NumHandles;\r
-  UINTN                       Index;\r
-  BOOLEAN                     Installed;\r
-\r
-  EbcProtocol      = NULL;\r
-  EbcDebugProtocol = NULL;\r
-\r
-  //\r
-  // Allocate memory for our protocol. Then fill in the blanks.\r
-  //\r
-  EbcProtocol = AllocatePool (sizeof (EFI_EBC_PROTOCOL));\r
-\r
-  if (EbcProtocol == NULL) {\r
-    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
-\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
-  if (Status == EFI_SUCCESS) {\r
-    //\r
-    // Loop through the handles\r
-    //\r
-    for (Index = 0; Index < NumHandles; Index++) {\r
-      Status = gBS->HandleProtocol (\r
-                      HandleBuffer[Index],\r
-                      &gEfiEbcProtocolGuid,\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
-          Installed = TRUE;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (HandleBuffer != NULL) {\r
-    FreePool (HandleBuffer);\r
-    HandleBuffer = NULL;\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
-                    &ImageHandle,\r
-                    &gEfiEbcProtocolGuid,\r
-                    EFI_NATIVE_INTERFACE,\r
-                    EbcProtocol\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (EbcProtocol);\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  Status = InitEBCStack();\r
-  if (EFI_ERROR(Status)) {\r
-    goto ErrorExit;\r
-  }\r
-\r
-  //\r
-  // Allocate memory for our debug protocol. Then fill in the blanks.\r
-  //\r
-  EbcDebugProtocol = AllocatePool (sizeof (EFI_DEBUG_SUPPORT_PROTOCOL));\r
-\r
-  if (EbcDebugProtocol == NULL) {\r
-    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
-\r
-  //\r
-  // Add the protocol so the debug agent can find us\r
-  //\r
-  Status = gBS->InstallProtocolInterface (\r
-                  &ImageHandle,\r
-                  &gEfiDebugSupportProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  EbcDebugProtocol\r
-                  );\r
-  //\r
-  // This is recoverable, so free the memory and continue.\r
-  //\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (EbcDebugProtocol);\r
-    goto ErrorExit;\r
-  }\r
-  //\r
-  // Install EbcDebugSupport Protocol Successfully\r
-  // Now we need to initialize the Ebc default Callback\r
-  //\r
-  Status = InitializeEbcCallback (EbcDebugProtocol);\r
-\r
-  //\r
-  // Produce a VM test interface protocol. Not required for execution.\r
-  //\r
-  DEBUG_CODE_BEGIN ();\r
-    InitEbcVmTestProtocol (&ImageHandle);\r
-  DEBUG_CODE_END ();\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
-  if (Status == EFI_SUCCESS) {\r
-    //\r
-    // Loop through the handles\r
-    //\r
-    for (Index = 0; Index < NumHandles; Index++) {\r
-      Status = gBS->HandleProtocol (\r
-                      HandleBuffer[Index],\r
-                      &gEfiEbcProtocolGuid,\r
-                      (VOID **) &OldEbcProtocol\r
-                      );\r
-      if (Status == EFI_SUCCESS) {\r
-        gBS->UninstallProtocolInterface (\r
-               HandleBuffer[Index],\r
-               &gEfiEbcProtocolGuid,\r
-               OldEbcProtocol\r
-               );\r
-      }\r
-    }\r
-  }\r
-\r
-  if (HandleBuffer != NULL) {\r
-    FreePool (HandleBuffer);\r
-    HandleBuffer = NULL;\r
-  }\r
-\r
-  FreePool (EbcProtocol);\r
-\r
-  return Status;\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
-  )\r
-/*++\r
-\r
-Routine Description:\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
-  processor-specific routine EbcCreateThunks().\r
-\r
-Arguments:\r
-\r
-  This          - protocol instance pointer\r
-  ImageHandle   - handle to the image. The EBC interpreter may use this to keep\r
-                  track of any resource allocations performed in loading and\r
-                  executing the image.\r
-  EbcEntryPoint - the entry point for the image (as defined in the file header)\r
-  Thunk         - pointer to thunk pointer where the address of the created\r
-                  thunk is returned.\r
-\r
-Returns:\r
-\r
-  EFI_STATUS\r
-\r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  Status = EbcCreateThunks (\r
-            ImageHandle,\r
-            EbcEntryPoint,\r
-            Thunk,\r
-            FLAG_THUNK_ENTRY_POINT\r
-            );\r
-  return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcDebugGetMaximumProcessorIndex (\r
-  IN EFI_DEBUG_SUPPORT_PROTOCOL          *This,\r
-  OUT UINTN                              *MaxProcessorIndex\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This EBC debugger protocol service is called by the debug agent\r
-\r
-Arguments:\r
-\r
-  This              - pointer to the caller's debug support protocol interface\r
-  MaxProcessorIndex - pointer to a caller allocated UINTN in which the maximum\r
-                      processor index is returned.\r
-\r
-Returns:\r
-\r
-  Standard EFI_STATUS\r
-\r
---*/\r
-{\r
-  *MaxProcessorIndex = 0;\r
-  return EFI_SUCCESS;\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
-  )\r
-/*++\r
-\r
-Routine Description:\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
-\r
-\r
-Arguments:\r
-\r
-  This              - pointer to the caller's debug support protocol interface\r
-  PeriodicCallback  - pointer to the function to call periodically\r
-\r
-Returns:\r
-\r
-  Always EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  if ((mDebugPeriodicCallback == NULL) && (PeriodicCallback == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  if ((mDebugPeriodicCallback != NULL) && (PeriodicCallback != NULL)) {\r
-    return EFI_ALREADY_STARTED;\r
-  }\r
-\r
-  mDebugPeriodicCallback = PeriodicCallback;\r
-  return EFI_SUCCESS;\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
-  )\r
-/*++\r
-\r
-Routine Description:\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
-\r
-\r
-Arguments:\r
-\r
-  This              - pointer to the caller's debug support protocol interface\r
-  ExceptionCallback - pointer to the function to the exception\r
-\r
-Returns:\r
-\r
-  Always EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  if ((ExceptionType < 0) || (ExceptionType > MAX_EBC_EXCEPTION)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  if ((mDebugExceptionCallback[ExceptionType] == NULL) && (ExceptionCallback == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  if ((mDebugExceptionCallback[ExceptionType] != NULL) && (ExceptionCallback != NULL)) {\r
-    return EFI_ALREADY_STARTED;\r
-  }\r
-  mDebugExceptionCallback[ExceptionType] = ExceptionCallback;\r
-  return EFI_SUCCESS;\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
-  )\r
-/*++\r
-\r
-Routine Description:\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
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-\r
---*/\r
-{\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EbcDebugSignalException (\r
-  IN EFI_EXCEPTION_TYPE                   ExceptionType,\r
-  IN EXCEPTION_FLAGS                      ExceptionFlags,\r
-  IN VM_CONTEXT                           *VmPtr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  The VM interpreter calls this function when an exception is detected.\r
-\r
-Arguments:\r
-\r
-  VmPtr - pointer to a VM context for passing info to the EFI debugger.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS if it returns at all\r
-\r
---*/\r
-{\r
-  EFI_SYSTEM_CONTEXT_EBC  EbcContext;\r
-  EFI_SYSTEM_CONTEXT      SystemContext;\r
-\r
-  ASSERT ((ExceptionType >= 0) && (ExceptionType <= MAX_EBC_EXCEPTION));\r
-  //\r
-  // Save the exception in the context passed in\r
-  //\r
-  VmPtr->ExceptionFlags |= ExceptionFlags;\r
-  VmPtr->LastException = 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
-  //\r
-  if (ExceptionFlags & EXCEPTION_FLAG_FATAL) {\r
-    VmPtr->StopFlags |= STOPFLAG_APP_DONE;\r
-  }\r
-\r
-  //\r
-  // If someone's registered for exception callbacks, then call them.\r
-  //\r
-  // EBC driver will register default exception callback to report the\r
-  // 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->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.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->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->Ip    = (VMIP)(UINTN)EbcContext.Ip;\r
-    VmPtr->Flags = EbcContext.Flags;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-InitializeEbcCallback (\r
-  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  To install default Callback function for the VM interpreter.\r
-\r
-Arguments:\r
-\r
-  This - pointer to the instance of DebugSupport protocol\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-{\r
-  INTN       Index;\r
-  EFI_STATUS Status;\r
-\r
-  //\r
-  // For ExceptionCallback\r
-  //\r
-  for (Index = 0; Index <= MAX_EBC_EXCEPTION; Index++) {\r
-    EbcDebugRegisterExceptionCallback (\r
-      This,\r
-      0,\r
-      CommonEbcExceptionHandler,\r
-      Index\r
-      );\r
-  }\r
-\r
-  //\r
-  // For PeriodicCallback\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  EbcPeriodicNotifyFunction,\r
-                  &mVmPtr,\r
-                  &mEbcPeriodicEvent\r
-                  );\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->SetTimer (\r
-                  mEbcPeriodicEvent,\r
-                  TimerPeriodic,\r
-                  EBC_VM_PERIODIC_CALLBACK_RATE\r
-                  );\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-VOID\r
-CommonEbcExceptionHandler (\r
-  IN EFI_EXCEPTION_TYPE   InterruptType,\r
-  IN EFI_SYSTEM_CONTEXT   SystemContext\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  The default Exception Callback for the VM interpreter.\r
-  In this function, we report status code, and print debug information\r
-  about EBC_CONTEXT, then dead loop.\r
-\r
-Arguments:\r
-\r
-  InterruptType - Interrupt type.\r
-  SystemContext - EBC system context.\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-{\r
-  //\r
-  // We deadloop here to make it easy to debug this issue.\r
-  //\r
-  ASSERT (FALSE);\r
-\r
-  return ;\r
-}\r
-\r
-STATIC\r
-VOID\r
-EFIAPI\r
-EbcPeriodicNotifyFunction (\r
-  IN EFI_EVENT     Event,\r
-  IN VOID          *Context\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  The periodic callback function for EBC VM interpreter, which is used\r
-  to support the EFI debug support protocol.\r
-\r
-Arguments:\r
-\r
-  Event   - The Periodic Callback Event.\r
-  Context - It should be the address of VM_CONTEXT pointer.\r
-\r
-Returns:\r
-\r
-  None.\r
-\r
---*/\r
-{\r
-  VM_CONTEXT *VmPtr;\r
-\r
-  VmPtr = *(VM_CONTEXT **)Context;\r
-\r
-  if (VmPtr != NULL) {\r
-    EbcDebugPeriodic (VmPtr);\r
-  }\r
-\r
-  return ;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EbcDebugPeriodic (\r
-  IN VM_CONTEXT *VmPtr\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  The VM interpreter calls this function on a periodic basis to support\r
-  the EFI debug support protocol.\r
-\r
-Arguments:\r
-\r
-  VmPtr - pointer to a VM context for passing info to the debugger.\r
-\r
-Returns:\r
-\r
-  Standard EFI status.\r
-\r
---*/\r
-{\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->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.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->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->Ip    = (VMIP)(UINTN)EbcContext.Ip;\r
-    VmPtr->Flags = EbcContext.Flags;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcUnloadImage (\r
-  IN EFI_EBC_PROTOCOL   *This,\r
-  IN EFI_HANDLE         ImageHandle\r
-  )\r
-/*++\r
-\r
-Routine Description:\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
-  Typically this will include freeing any memory allocated for thunk-creation.\r
-\r
-Arguments:\r
-\r
-  This          - protocol instance pointer\r
-  ImageHandle   - handle to the image being unloaded.\r
-\r
-Returns:\r
-\r
-  EFI_INVALID_PARAMETER  - the ImageHandle passed in was not found in\r
-                           the internal list of EBC image handles.\r
-  EFI_STATUS             - completed successfully\r
-\r
---*/\r
-{\r
-  EBC_THUNK_LIST  *ThunkList;\r
-  EBC_THUNK_LIST  *NextThunkList;\r
-  EBC_IMAGE_LIST  *ImageList;\r
-  EBC_IMAGE_LIST  *PrevImageList;\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
-  PrevImageList = NULL;\r
-  for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {\r
-    if (ImageList->ImageHandle == ImageHandle) {\r
-      break;\r
-    }\r
-    //\r
-    // Save the previous so we can connect the lists when we remove this one\r
-    //\r
-    PrevImageList = ImageList;\r
-  }\r
-\r
-  if (ImageList == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Free up all the thunk buffers and thunks list elements for this image\r
-  // handle.\r
-  //\r
-  ThunkList = ImageList->ThunkList;\r
-  while (ThunkList != NULL) {\r
-    NextThunkList = ThunkList->Next;\r
-    FreePool (ThunkList->ThunkBuffer);\r
-    FreePool (ThunkList);\r
-    ThunkList = NextThunkList;\r
-  }\r
-  //\r
-  // Now remove this image list element from the chain\r
-  //\r
-  if (PrevImageList == NULL) {\r
-    //\r
-    // Remove from head\r
-    //\r
-    mEbcImageList = ImageList->Next;\r
-  } else {\r
-    PrevImageList->Next = ImageList->Next;\r
-  }\r
-  //\r
-  // Now free up the image list element\r
-  //\r
-  FreePool (ImageList);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EbcAddImageThunk (\r
-  IN EFI_HANDLE      ImageHandle,\r
-  IN VOID            *ThunkBuffer,\r
-  IN UINT32          ThunkSize\r
-  )\r
-/*++\r
-\r
-Routine Description:\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
-  to memory that will be executed eventually.\r
-\r
-Arguments:\r
-\r
-  ImageHandle - the image handle to which the thunk is tied\r
-  ThunkBuffer - the buffer we've created/allocated\r
-  ThunkSize    - the size of the thunk memory allocated\r
-\r
-Returns:\r
-\r
-  EFI_OUT_OF_RESOURCES    - memory allocation failed\r
-  EFI_SUCCESS             - successful completion\r
-\r
---*/\r
-{\r
-  EBC_THUNK_LIST  *ThunkList;\r
-  EBC_IMAGE_LIST  *ImageList;\r
-  EFI_STATUS      Status;\r
-\r
-  //\r
-  // 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
-    if (EFI_ERROR (Status)) {\r
-      return Status;\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
-  //\r
-  for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {\r
-    if (ImageList->ImageHandle == ImageHandle) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  if (ImageList == NULL) {\r
-    //\r
-    // Allocate a new one\r
-    //\r
-    ImageList = AllocatePool (sizeof (EBC_IMAGE_LIST));\r
-\r
-    if (ImageList == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    ImageList->ThunkList    = NULL;\r
-    ImageList->ImageHandle  = ImageHandle;\r
-    ImageList->Next         = mEbcImageList;\r
-    mEbcImageList           = ImageList;\r
-  }\r
-  //\r
-  // Ok, now create a new thunk element to add to the list\r
-  //\r
-  ThunkList = AllocatePool (sizeof (EBC_THUNK_LIST));\r
-\r
-  if (ThunkList == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\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
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcRegisterICacheFlush (\r
-  IN EFI_EBC_PROTOCOL   *This,\r
-  IN EBC_ICACHE_FLUSH   Flush\r
-  )\r
-{\r
-  mEbcICacheFlush = Flush;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-EbcGetVersion (\r
-  IN EFI_EBC_PROTOCOL   *This,\r
-  IN OUT UINT64         *Version\r
-  )\r
-{\r
-  if (Version == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  *Version = GetVmVersion ();\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetEBCStack(\r
-  EFI_HANDLE Handle,\r
-  VOID       **StackBuffer,\r
-  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
-    if (mStackBufferIndex[Index] == NULL) {\r
-      mStackBufferIndex[Index] = Handle;\r
-      break;\r
-    }\r
-  }\r
-  gBS->RestoreTPL(OldTpl);\r
-  if (Index == mStackNum) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  *BufferIndex = Index;\r
-  *StackBuffer = mStackBuffer[Index];\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ReturnEBCStack(\r
-  UINTN Index\r
-  )\r
-{\r
-  mStackBufferIndex[Index] =NULL;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-ReturnEBCStackByHandle(\r
-  EFI_HANDLE Handle\r
-  )\r
-{\r
-  UINTN Index;\r
-  for (Index = 0; Index < mStackNum; Index ++) {\r
-    if (mStackBufferIndex[Index] == Handle) {\r
-      break;\r
-    }\r
-  }\r
-  if (Index == mStackNum) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-  mStackBufferIndex[Index] = NULL;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-InitEBCStack (\r
-  VOID\r
-  )\r
-{\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
-  if (mStackNum == 0) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-FreeEBCStack(\r
-  VOID\r
-  )\r
-{\r
-  UINTN Index;\r
-  for (Index = 0; Index < mStackNum; Index ++) {\r
-    FreePool(mStackBuffer[Index]);\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-STATIC\r
-EFI_STATUS\r
-InitEbcVmTestProtocol (\r
-  IN EFI_HANDLE     *IHandle\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Produce an EBC VM test protocol that can be used for regression tests.\r
-\r
-Arguments:\r
-\r
-  IHandle - handle on which to install the protocol.\r
-\r
-Returns:\r
-\r
-  EFI_OUT_OF_RESOURCES  - memory allocation failed\r
-  EFI_SUCCESS           - successful completion\r
-\r
---*/\r
-{\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
-  //\r
-  EbcVmTestProtocol = AllocatePool (sizeof (EFI_EBC_VM_TEST_PROTOCOL));\r
-  if (EbcVmTestProtocol == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\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
-  DEBUG_CODE_END ();\r
-\r
-  //\r
-  // Publish the protocol\r
-  //\r
-  Handle  = NULL;\r
-  Status  = gBS->InstallProtocolInterface (&Handle, &mEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (EbcVmTestProtocol);\r
-  }\r
-  return Status;\r
-}\r
-STATIC\r
-EFI_STATUS\r
-EbcVmTestUnsupported ()\r
-{\r
-  return EFI_UNSUPPORTED;\r
-}\r
-\r