Beispiel #1
0
/**
  Display the forbid load device path list (mAccessInfo.LoadForbid).

**/
VOID
DisplayLoadForbid (
  VOID
  )
{
  UINTN                     Offset;
  UINTN                     DPSize;
  UINTN                     Index;
  EFI_DEVICE_PATH_PROTOCOL  *Dp;
  VOID                      *StartOpCodeHandle;
  VOID                      *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL        *StartLabel;
  EFI_IFR_GUID_LABEL        *EndLabel;

  //
  // Initialize the container for dynamic opcodes.
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode.
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                        StartOpCodeHandle,
                                        &gEfiIfrTianoGuid,
                                        NULL,
                                        sizeof (EFI_IFR_GUID_LABEL)
                                        );
  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number        = LABLE_FORBID_LOAD_FUNC;

  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                      EndOpCodeHandle,
                                      &gEfiIfrTianoGuid,
                                      NULL,
                                      sizeof (EFI_IFR_GUID_LABEL)
                                      );
  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number        = LABEL_END;

  //
  // Add each forbid load drivers.
  //
  Offset  = 0;
  Index   = 0;
  while (Offset < mAccessInfo.LoadForbidLen) {
    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset);
    DPSize  = GetDevicePathSize (Dp);
    AddDevicePath (
      KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index,
      Dp,
      StartOpCodeHandle
      );
    Index++;
    Offset += DPSize;
  }

  HiiUpdateForm (
    mCallbackInfo->HiiHandle, // HII handle
    &gUserProfileManagerGuid, // Formset GUID
    FORMID_FORBID_LOAD_DP,    // Form ID
    StartOpCodeHandle,        // Label for where to insert opcodes
    EndOpCodeHandle           // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}
EFI_STATUS
EFIAPI
AmdRasSmmDxeDriverEntryPoint (
  IN       EFI_HANDLE        ImageHandle,
  IN       EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                      Status;
  BOOLEAN                         InSmm;
  EFI_HANDLE                      hNrthBrdgError = NULL;
  EFI_SMM_BASE_PROTOCOL           *SmmBase = NULL;
  EFI_LOADED_IMAGE_PROTOCOL       *LoadedImage = NULL;
  EFI_DEVICE_PATH_PROTOCOL        *ImageDevicePath = NULL;
  EFI_DEVICE_PATH_PROTOCOL        *NewFilePath = NULL;
  AMD_RAS_DXE_INTERFACE_PROTOCOL  *RasIntProtocol = NULL;
  SMM_SETUP_CONFIG                SmmSetupCfg;


  // Initialize Global Variables
  Status = InitializeRasRuntime (
                                 ImageHandle,          // IN EFI_HANDLE
                                 SystemTable           // IN EFI_SYSTEM_TABLE
                                 );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;          // Error detected while trying to locate SMM Base Protocol
  }

  // Locate SMM Base Protocol
  Status  = gBS->LocateProtocol (
                                 &gEfiSmmBaseProtocolGuid, // IN EFI_GUID Published unique identifier of requested protocol GUID to locate
                                 NULL,                     // IN VOID* Published unique identifier of requested protocol GUID
                                 &SmmBase                  // OUT VOID** Returns address of pointer for SMM Base protocol interface
                                 );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;          // Error detected while trying to locate SMM Base Protocol
  }

  // Save the SMM Base system table pointer
  SmmBase->GetSmstLocation (SmmBase, &gSmst);

  // Determine if we are in SMM or not
  SmmBase->InSmm (SmmBase, &InSmm);

  if (!InSmm) {
    //
    // Not in SMM so load this driver's SMM image to memory
    //
    // Configure Northbridge Interrupt Event to make an I/O Write to SMI Command Port in the
    // Southbridge and cause a Software SMI for which we will handle in the NbSmiHandler
    // SMI service routine.
    Status = ConfigNbSmiProcessing ();

    // Query image handle to see if it supports a requested protocol and then get an address of the protocol image to be loaded
    Status = gBS->HandleProtocol (
                                  ImageHandle,                   // Handle of requested protocol
                                  &gEfiLoadedImageProtocolGuid,  // Published unique identifier of requested protocol GUID
                                  (VOID*)&LoadedImage            // Returns address of pointer for requested protocol interface of the image
                                  );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;            // Error detected while trying to query LoadImage protocol
    }

    // Query device handle of loaded image to see if it supports a requested protocol and then get an address of the prototocl device path
    Status = gBS->HandleProtocol (
                                  LoadedImage->DeviceHandle,   // Handle of requested protocol
                                  &gEfiDevicePathProtocolGuid, // Published unique identifier of requested protocol GUID
                                  (VOID*)&ImageDevicePath      // Returns address of pointer for requested protocol interface
                                  );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;
    }

    // Add this image's device path to the loaded image device path image and return
    // a pointer to the new file path.
    NewFilePath = AddDevicePath (
                                 ImageDevicePath,      // IN EFI_DEVICE_PATH_PROTOCOL
                                 LoadedImage->FilePath // IN EFI_DEVICE_PATH_PROTOCOL Device Path Image to add
                                 );

    //Load the image in System Management RAM; it will automatically generate SMI.
    Status = SmmBase->Register (
                                SmmBase,         // IN *This Addreess of pointer for SMM Base protocol interface)
                                NewFilePath,     // IN EFI_DEVICE_PATH_PROTOCOL
                                NULL,            // IN SourceBuffer OPTIONAL
                                0,               // IN SourceSize OPTIONAL
                                &hNrthBrdgError, // OUT *ImageHandle
                                FALSE            // IN LegacyIA32Binary OPTIONAL
                                );

    // Free up residual heap memory if not equal to NULL
    if (NewFilePath) {
         gBS->FreePool (NewFilePath);
    }
  } else {
    // We are in SMM

    //
    // Callout to use platform-specific Setup
    //
    Status = AmdRasSmmCallout (ECC_HNDLR_CALLOUT_ID, &SmmSetupCfg);

    if (EFI_ERROR (Status)) {
      SmmSetupCfg.EccHandlerEnable = FALSE;   //Load default value = ECC Disabled
    }

    // Enable / Disable RAS MCA ECC Support
    if (SmmSetupCfg.EccHandlerEnable == TRUE) {
      // Callback to execute from within SMM, error occurs if called from Boot Services mode
      Status = SmmBase->RegisterCallback (
                                          SmmBase,        // IN *This
                                          ImageHandle,    // IN SmmImageHandle
                                          MC4SmmHandler,  // IN EFI SMM Dispatcher Callback Entry Point Address
                                          FALSE,          // IN Makelast (SMM Dispatcher should call this handler last) OPTIONAL
                                          FALSE           // IN FloatingPointSave OPTIONAL
                                          );
      if (EFI_ERROR (Status)) {
        ASSERT_EFI_ERROR (Status);
        return Status;
      }

      // Update Global Varibles for this driver
      Status = UpdateGlobalVars ();
      if (EFI_ERROR (Status)) {
        ASSERT_EFI_ERROR (Status);
        return Status;
      }
    }  //End-- Enable / Disable ECC Handler Support
  } // End-- if(!InSmm)

  if (!InSmm) {
    // Allocate memory for a new protocol structure
    Status = gBS->AllocatePool (
                                EfiBootServicesData,
                                sizeof (AMD_RAS_DXE_INTERFACE_PROTOCOL),
                                &RasIntProtocol
                                );

    if (RasIntProtocol == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    // Zero out memory buffer
    EfiCommonLibZeroMem (
                         RasIntProtocol,
                         sizeof (AMD_RAS_DXE_INTERFACE_PROTOCOL)
                         );

    // Locate AMD RAS Interface Protocol
    Status  = gBS->LocateProtocol (
                                   &gAmdRasDxeInterfaceProtocolGuid,  // IN EFI_GUID Published unique identifier of requested protocol GUID to locate
                                   NULL,                              // IN VOID* Published unique identifier of requested protocol GUID
                                   (VOID **)&RasIntProtocol           // OUT VOID** Returns address of pointer for SMM Base protocol interface
                                   );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_SUCCESS;         // Error detected while trying to locate RAS Interface Protocol
    }

    // Callout to get ECC Threshold BIOS Setup option config.
    Status = AmdRasSmmCallout (ECC_THRESH_COUNTER_CALLOUT_ID, &SmmSetupCfg);

    if (EFI_ERROR (Status)) {
      gRasNbCorrMemConfig.ThreshLimit = 0xFFE;   // Load default value = threshold value of 1 (1's complement)
    } else {
      gRasNbCorrMemConfig.ThreshLimit = SmmSetupCfg.DramErrorThreshold;
    }

    // Callout to get RAS Handle Type BIOS Setup option config.
    Status = AmdRasSmmCallout (RAS_HANDLE_CALLOUT_ID, &SmmSetupCfg);

    if (EFI_ERROR (Status)) {
        gRasNbCorrMemConfig.DevCommon.ErrorMonitorType = APIC;    // Default to APIC interrupt = 1 on error
    } else {
      if (SmmSetupCfg.RasHandleType == 1) {
        gRasNbCorrMemConfig.DevCommon.ErrorMonitorType = APIC;    // APIC interrupt = 1
      }
    }

    // Configure Correctable Memory Error Operation
    Status = RasIntProtocol->AmdSetErrorConfigDevice (
                                                      RasIntProtocol,                          // IN *This
                                                      gRasNbCorrMemConfig.DevCommon.DeviceID,  // IN UINTN (enum AMD_RAS_DEVICE_ID)
                                                      (VOID*) &gRasNbCorrMemConfig             // IN OUT VOID* RAS Device Struct
                                                      );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_SUCCESS;       // Error detected while trying to locate SMM Base Protocol
    }

    // Configure UnCorrectable Memory Error Operation
    Status = RasIntProtocol->AmdSetErrorConfigDevice (
                                                      RasIntProtocol,                            // IN *This
                                                      gRasNbUnCorrMemConfig.DevCommon.DeviceID,  // IN UINTN (enum AMD_RAS_DEVICE_ID)
                                                      (VOID*) &gRasNbUnCorrMemConfig             // IN OUT VOID* RAS Device Struct
                                                      );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_SUCCESS;       // Error detected while trying to locate SMM Base Protocol
    }
  } // End-- if (!InSmm)

  return Status;
}
Beispiel #3
0
/**
  Display the permit load device path in the loadable device path list.

**/
VOID
DisplayLoadPermit(
  VOID
  )
{
  EFI_STATUS          Status;
  CHAR16              *Order;
  UINTN               OrderSize;
  UINTN               ListCount;
  UINTN               Index;
  UINT8               *Var;
  UINT8               *VarPtr;
  CHAR16              VarName[12];
  VOID                *StartOpCodeHandle;
  VOID                *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL  *StartLabel;
  EFI_IFR_GUID_LABEL  *EndLabel;

  //
  // Get DriverOrder.
  //
  OrderSize = 0;
  Status    = gRT->GetVariable (
                     L"DriverOrder", 
                     &gEfiGlobalVariableGuid, 
                     NULL, 
                     &OrderSize, 
                     NULL
                     );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return ;
  }

  Order = AllocateZeroPool (OrderSize);
  if (Order == NULL) {
    return ;
  }

  Status = gRT->GetVariable (
                  L"DriverOrder", 
                  &gEfiGlobalVariableGuid, 
                  NULL, 
                  &OrderSize, 
                  Order
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }
  
  //
  // Initialize the container for dynamic opcodes.
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode.
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                        StartOpCodeHandle,
                                        &gEfiIfrTianoGuid,
                                        NULL,
                                        sizeof (EFI_IFR_GUID_LABEL)
                                        );
  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number        = LABEL_PERMIT_LOAD_FUNC;

  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                      EndOpCodeHandle,
                                      &gEfiIfrTianoGuid,
                                      NULL,
                                      sizeof (EFI_IFR_GUID_LABEL)
                                      );
  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number        = LABEL_END;

  //
  // Add each driver option.
  //
  Var       = NULL;
  ListCount = OrderSize / sizeof (UINT16);
  for (Index = 0; Index < ListCount; Index++) {
    //
    // Get driver device path.
    //
    UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]);
    Var = GetEfiGlobalVariable (VarName);
    if (Var == NULL) {
      continue;
    }
    
    //
    // Check whether the driver is already forbidden.
    //
    
    VarPtr = Var;
    //
    // Skip attribute.
    //
    VarPtr += sizeof (UINT32);

    //
    // Skip device path lenth.
    //
    VarPtr += sizeof (UINT16);

    //
    // Skip descript string.
    //
    VarPtr += StrSize ((UINT16 *) VarPtr);

    if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) {
      FreePool (Var);
      Var = NULL;
      continue;
    }

    AddDevicePath (
      KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index],
      (EFI_DEVICE_PATH_PROTOCOL *) VarPtr,
      StartOpCodeHandle
      );
    FreePool (Var);
    Var = NULL;
  }

  HiiUpdateForm (
    mCallbackInfo->HiiHandle, // HII handle
    &gUserProfileManagerGuid, // Formset GUID
    FORMID_PERMIT_LOAD_DP,    // Form ID
    StartOpCodeHandle,        // Label for where to insert opcodes
    EndOpCodeHandle           // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  //
  // Clear Environment.
  //
  if (Var != NULL) {
    FreePool (Var);
  }
  FreePool (Order);
}
EFI_STATUS
EFIAPI
AmdRasApeiDxeDriverEntryPoint (
  IN   EFI_HANDLE        ImageHandle,
  IN   EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                      Status = EFI_SUCCESS;
  EFI_HANDLE                      Handle = NULL;
  EFI_HANDLE                      hEinj = NULL;
  AMD_RAS_APEI_PROTOCOL           *AmdRasApeiProtocol;
  BOOLEAN                         InSmm;
  EFI_SMM_BASE_PROTOCOL           *SmmBase = NULL;
  EFI_DEVICE_PATH_PROTOCOL        *ImageDevicePath = NULL;
  EFI_DEVICE_PATH_PROTOCOL        *NewFilePath = NULL;
  EFI_LOADED_IMAGE_PROTOCOL       *LoadedImage = NULL;
  EFI_SMM_SW_DISPATCH_PROTOCOL    *SwDispatch = NULL;
  EFI_SMM_SW_DISPATCH_CONTEXT     SwContext;
  EFI_ACPI_SUPPORT_PROTOCOL       *AcpiSupportProtocol = NULL;
  EFI_HANDLE                      SwHandle = NULL;
  EFI_HANDLE                      hNewHandle = NULL;
  UINTN                           BufferSize;
  UINTN                           HestTblHandle;
  UINT64                          Address64;
  UINT32                          Value32;
  //
  // Initialize Local Variables
  //
  InSmm = FALSE;
  BufferSize = 0;
  HestTblHandle = 0;

  //
  // Initialize Global Variables
  //
  EfiInitializeApei (ImageHandle, SystemTable);

  // Locate SMM Base Protocol
  Status  = gBS->LocateProtocol (
                                 &gEfiSmmBaseProtocolGuid,  // IN EFI_GUID Published unique identifier of requested protocol GUID to locate
                                 NULL,                      // IN VOID* Published unique identifier of requested protocol GUID
                                 &SmmBase                   // OUT VOID** Returns address of pointer for SMM Base protocol interface
                                 );

  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;     // Error detected while trying to locate SMM Base Protocol
  }

  // Save the SMM Base system table pointer
  SmmBase->GetSmstLocation (SmmBase, &gSmst);

  // Determine if we are in SMM or not
  SmmBase->InSmm (SmmBase, &InSmm);

  if (!InSmm) {
    // Query image handle to see if it supports a requested protocol and then get an address of the protocol image to be loaded
    Status = gBS->HandleProtocol (
                                  ImageHandle,                  // Handle of requested protocol
                                  &gEfiLoadedImageProtocolGuid, // Published unique identifier of requested protocol GUID
                                  (VOID*)&LoadedImage           // Returns address of pointer for requested protocol interface of the image
                                  );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;            // Error detected while trying to query LoadImage protocol
    }

    // Query device handle of loaded image to see if it supports a requested protocol and then get an address of the prototocl device path
    Status = gBS->HandleProtocol (
                                  LoadedImage->DeviceHandle,   // Handle of requested protocol
                                  &gEfiDevicePathProtocolGuid, // Published unique identifier of requested protocol GUID
                                  (VOID*) &ImageDevicePath     // Returns address of pointer for requested protocol interface
                                  );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;
    }

    // Add this image's device path to the loaded image device path image and return
    // a pointer to the new file path.
    NewFilePath = AddDevicePath (
                                 ImageDevicePath,         // IN EFI_DEVICE_PATH_PROTOCOL*
                                 LoadedImage->FilePath    // IN EFI_DEVICE_PATH_PROTOCOL* Device Path Image to add
                                 );

    //Load the image in System Management RAM; it will automatically generate an SMI.
    Status = SmmBase->Register (
                                SmmBase,      // IN *This Addreess of pointer for SMM Base protocol interface)
                                NewFilePath,  // IN EFI_DEVICE_PATH_PROTOCOL
                                NULL,         // IN SourceBuffer OPTIONAL
                                0,            // IN SourceSize OPTIONAL
                                &hEinj,       // OUT *ImageHandle
                                FALSE         // IN LegacyIA32Binary OPTIONAL
                                );

    // Free up residual heap memory if not equal to NULL
    if (NewFilePath) {
      gBS->FreePool (NewFilePath);
    }

    if (EFI_ERROR (Status)) {
      switch (EFIERR (Status))
      {
      case EFI_LOAD_ERROR:
        break;
      case EFI_INVALID_PARAMETER:
        break;
      case EFI_UNSUPPORTED:
        break;
      default:
        ;
      }
      return Status;
    }
  } else {
    // We are in SMM...
    // Allocate Memory for type Runtime Services Data - APEI Module Private Data
    Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof (APEI_DRIVER_PRIVATE_DATA), &mApeiPrivData);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    // Allocate Memory for type Runtime Services Data - APEI Interface
    Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof (AMD_APEI_INTERFACE), &mApeiInterface);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    // Locate SW SMM Dispatch Protocol
    Status  = gBS->LocateProtocol (
                                   &gEfiSmmSwDispatchProtocolGuid, // IN EFI_GUID Published unique identifier of requested protocol GUID to locate
                                   NULL,                           // IN VOID* Published unique identifier of requested protocol GUID
                                   &SwDispatch                     // OUT VOID** Returns address of pointer for SMM Base protocol interface
                                   );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;
    }

    SwContext.SwSmiInputValue = EINJ_BEGIN_INJ_CMD;
    // Register EINJ SMM callback handler.
    Status = SwDispatch->Register (
                                   SwDispatch,           // IN *This
                                   ApeiEinjSwSmiHandler, // IN EFI SW SMM Dispatcher Callback Entry Point Address
                                   &SwContext,           // IN SwContext
                                   &SwHandle             // IN OUT SwHandle
                                   );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;
    }

    SwContext.SwSmiInputValue = ERST_EXECUTE_OPERATION_CMD;
    // Register ERST SMM callback handler.
    Status = SwDispatch->Register (
                                   SwDispatch,
                                   ApeiErstSwSmiHandler,
                                   &SwContext,
                                   &SwHandle
                                   );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;
    }

    // Allocate Memory for the the AMD_RAS_APEI_PROTOCOL protocol.
    Status = gBS->AllocatePool (
                                EfiBootServicesData,              // IN EFI_MEMORY_TYPE PoolType
                                sizeof (AMD_RAS_APEI_PROTOCOL),   // IN UINTN Size
                                &AmdRasApeiProtocol               // OUT VOID **Buffer
                                );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_OUT_OF_RESOURCES;    // Error detected while trying to locate SMM Base Protocol
    }

    EfiCommonLibZeroMem (AmdRasApeiProtocol, sizeof (AMD_RAS_APEI_PROTOCOL));

    // Initialize BERT
    ApeiBertInit ();
    // Initialize HEST
    ApeiHestInit ();
    // Determine if we have ECC error enable bits set
    Address64 = mCfgMmioBase | ((0x18 << 15) | (3 << 12) | 0x44); //F3:44 MC4_NB_CFG
    Value32 = RasSmmReadMem32 (Address64);
    if (Value32 & (1 << 22)) {
      //Initialize EINJ if ECC is Enabled
      ApeiEinjInit ();
    }
    // Initialize ERST
    ApeiErstInit ();

    AmdRasApeiProtocol->AmdApeiInterface = mApeiInterface;
    mApeiInterface->ApeiPrivData = mApeiPrivData;

    AmdRasApeiProtocol->AddBootErrorRecordEntry = 0;
    AmdRasApeiProtocol->AddHestErrorSourceEntry = 0;

    Status = gBS->InstallProtocolInterface (
                                            &Handle,                  // IN OUT EFI_HANDLE
                                            &gAmdRasApeiProtocolGuid, // IN EFI_GUID
                                            EFI_NATIVE_INTERFACE,     // IN EFI_INITERFACE_TYPE
                                            AmdRasApeiProtocol        // IN VOID* Interface
                                            );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_PROTOCOL_ERROR;    // Error detected while trying to locate SMM Base Protocol
    }
  } // End-- if(!InSmm)

  //
  // Do more non-SMM configuration
  //
  if (!InSmm) {
    Status = gBS->LocateProtocol (
                                  &gAmdRasApeiProtocolGuid,
                                  NULL,
                                  &AmdRasApeiProtocol
                                  );

    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_PROTOCOL_ERROR;   // Error detected while trying to locate SMM Base Protocol
    }

    mApeiInterface = AmdRasApeiProtocol->AmdApeiInterface;
    mApeiPrivData = mApeiInterface->ApeiPrivData;

    // Initialize function pointers to protocol interfaces
    AmdRasApeiProtocol->AddBootErrorRecordEntry = &AddBertErrorRecord;
    AmdRasApeiProtocol->AddHestErrorSourceEntry = &AddHestErrorRecord;

    //
    //  Find the protocol that was installed during SMM phase and reinstall it during
    //  Non-SMM phase as well.
    //

    // Get the buffer size for the EFI_HANDLE
    BufferSize = sizeof (EFI_HANDLE);

    // Returns an array of handles that support a specified protocol.
    Status = gBS->LocateHandle (
                                ByProtocol,               // IN EFI_LOCATE_SEARCH_TYPE SearchType
                                &gAmdRasApeiProtocolGuid, // IN EFI_GUID *Protocol OPTIONAL
                                NULL,                     // IN VOID *SearchKey OPTIONAL
                                &BufferSize,              // IN OUT UINTN BufferSize
                                &hNewHandle               // OUT EFI_HANDLE *Buffer
                                );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_PROTOCOL_ERROR;   // Error detected while trying to locate SMM Base Protocol
    }

    // Queries a handle to determine if it supports a specified protocol.
    Status = gBS->HandleProtocol (
                                  hNewHandle,                     // IN EFI_HANDLE Handle
                                  &gAmdRasApeiProtocolGuid,       // IN EFI_GUID *Protocol
                                  (VOID **) &AmdRasApeiProtocol   // OUT VOID *NewInterface
                                  );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_PROTOCOL_ERROR;    // Error detected while trying to locate SMM Base Protocol
    }

    // Local ACPI Protocol
    Status = gBS->LocateProtocol (
                                  &gAcpiSupportGuid,
                                  NULL,
                                  (VOID **) &AcpiSupportProtocol
                                  );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_PROTOCOL_ERROR;    // Error detected while trying to locate ACPI Support Protocol
    }

    //Add HEST table to the ACPI aware OS
    Status = AcpiSupportProtocol->SetAcpiTable (
                                                AcpiSupportProtocol,                        // IN EFI_ACPI_SUPPORT_PROTOCOL *This
                                                mApeiInterface->ApeiPrivData->ApeiHestTbl,  // IN VOID  *Table OPTIONAL
                                                TRUE,                                       // IN BOOLEAN Checksum
                                                EFI_ACPI_TABLE_VERSION_ALL,                 // IN EFI_ACPI_TABLE_VERSION Version
                                                &HestTblHandle                              // IN OUT UINTN *TableHandle
                                                );
    ASSERT_EFI_ERROR (Status);

    // Reinstalls a protocol interface on a device handle.
    Status = gBS->ReinstallProtocolInterface (
                                              hNewHandle,               // IN EFI_HANDLE Handle
                                              &gAmdRasApeiProtocolGuid, // IN EFI_GUID *Protocol
                                              AmdRasApeiProtocol,       // IN VOID *OldInterface
                                              AmdRasApeiProtocol        // IN VOID *NewInterface
                                              );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_PROTOCOL_ERROR;    // Error detected while trying to locate SMM Base Protocol
    }

    // Create a callback event to be executed at ReadyToBoot to publish APEI tables to OS.
    Status = gBS->CreateEventEx (
                                 EFI_EVENT_NOTIFY_SIGNAL,
                                 EFI_TPL_NOTIFY,
                                 AddApeiTables,
                                 NULL,
                                 &gEfiEventReadyToBootGuid,
                                 &mEvtApeiReadyToBoot
                                 );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return EFI_OUT_OF_RESOURCES;    // Error detected while trying to locate SMM Base Protocol
    }
  }

  return Status;
}