/** @file
  Top level module for the EBC virtual machine implementation.
  Provides auxiliary support routines for the VM. That is, routines
  that are not particularly related to VM execution of EBC instructions.

Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "EbcInt.h"
#include "EbcExecute.h"
#include "EbcDebuggerHook.h"

//
// We'll keep track of all thunks we create in a linked list. Each
// thunk is tied to an image handle, so we have a linked list of
// image handles, with each having a linked list of thunks allocated
// to that image handle.
//
typedef struct _EBC_THUNK_LIST EBC_THUNK_LIST;
struct _EBC_THUNK_LIST {
  VOID              *ThunkBuffer;
  EBC_THUNK_LIST    *Next;
};

typedef struct _EBC_IMAGE_LIST EBC_IMAGE_LIST;
struct _EBC_IMAGE_LIST {
  EBC_IMAGE_LIST    *Next;
  EFI_HANDLE        ImageHandle;
  EBC_THUNK_LIST    *ThunkList;
};

/**
  This routine is called by the core when an image is being unloaded from
  memory. Basically we now have the opportunity to do any necessary cleanup.
  Typically this will include freeing any memory allocated for thunk-creation.

  @param  This                  A pointer to the EFI_EBC_PROTOCOL instance.
  @param  ImageHandle           Handle of image for which the thunk is being
                                created.

  @retval EFI_INVALID_PARAMETER The ImageHandle passed in was not found in the
                                internal list of EBC image handles.
  @retval EFI_SUCCESS           The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcUnloadImage (
  IN EFI_EBC_PROTOCOL  *This,
  IN EFI_HANDLE        ImageHandle
  );

/**
  This is the top-level routine plugged into the EBC protocol. Since thunks
  are very processor-specific, from here we dispatch directly to the very
  processor-specific routine EbcCreateThunks().

  @param  This                  A pointer to the EFI_EBC_PROTOCOL instance.
  @param  ImageHandle           Handle of image for which the thunk is being
                                created. The EBC interpreter may use this to
                                keep track of any resource allocations
                                performed in loading and executing the image.
  @param  EbcEntryPoint         Address of the actual EBC entry point or
                                protocol service the thunk should call.
  @param  Thunk                 Returned pointer to a thunk created.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_INVALID_PARAMETER Image entry point is not 2-byte aligned.
  @retval EFI_OUT_OF_RESOURCES  Memory could not be allocated for the thunk.

**/
EFI_STATUS
EFIAPI
EbcCreateThunk (
  IN EFI_EBC_PROTOCOL  *This,
  IN EFI_HANDLE        ImageHandle,
  IN VOID              *EbcEntryPoint,
  OUT VOID             **Thunk
  );

/**
  Called to get the version of the interpreter.

  @param  This                  A pointer to the EFI_EBC_PROTOCOL instance.
  @param  Version               Pointer to where to store the returned version
                                of the interpreter.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_INVALID_PARAMETER Version pointer is NULL.

**/
EFI_STATUS
EFIAPI
EbcGetVersion (
  IN EFI_EBC_PROTOCOL  *This,
  IN OUT UINT64        *Version
  );

/**
  To install default Callback function for the VM interpreter.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval Others                Some error occurs when creating periodic event.

**/
EFI_STATUS
EFIAPI
InitializeEbcCallback (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This
  );

/**
  The default Exception Callback for the VM interpreter.
  In this function, we report status code, and print debug information
  about EBC_CONTEXT, then dead loop.

  @param  InterruptType          Interrupt type.
  @param  SystemContext          EBC system context.

**/
VOID
EFIAPI
CommonEbcExceptionHandler (
  IN EFI_EXCEPTION_TYPE  InterruptType,
  IN EFI_SYSTEM_CONTEXT  SystemContext
  );

/**
  The periodic callback function for EBC VM interpreter, which is used
  to support the EFI debug support protocol.

  @param  Event                  The Periodic Callback Event.
  @param  Context                It should be the address of VM_CONTEXT pointer.

**/
VOID
EFIAPI
EbcPeriodicNotifyFunction (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  );

/**
  The VM interpreter calls this function on a periodic basis to support
  the EFI debug support protocol.

  @param  VmPtr                  Pointer to a VM context for passing info to the
                                 debugger.

  @retval EFI_SUCCESS            The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcDebugPeriodic (
  IN VM_CONTEXT  *VmPtr
  );

//
// These two functions and the  GUID are used to produce an EBC test protocol.
// This functionality is definitely not required for execution.
//

/**
  Produces an EBC VM test protocol that can be used for regression tests.

  @param  IHandle                Handle on which to install the protocol.

  @retval EFI_OUT_OF_RESOURCES   Memory allocation failed.
  @retval EFI_SUCCESS            The function completed successfully.

**/
EFI_STATUS
InitEbcVmTestProtocol (
  IN EFI_HANDLE  *IHandle
  );

/**
  Returns the EFI_UNSUPPORTED Status.

  @return EFI_UNSUPPORTED  This function always return EFI_UNSUPPORTED status.

**/
EFI_STATUS
EFIAPI
EbcVmTestUnsupported (
  VOID
  );

/**
  Registers a callback function that the EBC interpreter calls to flush the
  processor instruction cache following creation of thunks.

  @param  This        A pointer to the EFI_EBC_PROTOCOL instance.
  @param  Flush       Pointer to a function of type EBC_ICACH_FLUSH.

  @retval EFI_SUCCESS The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcRegisterICacheFlush (
  IN EFI_EBC_PROTOCOL  *This,
  IN EBC_ICACHE_FLUSH  Flush
  );

/**
  This EBC debugger protocol service is called by the debug agent

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.
  @param  MaxProcessorIndex     Pointer to a caller-allocated UINTN in which the
                                maximum supported processor index is returned.

  @retval EFI_SUCCESS           The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcDebugGetMaximumProcessorIndex (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  OUT UINTN                      *MaxProcessorIndex
  );

/**
  This protocol service is called by the debug agent to register a function
  for us to call on a periodic basis.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.
  @param  ProcessorIndex        Specifies which processor the callback function
                                applies to.
  @param  PeriodicCallback      A pointer to a function of type
                                PERIODIC_CALLBACK that is the main periodic
                                entry point of the debug agent. It receives as a
                                parameter a pointer to the full context of the
                                interrupted execution thread.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_ALREADY_STARTED   Non-NULL PeriodicCallback parameter when a
                                callback function was previously registered.
  @retval EFI_INVALID_PARAMETER Null PeriodicCallback parameter when no
                                callback function was previously registered.

**/
EFI_STATUS
EFIAPI
EbcDebugRegisterPeriodicCallback (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN EFI_PERIODIC_CALLBACK       PeriodicCallback
  );

/**
  This protocol service is called by the debug agent to register a function
  for us to call when we detect an exception.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.
  @param  ProcessorIndex        Specifies which processor the callback function
                                applies to.
  @param  ExceptionCallback     A pointer to a function of type
                                EXCEPTION_CALLBACK that is called when the
                                processor exception specified by ExceptionType
                                occurs. Passing NULL unregisters any previously
                                registered function associated with
                                ExceptionType.
  @param  ExceptionType         Specifies which processor exception to hook.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_ALREADY_STARTED   Non-NULL ExceptionCallback parameter when a
                                callback function was previously registered.
  @retval EFI_INVALID_PARAMETER ExceptionType parameter is negative or exceeds
                                MAX_EBC_EXCEPTION.
  @retval EFI_INVALID_PARAMETER Null ExceptionCallback parameter when no
                                callback function was previously registered.

**/
EFI_STATUS
EFIAPI
EbcDebugRegisterExceptionCallback (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN EFI_EXCEPTION_CALLBACK      ExceptionCallback,
  IN EFI_EXCEPTION_TYPE          ExceptionType
  );

/**
  This EBC debugger protocol service is called by the debug agent.  Required
  for DebugSupport compliance but is only stubbed out for EBC.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.
  @param  ProcessorIndex        Specifies which processor the callback function
                                applies to.
  @param  Start                 StartSpecifies the physical base of the memory
                                range to be invalidated.
  @param  Length                Specifies the minimum number of bytes in the
                                processor's instruction cache to invalidate.

  @retval EFI_SUCCESS           The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcDebugInvalidateInstructionCache (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN VOID                        *Start,
  IN UINT64                      Length
  );

//
// We have one linked list of image handles for the whole world. Since
// there should only be one interpreter, make them global. They must
// also be global since the execution of an EBC image does not provide
// a This pointer.
//
EBC_IMAGE_LIST  *mEbcImageList = NULL;

//
// Callback function to flush the icache after thunk creation
//
EBC_ICACHE_FLUSH  mEbcICacheFlush;

//
// These get set via calls by the debug agent
//
EFI_PERIODIC_CALLBACK   mDebugPeriodicCallback                         = NULL;
EFI_EXCEPTION_CALLBACK  mDebugExceptionCallback[MAX_EBC_EXCEPTION + 1] = { NULL };

VOID        *mStackBuffer[MAX_STACK_NUM];
EFI_HANDLE  mStackBufferIndex[MAX_STACK_NUM];
UINTN       mStackNum = 0;

//
// Event for Periodic callback
//
EFI_EVENT   mEbcPeriodicEvent;
VM_CONTEXT  *mVmPtr = NULL;

/**
  Check whether the emulator supports executing a certain PE/COFF image

  @param[in] This         This pointer for EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL
                          structure
  @param[in] ImageType    Whether the image is an application, a boot time
                          driver or a runtime driver.
  @param[in] DevicePath   Path to device where the image originated
                          (e.g., a PCI option ROM)

  @retval TRUE            The image is supported by the emulator
  @retval FALSE           The image is not supported by the emulator.
**/
BOOLEAN
EFIAPI
EbcIsImageSupported (
  IN  EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL  *This,
  IN  UINT16                                ImageType,
  IN  EFI_DEVICE_PATH_PROTOCOL              *DevicePath   OPTIONAL
  )
{
  if ((ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) &&
      (ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER))
  {
    return FALSE;
  }

  return TRUE;
}

/**
  Register a supported PE/COFF image with the emulator. After this call
  completes successfully, the PE/COFF image may be started as usual, and
  it is the responsibility of the emulator implementation that any branch
  into the code section of the image (including returns from functions called
  from the foreign code) is executed as if it were running on the machine
  type it was built for.

  @param[in]      This          This pointer for
                                EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL structure
  @param[in]      ImageBase     The base address in memory of the PE/COFF image
  @param[in]      ImageSize     The size in memory of the PE/COFF image
  @param[in,out]  EntryPoint    The entry point of the PE/COFF image. Passed by
                                reference so that the emulator may modify it.

  @retval EFI_SUCCESS           The image was registered with the emulator and
                                can be started as usual.
  @retval other                 The image could not be registered.

  If the PE/COFF machine type or image type are not supported by the emulator,
  then ASSERT().
**/
EFI_STATUS
EFIAPI
EbcRegisterImage (
  IN      EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL  *This,
  IN      EFI_PHYSICAL_ADDRESS                  ImageBase,
  IN      UINT64                                ImageSize,
  IN  OUT EFI_IMAGE_ENTRY_POINT                 *EntryPoint
  )
{
  DEBUG_CODE_BEGIN ();
  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;
  EFI_STATUS                    Status;

  ZeroMem (&ImageContext, sizeof (ImageContext));

  ImageContext.Handle    = (VOID *)(UINTN)ImageBase;
  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;

  Status = PeCoffLoaderGetImageInfo (&ImageContext);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (ImageContext.Machine == EFI_IMAGE_MACHINE_EBC);
  ASSERT (
    ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ||
    ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
    );
  DEBUG_CODE_END ();

  EbcRegisterICacheFlush (
    NULL,
    (EBC_ICACHE_FLUSH)InvalidateInstructionCacheRange
    );

  return EbcCreateThunk (
           NULL,
           (VOID *)(UINTN)ImageBase,
           (VOID *)(UINTN)*EntryPoint,
           (VOID **)EntryPoint
           );
}

/**
  Unregister a PE/COFF image that has been registered with the emulator.
  This should be done before the image is unloaded from memory.

  @param[in] This         This pointer for EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL
                          structure
  @param[in] ImageBase    The base address in memory of the PE/COFF image

  @retval EFI_SUCCESS     The image was unregistered with the emulator.
  @retval other           Image could not be unloaded.
**/
EFI_STATUS
EFIAPI
EbcUnregisterImage (
  IN  EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL  *This,
  IN  EFI_PHYSICAL_ADDRESS                  ImageBase
  )
{
  return EbcUnloadImage (NULL, (VOID *)(UINTN)ImageBase);
}

STATIC EDKII_PECOFF_IMAGE_EMULATOR_PROTOCOL  mPeCoffEmuProtocol = {
  EbcIsImageSupported,
  EbcRegisterImage,
  EbcUnregisterImage,
  EDKII_PECOFF_IMAGE_EMULATOR_VERSION,
  EFI_IMAGE_MACHINE_EBC
};

/**
  Initializes the VM EFI interface.  Allocates memory for the VM interface
  and registers the VM protocol.

  @param  ImageHandle            EFI image handle.
  @param  SystemTable            Pointer to the EFI system table.

  @return Standard EFI status code.

**/
EFI_STATUS
EFIAPI
InitializeEbcDriver (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_EBC_PROTOCOL            *EbcProtocol;
  EFI_EBC_PROTOCOL            *OldEbcProtocol;
  EFI_STATUS                  Status;
  EFI_DEBUG_SUPPORT_PROTOCOL  *EbcDebugProtocol;
  EFI_HANDLE                  *HandleBuffer;
  UINTN                       NumHandles;
  UINTN                       Index;
  BOOLEAN                     Installed;

  EbcProtocol      = NULL;
  EbcDebugProtocol = NULL;

  //
  // Allocate memory for our protocol. Then fill in the blanks.
  //
  EbcProtocol = AllocatePool (sizeof (EFI_EBC_PROTOCOL));

  if (EbcProtocol == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  EbcProtocol->CreateThunk         = EbcCreateThunk;
  EbcProtocol->UnloadImage         = EbcUnloadImage;
  EbcProtocol->RegisterICacheFlush = EbcRegisterICacheFlush;
  EbcProtocol->GetVersion          = EbcGetVersion;
  mEbcICacheFlush                  = NULL;

  //
  // Find any already-installed EBC protocols and uninstall them
  //
  Installed    = FALSE;
  HandleBuffer = NULL;
  Status       = gBS->LocateHandleBuffer (
                        ByProtocol,
                        &gEfiEbcProtocolGuid,
                        NULL,
                        &NumHandles,
                        &HandleBuffer
                        );
  if (Status == EFI_SUCCESS) {
    //
    // Loop through the handles
    //
    for (Index = 0; Index < NumHandles; Index++) {
      Status = gBS->HandleProtocol (
                      HandleBuffer[Index],
                      &gEfiEbcProtocolGuid,
                      (VOID **)&OldEbcProtocol
                      );
      if (Status == EFI_SUCCESS) {
        if (gBS->ReinstallProtocolInterface (
                   HandleBuffer[Index],
                   &gEfiEbcProtocolGuid,
                   OldEbcProtocol,
                   EbcProtocol
                   ) == EFI_SUCCESS)
        {
          Installed = TRUE;
        }
      }
    }
  }

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
    HandleBuffer = NULL;
  }

  //
  // Add the protocol so someone can locate us if we haven't already.
  //
  if (!Installed) {
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ImageHandle,
                    &gEfiEbcProtocolGuid,
                    EbcProtocol,
                    &gEdkiiPeCoffImageEmulatorProtocolGuid,
                    &mPeCoffEmuProtocol,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      FreePool (EbcProtocol);
      return Status;
    }
  }

  Status = InitEBCStack ();
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Allocate memory for our debug protocol. Then fill in the blanks.
  //
  EbcDebugProtocol = AllocatePool (sizeof (EFI_DEBUG_SUPPORT_PROTOCOL));

  if (EbcDebugProtocol == NULL) {
    goto ErrorExit;
  }

  EbcDebugProtocol->Isa                        = IsaEbc;
  EbcDebugProtocol->GetMaximumProcessorIndex   = EbcDebugGetMaximumProcessorIndex;
  EbcDebugProtocol->RegisterPeriodicCallback   = EbcDebugRegisterPeriodicCallback;
  EbcDebugProtocol->RegisterExceptionCallback  = EbcDebugRegisterExceptionCallback;
  EbcDebugProtocol->InvalidateInstructionCache = EbcDebugInvalidateInstructionCache;

  //
  // Add the protocol so the debug agent can find us
  //
  Status = gBS->InstallProtocolInterface (
                  &ImageHandle,
                  &gEfiDebugSupportProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  EbcDebugProtocol
                  );
  //
  // This is recoverable, so free the memory and continue.
  //
  if (EFI_ERROR (Status)) {
    FreePool (EbcDebugProtocol);
    goto ErrorExit;
  }

  //
  // Install EbcDebugSupport Protocol Successfully
  // Now we need to initialize the Ebc default Callback
  //
  Status = InitializeEbcCallback (EbcDebugProtocol);

  //
  // Produce a VM test interface protocol. Not required for execution.
  //
  DEBUG_CODE_BEGIN ();
  InitEbcVmTestProtocol (&ImageHandle);
  DEBUG_CODE_END ();

  EbcDebuggerHookInit (ImageHandle, EbcDebugProtocol);

  return EFI_SUCCESS;

ErrorExit:
  FreeEBCStack ();
  HandleBuffer = NULL;
  Status       = gBS->LocateHandleBuffer (
                        ByProtocol,
                        &gEfiEbcProtocolGuid,
                        NULL,
                        &NumHandles,
                        &HandleBuffer
                        );
  if (Status == EFI_SUCCESS) {
    //
    // Loop through the handles
    //
    for (Index = 0; Index < NumHandles; Index++) {
      Status = gBS->HandleProtocol (
                      HandleBuffer[Index],
                      &gEfiEbcProtocolGuid,
                      (VOID **)&OldEbcProtocol
                      );
      if (Status == EFI_SUCCESS) {
        gBS->UninstallProtocolInterface (
               HandleBuffer[Index],
               &gEfiEbcProtocolGuid,
               OldEbcProtocol
               );
      }
    }
  }

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
    HandleBuffer = NULL;
  }

  FreePool (EbcProtocol);

  return Status;
}

/**
  This is the top-level routine plugged into the EBC protocol. Since thunks
  are very processor-specific, from here we dispatch directly to the very
  processor-specific routine EbcCreateThunks().

  @param  This                  A pointer to the EFI_EBC_PROTOCOL instance.
  @param  ImageHandle           Handle of image for which the thunk is being
                                created. The EBC interpreter may use this to
                                keep track of any resource allocations
                                performed in loading and executing the image.
  @param  EbcEntryPoint         Address of the actual EBC entry point or
                                protocol service the thunk should call.
  @param  Thunk                 Returned pointer to a thunk created.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_INVALID_PARAMETER Image entry point is not 2-byte aligned.
  @retval EFI_OUT_OF_RESOURCES  Memory could not be allocated for the thunk.

**/
EFI_STATUS
EFIAPI
EbcCreateThunk (
  IN EFI_EBC_PROTOCOL  *This,
  IN EFI_HANDLE        ImageHandle,
  IN VOID              *EbcEntryPoint,
  OUT VOID             **Thunk
  )
{
  EFI_STATUS  Status;

  Status = EbcCreateThunks (
             ImageHandle,
             EbcEntryPoint,
             Thunk,
             FLAG_THUNK_ENTRY_POINT
             );
  return Status;
}

/**
  This EBC debugger protocol service is called by the debug agent

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.
  @param  MaxProcessorIndex     Pointer to a caller-allocated UINTN in which the
                                maximum supported processor index is returned.

  @retval EFI_SUCCESS           The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcDebugGetMaximumProcessorIndex (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  OUT UINTN                      *MaxProcessorIndex
  )
{
  *MaxProcessorIndex = 0;
  return EFI_SUCCESS;
}

/**
  This protocol service is called by the debug agent to register a function
  for us to call on a periodic basis.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.
  @param  ProcessorIndex        Specifies which processor the callback function
                                applies to.
  @param  PeriodicCallback      A pointer to a function of type
                                PERIODIC_CALLBACK that is the main periodic
                                entry point of the debug agent. It receives as a
                                parameter a pointer to the full context of the
                                interrupted execution thread.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_ALREADY_STARTED   Non-NULL PeriodicCallback parameter when a
                                callback function was previously registered.
  @retval EFI_INVALID_PARAMETER Null PeriodicCallback parameter when no
                                callback function was previously registered.

**/
EFI_STATUS
EFIAPI
EbcDebugRegisterPeriodicCallback (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN EFI_PERIODIC_CALLBACK       PeriodicCallback
  )
{
  if ((mDebugPeriodicCallback == NULL) && (PeriodicCallback == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((mDebugPeriodicCallback != NULL) && (PeriodicCallback != NULL)) {
    return EFI_ALREADY_STARTED;
  }

  mDebugPeriodicCallback = PeriodicCallback;
  return EFI_SUCCESS;
}

/**
  This protocol service is called by the debug agent to register a function
  for us to call when we detect an exception.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.
  @param  ProcessorIndex        Specifies which processor the callback function
                                applies to.
  @param  ExceptionCallback     A pointer to a function of type
                                EXCEPTION_CALLBACK that is called when the
                                processor exception specified by ExceptionType
                                occurs. Passing NULL unregisters any previously
                                registered function associated with
                                ExceptionType.
  @param  ExceptionType         Specifies which processor exception to hook.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_ALREADY_STARTED   Non-NULL ExceptionCallback parameter when a
                                callback function was previously registered.
  @retval EFI_INVALID_PARAMETER ExceptionType parameter is negative or exceeds
                                MAX_EBC_EXCEPTION.
  @retval EFI_INVALID_PARAMETER Null ExceptionCallback parameter when no
                                callback function was previously registered.

**/
EFI_STATUS
EFIAPI
EbcDebugRegisterExceptionCallback (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN EFI_EXCEPTION_CALLBACK      ExceptionCallback,
  IN EFI_EXCEPTION_TYPE          ExceptionType
  )
{
  if ((ExceptionType < 0) || (ExceptionType > MAX_EBC_EXCEPTION)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((mDebugExceptionCallback[ExceptionType] == NULL) && (ExceptionCallback == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((mDebugExceptionCallback[ExceptionType] != NULL) && (ExceptionCallback != NULL)) {
    return EFI_ALREADY_STARTED;
  }

  mDebugExceptionCallback[ExceptionType] = ExceptionCallback;
  return EFI_SUCCESS;
}

/**
  This EBC debugger protocol service is called by the debug agent.  Required
  for DebugSupport compliance but is only stubbed out for EBC.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.
  @param  ProcessorIndex        Specifies which processor the callback function
                                applies to.
  @param  Start                 StartSpecifies the physical base of the memory
                                range to be invalidated.
  @param  Length                Specifies the minimum number of bytes in the
                                processor's instruction cache to invalidate.

  @retval EFI_SUCCESS           The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcDebugInvalidateInstructionCache (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This,
  IN UINTN                       ProcessorIndex,
  IN VOID                        *Start,
  IN UINT64                      Length
  )
{
  return EFI_SUCCESS;
}

/**
  The VM interpreter calls this function when an exception is detected.

  @param  ExceptionType          Specifies the processor exception detected.
  @param  ExceptionFlags         Specifies the exception context.
  @param  VmPtr                  Pointer to a VM context for passing info to the
                                 EFI debugger.

  @retval EFI_SUCCESS            This function completed successfully.

**/
EFI_STATUS
EbcDebugSignalException (
  IN EFI_EXCEPTION_TYPE  ExceptionType,
  IN EXCEPTION_FLAGS     ExceptionFlags,
  IN VM_CONTEXT          *VmPtr
  )
{
  EFI_SYSTEM_CONTEXT_EBC  EbcContext;
  EFI_SYSTEM_CONTEXT      SystemContext;

  ASSERT ((ExceptionType >= 0) && (ExceptionType <= MAX_EBC_EXCEPTION));
  //
  // Save the exception in the context passed in
  //
  VmPtr->ExceptionFlags |= ExceptionFlags;
  VmPtr->LastException   = (UINTN)ExceptionType;
  //
  // If it's a fatal exception, then flag it in the VM context in case an
  // attached debugger tries to return from it.
  //
  if ((ExceptionFlags & EXCEPTION_FLAG_FATAL) != 0) {
    VmPtr->StopFlags |= STOPFLAG_APP_DONE;
  }

  //
  // If someone's registered for exception callbacks, then call them.
  //
  // EBC driver will register default exception callback to report the
  // status code via the status code API
  //
  if (mDebugExceptionCallback[ExceptionType] != NULL) {
    //
    // Initialize the context structure
    //
    EbcContext.R0                  = (UINT64)VmPtr->Gpr[0];
    EbcContext.R1                  = (UINT64)VmPtr->Gpr[1];
    EbcContext.R2                  = (UINT64)VmPtr->Gpr[2];
    EbcContext.R3                  = (UINT64)VmPtr->Gpr[3];
    EbcContext.R4                  = (UINT64)VmPtr->Gpr[4];
    EbcContext.R5                  = (UINT64)VmPtr->Gpr[5];
    EbcContext.R6                  = (UINT64)VmPtr->Gpr[6];
    EbcContext.R7                  = (UINT64)VmPtr->Gpr[7];
    EbcContext.Ip                  = (UINT64)(UINTN)VmPtr->Ip;
    EbcContext.Flags               = VmPtr->Flags;
    EbcContext.ControlFlags        = 0;
    SystemContext.SystemContextEbc = &EbcContext;

    mDebugExceptionCallback[ExceptionType](ExceptionType, SystemContext);
    //
    // Restore the context structure and continue to execute
    //
    VmPtr->Gpr[0] = EbcContext.R0;
    VmPtr->Gpr[1] = EbcContext.R1;
    VmPtr->Gpr[2] = EbcContext.R2;
    VmPtr->Gpr[3] = EbcContext.R3;
    VmPtr->Gpr[4] = EbcContext.R4;
    VmPtr->Gpr[5] = EbcContext.R5;
    VmPtr->Gpr[6] = EbcContext.R6;
    VmPtr->Gpr[7] = EbcContext.R7;
    VmPtr->Ip     = (VMIP)(UINTN)EbcContext.Ip;
    VmPtr->Flags  = EbcContext.Flags;
  }

  return EFI_SUCCESS;
}

/**
  To install default Callback function for the VM interpreter.

  @param  This                  A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL
                                instance.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval Others                Some error occurs when creating periodic event.

**/
EFI_STATUS
EFIAPI
InitializeEbcCallback (
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *This
  )
{
  INTN        Index;
  EFI_STATUS  Status;

  //
  // For ExceptionCallback
  //
  for (Index = 0; Index <= MAX_EBC_EXCEPTION; Index++) {
    EbcDebugRegisterExceptionCallback (
      This,
      0,
      CommonEbcExceptionHandler,
      Index
      );
  }

  //
  // For PeriodicCallback
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  EbcPeriodicNotifyFunction,
                  &mVmPtr,
                  &mEbcPeriodicEvent
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->SetTimer (
                  mEbcPeriodicEvent,
                  TimerPeriodic,
                  EBC_VM_PERIODIC_CALLBACK_RATE
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  The default Exception Callback for the VM interpreter.
  In this function, we report status code, and print debug information
  about EBC_CONTEXT, then dead loop.

  @param  InterruptType          Interrupt type.
  @param  SystemContext          EBC system context.

**/
VOID
EFIAPI
CommonEbcExceptionHandler (
  IN EFI_EXCEPTION_TYPE  InterruptType,
  IN EFI_SYSTEM_CONTEXT  SystemContext
  )
{
  //
  // We print debug information to let user know what happen.
  //
  DEBUG ((
    DEBUG_ERROR,
    "EBC Interrupter Version - 0x%016lx\n",
    (UINT64)(((VM_MAJOR_VERSION & 0xFFFF) << 16) | ((VM_MINOR_VERSION & 0xFFFF)))
    ));
  DEBUG ((
    DEBUG_ERROR,
    "Exception Type - 0x%016lx\n",
    (UINT64)(UINTN)InterruptType
    ));
  DEBUG ((
    DEBUG_ERROR,
    "  R0 - 0x%016lx, R1 - 0x%016lx\n",
    SystemContext.SystemContextEbc->R0,
    SystemContext.SystemContextEbc->R1
    ));
  DEBUG ((
    DEBUG_ERROR,
    "  R2 - 0x%016lx, R3 - 0x%016lx\n",
    SystemContext.SystemContextEbc->R2,
    SystemContext.SystemContextEbc->R3
    ));
  DEBUG ((
    DEBUG_ERROR,
    "  R4 - 0x%016lx, R5 - 0x%016lx\n",
    SystemContext.SystemContextEbc->R4,
    SystemContext.SystemContextEbc->R5
    ));
  DEBUG ((
    DEBUG_ERROR,
    "  R6 - 0x%016lx, R7 - 0x%016lx\n",
    SystemContext.SystemContextEbc->R6,
    SystemContext.SystemContextEbc->R7
    ));
  DEBUG ((
    DEBUG_ERROR,
    "  Flags - 0x%016lx\n",
    SystemContext.SystemContextEbc->Flags
    ));
  DEBUG ((
    DEBUG_ERROR,
    "  ControlFlags - 0x%016lx\n",
    SystemContext.SystemContextEbc->ControlFlags
    ));
  DEBUG ((
    DEBUG_ERROR,
    "  Ip - 0x%016lx\n\n",
    SystemContext.SystemContextEbc->Ip
    ));

  //
  // We deadloop here to make it easy to debug this issue.
  //
  CpuDeadLoop ();

  return;
}

/**
  The periodic callback function for EBC VM interpreter, which is used
  to support the EFI debug support protocol.

  @param  Event                  The Periodic Callback Event.
  @param  Context                It should be the address of VM_CONTEXT pointer.

**/
VOID
EFIAPI
EbcPeriodicNotifyFunction (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  VM_CONTEXT  *VmPtr;

  VmPtr = *(VM_CONTEXT **)Context;

  if (VmPtr != NULL) {
    EbcDebugPeriodic (VmPtr);
  }

  return;
}

/**
  The VM interpreter calls this function on a periodic basis to support
  the EFI debug support protocol.

  @param  VmPtr                  Pointer to a VM context for passing info to the
                                 debugger.

  @retval EFI_SUCCESS            The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcDebugPeriodic (
  IN VM_CONTEXT  *VmPtr
  )
{
  EFI_SYSTEM_CONTEXT_EBC  EbcContext;
  EFI_SYSTEM_CONTEXT      SystemContext;

  //
  // If someone's registered for periodic callbacks, then call them.
  //
  if (mDebugPeriodicCallback != NULL) {
    //
    // Initialize the context structure
    //
    EbcContext.R0                  = (UINT64)VmPtr->Gpr[0];
    EbcContext.R1                  = (UINT64)VmPtr->Gpr[1];
    EbcContext.R2                  = (UINT64)VmPtr->Gpr[2];
    EbcContext.R3                  = (UINT64)VmPtr->Gpr[3];
    EbcContext.R4                  = (UINT64)VmPtr->Gpr[4];
    EbcContext.R5                  = (UINT64)VmPtr->Gpr[5];
    EbcContext.R6                  = (UINT64)VmPtr->Gpr[6];
    EbcContext.R7                  = (UINT64)VmPtr->Gpr[7];
    EbcContext.Ip                  = (UINT64)(UINTN)VmPtr->Ip;
    EbcContext.Flags               = VmPtr->Flags;
    EbcContext.ControlFlags        = 0;
    SystemContext.SystemContextEbc = &EbcContext;

    mDebugPeriodicCallback (SystemContext);

    //
    // Restore the context structure and continue to execute
    //
    VmPtr->Gpr[0] = EbcContext.R0;
    VmPtr->Gpr[1] = EbcContext.R1;
    VmPtr->Gpr[2] = EbcContext.R2;
    VmPtr->Gpr[3] = EbcContext.R3;
    VmPtr->Gpr[4] = EbcContext.R4;
    VmPtr->Gpr[5] = EbcContext.R5;
    VmPtr->Gpr[6] = EbcContext.R6;
    VmPtr->Gpr[7] = EbcContext.R7;
    VmPtr->Ip     = (VMIP)(UINTN)EbcContext.Ip;
    VmPtr->Flags  = EbcContext.Flags;
  }

  return EFI_SUCCESS;
}

/**
  This routine is called by the core when an image is being unloaded from
  memory. Basically we now have the opportunity to do any necessary cleanup.
  Typically this will include freeing any memory allocated for thunk-creation.

  @param  This                  A pointer to the EFI_EBC_PROTOCOL instance.
  @param  ImageHandle           Handle of image for which the thunk is being
                                created.

  @retval EFI_INVALID_PARAMETER The ImageHandle passed in was not found in the
                                internal list of EBC image handles.
  @retval EFI_SUCCESS           The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcUnloadImage (
  IN EFI_EBC_PROTOCOL  *This,
  IN EFI_HANDLE        ImageHandle
  )
{
  EBC_THUNK_LIST  *ThunkList;
  EBC_THUNK_LIST  *NextThunkList;
  EBC_IMAGE_LIST  *ImageList;
  EBC_IMAGE_LIST  *PrevImageList;

  //
  // First go through our list of known image handles and see if we've already
  // created an image list element for this image handle.
  //
  ReturnEBCStackByHandle (ImageHandle);
  PrevImageList = NULL;
  for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {
    if (ImageList->ImageHandle == ImageHandle) {
      break;
    }

    //
    // Save the previous so we can connect the lists when we remove this one
    //
    PrevImageList = ImageList;
  }

  if (ImageList == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Free up all the thunk buffers and thunks list elements for this image
  // handle.
  //
  ThunkList = ImageList->ThunkList;
  while (ThunkList != NULL) {
    NextThunkList = ThunkList->Next;
    FreePool (ThunkList->ThunkBuffer);
    FreePool (ThunkList);
    ThunkList = NextThunkList;
  }

  //
  // Now remove this image list element from the chain
  //
  if (PrevImageList == NULL) {
    //
    // Remove from head
    //
    mEbcImageList = ImageList->Next;
  } else {
    PrevImageList->Next = ImageList->Next;
  }

  //
  // Now free up the image list element
  //
  FreePool (ImageList);

  EbcDebuggerHookEbcUnloadImage (ImageHandle);

  return EFI_SUCCESS;
}

/**
  Add a thunk to our list of thunks for a given image handle.
  Also flush the instruction cache since we've written thunk code
  to memory that will be executed eventually.

  @param  ImageHandle            The image handle to which the thunk is tied.
  @param  ThunkBuffer            The buffer that has been created/allocated.
  @param  ThunkSize              The size of the thunk memory allocated.

  @retval EFI_OUT_OF_RESOURCES   Memory allocation failed.
  @retval EFI_SUCCESS            The function completed successfully.

**/
EFI_STATUS
EbcAddImageThunk (
  IN EFI_HANDLE  ImageHandle,
  IN VOID        *ThunkBuffer,
  IN UINT32      ThunkSize
  )
{
  EBC_THUNK_LIST  *ThunkList;
  EBC_IMAGE_LIST  *ImageList;
  EFI_STATUS      Status;

  //
  // It so far so good, then flush the instruction cache
  //
  if (mEbcICacheFlush != NULL) {
    Status = mEbcICacheFlush ((EFI_PHYSICAL_ADDRESS)(UINTN)ThunkBuffer, ThunkSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Go through our list of known image handles and see if we've already
  // created a image list element for this image handle.
  //
  for (ImageList = mEbcImageList; ImageList != NULL; ImageList = ImageList->Next) {
    if (ImageList->ImageHandle == ImageHandle) {
      break;
    }
  }

  if (ImageList == NULL) {
    //
    // Allocate a new one
    //
    ImageList = AllocatePool (sizeof (EBC_IMAGE_LIST));

    if (ImageList == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    ImageList->ThunkList   = NULL;
    ImageList->ImageHandle = ImageHandle;
    ImageList->Next        = mEbcImageList;
    mEbcImageList          = ImageList;
  }

  //
  // Ok, now create a new thunk element to add to the list
  //
  ThunkList = AllocatePool (sizeof (EBC_THUNK_LIST));

  if (ThunkList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Add it to the head of the list
  //
  ThunkList->Next        = ImageList->ThunkList;
  ThunkList->ThunkBuffer = ThunkBuffer;
  ImageList->ThunkList   = ThunkList;
  return EFI_SUCCESS;
}

/**
  Registers a callback function that the EBC interpreter calls to flush the
  processor instruction cache following creation of thunks.

  @param  This        A pointer to the EFI_EBC_PROTOCOL instance.
  @param  Flush       Pointer to a function of type EBC_ICACH_FLUSH.

  @retval EFI_SUCCESS The function completed successfully.

**/
EFI_STATUS
EFIAPI
EbcRegisterICacheFlush (
  IN EFI_EBC_PROTOCOL  *This,
  IN EBC_ICACHE_FLUSH  Flush
  )
{
  mEbcICacheFlush = Flush;
  return EFI_SUCCESS;
}

/**
  Called to get the version of the interpreter.

  @param  This                  A pointer to the EFI_EBC_PROTOCOL instance.
  @param  Version               Pointer to where to store the returned version
                                of the interpreter.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_INVALID_PARAMETER Version pointer is NULL.

**/
EFI_STATUS
EFIAPI
EbcGetVersion (
  IN EFI_EBC_PROTOCOL  *This,
  IN OUT UINT64        *Version
  )
{
  if (Version == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Version = GetVmVersion ();
  return EFI_SUCCESS;
}

/**
  Returns the stack index and buffer assosicated with the Handle parameter.

  @param  Handle                The EFI handle as the index to the EBC stack.
  @param  StackBuffer           A pointer to hold the returned stack buffer.
  @param  BufferIndex           A pointer to hold the returned stack index.

  @retval EFI_OUT_OF_RESOURCES  The Handle parameter does not correspond to any
                                existing EBC stack.
  @retval EFI_SUCCESS           The stack index and buffer were found and
                                returned to the caller.

**/
EFI_STATUS
GetEBCStack (
  IN  EFI_HANDLE  Handle,
  OUT VOID        **StackBuffer,
  OUT UINTN       *BufferIndex
  )
{
  UINTN    Index;
  EFI_TPL  OldTpl;

  OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
  for (Index = 0; Index < mStackNum; Index++) {
    if (mStackBufferIndex[Index] == NULL) {
      mStackBufferIndex[Index] = Handle;
      break;
    }
  }

  gBS->RestoreTPL (OldTpl);
  if (Index == mStackNum) {
    return EFI_OUT_OF_RESOURCES;
  }

  *BufferIndex = Index;
  *StackBuffer = mStackBuffer[Index];
  return EFI_SUCCESS;
}

/**
  Returns from the EBC stack by stack Index.

  @param  Index        Specifies which EBC stack to return from.

  @retval EFI_SUCCESS  The function completed successfully.

**/
EFI_STATUS
ReturnEBCStack (
  IN UINTN  Index
  )
{
  mStackBufferIndex[Index] = NULL;
  return EFI_SUCCESS;
}

/**
  Returns from the EBC stack associated with the Handle parameter.

  @param  Handle      Specifies the EFI handle to find the EBC stack with.

  @retval EFI_SUCCESS The function completed successfully.

**/
EFI_STATUS
ReturnEBCStackByHandle (
  IN EFI_HANDLE  Handle
  )
{
  UINTN  Index;

  for (Index = 0; Index < mStackNum; Index++) {
    if (mStackBufferIndex[Index] == Handle) {
      break;
    }
  }

  if (Index == mStackNum) {
    return EFI_NOT_FOUND;
  }

  mStackBufferIndex[Index] = NULL;
  return EFI_SUCCESS;
}

/**
  Allocates memory to hold all the EBC stacks.

  @retval EFI_SUCCESS          The EBC stacks were allocated successfully.
  @retval EFI_OUT_OF_RESOURCES Not enough memory available for EBC stacks.

**/
EFI_STATUS
InitEBCStack (
  VOID
  )
{
  for (mStackNum = 0; mStackNum < MAX_STACK_NUM; mStackNum++) {
    mStackBuffer[mStackNum]      = AllocatePool (STACK_POOL_SIZE);
    mStackBufferIndex[mStackNum] = NULL;
    if (mStackBuffer[mStackNum] == NULL) {
      break;
    }
  }

  if (mStackNum == 0) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Free all EBC stacks allocated before.

  @retval EFI_SUCCESS   All the EBC stacks were freed.

**/
EFI_STATUS
FreeEBCStack (
  VOID
  )
{
  UINTN  Index;

  for (Index = 0; Index < mStackNum; Index++) {
    FreePool (mStackBuffer[Index]);
  }

  return EFI_SUCCESS;
}

/**
  Produces an EBC VM test protocol that can be used for regression tests.

  @param  IHandle                Handle on which to install the protocol.

  @retval EFI_OUT_OF_RESOURCES   Memory allocation failed.
  @retval EFI_SUCCESS            The function completed successfully.

**/
EFI_STATUS
InitEbcVmTestProtocol (
  IN EFI_HANDLE  *IHandle
  )
{
  EFI_HANDLE                Handle;
  EFI_STATUS                Status;
  EFI_EBC_VM_TEST_PROTOCOL  *EbcVmTestProtocol;

  //
  // Allocate memory for the protocol, then fill in the fields
  //
  EbcVmTestProtocol = AllocatePool (sizeof (EFI_EBC_VM_TEST_PROTOCOL));
  if (EbcVmTestProtocol == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  EbcVmTestProtocol->Execute = (EBC_VM_TEST_EXECUTE)EbcExecuteInstructions;

  DEBUG_CODE_BEGIN ();
  EbcVmTestProtocol->Assemble    = (EBC_VM_TEST_ASM)EbcVmTestUnsupported;
  EbcVmTestProtocol->Disassemble = (EBC_VM_TEST_DASM)EbcVmTestUnsupported;
  DEBUG_CODE_END ();

  //
  // Publish the protocol
  //
  Handle = NULL;
  Status = gBS->InstallProtocolInterface (&Handle, &gEfiEbcVmTestProtocolGuid, EFI_NATIVE_INTERFACE, EbcVmTestProtocol);
  if (EFI_ERROR (Status)) {
    FreePool (EbcVmTestProtocol);
  }

  return Status;
}

/**
  Returns the EFI_UNSUPPORTED Status.

  @return EFI_UNSUPPORTED  This function always return EFI_UNSUPPORTED status.

**/
EFI_STATUS
EFIAPI
EbcVmTestUnsupported (
  VOID
  )
{
  return EFI_UNSUPPORTED;
}

/**
  Allocates a buffer of type EfiBootServicesCode.

  @param  AllocationSize        The number of bytes to allocate.

  @return A pointer to the allocated buffer or NULL if allocation fails.

**/
VOID *
EFIAPI
EbcAllocatePoolForThunk (
  IN UINTN  AllocationSize
  )
{
  VOID        *Buffer;
  EFI_STATUS  Status;

  Status = gBS->AllocatePool (EfiBootServicesCode, AllocationSize, &Buffer);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  return Buffer;
}
