From: qhuang8 Date: Thu, 28 Jun 2007 14:01:00 +0000 (+0000) Subject: Add DataHub & DataHubStdErr modules X-Git-Tag: edk2-stable201903~23104 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=83f6d1a03b9037663fb1587d135020c7333235cb Add DataHub & DataHubStdErr modules git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2851 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.c b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.c new file mode 100644 index 0000000000..aa0cced530 --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.c @@ -0,0 +1,660 @@ +/*++ + +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. + +Module Name: + + DataHub.c + +Abstract: + + This code produces the Data Hub protocol. It preloads the data hub + with status information copied in from PEI HOBs. + + Only code that implements the Data Hub protocol should go in this file! + + The Term MTC stands for MonoTonicCounter. + + For more information please look at DataHub.doc + + NOTE: For extra security of the log GetNextDataRecord () could return a copy + of the data record. +--*/ + +#include "DataHub.h" + +CONST EFI_GUID gZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } }; + +// +// Worker functions private to this file +// +STATIC +DATA_HUB_FILTER_DRIVER * +FindFilterDriverByEvent ( + IN LIST_ENTRY *Head, + IN EFI_EVENT Event + ); + +STATIC +EFI_DATA_RECORD_HEADER * +GetNextDataRecord ( + IN LIST_ENTRY *Head, + IN UINT64 ClassFilter, + IN OUT UINT64 *PtrCurrentMTC + ); + +STATIC +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 + ) +/*++ + +Routine Description: + + Log data record into the data logging hub + +Arguments: + + This - Protocol instance structure + + DataRecordGuid - GUID that defines record contents + + ProducerName - GUID that defines the name of the producer of the data + + DataRecordClass - Class that defines generic record type + + RawData - Data Log record as defined by DataRecordGuid + + RawDataSize - Size of Data Log data in bytes + +Returns: + + EFI_SUCCESS - If data was logged + + EFI_OUT_OF_RESOURCES - If data was not logged due to lack of system + resources. +--*/ +{ + 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; + + 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; + + // + // The Logging action is the critical section, so it is locked. + // The MTC asignment & update, time, 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 = 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; + + Record->LogMonotonicCount = Private->GlobalMonotonicCount++; + + gRT->GetTime (&Record->LogTime, NULL); + + // + // 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 = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) { + 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; +} + +STATIC +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 + ) +/*++ + +Routine Description: + + 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. + +Arguments: + + This - The EFI_DATA_HUB_PROTOCOL instance. + 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. + 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. + Record - Returns a dynamically allocated memory buffer with a data + record that matches MonotonicCount. + +Returns: + + EFI_SUCCESS - Data was returned in Record. + EFI_INVALID_PARAMETER - FilterDriverEvent was passed in but does not exist. + 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. + EFI_OUT_OF_RESOURCES - Record was not returned due to lack of system resources. + +--*/ +{ + DATA_HUB_INSTANCE *Private; + DATA_HUB_FILTER_DRIVER *FilterDriver; + UINT64 ClassFilter; + UINT64 FilterMonotonicCount; + + Private = DATA_HUB_INSTANCE_FROM_THIS (This); + + FilterDriver = NULL; + FilterMonotonicCount = 0; + ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG | + EFI_DATA_RECORD_CLASS_ERROR | + EFI_DATA_RECORD_CLASS_DATA | + EFI_DATA_RECORD_CLASS_PROGRESS_CODE; + + if (FilterDriverEvent != NULL) { + // + // 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; + + if (*MonotonicCount == 0) { + // + // Use the MTC from the Filter Driver. + // + FilterMonotonicCount = FilterDriver->GetNextMonotonicCount; + if (FilterMonotonicCount != 0) { + // + // The GetNextMonotonicCount field remembers the last value from the previous time. + // But we already processed this vaule, so we need to find the next one. So if + // It is not the first time get the new record entry. + // + *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, &FilterMonotonicCount); + *MonotonicCount = FilterMonotonicCount; + if (FilterMonotonicCount == 0) { + // + // If there is no new record to get exit now. + // + return EFI_NOT_FOUND; + } + } + } + } + // + // Return the record + // + *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); + if (*Record == NULL) { + return EFI_NOT_FOUND; + } + + if (FilterDriver != NULL) { + // + // If we have a filter driver update the records that have been read. + // If MonotonicCount is zero No more reacords left. + // + if (*MonotonicCount == 0) { + if (FilterMonotonicCount != 0) { + // + // Return the result of our extra GetNextDataRecord. + // + FilterDriver->GetNextMonotonicCount = FilterMonotonicCount; + } + } else { + // + // Point to next undread record + // + FilterDriver->GetNextMonotonicCount = *MonotonicCount; + } + } + + return EFI_SUCCESS; +} + +STATIC +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 + ) +/*++ + +Routine Description: + + 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. + +Arguments: + + This - The EFI_DATA_HUB_PROTOCOL instance. + FilterEvent - The EFI_EVENT to signal whenever data that matches + 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 *) 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; +} + +STATIC +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 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; + 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 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; + 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_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; + + 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; +} diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.dxs b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.dxs new file mode 100644 index 0000000000..226acc532f --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.dxs @@ -0,0 +1,25 @@ +/*++ + +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. + +Module Name: + + DataHub.dxs + +Abstract: + + Dependency expression source file. + +--*/ +#include + +DEPENDENCY_START + TRUE +DEPENDENCY_END diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.h b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.h new file mode 100644 index 0000000000..8f90e998c6 --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.h @@ -0,0 +1,141 @@ +/*++ + +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. + +Module Name: + + DataHub.h + +Abstract: + This code supports a the private implementation + of the Data Hub protocol + +--*/ + +#ifndef _DATA_HUB_H_ +#define _DATA_HUB_H_ + +// +// The package level header files this module uses +// +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include + +#define DATA_HUB_INSTANCE_SIGNATURE EFI_SIGNATURE_32 ('D', 'H', 'u', 'b') +typedef struct { + UINT32 Signature; + + EFI_HANDLE Handle; + + // + // Produced protocol(s) + // + EFI_DATA_HUB_PROTOCOL DataHub; + + // + // Private Data + // + // + // Updates to GlobalMonotonicCount, LogListHead, and FilterDriverListHead + // must be locked. + // + EFI_LOCK DataLock; + + // + // Runing Monotonic Count to use for each error record. + // Increment AFTER use in an error record. + // + UINT64 GlobalMonotonicCount; + + // + // List of EFI_DATA_ENTRY structures. This is the data log! The list + // must be in assending order of LogMonotonicCount. + // + LIST_ENTRY DataListHead; + + // + // List of EFI_DATA_HUB_FILTER_DRIVER structures. Represents all + // the registered filter drivers. + // + LIST_ENTRY FilterDriverListHead; + +} DATA_HUB_INSTANCE; + +#define DATA_HUB_INSTANCE_FROM_THIS(this) CR (this, DATA_HUB_INSTANCE, DataHub, DATA_HUB_INSTANCE_SIGNATURE) + +// +// Private data structure to contain the data log. One record per +// structure. Head pointer to the list is the Log member of +// EFI_DATA_ENTRY. Record is a copy of the data passed in. +// +#define EFI_DATA_ENTRY_SIGNATURE EFI_SIGNATURE_32 ('D', 'r', 'e', 'c') +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + + EFI_DATA_RECORD_HEADER *Record; + + UINTN RecordSize; + +} EFI_DATA_ENTRY; + +#define DATA_ENTRY_FROM_LINK(link) CR (link, EFI_DATA_ENTRY, Link, EFI_DATA_ENTRY_SIGNATURE) + +// +// Private data to contain the filter driver Event and it's +// associated EFI_TPL. +// +#define EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('D', 'h', 'F', 'd') + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + + // + // Store Filter Driver Event and Tpl level it can be Signaled at. + // + EFI_EVENT Event; + EFI_TPL Tpl; + + // + // Monotonic count on the get next operation for Event. + // Zero indicates get next has not been called for this event yet. + // + UINT64 GetNextMonotonicCount; + + // + // Filter driver will register what class filter should be used. + // + UINT64 ClassFilter; + + // + // Filter driver will register what record guid filter should be used. + // + EFI_GUID FilterDataRecordGuid; + +} DATA_HUB_FILTER_DRIVER; + +#define FILTER_ENTRY_FROM_LINK(link) CR (link, DATA_HUB_FILTER_DRIVER, Link, EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE) + +#endif diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.inf b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.inf new file mode 100644 index 0000000000..279bb7b64c --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.inf @@ -0,0 +1,100 @@ +#/** @file +# Component description file for DataHub module. +# +# This driver initializes and installs the Data Hub protocol. +# Copyright (c) 2006 - 2007, 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DataHub + FILE_GUID = 53BCC14F-C24F-434C-B294-8ED2D4CC1860 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = DataHubInstall + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + DataHub.h + DataHub.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + IntelFrameworkPkg/IntelFrameworkPkg.dec + MdePkg/MdePkg.dec + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + BaseLib + UefiLib + UefiDriverEntryPoint + DebugLib + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiDataHubProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +################################################################################ +# +# Dependency Expression Section - list of Dependency expressions that are required for +# this module. +# +################################################################################ + +[Depex] + TRUE + diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.msa b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.msa new file mode 100644 index 0000000000..d51f6063d5 --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHub/Dxe/DataHub.msa @@ -0,0 +1,71 @@ + + + + DataHub + DXE_DRIVER + 53BCC14F-C24F-434C-B294-8ED2D4CC1860 + 1.0 + Component description file for DataHub module. + This driver initializes and installs the Data Hub protocol. + Copyright (c) 2006 - 2007, 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + DataHub + + + + DebugLib + + + UefiDriverEntryPoint + + + UefiLib + + + BaseLib + + + BaseMemoryLib + + + MemoryAllocationLib + + + UefiBootServicesTableLib + + + UefiRuntimeServicesTableLib + + + + DataHub.c + DataHub.h + DataHub.dxs + + + + + + + + gEfiDataHubProtocolGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + DataHubInstall + + + diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c new file mode 100644 index 0000000000..50e40c0bae --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c @@ -0,0 +1,181 @@ +/*++ + +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. + +Module Name: + + DataHubStdErr.c + +Abstract: + + Data Hub filter driver that takes DEBUG () info from Data Hub and writes it + to StdErr if it exists. + +--*/ + +// +// The package level header files this module uses +// +#include +#include +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include + +EFI_DATA_HUB_PROTOCOL *mDataHub = NULL; + +EFI_EVENT mDataHubStdErrEvent; + +STATIC +VOID +EFIAPI +DataHubStdErrEventHandler ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + +Routine Description: + Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This + handler reads the Data Hub and sends any DEBUG info to StdErr. + +Arguments: + Event - The event that occured, not used + Context - DataHub Protocol Pointer + +Returns: + None. + +--*/ +{ + EFI_STATUS Status; + EFI_DATA_HUB_PROTOCOL *DataHub; + EFI_DATA_RECORD_HEADER *Record; + DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord; + UINT64 Mtc; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto; + INT32 OldAttribute; + + DataHub = (EFI_DATA_HUB_PROTOCOL *) Context; + + // + // If StdErr is not yet initialized just return a DEBUG print in the BDS + // after consoles are connect will make sure data gets flushed properly + // when StdErr is availible. + // + if (gST == NULL) { + return ; + } + + if (gST->StdErr == NULL) { + return ; + } + // + // Mtc of zero means return the next record that has not been read by the + // event handler. + // + Mtc = 0; + do { + Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record); + if (!EFI_ERROR (Status)) { + if (CompareGuid (&Record->DataRecordGuid, &gEfiStatusCodeGuid)) { + DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize); + + if (DataRecord->Data.HeaderSize > 0) { + if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) { + // + // If the Data record is from a DEBUG () then send it to Standard Error + // + Sto = gST->StdErr; + OldAttribute = Sto->Mode->Attribute; + Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK)); + Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1)); + Sto->SetAttribute (Sto, OldAttribute); + } + } + } + } + } while ((Mtc != 0) && !EFI_ERROR (Status)); +} + +EFI_STATUS +EFIAPI +DataHubStdErrInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Register an event handler with the Data Hub to parse EFI_DEBUG_CODE. This + handler reads the Data Hub and sends any DEBUG info to StdErr. + +Arguments: + + ImageHandle - Image handle of this driver. + SystemTable - Pointer to EFI system table. + +Returns: + + EFI_SUCCESS - The event handler was registered. + EFI_OUT_OF_RESOURCES - The event hadler was not registered due to lack of + system resources. + +--*/ +{ + EFI_STATUS Status; + UINT64 DataClass; + + gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub); + // + // Should never fail due to Depex grammer. + // + ASSERT (mDataHub != NULL); + + // + // Create an event and register it with the filter driver + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + DataHubStdErrEventHandler, + mDataHub, + &mDataHubStdErrEvent + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DataClass = EFI_DATA_RECORD_CLASS_DEBUG | EFI_DATA_RECORD_CLASS_ERROR; + Status = mDataHub->RegisterFilterDriver ( + mDataHub, + mDataHubStdErrEvent, + TPL_CALLBACK, + DataClass, + NULL + ); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (mDataHubStdErrEvent); + } + + return Status; +} diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.dxs b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.dxs new file mode 100644 index 0000000000..9603a3e140 --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.dxs @@ -0,0 +1,26 @@ +/*++ + +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. + +Module Name: + + DataHubStdErr.dxs + +Abstract: + + Dependency expression source file. + +--*/ +#include + + +DEPENDENCY_START + EFI_DATA_HUB_PROTOCOL_GUID +DEPENDENCY_END diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.inf b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.inf new file mode 100644 index 0000000000..728e634d8d --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.inf @@ -0,0 +1,111 @@ +#/** @file +# Component description file for Data Hub filter driver. +# +# This driver takes DEBUG () info from Data Hub and writes it to StdErr if it exists. +# Copyright (c) 2006 - 2007, 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. +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DataHubStdErr + FILE_GUID = CA515306-00CE-4032-874E-11B755FF6866 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + EDK_RELEASE_VERSION = 0x00020000 + EFI_SPECIFICATION_VERSION = 0x00020000 + + ENTRY_POINT = DataHubStdErrInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources.common] + DataHubStdErr.c + +[Includes] + IntelFrameworkModulePkg/Include + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + + + + +################################################################################ +# +# Library Class Section - list of Library Classes that are required for +# this module. +# +################################################################################ + +[LibraryClasses] + UefiBootServicesTableLib + BaseMemoryLib + UefiDriverEntryPoint + DebugLib + + +################################################################################ +# +# Guid C Name Section - list of Guids that this module uses or produces. +# +################################################################################ + +[Guids] + gEfiStatusCodeDataTypeDebugGuid # SOMETIMES_CONSUMED + gEfiStatusCodeGuid # SOMETIMES_CONSUMED + + +################################################################################ +# +# Protocol C Name Section - list of Protocol and Protocol Notify C Names +# that this module uses or produces. +# +################################################################################ + +[Protocols] + gEfiDataHubProtocolGuid # PROTOCOL ALWAYS_CONSUMED + + +################################################################################ +# +# Dependency Expression Section - list of Dependency expressions that are required for +# this module. +# +################################################################################ + +[Depex] + gEfiDataHubProtocolGuid + diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa new file mode 100644 index 0000000000..b1d4c6114d --- /dev/null +++ b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa @@ -0,0 +1,73 @@ + + + + DataHubStdErr + DXE_DRIVER + CA515306-00CE-4032-874E-11B755FF6866 + 1.0 + Component description file for Data Hub filter driver. + This driver takes DEBUG () info from Data Hub and writes it to StdErr if it exists. + Copyright (c) 2006 - 2007, 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. + FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052 + + + IA32 X64 IPF EBC + false + DataHubStdErr + + + + DebugLib + + + UefiDriverEntryPoint + + + BaseMemoryLib + + + UefiBootServicesTableLib + + + + DataHubStdErr.c + DataHubStdErr.dxs + + + + + + + + + gEfiDataHubProtocolGuid + + + + + DATA_HUB_STATUS_CODE_DATA_RECORD + DEBUG() data that is recorded in status code data hub will be sent to Standard Error. + + + + + gEfiStatusCodeGuid + + + gEfiStatusCodeDataTypeDebugGuid + + + + EFI_SPECIFICATION_VERSION 0x00020000 + EDK_RELEASE_VERSION 0x00020000 + + DataHubStdErrInitialize + + +