/** @file
  SMM Base Helper SMM driver.

  This driver is the counterpart of the SMM Base On SMM Base2 Thunk driver. It
  provides helping services in SMM to the SMM Base On SMM Base2 Thunk driver.

  Caution: This module requires additional review when modified.
  This driver will have external input - communicate buffer in SMM mode.
  This external input must be validated carefully to avoid security issue like
  buffer overflow, integer overflow.

  SmmHandlerEntry() will receive untrusted input and do validation.

  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <PiSmm.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/SmmServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PeCoffLib.h>
#include <Library/DevicePathLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/SynchronizationLib.h>
#include <Library/CpuLib.h>
#include <Library/SmmMemLib.h>
#include <Guid/SmmBaseThunkCommunication.h>
#include <Protocol/SmmBaseHelperReady.h>
#include <Protocol/SmmCpu.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/SmmCpuSaveState.h>
#include <Protocol/MpService.h>
#include <Protocol/LoadPe32Image.h>
#include <Protocol/SmmReadyToLock.h>

/**
  Register SMM image to SMRAM profile.

  @param[in] FilePath           File path of the image.
  @param[in] ImageBuffer        Image base address.
  @param[in] NumberOfPage       Number of page.

  @retval TRUE                  Register success.
  @retval FALSE                 Register fail.

**/
BOOLEAN
RegisterSmramProfileImage (
  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
  IN PHYSICAL_ADDRESS           ImageBuffer,
  IN UINTN                      NumberOfPage
  );

/**
  Unregister SMM image from SMRAM profile.

  @param[in] FilePath           File path of the image.
  @param[in] ImageBuffer        Image base address.
  @param[in] NumberOfPage       Number of page.

  @retval TRUE                  Unregister success.
  @retval FALSE                 Unregister fail.

**/
BOOLEAN
UnregisterSmramProfileImage (
  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
  IN PHYSICAL_ADDRESS           ImageBuffer,
  IN UINTN                      NumberOfPage
  );

///
/// Structure for tracking paired information of registered Framework SMI handler
/// and correpsonding dispatch handle for SMI handler thunk.
///
typedef struct {
  LIST_ENTRY                    Link;
  EFI_HANDLE                    DispatchHandle;
  EFI_HANDLE                    SmmImageHandle;
  EFI_SMM_CALLBACK_ENTRY_POINT  CallbackAddress;
  VOID                          *CommunicationBuffer;
  UINTN                         *SourceSize;
} CALLBACK_INFO;

typedef struct {
  ///
  /// PI SMM CPU Save State register index
  ///
  EFI_SMM_SAVE_STATE_REGISTER   Register;
  ///
  /// Offset in Framework SMST
  ///
  UINTN                         Offset;
} CPU_SAVE_STATE_CONVERSION;

#define CPU_SAVE_STATE_GET_OFFSET(Field)  (UINTN)(&(((EFI_SMM_CPU_SAVE_STATE *) 0)->Ia32SaveState.Field))


EFI_HANDLE                         mDispatchHandle;
EFI_SMM_CPU_PROTOCOL               *mSmmCpu;
EFI_PE32_IMAGE_PROTOCOL            *mLoadPe32Image;
EFI_GUID                           mEfiSmmCpuIoGuid = EFI_SMM_CPU_IO_GUID;
EFI_SMM_BASE_HELPER_READY_PROTOCOL *mSmmBaseHelperReady;
EFI_SMM_SYSTEM_TABLE               *mFrameworkSmst;
UINTN                              mNumberOfProcessors;
BOOLEAN                            mLocked = FALSE;
BOOLEAN                            mPageTableHookEnabled;
BOOLEAN                            mHookInitialized;
UINT64                             *mCpuStatePageTable;
SPIN_LOCK                          mPFLock;
UINT64                             mPhyMask;
VOID                               *mOriginalHandler;
EFI_SMM_CPU_SAVE_STATE             *mShadowSaveState;

LIST_ENTRY mCallbackInfoListHead = INITIALIZE_LIST_HEAD_VARIABLE (mCallbackInfoListHead);

CPU_SAVE_STATE_CONVERSION mCpuSaveStateConvTable[] = {
  {EFI_SMM_SAVE_STATE_REGISTER_LDTBASE  , CPU_SAVE_STATE_GET_OFFSET(LDTBase)},
  {EFI_SMM_SAVE_STATE_REGISTER_ES       , CPU_SAVE_STATE_GET_OFFSET(ES)},
  {EFI_SMM_SAVE_STATE_REGISTER_CS       , CPU_SAVE_STATE_GET_OFFSET(CS)},
  {EFI_SMM_SAVE_STATE_REGISTER_SS       , CPU_SAVE_STATE_GET_OFFSET(SS)},
  {EFI_SMM_SAVE_STATE_REGISTER_DS       , CPU_SAVE_STATE_GET_OFFSET(DS)},
  {EFI_SMM_SAVE_STATE_REGISTER_FS       , CPU_SAVE_STATE_GET_OFFSET(FS)},
  {EFI_SMM_SAVE_STATE_REGISTER_GS       , CPU_SAVE_STATE_GET_OFFSET(GS)},
  {EFI_SMM_SAVE_STATE_REGISTER_TR_SEL   , CPU_SAVE_STATE_GET_OFFSET(TR)},
  {EFI_SMM_SAVE_STATE_REGISTER_DR7      , CPU_SAVE_STATE_GET_OFFSET(DR7)},
  {EFI_SMM_SAVE_STATE_REGISTER_DR6      , CPU_SAVE_STATE_GET_OFFSET(DR6)},
  {EFI_SMM_SAVE_STATE_REGISTER_RAX      , CPU_SAVE_STATE_GET_OFFSET(EAX)},
  {EFI_SMM_SAVE_STATE_REGISTER_RBX      , CPU_SAVE_STATE_GET_OFFSET(EBX)},
  {EFI_SMM_SAVE_STATE_REGISTER_RCX      , CPU_SAVE_STATE_GET_OFFSET(ECX)},
  {EFI_SMM_SAVE_STATE_REGISTER_RDX      , CPU_SAVE_STATE_GET_OFFSET(EDX)},
  {EFI_SMM_SAVE_STATE_REGISTER_RSP      , CPU_SAVE_STATE_GET_OFFSET(ESP)},
  {EFI_SMM_SAVE_STATE_REGISTER_RBP      , CPU_SAVE_STATE_GET_OFFSET(EBP)},
  {EFI_SMM_SAVE_STATE_REGISTER_RSI      , CPU_SAVE_STATE_GET_OFFSET(ESI)},
  {EFI_SMM_SAVE_STATE_REGISTER_RDI      , CPU_SAVE_STATE_GET_OFFSET(EDI)},
  {EFI_SMM_SAVE_STATE_REGISTER_RIP      , CPU_SAVE_STATE_GET_OFFSET(EIP)},
  {EFI_SMM_SAVE_STATE_REGISTER_RFLAGS   , CPU_SAVE_STATE_GET_OFFSET(EFLAGS)},
  {EFI_SMM_SAVE_STATE_REGISTER_CR0      , CPU_SAVE_STATE_GET_OFFSET(CR0)},
  {EFI_SMM_SAVE_STATE_REGISTER_CR3      , CPU_SAVE_STATE_GET_OFFSET(CR3)}
};

/**
  Page fault handler.

**/
VOID
PageFaultHandlerHook (
  VOID
  );

/**
  Read CpuSaveStates from PI for Framework use.

  The function reads PI style CpuSaveStates of CpuIndex-th CPU for Framework driver use. If
  ToRead is specified, the CpuSaveStates will be copied to ToRead, otherwise copied to
  mFrameworkSmst->CpuSaveState[CpuIndex].

  @param[in]      CpuIndex        The zero-based CPU index.
  @param[in, out] ToRead          If not NULL, CpuSaveStates will be copied to it.

**/
VOID
ReadCpuSaveState (
  IN     UINTN                   CpuIndex,
  IN OUT EFI_SMM_CPU_SAVE_STATE  *ToRead
  )
{
  EFI_STATUS Status;
  UINTN Index;
  EFI_SMM_CPU_STATE *State;
  EFI_SMI_CPU_SAVE_STATE *SaveState;

  State = (EFI_SMM_CPU_STATE *)gSmst->CpuSaveState[CpuIndex];
  if (ToRead != NULL) {
    SaveState = &ToRead->Ia32SaveState;
  } else {
    SaveState = &mFrameworkSmst->CpuSaveState[CpuIndex].Ia32SaveState;
  }

  //
  // Note that SMBASE/SMMRevId/IORestart/AutoHALTRestart are in same location in IA32 and X64 CPU Save State Map.
  //
  SaveState->SMBASE = State->x86.SMBASE;
  SaveState->SMMRevId = State->x86.SMMRevId;
  SaveState->IORestart = State->x86.IORestart;
  SaveState->AutoHALTRestart = State->x86.AutoHALTRestart;

  for (Index = 0; Index < sizeof (mCpuSaveStateConvTable) / sizeof (CPU_SAVE_STATE_CONVERSION); Index++) {
    ///
    /// Try to use SMM CPU Protocol to access CPU save states if possible
    ///
    Status = mSmmCpu->ReadSaveState (
                        mSmmCpu,
                        (UINTN)sizeof (UINT32),
                        mCpuSaveStateConvTable[Index].Register,
                        CpuIndex,
                        ((UINT8 *)SaveState) + mCpuSaveStateConvTable[Index].Offset
                        );
    ASSERT_EFI_ERROR (Status);
  }
}

/**
  Write CpuSaveStates from Framework into PI.

  The function writes back CpuSaveStates of CpuIndex-th CPU from PI to Framework. If
  ToWrite is specified, it contains the CpuSaveStates to write from, otherwise CpuSaveStates
  to write from mFrameworkSmst->CpuSaveState[CpuIndex].

  @param[in] CpuIndex      The zero-based CPU index.
  @param[in] ToWrite       If not NULL, CpuSaveStates to write from.

**/
VOID
WriteCpuSaveState (
  IN UINTN                   CpuIndex,
  IN EFI_SMM_CPU_SAVE_STATE  *ToWrite
  )
{
  UINTN                  Index;
  EFI_SMM_CPU_STATE      *State;
  EFI_SMI_CPU_SAVE_STATE *SaveState;

  State = (EFI_SMM_CPU_STATE *)gSmst->CpuSaveState[CpuIndex];

  if (ToWrite != NULL) {
    SaveState = &ToWrite->Ia32SaveState;
  } else {
    SaveState = &mFrameworkSmst->CpuSaveState[CpuIndex].Ia32SaveState;
  }

  //
  // SMMRevId is read-only.
  // Note that SMBASE/IORestart/AutoHALTRestart are in same location in IA32 and X64 CPU Save State Map.
  //
  State->x86.SMBASE = SaveState->SMBASE;
  State->x86.IORestart = SaveState->IORestart;
  State->x86.AutoHALTRestart = SaveState->AutoHALTRestart;
  
  for (Index = 0; Index < sizeof (mCpuSaveStateConvTable) / sizeof (CPU_SAVE_STATE_CONVERSION); Index++) {
    mSmmCpu->WriteSaveState (
               mSmmCpu,
               (UINTN)sizeof (UINT32),
               mCpuSaveStateConvTable[Index].Register,
               CpuIndex,
               ((UINT8 *)SaveState) +
               mCpuSaveStateConvTable[Index].Offset
               );
  }
}

/**
  Read or write a page that contains CpuSaveStates. Read is from PI to Framework.
  Write is from Framework to PI.

  This function reads or writes a page that contains CpuSaveStates. The page contains Framework
  CpuSaveStates. On read, it reads PI style CpuSaveStates and fill the page up. On write, it
  writes back from the page content to PI CpuSaveStates struct.
  The first Framework CpuSaveStates (for CPU 0) is from mFrameworkSmst->CpuSaveState which is
  page aligned. Because Framework CpuSaveStates are continuous, we can know which CPUs' SaveStates
  are in the page start from PageAddress.

  @param[in] PageAddress   The base address for a page.
  @param[in] IsRead        TRUE for Read, FALSE for Write.

**/
VOID
ReadWriteCpuStatePage (
  IN UINT64  PageAddress,
  IN BOOLEAN IsRead
  )
{
  UINTN          FirstSSIndex;   // Index of first CpuSaveState in the page
  UINTN          LastSSIndex;    // Index of last CpuSaveState in the page
  BOOLEAN        FirstSSAligned; // Whether first CpuSaveState is page-aligned
  BOOLEAN        LastSSAligned;  // Whether the end of last CpuSaveState is page-aligned
  UINTN          ClippedSize;
  UINTN          CpuIndex;

  FirstSSIndex = ((UINTN)PageAddress - (UINTN)mFrameworkSmst->CpuSaveState) / sizeof (EFI_SMM_CPU_SAVE_STATE);
  FirstSSAligned = TRUE;
  if (((UINTN)PageAddress - (UINTN)mFrameworkSmst->CpuSaveState) % sizeof (EFI_SMM_CPU_SAVE_STATE) != 0) {
    FirstSSIndex++;
    FirstSSAligned = FALSE;
  }
  LastSSIndex = ((UINTN)PageAddress + SIZE_4KB - (UINTN)mFrameworkSmst->CpuSaveState - 1) / sizeof (EFI_SMM_CPU_SAVE_STATE);
  LastSSAligned = TRUE;
  if (((UINTN)PageAddress + SIZE_4KB - (UINTN)mFrameworkSmst->CpuSaveState) % sizeof (EFI_SMM_CPU_SAVE_STATE) != 0) {
    LastSSIndex--;
    LastSSAligned = FALSE;
  }
  for (CpuIndex = FirstSSIndex; CpuIndex <= LastSSIndex && CpuIndex < mNumberOfProcessors; CpuIndex++) {
    if (IsRead) {
      ReadCpuSaveState (CpuIndex, NULL);
    } else {
      WriteCpuSaveState (CpuIndex, NULL);
    }
  }
  if (!FirstSSAligned) {
    ReadCpuSaveState (FirstSSIndex - 1, mShadowSaveState);
    ClippedSize = (UINTN)&mFrameworkSmst->CpuSaveState[FirstSSIndex] & (SIZE_4KB - 1);
    if (IsRead) {
      CopyMem ((VOID*)(UINTN)PageAddress, (VOID*)((UINTN)(mShadowSaveState + 1) - ClippedSize), ClippedSize);
    } else {
      CopyMem ((VOID*)((UINTN)(mShadowSaveState + 1) - ClippedSize), (VOID*)(UINTN)PageAddress, ClippedSize);
      WriteCpuSaveState (FirstSSIndex - 1, mShadowSaveState);
    }
  }
  if (!LastSSAligned && LastSSIndex + 1 < mNumberOfProcessors) {
    ReadCpuSaveState (LastSSIndex + 1, mShadowSaveState);
    ClippedSize = SIZE_4KB - ((UINTN)&mFrameworkSmst->CpuSaveState[LastSSIndex + 1] & (SIZE_4KB - 1));
    if (IsRead) {
      CopyMem (&mFrameworkSmst->CpuSaveState[LastSSIndex + 1], mShadowSaveState, ClippedSize);
    } else {
      CopyMem (mShadowSaveState, &mFrameworkSmst->CpuSaveState[LastSSIndex + 1], ClippedSize);
      WriteCpuSaveState (LastSSIndex + 1, mShadowSaveState);
    }
  }
}

/**
  The page fault handler that on-demand read PI CpuSaveStates for framework use. If the fault
  is not targeted to mFrameworkSmst->CpuSaveState range, the function will return FALSE to let
  PageFaultHandlerHook know it needs to pass the fault over to original page fault handler.
  
  @retval TRUE     The page fault is correctly handled.
  @retval FALSE    The page fault is not handled and is passed through to original handler.

**/
BOOLEAN
PageFaultHandler (
  VOID
  )
{
  BOOLEAN        IsHandled;
  UINT64         PFAddress;
  UINTN          NumCpuStatePages;
  
  ASSERT (mPageTableHookEnabled);
  AcquireSpinLock (&mPFLock);

  PFAddress = AsmReadCr2 ();
  NumCpuStatePages = EFI_SIZE_TO_PAGES (mNumberOfProcessors * sizeof (EFI_SMM_CPU_SAVE_STATE));
  IsHandled = FALSE;
  if (((UINTN)mFrameworkSmst->CpuSaveState & ~(SIZE_2MB-1)) == (PFAddress & ~(SIZE_2MB-1))) {
    if ((UINTN)mFrameworkSmst->CpuSaveState <= PFAddress &&
        PFAddress < (UINTN)mFrameworkSmst->CpuSaveState + EFI_PAGES_TO_SIZE (NumCpuStatePages)
        ) {
      mCpuStatePageTable[BitFieldRead64 (PFAddress, 12, 20)] |= BIT0 | BIT1; // present and rw
      CpuFlushTlb ();
      ReadWriteCpuStatePage (PFAddress & ~(SIZE_4KB-1), TRUE);
      IsHandled = TRUE;
    } else {
      ASSERT (FALSE);
    }
  }

  ReleaseSpinLock (&mPFLock);
  return IsHandled;
}

/**
  Write back the dirty Framework CpuSaveStates to PI.
  
  The function scans the page table for dirty pages in mFrameworkSmst->CpuSaveState
  to write back to PI CpuSaveStates. It is meant to be called on each SmmBaseHelper SMI
  callback after Framework handler is called.

**/
VOID
WriteBackDirtyPages (
  VOID
  )
{
  UINTN  NumCpuStatePages;
  UINTN  PTIndex;
  UINTN  PTStartIndex;
  UINTN  PTEndIndex;

  NumCpuStatePages = EFI_SIZE_TO_PAGES (mNumberOfProcessors * sizeof (EFI_SMM_CPU_SAVE_STATE));
  PTStartIndex = (UINTN)BitFieldRead64 ((UINT64) (UINTN) mFrameworkSmst->CpuSaveState, 12, 20);
  PTEndIndex   = (UINTN)BitFieldRead64 ((UINT64) (UINTN) mFrameworkSmst->CpuSaveState + EFI_PAGES_TO_SIZE(NumCpuStatePages) - 1, 12, 20);
  for (PTIndex = PTStartIndex; PTIndex <= PTEndIndex; PTIndex++) {
    if ((mCpuStatePageTable[PTIndex] & (BIT0|BIT6)) == (BIT0|BIT6)) { // present and dirty?
      ReadWriteCpuStatePage (mCpuStatePageTable[PTIndex] & mPhyMask, FALSE);
    }
  }
}

/**
  Hook IDT with our page fault handler so that the on-demand paging works on page fault.
  
  The function hooks the IDT with PageFaultHandlerHook to get on-demand paging work for
  PI<->Framework CpuSaveStates marshalling. It also saves original handler for pass-through
  purpose.

**/
VOID
HookPageFaultHandler (
  VOID
  )
{
  IA32_DESCRIPTOR           Idtr;
  IA32_IDT_GATE_DESCRIPTOR  *IdtGateDesc;
  UINT32                    OffsetUpper;
  
  InitializeSpinLock (&mPFLock);
  
  AsmReadIdtr (&Idtr);
  IdtGateDesc = (IA32_IDT_GATE_DESCRIPTOR *) Idtr.Base;
  OffsetUpper = *(UINT32*)((UINT64*)IdtGateDesc + 1);
  mOriginalHandler = (VOID *)(UINTN)(LShiftU64 (OffsetUpper, 32) + IdtGateDesc[14].Bits.OffsetLow + (IdtGateDesc[14].Bits.OffsetHigh << 16));
  IdtGateDesc[14].Bits.OffsetLow = (UINT32)((UINTN)PageFaultHandlerHook & ((1 << 16) - 1));
  IdtGateDesc[14].Bits.OffsetHigh = (UINT32)(((UINTN)PageFaultHandlerHook >> 16) & ((1 << 16) - 1));
}

/**
  Initialize page table for pages contain HookData.
  
  The function initialize PDE for 2MB range that contains HookData. If the related PDE points
  to a 2MB page, a page table will be allocated and initialized for 4KB pages. Otherwise we juse
  use the original page table.

  @param[in] HookData   Based on which to initialize page table.

  @return    The pointer to a Page Table that points to 4KB pages which contain HookData.
**/
UINT64 *
InitCpuStatePageTable (
  IN VOID *HookData
  )
{
  UINTN  Index;
  UINT64 *PageTable;
  UINT64 *Pdpte;
  UINT64 HookAddress;
  UINT64 Pde;
  UINT64 Address;
  
  //
  // Initialize physical address mask
  // NOTE: Physical memory above virtual address limit is not supported !!!
  //
  AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL);
  mPhyMask = LShiftU64 (1, (UINT8)Index) - 1;
  mPhyMask &= (1ull << 48) - EFI_PAGE_SIZE;
  
  HookAddress = (UINT64)(UINTN)HookData;
  PageTable   = (UINT64 *)(UINTN)(AsmReadCr3 () & mPhyMask);
  PageTable = (UINT64 *)(UINTN)(PageTable[BitFieldRead64 (HookAddress, 39, 47)] & mPhyMask);
  PageTable = (UINT64 *)(UINTN)(PageTable[BitFieldRead64 (HookAddress, 30, 38)] & mPhyMask);
  
  Pdpte = (UINT64 *)(UINTN)PageTable;
  Pde = Pdpte[BitFieldRead64 (HookAddress, 21, 29)];
  ASSERT ((Pde & BIT0) != 0); // Present and 2M Page
  
  if ((Pde & BIT7) == 0) { // 4KB Page Directory
    PageTable = (UINT64 *)(UINTN)(Pde & mPhyMask);
  } else {
    ASSERT ((Pde & mPhyMask) == (HookAddress & ~(SIZE_2MB-1))); // 2MB Page Point to HookAddress
    PageTable = AllocatePages (1);
    ASSERT (PageTable != NULL);
    Address = HookAddress & ~(SIZE_2MB-1);
    for (Index = 0; Index < 512; Index++) {
      PageTable[Index] = Address | BIT0 | BIT1; // Present and RW
      Address += SIZE_4KB;
    }
    Pdpte[BitFieldRead64 (HookAddress, 21, 29)] = (UINT64)(UINTN)PageTable | BIT0 | BIT1; // Present and RW
  }
  return PageTable;
}

/**
  Mark all the CpuSaveStates as not present.
  
  The function marks all CpuSaveStates memory range as not present so that page fault can be triggered
  on CpuSaveStates access. It is meant to be called on each SmmBaseHelper SMI callback before Framework
  handler is called.

  @param[in] CpuSaveState   The base of CpuSaveStates.

**/
VOID
HookCpuStateMemory (
  IN EFI_SMM_CPU_SAVE_STATE *CpuSaveState
  )
{
  UINT64 Index;
  UINT64 PTStartIndex;
  UINT64 PTEndIndex;

  PTStartIndex = BitFieldRead64 ((UINTN)CpuSaveState, 12, 20);
  PTEndIndex = BitFieldRead64 ((UINTN)CpuSaveState + mNumberOfProcessors * sizeof (EFI_SMM_CPU_SAVE_STATE) - 1, 12, 20);
  for (Index = PTStartIndex; Index <= PTEndIndex; Index++) {
    mCpuStatePageTable[Index] &= ~(BIT0|BIT5|BIT6); // not present nor accessed nor dirty
  }
}  

/**
  Framework SMST SmmInstallConfigurationTable() Thunk.

  This thunk calls the PI SMM SmmInstallConfigurationTable() and then update the configuration
  table related fields in the Framework SMST because the PI SMM SmmInstallConfigurationTable()
  function may modify these fields.

  @param[in] SystemTable         A pointer to the SMM System Table.
  @param[in] Guid                A pointer to the GUID for the entry to add, update, or remove.
  @param[in] Table               A pointer to the buffer of the table to add.
  @param[in] TableSize           The size of the table to install.

  @retval EFI_SUCCESS            The (Guid, Table) pair was added, updated, or removed.
  @retval EFI_INVALID_PARAMETER  Guid is not valid.
  @retval EFI_NOT_FOUND          An attempt was made to delete a non-existent entry.
  @retval EFI_OUT_OF_RESOURCES   There is not enough memory available to complete the operation.
**/
EFI_STATUS
EFIAPI
SmmInstallConfigurationTable (
  IN EFI_SMM_SYSTEM_TABLE  *SystemTable,
  IN EFI_GUID              *Guid,
  IN VOID                  *Table,
  IN UINTN                 TableSize
  )
{
  EFI_STATUS  Status;
  
  Status = gSmst->SmmInstallConfigurationTable (gSmst, Guid, Table, TableSize);
  if (!EFI_ERROR (Status)) {
    mFrameworkSmst->NumberOfTableEntries = gSmst->NumberOfTableEntries;
    mFrameworkSmst->SmmConfigurationTable = gSmst->SmmConfigurationTable;
  }
  return Status;         
}

/**
  Initialize all the stuff needed for on-demand paging hooks for PI<->Framework
  CpuSaveStates marshalling.

  @param[in] FrameworkSmst   Framework SMM system table pointer.

**/
VOID
InitHook (
  IN EFI_SMM_SYSTEM_TABLE  *FrameworkSmst
  )
{
  UINTN                 NumCpuStatePages;
  UINTN                 CpuStatePage;
  UINTN                 Bottom2MPage;
  UINTN                 Top2MPage;
  
  mPageTableHookEnabled = FALSE;
  NumCpuStatePages = EFI_SIZE_TO_PAGES (mNumberOfProcessors * sizeof (EFI_SMM_CPU_SAVE_STATE));
  //
  // Only hook page table for X64 image and less than 2MB needed to hold all CPU Save States
  //
  if (EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_X64) && NumCpuStatePages <= EFI_SIZE_TO_PAGES (SIZE_2MB)) {
    //
    // Allocate double page size to make sure all CPU Save States are in one 2MB page.
    //
    CpuStatePage = (UINTN)AllocatePages (NumCpuStatePages * 2);
    ASSERT (CpuStatePage != 0);
    Bottom2MPage = CpuStatePage & ~(SIZE_2MB-1);
    Top2MPage    = (CpuStatePage + EFI_PAGES_TO_SIZE (NumCpuStatePages * 2) - 1) & ~(SIZE_2MB-1);
    if (Bottom2MPage == Top2MPage ||
        CpuStatePage + EFI_PAGES_TO_SIZE (NumCpuStatePages * 2) - Top2MPage >= EFI_PAGES_TO_SIZE (NumCpuStatePages)
        ) {
      //
      // If the allocated 4KB pages are within the same 2MB page or higher portion is larger, use higher portion pages.
      //
      FrameworkSmst->CpuSaveState = (EFI_SMM_CPU_SAVE_STATE *)(CpuStatePage + EFI_PAGES_TO_SIZE (NumCpuStatePages));
      FreePages ((VOID*)CpuStatePage, NumCpuStatePages);
    } else {
      FrameworkSmst->CpuSaveState = (EFI_SMM_CPU_SAVE_STATE *)CpuStatePage;
      FreePages ((VOID*)(CpuStatePage + EFI_PAGES_TO_SIZE (NumCpuStatePages)), NumCpuStatePages);
    }
    //
    // Add temporary working buffer for hooking
    //
    mShadowSaveState = (EFI_SMM_CPU_SAVE_STATE*) AllocatePool (sizeof (EFI_SMM_CPU_SAVE_STATE));
    ASSERT (mShadowSaveState != NULL);
    //
    // Allocate and initialize 4KB Page Table for hooking CpuSaveState.
    // Replace the original 2MB PDE with new 4KB page table.
    //
    mCpuStatePageTable = InitCpuStatePageTable (FrameworkSmst->CpuSaveState);
    //
    // Mark PTE for CpuSaveState as non-exist.
    //
    HookCpuStateMemory (FrameworkSmst->CpuSaveState);
    HookPageFaultHandler ();
    CpuFlushTlb ();
    mPageTableHookEnabled = TRUE;
  }
  mHookInitialized = TRUE;
}

/**
  Construct a Framework SMST based on the PI SMM SMST.

  @return  Pointer to the constructed Framework SMST.
**/
EFI_SMM_SYSTEM_TABLE *
ConstructFrameworkSmst (
  VOID
  )
{
  EFI_SMM_SYSTEM_TABLE  *FrameworkSmst;

  FrameworkSmst = (EFI_SMM_SYSTEM_TABLE  *)AllocatePool (sizeof (EFI_SMM_SYSTEM_TABLE));
  ASSERT (FrameworkSmst != NULL);

  ///
  /// Copy same things from PI SMST to Framework SMST
  ///
  CopyMem (FrameworkSmst, gSmst, (UINTN)(&((EFI_SMM_SYSTEM_TABLE *)0)->SmmIo));
  CopyMem (
    &FrameworkSmst->SmmIo, 
    &gSmst->SmmIo,
    sizeof (EFI_SMM_SYSTEM_TABLE) - (UINTN)(&((EFI_SMM_SYSTEM_TABLE *)0)->SmmIo)
    );

  ///
  /// Update Framework SMST
  ///
  FrameworkSmst->Hdr.Revision = EFI_SMM_SYSTEM_TABLE_REVISION;
  CopyGuid (&FrameworkSmst->EfiSmmCpuIoGuid, &mEfiSmmCpuIoGuid);

  mHookInitialized = FALSE;
  FrameworkSmst->CpuSaveState = (EFI_SMM_CPU_SAVE_STATE *)AllocateZeroPool (mNumberOfProcessors * sizeof (EFI_SMM_CPU_SAVE_STATE));
  ASSERT (FrameworkSmst->CpuSaveState != NULL);

  ///
  /// Do not support floating point state now
  ///
  FrameworkSmst->CpuOptionalFloatingPointState = NULL;

  FrameworkSmst->SmmInstallConfigurationTable = SmmInstallConfigurationTable;

  return FrameworkSmst;
}

/**
  Load a given Framework SMM driver into SMRAM and invoke its entry point.

  @param[in]   ParentImageHandle     Parent Image Handle.
  @param[in]   FilePath              Location of the image to be installed as the handler.
  @param[in]   SourceBuffer          Optional source buffer in case the image file
                                     is in memory.
  @param[in]   SourceSize            Size of the source image file, if in memory.
  @param[out]  ImageHandle           The handle that the base driver uses to decode 
                                     the handler. Unique among SMM handlers only, 
                                     not unique across DXE/EFI.

  @retval      EFI_SUCCESS           The operation was successful.
  @retval      EFI_OUT_OF_RESOURCES  There were no additional SMRAM resources to load the handler
  @retval      EFI_UNSUPPORTED       Can not find its copy in normal memory.
  @retval      EFI_INVALID_PARAMETER The handlers was not the correct image type
**/
EFI_STATUS
LoadImage (
  IN      EFI_HANDLE                ParentImageHandle,
  IN      EFI_DEVICE_PATH_PROTOCOL  *FilePath,
  IN      VOID                      *SourceBuffer,
  IN      UINTN                     SourceSize,
  OUT     EFI_HANDLE                *ImageHandle
  )
{
  EFI_STATUS            Status;
  UINTN                 PageCount;
  UINTN                 OrgPageCount;
  EFI_PHYSICAL_ADDRESS  DstBuffer;

  if (FilePath == NULL || ImageHandle == NULL) {    
    return EFI_INVALID_PARAMETER;
  }

  PageCount = 1;
  do {
    OrgPageCount = PageCount;
    DstBuffer = (UINTN)-1;
    Status = gSmst->SmmAllocatePages (
                      AllocateMaxAddress,
                      EfiRuntimeServicesCode,
                      PageCount,
                      &DstBuffer
                      );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = mLoadPe32Image->LoadPeImage (
                               mLoadPe32Image,
                               ParentImageHandle,
                               FilePath,
                               SourceBuffer,
                               SourceSize,
                               DstBuffer,
                               &PageCount,
                               ImageHandle,
                               NULL,
                               EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE
                               );
    if (EFI_ERROR (Status)) {
      FreePages ((VOID *)(UINTN)DstBuffer, OrgPageCount);
    }
  } while (Status == EFI_BUFFER_TOO_SMALL);

  if (!EFI_ERROR (Status)) {
    ///
    /// Update MP state in Framework SMST before transferring control to Framework SMM driver entry point
    ///
    mFrameworkSmst->SmmStartupThisAp      = gSmst->SmmStartupThisAp;
    mFrameworkSmst->NumberOfCpus          = mNumberOfProcessors;
    mFrameworkSmst->CurrentlyExecutingCpu = gSmst->CurrentlyExecutingCpu;

    RegisterSmramProfileImage (FilePath, DstBuffer, PageCount);
    Status = gBS->StartImage (*ImageHandle, NULL, NULL);
    if (EFI_ERROR (Status)) {
      UnregisterSmramProfileImage (FilePath, DstBuffer, PageCount);
      mLoadPe32Image->UnLoadPeImage (mLoadPe32Image, *ImageHandle);
      *ImageHandle = NULL;
      FreePages ((VOID *)(UINTN)DstBuffer, PageCount);
    }
  }

  return Status;
}

/** 
  Thunk service of EFI_SMM_BASE_PROTOCOL.Register().

  @param[in, out] FunctionData  Pointer to SMMBASE_FUNCTION_DATA.
**/
VOID
Register (
  IN OUT SMMBASE_FUNCTION_DATA *FunctionData
  )
{
  EFI_STATUS Status;

  if (mLocked || FunctionData->Args.Register.LegacyIA32Binary) {
    Status = EFI_UNSUPPORTED;
  } else {
    Status = LoadImage (
               FunctionData->SmmBaseImageHandle,
               FunctionData->Args.Register.FilePath,
               FunctionData->Args.Register.SourceBuffer,
               FunctionData->Args.Register.SourceSize,
               FunctionData->Args.Register.ImageHandle
               );
  }
  FunctionData->Status = Status;
}

/** 
  Thunk service of EFI_SMM_BASE_PROTOCOL.UnRegister().

  @param[in, out] FunctionData  Pointer to SMMBASE_FUNCTION_DATA.
**/
VOID
UnRegister (
  IN OUT SMMBASE_FUNCTION_DATA *FunctionData
  )
{
  ///
  /// Unregister not supported now
  ///
  FunctionData->Status = EFI_UNSUPPORTED;
}

/**
  Search for Framework SMI handler information according to specific PI SMM dispatch handle.

  @param[in] DispatchHandle  The unique handle assigned by SmiHandlerRegister().  

  @return  Pointer to CALLBACK_INFO. If NULL, no callback info record is found.
**/
CALLBACK_INFO *
GetCallbackInfo (
  IN EFI_HANDLE  DispatchHandle
  )
{
  LIST_ENTRY  *Node;

  Node = GetFirstNode (&mCallbackInfoListHead);
  while (!IsNull (&mCallbackInfoListHead, Node)) {
    if (((CALLBACK_INFO *)Node)->DispatchHandle == DispatchHandle) {
      return (CALLBACK_INFO *)Node;
    }
    Node = GetNextNode (&mCallbackInfoListHead, Node);
  }
  return NULL;
}

/**
  Callback thunk for Framework SMI handler.

  This thunk functions calls the Framework SMI handler and converts the return value
  defined from Framework SMI handlers to a correpsonding return value defined by PI SMM.

  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
  @param[in]     Context         Points to an optional handler context which was specified when the
                                 handler was registered.
  @param[in, out] CommBuffer      A pointer to a collection of data in memory that will
                                 be conveyed from a non-SMM environment into an SMM environment.
  @param[in, out] CommBufferSize  The size of the CommBuffer.

  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers 
                                              should still be called.
  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should 
                                              still be called.
  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still 
                                              be called.
  @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.
**/
EFI_STATUS
EFIAPI
CallbackThunk (
  IN EFI_HANDLE  DispatchHandle,
  IN CONST VOID  *Context         OPTIONAL,
  IN OUT VOID    *CommBuffer      OPTIONAL,
  IN OUT UINTN   *CommBufferSize  OPTIONAL
  )
{
  EFI_STATUS        Status;
  CALLBACK_INFO     *CallbackInfo;
  UINTN             CpuIndex;

  ///
  /// Before transferring the control into the Framework SMI handler, update CPU Save States
  /// and MP states in the Framework SMST.
  ///

  if (!mHookInitialized) {
    InitHook (mFrameworkSmst);
  }
  if (mPageTableHookEnabled) {
    HookCpuStateMemory (mFrameworkSmst->CpuSaveState);
    CpuFlushTlb ();
  } else {
    for (CpuIndex = 0; CpuIndex < mNumberOfProcessors; CpuIndex++) {
      ReadCpuSaveState (CpuIndex, NULL);
    }
  }

  mFrameworkSmst->SmmStartupThisAp      = gSmst->SmmStartupThisAp;
  mFrameworkSmst->NumberOfCpus          = mNumberOfProcessors;
  mFrameworkSmst->CurrentlyExecutingCpu = gSmst->CurrentlyExecutingCpu;

  ///
  /// Search for Framework SMI handler information
  ///
  CallbackInfo = GetCallbackInfo (DispatchHandle);
  ASSERT (CallbackInfo != NULL);

  ///
  /// Thunk into original Framwork SMI handler
  ///
  Status = (CallbackInfo->CallbackAddress) (
                            CallbackInfo->SmmImageHandle,
                            CallbackInfo->CommunicationBuffer,
                            CallbackInfo->SourceSize
                            );
  ///
  /// Save CPU Save States in case any of them was modified
  ///
  if (mPageTableHookEnabled) {
    WriteBackDirtyPages ();
  } else {
    for (CpuIndex = 0; CpuIndex < mNumberOfProcessors; CpuIndex++) {
      WriteCpuSaveState (CpuIndex, NULL);
    }
  }

  ///
  /// Conversion of returned status code
  ///
  switch (Status) {
    case EFI_HANDLER_SUCCESS:
      Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
      break;
    case EFI_HANDLER_CRITICAL_EXIT:
    case EFI_HANDLER_SOURCE_QUIESCED:
      Status = EFI_SUCCESS;
      break;
    case EFI_HANDLER_SOURCE_PENDING:
      Status = EFI_WARN_INTERRUPT_SOURCE_PENDING;
      break;
  }
  return Status;
}

/** 
  Thunk service of EFI_SMM_BASE_PROTOCOL.RegisterCallback().

  @param[in, out] FunctionData  Pointer to SMMBASE_FUNCTION_DATA.
**/
VOID
RegisterCallback (
  IN OUT SMMBASE_FUNCTION_DATA  *FunctionData
  )
{
  CALLBACK_INFO  *Buffer;

  if (mLocked) {
    FunctionData->Status = EFI_UNSUPPORTED;
    return;
  }

  ///
  /// Note that MakeLast and FloatingPointSave options are not supported in PI SMM
  ///

  ///
  /// Allocate buffer for callback thunk information
  ///
  Buffer = (CALLBACK_INFO *)AllocateZeroPool (sizeof (CALLBACK_INFO));
  if (Buffer == NULL) {
    FunctionData->Status = EFI_OUT_OF_RESOURCES;
    return;
  }

  ///
  /// Fill SmmImageHandle and CallbackAddress into the thunk
  ///
  Buffer->SmmImageHandle = FunctionData->Args.RegisterCallback.SmmImageHandle;
  Buffer->CallbackAddress = FunctionData->Args.RegisterCallback.CallbackAddress;

  ///
  /// Register the thunk code as a root SMI handler
  ///
  FunctionData->Status = gSmst->SmiHandlerRegister (
                                  CallbackThunk,
                                  NULL,
                                  &Buffer->DispatchHandle
                                  );
  if (EFI_ERROR (FunctionData->Status)) {
    FreePool (Buffer);
    return;
  }

  ///
  /// Save this callback info
  ///
  InsertTailList (&mCallbackInfoListHead, &Buffer->Link);
}


/** 
  Thunk service of EFI_SMM_BASE_PROTOCOL.SmmAllocatePool().

  @param[in, out] FunctionData  Pointer to SMMBASE_FUNCTION_DATA.
**/
VOID
HelperAllocatePool (
  IN OUT SMMBASE_FUNCTION_DATA *FunctionData
  )
{
  if (mLocked) {
    FunctionData->Status =  EFI_UNSUPPORTED;
  } else {
    FunctionData->Status = gSmst->SmmAllocatePool (
                                    FunctionData->Args.AllocatePool.PoolType,
                                    FunctionData->Args.AllocatePool.Size,
                                    FunctionData->Args.AllocatePool.Buffer
                                    );
  }
}

/** 
  Thunk service of EFI_SMM_BASE_PROTOCOL.SmmFreePool().

  @param[in, out] FunctionData  Pointer to SMMBASE_FUNCTION_DATA.
**/
VOID
HelperFreePool (
  IN OUT SMMBASE_FUNCTION_DATA *FunctionData
  )
{
  if (mLocked) {
    FunctionData->Status =  EFI_UNSUPPORTED;
  } else {
    FreePool (FunctionData->Args.FreePool.Buffer);
    FunctionData->Status = EFI_SUCCESS;
  }
}

/** 
  Thunk service of EFI_SMM_BASE_PROTOCOL.Communicate().

  @param[in, out] FunctionData  Pointer to SMMBASE_FUNCTION_DATA.
**/
VOID
HelperCommunicate (
  IN OUT SMMBASE_FUNCTION_DATA *FunctionData
  )
{
  LIST_ENTRY     *Node;
  CALLBACK_INFO  *CallbackInfo;

  if (FunctionData->Args.Communicate.CommunicationBuffer == NULL) {
    FunctionData->Status = EFI_INVALID_PARAMETER;
    return;
  }

  Node = GetFirstNode (&mCallbackInfoListHead);
  while (!IsNull (&mCallbackInfoListHead, Node)) {
    CallbackInfo = (CALLBACK_INFO *)Node;

    if (FunctionData->Args.Communicate.ImageHandle == CallbackInfo->SmmImageHandle) {
      CallbackInfo->CommunicationBuffer = FunctionData->Args.Communicate.CommunicationBuffer;
      CallbackInfo->SourceSize          = FunctionData->Args.Communicate.SourceSize;

      ///
      /// The message was successfully posted.
      ///
      FunctionData->Status = EFI_SUCCESS;
      return;
    }
    Node = GetNextNode (&mCallbackInfoListHead, Node);
  }

  FunctionData->Status = EFI_INVALID_PARAMETER;
}

/**
  Communication service SMI Handler entry.

  This SMI handler provides services for the SMM Base Thunk driver.

  Caution: This function may receive untrusted input during runtime.
  The communicate buffer is external input, so this function will do operations only if the communicate
  buffer is outside of SMRAM so that returning the status code in the buffer won't overwrite anywhere in SMRAM.

  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
  @param[in]     RegisterContext Points to an optional handler context which was specified when the
                                 handler was registered.
  @param[in, out] CommBuffer      A pointer to a collection of data in memory that will
                                 be conveyed from a non-SMM environment into an SMM environment.
  @param[in, out] CommBufferSize  The size of the CommBuffer.

  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers 
                                              should still be called.
  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should 
                                              still be called.
  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still 
                                              be called.
  @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.
**/
EFI_STATUS
EFIAPI
SmmHandlerEntry (
  IN     EFI_HANDLE               DispatchHandle,
  IN     CONST VOID               *RegisterContext,
  IN OUT VOID                     *CommBuffer,
  IN OUT UINTN                    *CommBufferSize
  )
{
  SMMBASE_FUNCTION_DATA *FunctionData;

  ASSERT (CommBuffer != NULL);
  ASSERT (CommBufferSize != NULL);

  if (*CommBufferSize == sizeof (SMMBASE_FUNCTION_DATA) &&
      SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer, (UINT64)*CommBufferSize)) {
    FunctionData = (SMMBASE_FUNCTION_DATA *)CommBuffer;

    switch (FunctionData->Function) {
      case SmmBaseFunctionRegister:
        Register (FunctionData);
        break;
      case SmmBaseFunctionUnregister:
        UnRegister (FunctionData);
        break;
      case SmmBaseFunctionRegisterCallback:
        RegisterCallback (FunctionData);
        break;
      case SmmBaseFunctionAllocatePool:
        HelperAllocatePool (FunctionData);
        break;
      case SmmBaseFunctionFreePool:
        HelperFreePool (FunctionData);
        break;
      case SmmBaseFunctionCommunicate:
        HelperCommunicate (FunctionData);
        break;
      default:
        DEBUG ((EFI_D_WARN, "SmmBaseHelper: invalid SMM Base function.\n"));
        FunctionData->Status = EFI_UNSUPPORTED;
    }
  }
  return EFI_SUCCESS;
}

/**
  Smm Ready To Lock event notification handler.

  It sets a flag indicating that SMRAM has been locked.
  
  @param[in] Protocol   Points to the protocol's unique identifier.
  @param[in] Interface  Points to the interface instance.
  @param[in] Handle     The handle on which the interface was installed.

  @retval EFI_SUCCESS   Notification handler runs successfully.
 **/
EFI_STATUS
EFIAPI
SmmReadyToLockEventNotify (
  IN CONST EFI_GUID  *Protocol,
  IN VOID            *Interface,
  IN EFI_HANDLE      Handle
  )
{
  mLocked = TRUE;
  return EFI_SUCCESS;
}

/**
  Entry point function of the SMM Base Helper SMM driver.

  @param[in] ImageHandle  The firmware allocated handle for the EFI image.  
  @param[in] SystemTable  A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS     The entry point is executed successfully.
  @retval other           Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
SmmBaseHelperMain (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  EFI_MP_SERVICES_PROTOCOL   *MpServices;
  EFI_HANDLE                 Handle;
  UINTN                      NumberOfEnabledProcessors;
  VOID                       *Registration;
  
  Handle = NULL;
  ///
  /// Locate SMM CPU Protocol which is used later to retrieve/update CPU Save States
  ///
  Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **) &mSmmCpu);
  ASSERT_EFI_ERROR (Status);

  ///
  /// Locate PE32 Image Protocol which is used later to load Framework SMM driver
  ///
  Status = SystemTable->BootServices->LocateProtocol (&gEfiLoadPeImageProtocolGuid, NULL, (VOID **) &mLoadPe32Image);
  ASSERT_EFI_ERROR (Status);

  //
  // Get MP Services Protocol
  //
  Status = SystemTable->BootServices->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices);
  ASSERT_EFI_ERROR (Status);

  //
  // Use MP Services Protocol to retrieve the number of processors and number of enabled processors
  //
  Status = MpServices->GetNumberOfProcessors (MpServices, &mNumberOfProcessors, &NumberOfEnabledProcessors);
  ASSERT_EFI_ERROR (Status);
  
  ///
  /// Interface structure of SMM BASE Helper Ready Protocol is allocated from UEFI pool
  /// instead of SMM pool so that SMM Base Thunk driver can access it in Non-SMM mode.
  ///
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  sizeof (EFI_SMM_BASE_HELPER_READY_PROTOCOL),
                  (VOID **)&mSmmBaseHelperReady
                  );
  ASSERT_EFI_ERROR (Status);

  ///
  /// Construct Framework SMST from PI SMST
  ///
  mFrameworkSmst = ConstructFrameworkSmst ();
  mSmmBaseHelperReady->FrameworkSmst = mFrameworkSmst;
  mSmmBaseHelperReady->ServiceEntry = SmmHandlerEntry;

  //
  // Register SMM Ready To Lock Protocol notification
  //
  Status = gSmst->SmmRegisterProtocolNotify (
                    &gEfiSmmReadyToLockProtocolGuid,
                    SmmReadyToLockEventNotify,
                    &Registration
                    );
  ASSERT_EFI_ERROR (Status);

  ///
  /// Register SMM Base Helper services for SMM Base Thunk driver
  ///
  Status = gSmst->SmiHandlerRegister (SmmHandlerEntry, &gEfiSmmBaseThunkCommunicationGuid, &mDispatchHandle);
  ASSERT_EFI_ERROR (Status);

  ///
  /// Install EFI SMM Base Helper Protocol in the UEFI handle database
  ///
  Status = gBS->InstallProtocolInterface (
                  &Handle,
                  &gEfiSmmBaseHelperReadyProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  mSmmBaseHelperReady
                  );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

