/** @file
  Data Hub status code worker in DXE.

  Copyright (c) 2006, Intel Corporation
  All rights reserved. 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 "DxeStatusCode.h"

//
// Initialize FIFO to cache records.
//
STATIC
LIST_ENTRY                mRecordsFifo          = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo);
STATIC
LIST_ENTRY                mRecordsBuffer        = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer);
STATIC
UINT32                    mLogDataHubStatus     = 0;
STATIC
EFI_EVENT                 mLogDataHubEvent;
//
// Cache data hub protocol.
//
STATIC
EFI_DATA_HUB_PROTOCOL     *mDataHubProtocol;


/**
  Return one DATAHUB_STATUSCODE_RECORD space.
  The size of free record pool would be extend, if the pool is empty.


  @retval  NULL   Can not allocate free memeory for record.
  @retval  !NULL  Point to buffer of record.

**/
STATIC
DATA_HUB_STATUS_CODE_DATA_RECORD *
AcquireRecordBuffer (
  VOID
  )
{
  DATAHUB_STATUSCODE_RECORD *Record;
  EFI_TPL                   CurrentTpl;
  LIST_ENTRY                *Node;
  UINT32                    Index;

  CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);

  if (!IsListEmpty (&mRecordsBuffer)) {
    Node = GetFirstNode (&mRecordsBuffer);
    RemoveEntryList (Node);

    Record = _CR (Node, DATAHUB_STATUSCODE_RECORD, Node);
  } else {
    if (CurrentTpl > TPL_NOTIFY) {
      //
      // Memory management should work at <=TPL_NOTIFY
      // 
      gBS->RestoreTPL (CurrentTpl);
      return NULL;
    }

    gBS->RestoreTPL (CurrentTpl);
    Record   = (DATAHUB_STATUSCODE_RECORD *) AllocateZeroPool (sizeof (DATAHUB_STATUSCODE_RECORD) * 16);
    if (NULL == Record) {
      return NULL;
    }

    CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
    for (Index = 1; Index < 16; Index++) {
      InsertTailList (&mRecordsBuffer, &Record[Index].Node);
    }
  }

  Record->Signature = DATAHUB_STATUS_CODE_SIGNATURE;
  InsertTailList (&mRecordsFifo, &Record->Node);

  gBS->RestoreTPL (CurrentTpl);

  return (DATA_HUB_STATUS_CODE_DATA_RECORD *) (Record->Data);
}


/**
  Retrieve one record from Records FIFO. The record would be removed from FIFO and
  release to free record buffer.

  @return   !NULL   Point to record, which is ready to be logged.
  @return   NULL    the FIFO of record is empty.

**/
STATIC
DATA_HUB_STATUS_CODE_DATA_RECORD *
RetrieveRecord (
  VOID
  )
{
  DATA_HUB_STATUS_CODE_DATA_RECORD  *RecordData = NULL;
  DATAHUB_STATUSCODE_RECORD         *Record;
  LIST_ENTRY                        *Node;
  EFI_TPL                           CurrentTpl;

  CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);

  if (!IsListEmpty (&mRecordsFifo)) {
    Node = GetFirstNode (&mRecordsFifo);
    Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE);
    ASSERT (NULL != Record);

    RemoveEntryList (&Record->Node);
    RecordData = (DATA_HUB_STATUS_CODE_DATA_RECORD *) Record->Data;
  }

  gBS->RestoreTPL (CurrentTpl);

  return RecordData;
}

/**
  Release Records to FIFO.
  
  @param RecordData  Point to the record buffer allocated
                     from AcquireRecordBuffer.

**/
STATIC
VOID
ReleaseRecord (
  DATA_HUB_STATUS_CODE_DATA_RECORD  *RecordData
  )
{
  DATAHUB_STATUSCODE_RECORD         *Record;
  EFI_TPL                           CurrentTpl;

  Record = CR (RecordData, DATAHUB_STATUSCODE_RECORD, Data[0], DATAHUB_STATUS_CODE_SIGNATURE);
  ASSERT (NULL != Record);

  CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);

  InsertTailList (&mRecordsBuffer, &Record->Node);
  Record->Signature = 0;

  gBS->RestoreTPL (CurrentTpl);
}



/**
  Report status code into DataHub.

  @param  CodeType      Indicates the type of status code being reported.  Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions" below.

  @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.
                        Type EFI_STATUS_CODE_VALUE is defined in "Related Definitions" below.
                        Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.

  @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.
                        Type EFI_GUID is defined in InstallProtocolInterface() in the EFI 1.10 Specification.


  @param  Data          This optional parameter may be used to pass additional data

  @retval EFI_OUT_OF_RESOURCES   Can not acquire record buffer.
  @retval EFI_DEVICE_ERROR       EFI serial device can not work after ExitBootService() is called .
  @retval EFI_SUCCESS            Success to cache status code and signal log data event.

**/
EFI_STATUS
DataHubStatusCodeReportWorker (
  IN EFI_STATUS_CODE_TYPE     CodeType,
  IN EFI_STATUS_CODE_VALUE    Value,
  IN UINT32                   Instance,
  IN EFI_GUID                 *CallerId,
  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
  )
{
  DATA_HUB_STATUS_CODE_DATA_RECORD  *Record;
  UINT32                            ErrorLevel;
  VA_LIST                           Marker;
  CHAR8                             *Format;
  UINTN                             CharCount;


  //
  // Use atom operation to avoid the reentant of report.
  // If current status is not zero, then the function is reentrancy.
  //
  if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 0)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // See whether in runtime phase or not.
  //
  if (EfiAtRuntime ()) {
    return EFI_DEVICE_ERROR;
  }

  Record = AcquireRecordBuffer ();
  if (Record == NULL) {
    //
    // There are no empty record buffer in private buffers
    //
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Construct Data Hub Extended Data
  //
  Record->CodeType = CodeType;
  Record->Value    = Value;
  Record->Instance = Instance;

  if (CallerId != NULL) {
    CopyMem (&Record->CallerId, CallerId, sizeof (EFI_GUID));
  }

  if (Data != NULL) {
    if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
      CharCount = UnicodeVSPrintAsciiFormat (
                    (CHAR16 *) (Record + 1),
                    EFI_STATUS_CODE_DATA_MAX_SIZE,
                    Format,
                    Marker
                    );
      //
      // Change record data type from DebugType to String Type.
      //
      CopyGuid (&Record->Data.Type, &gEfiStatusCodeDataTypeDebugGuid);
      Record->Data.HeaderSize = Data->HeaderSize;
      Record->Data.Size = (UINT16) ((CharCount + 1) * sizeof (CHAR16));
    } else {
      //
      // Copy status code data header
      //
      CopyMem (&Record->Data, Data, sizeof (EFI_STATUS_CODE_DATA));

      if (Data->Size > EFI_STATUS_CODE_DATA_MAX_SIZE) {
        Record->Data.Size = EFI_STATUS_CODE_DATA_MAX_SIZE;
      }
      CopyMem ((VOID *) (Record + 1), Data + 1, Record->Data.Size);
    }
  }

  gBS->SignalEvent (mLogDataHubEvent);

  return EFI_SUCCESS;
}


/**
  The Event handler which will be notified to log data in Data Hub.

  @param  Event       Instance of the EFI_EVENT to signal whenever data is
                      available to be logged in the system.
  @param  Context     Context of the event.

**/
STATIC
VOID
EFIAPI
LogDataHubEventCallBack (
  IN  EFI_EVENT     Event,
  IN  VOID          *Context
  )
{
  DATA_HUB_STATUS_CODE_DATA_RECORD  *Record;
  UINT32                            Size;
  UINT64                            DataRecordClass;

  //
  // Use atom operation to avoid the reentant of report.
  // If current status is not zero, then the function is reentrancy.
  //
  if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 1)) {
    return;
  }

  //
  // Log DataRecord in Data Hub.
  // Journal records fifo to find all record entry.
  //
  while (1) {
    Record = RetrieveRecord ();
    if (Record == NULL) {
      break;
    }
    //
    // Add in the size of the header we added.
    //
    Size = sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD) + (UINT32) Record->Data.Size;

    if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
      DataRecordClass = EFI_DATA_RECORD_CLASS_PROGRESS_CODE;
    } else if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
      DataRecordClass = EFI_DATA_RECORD_CLASS_ERROR;
    } else if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
      DataRecordClass = EFI_DATA_RECORD_CLASS_DEBUG;
    } else {
      //
      // Should never get here.
      //
      DataRecordClass = EFI_DATA_RECORD_CLASS_DEBUG |
        EFI_DATA_RECORD_CLASS_ERROR |
        EFI_DATA_RECORD_CLASS_DATA |
        EFI_DATA_RECORD_CLASS_PROGRESS_CODE;
    }

    //
    // Log DataRecord in Data Hub
    //

    mDataHubProtocol->LogData (
                        mDataHubProtocol,
                        &gEfiDataHubStatusCodeRecordGuid,
                        &gEfiStatusCodeRuntimeProtocolGuid,
                        DataRecordClass,
                        Record,
                        Size
                        );

    ReleaseRecord (Record);
  }

  //
  // Restore the nest status of report
  //
  InterlockedCompareExchange32 (&mLogDataHubStatus, 1, 0);
}


/**
  Initialize data hubstatus code.
  Create a data hub listener.

  @return  The function always return EFI_SUCCESS

**/
EFI_STATUS
DataHubStatusCodeInitializeWorker (
  VOID
  )
{
  EFI_STATUS  Status;

  Status = gBS->LocateProtocol (
                  &gEfiDataHubProtocolGuid, 
                  NULL, 
                  (VOID **) &mDataHubProtocol
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Create a Notify Event to log data in Data Hub
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  LogDataHubEventCallBack,
                  NULL,
                  &mLogDataHubEvent
                  );

  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}


