/** @file
  This code produces the Data Hub protocol. It preloads the data hub
  with status information copied in from PEI HOBs.
  
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 "DataHub.h"

CONST EFI_GUID gZeroGuid  = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };

//
//  Since this driver will only ever produce one instance of the Logging Hub
//  protocol you are not required to dynamically allocate the PrivateData.
//
DATA_HUB_INSTANCE mPrivateData;

/**
  Log data record into the data logging hub

  @param This                   Protocol instance structure
  @param DataRecordGuid         GUID that defines record contents
  @param ProducerName           GUID that defines the name of the producer of the data
  @param DataRecordClass        Class that defines generic record type
  @param RawData                Data Log record as defined by DataRecordGuid
  @param RawDataSize            Size of Data Log data in bytes

  @retval EFI_SUCCESS           If data was logged
  @retval EFI_OUT_OF_RESOURCES  If data was not logged due to lack of system 
                                resources.
**/
EFI_STATUS
EFIAPI
DataHubLogData (
  IN  EFI_DATA_HUB_PROTOCOL   *This,
  IN  EFI_GUID                *DataRecordGuid,
  IN  EFI_GUID                *ProducerName,
  IN  UINT64                  DataRecordClass,
  IN  VOID                    *RawData,
  IN  UINT32                  RawDataSize
  )
{
  EFI_STATUS              Status;
  DATA_HUB_INSTANCE       *Private;
  EFI_DATA_ENTRY          *LogEntry;
  UINT32                  TotalSize;
  UINT32                  RecordSize;
  EFI_DATA_RECORD_HEADER  *Record;
  VOID                    *Raw;
  DATA_HUB_FILTER_DRIVER  *FilterEntry;
  LIST_ENTRY              *Link;
  LIST_ENTRY              *Head;
  EFI_TIME                LogTime;

  Private = DATA_HUB_INSTANCE_FROM_THIS (This);

  //
  // Combine the storage for the internal structs and a copy of the log record.
  //  Record follows PrivateLogEntry. The consumer will be returned a pointer
  //  to Record so we don't what it to be the thing that was allocated from
  //  pool, so the consumer can't free an data record by mistake.
  //
  RecordSize  = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize;
  TotalSize   = sizeof (EFI_DATA_ENTRY) + RecordSize;
  
  //
  // First try to get log time at TPL level <= TPL_CALLBACK.
  //
  ZeroMem (&LogTime, sizeof (LogTime));
  if (EfiGetCurrentTpl() <= TPL_CALLBACK) {
    gRT->GetTime (&LogTime, NULL);
  }

  //
  // The Logging action is the critical section, so it is locked.
  //  The MTC asignment & update and logging must be an
  //  atomic operation, so use the lock.
  //
  Status = EfiAcquireLockOrFail (&Private->DataLock);
  if (EFI_ERROR (Status)) {
    //
    // Reentrancy detected so exit!
    //
    return Status;
  }

  LogEntry = AllocatePool (TotalSize);

  if (LogEntry == NULL) {
    EfiReleaseLock (&Private->DataLock);
    return EFI_OUT_OF_RESOURCES;
  }

  ZeroMem (LogEntry, TotalSize);

  Record  = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1);
  Raw     = (VOID *) (Record + 1);

  //
  // Build Standard Log Header
  //
  Record->Version     = EFI_DATA_RECORD_HEADER_VERSION;
  Record->HeaderSize  = (UINT16) sizeof (EFI_DATA_RECORD_HEADER);
  Record->RecordSize  = RecordSize;
  CopyMem (&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID));
  CopyMem (&Record->ProducerName, ProducerName, sizeof (EFI_GUID));
  Record->DataRecordClass   = DataRecordClass;

  //
  // Ensure LogMonotonicCount is not zero
  //
  Record->LogMonotonicCount = ++Private->GlobalMonotonicCount;

  CopyMem (&Record->LogTime, &LogTime, sizeof (LogTime));

  //
  // Insert log into the internal linked list.
  //
  LogEntry->Signature   = EFI_DATA_ENTRY_SIGNATURE;
  LogEntry->Record      = Record;
  LogEntry->RecordSize  = sizeof (EFI_DATA_ENTRY) + RawDataSize;
  InsertTailList (&Private->DataListHead, &LogEntry->Link);

  CopyMem (Raw, RawData, RawDataSize);

  EfiReleaseLock (&Private->DataLock);

  //
  // Send Signal to all the filter drivers which are interested
  //  in the record's class and guid.
  //
  Head = &Private->FilterDriverListHead;
  for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) {
    FilterEntry = FILTER_ENTRY_FROM_LINK (Link);
    if (((FilterEntry->ClassFilter & DataRecordClass) != 0) &&
        (CompareGuid (&FilterEntry->FilterDataRecordGuid, &gZeroGuid) || 
         CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) {
      gBS->SignalEvent (FilterEntry->Event);
    }
  }

  return EFI_SUCCESS;
}

/**
  Search the Head doubly linked list for the passed in MTC. Return the 
  matching element in Head and the MTC on the next entry.

  @param Head             Head of Data Log linked list.
  @param ClassFilter      Only match the MTC if it is in the same Class as the
                          ClassFilter.
  @param PtrCurrentMTC    On IN contians MTC to search for. On OUT contians next
                          MTC in the data log list or zero if at end of the list.
  
  @retval EFI_DATA_LOG_ENTRY  Return pointer to data log data from Head list.
  @retval NULL                If no data record exists.

**/
EFI_DATA_RECORD_HEADER *
GetNextDataRecord (
  IN  LIST_ENTRY          *Head,
  IN  UINT64              ClassFilter,
  IN OUT  UINT64          *PtrCurrentMTC
  )

{
  EFI_DATA_ENTRY          *LogEntry;
  LIST_ENTRY              *Link;
  BOOLEAN                 ReturnFirstEntry;
  EFI_DATA_RECORD_HEADER  *Record;
  EFI_DATA_ENTRY          *NextLogEntry;

  //
  // If MonotonicCount == 0 just return the first one
  //
  ReturnFirstEntry  = (BOOLEAN) (*PtrCurrentMTC == 0);

  Record            = NULL;
  for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) {
    LogEntry = DATA_ENTRY_FROM_LINK (Link);
    if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) {
      //
      // Skip any entry that does not have the correct ClassFilter
      //
      continue;
    }

    if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) {
      //
      // Return record to the user
      //
      Record = LogEntry->Record;

      //
      // Calculate the next MTC value. If there is no next entry set
      // MTC to zero.
      //
      *PtrCurrentMTC = 0;
      for (Link = GetNextNode(Head, Link); Link != Head; Link = GetNextNode(Head, Link)) {
        NextLogEntry = DATA_ENTRY_FROM_LINK (Link);
        if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) {
          //
          // Return the MTC of the next thing to search for if found
          //
          *PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount;
          break;
        }
      }
      //
      // Record found exit loop and return
      //
      break;
    }
  }

  return Record;
}

/**
  Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that
  represents Event and return it.

  @param Head   Pointer to head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER structures.
  @param Event  Event to be search for in the Head list.

  @retval EFI_DATA_HUB_FILTER_DRIVER  Returned if Event stored in the Head doubly linked list.
  @retval NULL                        If Event is not in the list

**/
DATA_HUB_FILTER_DRIVER *
FindFilterDriverByEvent (
  IN  LIST_ENTRY      *Head,
  IN  EFI_EVENT       Event
  )
{
  DATA_HUB_FILTER_DRIVER  *FilterEntry;
  LIST_ENTRY              *Link;

  for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) {
    FilterEntry = FILTER_ENTRY_FROM_LINK (Link);
    if (FilterEntry->Event == Event) {
      return FilterEntry;
    }
  }

  return NULL;
}

/**

  Get a previously logged data record and the MonotonicCount for the next
  availible Record. This allows all records or all records later 
  than a give MonotonicCount to be returned. If an optional FilterDriverEvent
  is passed in with a MonotonicCout of zero return the first record 
  not yet read by the filter driver. If FilterDriverEvent is NULL and 
  MonotonicCount is zero return the first data record.

  @param This                     Pointer to the EFI_DATA_HUB_PROTOCOL instance.
  @param MonotonicCount           Specifies the Record to return. On input, zero means
                                  return the first record. On output, contains the next
                                  record to availible. Zero indicates no more records.
  @param FilterDriverEvent        If FilterDriverEvent is not passed in a MonotonicCount 
                                  of zero, it means to return the first data record. 
                                  If FilterDriverEvent is passed in, then a MonotonicCount 
                                  of zero means to return the first data not yet read by 
                                  FilterDriverEvent.
  @param Record                   Returns a dynamically allocated memory buffer with a data 
                                  record that matches MonotonicCount.

  @retval EFI_SUCCESS             Data was returned in Record.
  @retval EFI_INVALID_PARAMETER   FilterDriverEvent was passed in but does not exist.
  @retval EFI_NOT_FOUND           MonotonicCount does not match any data record in the
                                  system. If a MonotonicCount of zero was passed in, then
                                  no data records exist in the system.
  @retval EFI_OUT_OF_RESOURCES    Record was not returned due to lack of system resources.

**/
EFI_STATUS
EFIAPI
DataHubGetNextRecord (
  IN EFI_DATA_HUB_PROTOCOL            *This,
  IN OUT UINT64                       *MonotonicCount,
  IN EFI_EVENT                        *FilterDriverEvent, OPTIONAL
  OUT EFI_DATA_RECORD_HEADER          **Record
  )
{
  DATA_HUB_INSTANCE       *Private;
  DATA_HUB_FILTER_DRIVER  *FilterDriver;
  UINT64                  ClassFilter;

  Private               = DATA_HUB_INSTANCE_FROM_THIS (This);

  FilterDriver          = NULL;
  ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |
    EFI_DATA_RECORD_CLASS_ERROR |
    EFI_DATA_RECORD_CLASS_DATA |
    EFI_DATA_RECORD_CLASS_PROGRESS_CODE;

  //
  // If FilterDriverEvent is NULL, then return the next record
  //
  if (FilterDriverEvent == NULL) {
    *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);
    if (*Record == NULL) {
      return EFI_NOT_FOUND;
    }
    return EFI_SUCCESS;
  }
    
  //
  // For events the beginning is the last unread record. This info is
  // stored in the instance structure, so we must look up the event
  // to get the data.
  //
  FilterDriver = FindFilterDriverByEvent (
                  &Private->FilterDriverListHead,
                  *FilterDriverEvent
                  );
  if (FilterDriver == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  //
  // Use the Class filter the event was created with.
  //
  ClassFilter = FilterDriver->ClassFilter;

  //
  // Retrieve the next record or the first record.
  //   
  if (*MonotonicCount != 0 || FilterDriver->GetNextMonotonicCount == 0) { 
    *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);
    if (*Record == NULL) {
      return EFI_NOT_FOUND;
    }
    
    if (*MonotonicCount != 0) {
      //
      // If this was not the last record then update the count associated with the filter 
      //
      FilterDriver->GetNextMonotonicCount = *MonotonicCount;
    } else {
      //
      // Save the MonotonicCount of the last record which has been read
      //
      FilterDriver->GetNextMonotonicCount = (*Record)->LogMonotonicCount;
    }
    return EFI_SUCCESS;
  }
  
  //
  // This is a request to read the first record that has not been read yet.  
  // Set MonotoicCount to the last record successfuly read
  //
  *MonotonicCount = FilterDriver->GetNextMonotonicCount;
  
  //
  // Retrieve the last record successfuly read again, but do not return it since
  // it has already been returned before.
  //
  *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);
  if (*Record == NULL) {
    return EFI_NOT_FOUND;
  }
  
  if (*MonotonicCount != 0) {
    //
    // Update the count associated with the filter 
    //
    FilterDriver->GetNextMonotonicCount = *MonotonicCount;

    //
    // Retrieve the record after the last record successfuly read 
    //  
    *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount);
    if (*Record == NULL) {
      return EFI_NOT_FOUND;
    }
  }
  
  return EFI_SUCCESS;
}

/**
  This function registers the data hub filter driver that is represented 
  by FilterEvent. Only one instance of each FilterEvent can be registered.
  After the FilterEvent is registered, it will be signaled so it can sync 
  with data records that have been recorded prior to the FilterEvent being 
  registered.
    
  @param This                   Pointer to  The EFI_DATA_HUB_PROTOCOL instance.
  @param FilterEvent            The EFI_EVENT to signal whenever data that matches 
                                FilterClass is logged in the system.
  @param FilterTpl              The maximum EFI_TPL at which FilterEvent can be 
                                signaled. It is strongly recommended that you use the 
                                lowest EFI_TPL possible.
  @param FilterClass            FilterEvent will be signaled whenever a bit in 
                                EFI_DATA_RECORD_HEADER.DataRecordClass is also set in 
                                FilterClass. If FilterClass is zero, no class-based 
                                filtering will be performed.
  @param FilterDataRecordGuid   FilterEvent will be signaled whenever FilterDataRecordGuid 
                                matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If 
                                FilterDataRecordGuid is NULL, then no GUID-based filtering 
                                will be performed.              

  @retval EFI_SUCCESS           The filter driver event was registered.
  @retval EFI_ALREADY_STARTED   FilterEvent was previously registered and cannot be 
                                registered again.
  @retval EFI_OUT_OF_RESOURCES  The filter driver event was not registered due to lack of 
                                system resources.

**/
EFI_STATUS
EFIAPI
DataHubRegisterFilterDriver (
  IN EFI_DATA_HUB_PROTOCOL    * This,
  IN EFI_EVENT                FilterEvent,
  IN EFI_TPL                  FilterTpl,
  IN UINT64                   FilterClass,
  IN EFI_GUID                 * FilterDataRecordGuid OPTIONAL
  )

{
  DATA_HUB_INSTANCE       *Private;
  DATA_HUB_FILTER_DRIVER  *FilterDriver;

  Private       = DATA_HUB_INSTANCE_FROM_THIS (This);

  FilterDriver  = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool (sizeof (DATA_HUB_FILTER_DRIVER));
  if (FilterDriver == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Initialize filter driver info
  //
  FilterDriver->Signature             = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE;
  FilterDriver->Event                 = FilterEvent;
  FilterDriver->Tpl                   = FilterTpl;
  FilterDriver->GetNextMonotonicCount = 0;
  if (FilterClass == 0) {
    FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG |
      EFI_DATA_RECORD_CLASS_ERROR |
      EFI_DATA_RECORD_CLASS_DATA |
      EFI_DATA_RECORD_CLASS_PROGRESS_CODE;
  } else {
    FilterDriver->ClassFilter = FilterClass;
  }

  if (FilterDataRecordGuid != NULL) {
    CopyMem (&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID));
  }
  //
  // Search for duplicate entries
  //
  if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) {
    FreePool (FilterDriver);
    return EFI_ALREADY_STARTED;
  }
  //
  // Make insertion an atomic operation with the lock.
  //
  EfiAcquireLock (&Private->DataLock);
  InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link);
  EfiReleaseLock (&Private->DataLock);

  //
  // Signal the Filter driver we just loaded so they will recieve all the
  // previous history. If we did not signal here we would have to wait until
  // the next data was logged to get the history. In a case where no next
  // data was logged we would never get synced up.
  //
  gBS->SignalEvent (FilterEvent);

  return EFI_SUCCESS;
}

/**
  Remove a Filter Driver, so it no longer gets called when data 
   information is logged.

  @param This           Protocol instance structure

  @param FilterEvent    Event that represents a filter driver that is to be 
                        Unregistered.

  @retval EFI_SUCCESS   If FilterEvent was unregistered
  @retval EFI_NOT_FOUND If FilterEvent does not exist
**/
EFI_STATUS
EFIAPI
DataHubUnregisterFilterDriver (
  IN EFI_DATA_HUB_PROTOCOL    *This,
  IN EFI_EVENT                FilterEvent
  )
{
  DATA_HUB_INSTANCE       *Private;
  DATA_HUB_FILTER_DRIVER  *FilterDriver;

  Private = DATA_HUB_INSTANCE_FROM_THIS (This);

  //
  // Search for duplicate entries
  //
  FilterDriver = FindFilterDriverByEvent (
                  &Private->FilterDriverListHead,
                  FilterEvent
                  );
  if (FilterDriver == NULL) {
    return EFI_NOT_FOUND;
  }
  //
  // Make removal an atomic operation with the lock
  //
  EfiAcquireLock (&Private->DataLock);
  RemoveEntryList (&FilterDriver->Link);
  EfiReleaseLock (&Private->DataLock);

  return EFI_SUCCESS;
}



/**
  Driver's Entry point routine that install Driver to produce Data Hub protocol. 

  @param ImageHandle    Module's image handle
  @param SystemTable    Pointer of EFI_SYSTEM_TABLE

  @retval EFI_SUCCESS   Logging Hub protocol installed
  @retval Other         No protocol installed, unload driver.

**/
EFI_STATUS
EFIAPI
DataHubInstall (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS  Status;
  UINT32      HighMontonicCount;

  mPrivateData.Signature                      = DATA_HUB_INSTANCE_SIGNATURE;
  mPrivateData.DataHub.LogData                = DataHubLogData;
  mPrivateData.DataHub.GetNextRecord          = DataHubGetNextRecord;
  mPrivateData.DataHub.RegisterFilterDriver   = DataHubRegisterFilterDriver;
  mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver;

  //
  // Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is
  // required by this protocol
  //
  InitializeListHead (&mPrivateData.DataListHead);
  InitializeListHead (&mPrivateData.FilterDriverListHead);

  EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY);

  //
  // Make sure we get a bigger MTC number on every boot!
  //
  Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount);
  if (EFI_ERROR (Status)) {
    //
    // if system service fails pick a sane value.
    //
    mPrivateData.GlobalMonotonicCount = 0;
  } else {
    mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32);
  }
  //
  // Make a new handle and install the protocol
  //
  mPrivateData.Handle = NULL;
  Status = gBS->InstallProtocolInterface (
                  &mPrivateData.Handle,
                  &gEfiDataHubProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mPrivateData.DataHub
                  );
  return Status;
}

