/** @file
  Library constructor & destructor, event handlers, and other internal worker functions.

  Copyright (c) 2006 - 2011, 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 "ReportStatusCodeLibInternal.h"

EFI_EVENT                     mVirtualAddressChangeEvent;
EFI_EVENT                     mExitBootServicesEvent;
EFI_STATUS_CODE_DATA          *mStatusCodeData;
BOOLEAN                       mInSmm;
EFI_SMM_BASE_PROTOCOL         *mSmmBase;
EFI_RUNTIME_SERVICES          *mInternalRT;
BOOLEAN                       mHaveExitedBootServices = FALSE;
EFI_REPORT_STATUS_CODE        mReportStatusCode = NULL;
EFI_SMM_STATUS_CODE_PROTOCOL  *mSmmStatusCodeProtocol;

/**
  Locates and caches SMM Status Code Protocol.
 
**/
VOID
SmmStatusCodeInitialize (
  VOID
  )
{
  EFI_STATUS Status;

  Status = gBS->LocateProtocol (&gEfiSmmStatusCodeProtocolGuid, NULL, (VOID **) &mSmmStatusCodeProtocol);
  if (EFI_ERROR (Status)) {
    mSmmStatusCodeProtocol = NULL;
  }
}

/**
  Report status code via SMM Status Code Protocol.
 
  @param  Type          Indicates the type of status code being reported.
  @param  Value         Describes the current status of a hardware or software entity.  
                        This included information about the class and subclass that is used to classify the entity 
                        as well as an operation.  For progress codes, the operation is the current activity. 
                        For error codes, it is the exception.  For debug codes, it is not defined at this time. 
  @param  Instance      The enumeration of a hardware or software entity within the system.  
                        A system may contain multiple entities that match a class/subclass pairing. 
                        The instance differentiates between them.  An instance of 0 indicates that instance information is unavailable, 
                        not meaningful, or not relevant.  Valid instance numbers start with 1.
  @param  CallerId      This optional parameter may be used to identify the caller. 
                        This parameter allows the status code driver to apply different rules to different callers. 
  @param  Data          This optional parameter may be used to pass additional data
 
  @retval EFI_SUCCESS   Always return EFI_SUCCESS.

**/
EFI_STATUS
SmmStatusCodeReport (
  IN EFI_STATUS_CODE_TYPE     Type,
  IN EFI_STATUS_CODE_VALUE    Value,
  IN UINT32                   Instance,
  IN EFI_GUID                 *CallerId OPTIONAL,
  IN EFI_STATUS_CODE_DATA     *Data     OPTIONAL
  )
{
  if (mSmmStatusCodeProtocol != NULL) {
    (mSmmStatusCodeProtocol->ReportStatusCode) (mSmmStatusCodeProtocol, Type, Value, Instance, CallerId, Data);
  }
  return EFI_SUCCESS;
}

/**
  Locate the report status code service.

  In SMM, it tries to retrieve SMM Status Code Protocol.
  Otherwise, it first tries to retrieve ReportStatusCode() in Runtime Services Table.
  If not found, it then tries to retrieve ReportStatusCode() API of Report Status Code Protocol.

  @return   Function pointer to the report status code service.
            NULL is returned if no status code service is available.

**/
EFI_REPORT_STATUS_CODE
InternalGetReportStatusCode (
  VOID
  )
{
  EFI_STATUS_CODE_PROTOCOL  *StatusCodeProtocol;
  EFI_STATUS                Status;

  if (mInSmm) {
    return (EFI_REPORT_STATUS_CODE) SmmStatusCodeReport;
  } else if (mInternalRT != NULL && mInternalRT->Hdr.Revision < 0x20000) {
    return ((FRAMEWORK_EFI_RUNTIME_SERVICES*)mInternalRT)->ReportStatusCode;
  } else if (!mHaveExitedBootServices) {
  	//
  	// Check gBS just in case. ReportStatusCode is called before gBS is initialized.
  	//
    if (gBS != NULL) {
      Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID**)&StatusCodeProtocol);
      if (!EFI_ERROR (Status) && StatusCodeProtocol != NULL) {
        return StatusCodeProtocol->ReportStatusCode;
      }
    }
  }

  return NULL;
}

/**
  Internal worker function that reports a status code through the status code service.

  If status code service is not cached, then this function checks if status code service is
  available in system.  If status code service is not available, then EFI_UNSUPPORTED is
  returned.  If status code service is present, then it is cached in mReportStatusCode.
  Finally this function reports status code through the status code service.

  @param  Type              Status code type.
  @param  Value             Status code value.
  @param  Instance          Status code instance number.
  @param  CallerId          Pointer to a GUID that identifies the caller of this
                            function.  This is an optional parameter that may be
                            NULL.
  @param  Data              Pointer to the extended data buffer.  This is an
                            optional parameter that may be NULL.

  @retval EFI_SUCCESS       The status code was reported.
  @retval EFI_UNSUPPORTED   Status code service is not available.
  @retval EFI_UNSUPPORTED   Status code type is not supported.

**/
EFI_STATUS
InternalReportStatusCode (
  IN EFI_STATUS_CODE_TYPE     Type,
  IN EFI_STATUS_CODE_VALUE    Value,
  IN UINT32                   Instance,
  IN CONST EFI_GUID           *CallerId OPTIONAL,
  IN EFI_STATUS_CODE_DATA     *Data     OPTIONAL
  )
{
  if ((ReportProgressCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||
      (ReportErrorCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) ||
      (ReportDebugCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)) {
    //
    // If mReportStatusCode is NULL, then check if status code service is available in system.
    //
    if (mReportStatusCode == NULL) {
      mReportStatusCode = InternalGetReportStatusCode ();
      if (mReportStatusCode == NULL) {
        return EFI_UNSUPPORTED;
      }
    }
  
    //
    // A status code service is present in system, so pass in all the parameters to the service.
    //
    return (*mReportStatusCode) (Type, Value, Instance, (EFI_GUID *)CallerId, Data);
  }
  
  return EFI_UNSUPPORTED;
}

/**
  Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context

**/
VOID
EFIAPI
ReportStatusCodeLibVirtualAddressChange (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  )
{
  if (mReportStatusCode != NULL) {
    mInternalRT->ConvertPointer (0, (VOID **) &mReportStatusCode);
  }
  mInternalRT->ConvertPointer (0, (VOID **) &mStatusCodeData);
  mInternalRT->ConvertPointer (0, (VOID **) &mInternalRT);
}

/**
  Notification function of EVT_SIGNAL_EXIT_BOOT_SERVICES.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context

**/
VOID
EFIAPI
ReportStatusCodeLibExitBootServices (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  )
{
  //
  // If mReportStatusCode is NULL, then see if a Status Code Protocol instance is present
  // in the handle database.
  //
  if (mReportStatusCode == NULL) {
    mReportStatusCode = InternalGetReportStatusCode ();
  }

  mHaveExitedBootServices = TRUE;
}

/**
  The constructor function of SMM Runtime DXE Report Status Code Lib.

  This function allocates memory for extended status code data, caches
  the report status code service, and registers events.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
ReportStatusCodeLibConstruct (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS     Status;

  //
  // If in SMM mode, then allocates memory from SMRAM for extended status code data.
  //
  Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);
  if (!EFI_ERROR (Status)) {
    mSmmBase->InSmm (mSmmBase, &mInSmm);
    if (mInSmm) {
      Status = mSmmBase->SmmAllocatePool (
                           mSmmBase,
                           EfiRuntimeServicesData, 
                           sizeof (EFI_STATUS_CODE_DATA) + EFI_STATUS_CODE_DATA_MAX_SIZE, 
                           (VOID **) &mStatusCodeData
                           );
      ASSERT_EFI_ERROR (Status);
      SmmStatusCodeInitialize ();
      return EFI_SUCCESS;
    }
  }


  //
  // If not in SMM mode, then allocate runtime memory for extended status code data.
  //
  // Library should not use the gRT directly, for it may be converted by other library instance.
  // 
  mInternalRT = gRT;
  mInSmm      = FALSE;

  mStatusCodeData = AllocateRuntimePool (sizeof (EFI_STATUS_CODE_DATA) + EFI_STATUS_CODE_DATA_MAX_SIZE);
  ASSERT (mStatusCodeData != NULL);
  //
  // Cache the report status code service
  // 
  mReportStatusCode = InternalGetReportStatusCode ();

  //
  // Register notify function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
  // 
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  ReportStatusCodeLibVirtualAddressChange,
                  NULL,
                  &gEfiEventVirtualAddressChangeGuid,
                  &mVirtualAddressChangeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register notify function for EVT_SIGNAL_EXIT_BOOT_SERVICES
  // 
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  ReportStatusCodeLibExitBootServices,
                  NULL,
                  &gEfiEventExitBootServicesGuid,
                  &mExitBootServicesEvent
                  );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}

/**
  The destructor function of SMM Runtime DXE Report Status Code Lib.
  
  The destructor function frees memory allocated by constructor, and closes related events.
  It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS. 

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
ReportStatusCodeLibDestruct (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  if (!mInSmm) {
    ASSERT (gBS != NULL);
    Status = gBS->CloseEvent (mVirtualAddressChangeEvent);
    ASSERT_EFI_ERROR (Status);
    Status = gBS->CloseEvent (mExitBootServicesEvent);
    ASSERT_EFI_ERROR (Status);

    FreePool (mStatusCodeData);
  } else {
    mSmmBase->SmmFreePool (mSmmBase, mStatusCodeData);
  }

  return EFI_SUCCESS;
}

