/** @file
  Data Hub status code worker.

  Copyright (c) 2006 - 2010, 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 "StatusCodeRuntimeDxe.h"

//
// Initialize FIFO to cache records.
//
LIST_ENTRY                mRecordsFifo          = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo);
LIST_ENTRY                mRecordsBuffer        = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer);
UINT32                    mLogDataHubStatus     = 0;
EFI_EVENT                 mLogDataHubEvent;
//
// Cache data hub protocol.
//
EFI_DATA_HUB_PROTOCOL     *mDataHubProtocol = NULL;


/**
  Retrieve one record of from free record buffer. This record is removed from
  free record buffer.

  This function retrieves one record from free record buffer.
  If the pool has been exhausted, then new memory would be allocated for it.

  @return  Pointer to the free record.
           NULL means failure to allocate new memeory for free record buffer.

**/
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)) {
    //
    // Strip one entry from free record buffer.
    //
    Node = GetFirstNode (&mRecordsBuffer);
    RemoveEntryList (Node);

    Record = BASE_CR (Node, DATAHUB_STATUSCODE_RECORD, Node);
  } else {
    if (CurrentTpl > TPL_NOTIFY) {
      //
      // Memory management should work at <=TPL_NOTIFY
      // 
      gBS->RestoreTPL (CurrentTpl);
      return NULL;
    }

    //
    // If free record buffer is exhausted, then allocate 16 new records for it.
    //
    gBS->RestoreTPL (CurrentTpl);
    Record   = (DATAHUB_STATUSCODE_RECORD *) AllocateZeroPool (sizeof (DATAHUB_STATUSCODE_RECORD) * 16);
    if (Record == NULL) {
      return NULL;
    }

    CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
    //
    // Here we only insert 15 new records to the free record buffer, for the first record
    // will be returned immediately.
    //
    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.

  @return   Point to record, which is ready to be logged.
            NULL means the FIFO of record is empty.

**/
DATA_HUB_STATUS_CODE_DATA_RECORD *
RetrieveRecord (
  VOID
  )
{
  DATA_HUB_STATUS_CODE_DATA_RECORD  *RecordData;
  DATAHUB_STATUSCODE_RECORD         *Record;
  LIST_ENTRY                        *Node;
  EFI_TPL                           CurrentTpl;

  RecordData = NULL;

  CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);

  if (!IsListEmpty (&mRecordsFifo)) {
    Node = GetFirstNode (&mRecordsFifo);
    Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE);
    ASSERT (Record != NULL);

    RemoveEntryList (&Record->Node);
    RecordData = (DATA_HUB_STATUS_CODE_DATA_RECORD *) Record->Data;
  }

  gBS->RestoreTPL (CurrentTpl);

  return RecordData;
}

/**
  Release given record and return it to free record buffer.
  
  @param RecordData  Pointer to the record to release.

**/
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 (Record != NULL);

  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.
  @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.
  @param  Instance             The enumeration of a hardware or software entity within
                               the system. 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          The function completed successfully.
  @retval EFI_DEVICE_ERROR     Function is reentered.
  @retval EFI_DEVICE_ERROR     Function is called at runtime.
  @retval EFI_OUT_OF_RESOURCES Fail to allocate memory for free record buffer.

**/
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;
  BASE_LIST                         Marker;
  CHAR8                             *Format;
  UINTN                             CharCount;
  EFI_STATUS                        Status;

  //
  // Use atom operation to avoid the reentant of report.
  // If current status is not zero, then the function is reentrancy.
  //
  if (InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 0) == 1) {
    return EFI_DEVICE_ERROR;
  }

  //
  // See whether in runtime phase or not.
  //
  if (EfiAtRuntime ()) {
    return EFI_DEVICE_ERROR;
  }

  if (mDataHubProtocol == NULL) {
    Status = DataHubStatusCodeInitializeWorker ();
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }
  
  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 = UnicodeBSPrintAsciiFormat (
                    (CHAR16 *) (Record + 1),
                    EFI_STATUS_CODE_DATA_MAX_SIZE,
                    Format,
                    Marker
                    );
      //
      // Change record data type to DebugType.
      //
      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.

**/
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 (InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 1) == 1) {
    return;
  }

  //
  // Log DataRecord in Data Hub.
  // Journal records fifo to find all record entry.
  //
  while (TRUE) {
    //
    // Retrieve record from record FIFO until no more record can be retrieved.
    //
    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);
}


/**
  Locate Data Hub Protocol and create event for logging data
  as initialization for data hub status code worker.

  @retval EFI_SUCCESS  Initialization is successful.

**/
EFI_STATUS
DataHubStatusCodeInitializeWorker (
  VOID
  )
{
  EFI_STATUS  Status;

  Status = gBS->LocateProtocol (
                  &gEfiDataHubProtocolGuid, 
                  NULL, 
                  (VOID **) &mDataHubProtocol
                  );
  if (EFI_ERROR (Status)) {
    mDataHubProtocol = NULL;
    return 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;
}


