⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datahub.c

📁 EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是EFI BIOS源代码中的与平台无关部分的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
                          FilterClass is logged in the system.
  FilterTpl             - The maximum EFI_TPL at which FilterEvent can be 
                          signaled. It is strongly recommended that you use the 
                          lowest EFI_TPL possible.
  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.
  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.              
Returns: 

  EFI_SUCCESS             - The filter driver event was registered.
  EFI_ALREADY_STARTED     - FilterEvent was previously registered and cannot be 
                            registered again.
  EFI_OUT_OF_RESOURCES    - The filter driver event was not registered due to lack of 
                            system resources.

--*/
{
  DATA_HUB_INSTANCE       *Private;
  DATA_HUB_FILTER_DRIVER  *FilterDriver;

  Private       = DATA_HUB_INSTANCE_FROM_THIS (This);

  FilterDriver  = (DATA_HUB_FILTER_DRIVER *) EfiLibAllocateZeroPool (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) {
    EfiCopyMem (&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID));
  }
  //
  // Search for duplicate entries
  //
  if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) {
    gBS->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;
}

EFI_STATUS
EFIAPI
DataHubUnregisterFilterDriver (
  IN EFI_DATA_HUB_PROTOCOL    *This,
  IN EFI_EVENT                FilterEvent
  )
/*++

Routine Description:

  Remove a Filter Driver, so it no longer gets called when data 
   information is logged.

Arguments:

  This        - Protocol instance structure

  FilterEvent - Event that represents a filter driver that is to be 
                 Unregistered.

Returns: 

  EFI_SUCCESS   - If FilterEvent was unregistered

  EFI_NOT_FOUND - If FilterEvent does not exist

--*/
{
  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;
}
//
// STATIC Worker fucntions follow
//
STATIC
DATA_HUB_FILTER_DRIVER *
FindFilterDriverByEvent (
  IN  EFI_LIST_ENTRY  *Head,
  IN  EFI_EVENT       Event
  )
/*++

Routine Description:
  Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that
   represents Event and return it.

Arguments:

  Head  - Head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER
           structures.

  Event - Event to be search for in the Head list.

Returns: 

  EFI_DATA_HUB_FILTER_DRIVER - Returned if Event stored in the
                               Head doubly linked list.

  NULL - If Event is not in the list

--*/
{
  DATA_HUB_FILTER_DRIVER  *FilterEntry;
  EFI_LIST_ENTRY          *Link;

  for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
    FilterEntry = FILTER_ENTRY_FROM_LINK (Link);
    if (FilterEntry->Event == Event) {
      return FilterEntry;
    }
  }

  return NULL;
}

STATIC
EFI_DATA_RECORD_HEADER *
GetNextDataRecord (
  IN  EFI_LIST_ENTRY      *Head,
  IN  UINT64              ClassFilter,
  IN OUT  UINT64          *PtrCurrentMTC
  )
/*++

Routine Description:
  Search the Head doubly linked list for the passed in MTC. Return the 
   matching element in Head and the MTC on the next entry.

Arguments:

  Head          - Head of Data Log linked list.

  ClassFilter   - Only match the MTC if it is in the same Class as the
                  ClassFilter.

  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.
  
Returns:

  EFI_DATA_LOG_ENTRY - Return pointer to data log data from Head list.

  NULL - If no data record exists.

--*/
{
  EFI_DATA_ENTRY          *LogEntry;
  EFI_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 = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
    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 = Link->ForwardLink; Link != Head; Link = Link->ForwardLink) {
        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;
}
//
// Module Global:
//  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;

EFI_DRIVER_ENTRY_POINT (DataHubInstall)

EFI_STATUS
EFIAPI
DataHubInstall (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
/*++

Routine Description:
  Install Driver to produce Data Hub protocol. 

Arguments:
  (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)

Returns: 

  EFI_SUCCESS - Logging Hub protocol installed

  Other       - No protocol installed, unload driver.

--*/
{
  EFI_STATUS  Status;
  UINT32      HighMontonicCount;

  EfiInitializeDriverLib (ImageHandle, SystemTable);

  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, EFI_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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -