12ab239290ded075c540a463815dae5e74fea52c6klu/** @file 283f6d1a03b9037663fb1587d135020c7333235cbqhuang This code produces the Data Hub protocol. It preloads the data hub 383f6d1a03b9037663fb1587d135020c7333235cbqhuang with status information copied in from PEI HOBs. 483f6d1a03b9037663fb1587d135020c7333235cbqhuang 56692e0a89e3f4e6ffb101060e811990ac2815be5Hao WuCopyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR> 6180a5a35cb49699bd249dee19e41cee34c856a58hhtianThis program and the accompanying materials 73db510989eb500296c3f4839c427325a02aea2e3kluare licensed and made available under the terms and conditions of the BSD License 83db510989eb500296c3f4839c427325a02aea2e3kluwhich accompanies this distribution. The full text of the license may be found at 93db510989eb500296c3f4839c427325a02aea2e3kluhttp://opensource.org/licenses/bsd-license.php 103db510989eb500296c3f4839c427325a02aea2e3klu 113db510989eb500296c3f4839c427325a02aea2e3kluTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 123db510989eb500296c3f4839c427325a02aea2e3kluWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 133db510989eb500296c3f4839c427325a02aea2e3klu 143db510989eb500296c3f4839c427325a02aea2e3klu**/ 1583f6d1a03b9037663fb1587d135020c7333235cbqhuang 1683f6d1a03b9037663fb1587d135020c7333235cbqhuang#include "DataHub.h" 1783f6d1a03b9037663fb1587d135020c7333235cbqhuang 1883f6d1a03b9037663fb1587d135020c7333235cbqhuang// 199f6531d14d145918079d03926ff827f6c1a274a4gikidy// Since this driver will only ever produce one instance of the Logging Hub 209f6531d14d145918079d03926ff827f6c1a274a4gikidy// protocol you are not required to dynamically allocate the PrivateData. 219f6531d14d145918079d03926ff827f6c1a274a4gikidy// 229f6531d14d145918079d03926ff827f6c1a274a4gikidyDATA_HUB_INSTANCE mPrivateData; 239f6531d14d145918079d03926ff827f6c1a274a4gikidy 24a73d0c743b5192b1038a24711525eed71dfa300fklu/** 25a73d0c743b5192b1038a24711525eed71dfa300fklu Log data record into the data logging hub 26a73d0c743b5192b1038a24711525eed71dfa300fklu 272ab239290ded075c540a463815dae5e74fea52c6klu @param This Protocol instance structure 282ab239290ded075c540a463815dae5e74fea52c6klu @param DataRecordGuid GUID that defines record contents 292ab239290ded075c540a463815dae5e74fea52c6klu @param ProducerName GUID that defines the name of the producer of the data 302ab239290ded075c540a463815dae5e74fea52c6klu @param DataRecordClass Class that defines generic record type 312ab239290ded075c540a463815dae5e74fea52c6klu @param RawData Data Log record as defined by DataRecordGuid 322ab239290ded075c540a463815dae5e74fea52c6klu @param RawDataSize Size of Data Log data in bytes 33a73d0c743b5192b1038a24711525eed71dfa300fklu 342ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_SUCCESS If data was logged 352ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_OUT_OF_RESOURCES If data was not logged due to lack of system 362ab239290ded075c540a463815dae5e74fea52c6klu resources. 37a73d0c743b5192b1038a24711525eed71dfa300fklu**/ 3883f6d1a03b9037663fb1587d135020c7333235cbqhuangEFI_STATUS 3983f6d1a03b9037663fb1587d135020c7333235cbqhuangEFIAPI 4083f6d1a03b9037663fb1587d135020c7333235cbqhuangDataHubLogData ( 4183f6d1a03b9037663fb1587d135020c7333235cbqhuang IN EFI_DATA_HUB_PROTOCOL *This, 4283f6d1a03b9037663fb1587d135020c7333235cbqhuang IN EFI_GUID *DataRecordGuid, 4383f6d1a03b9037663fb1587d135020c7333235cbqhuang IN EFI_GUID *ProducerName, 4483f6d1a03b9037663fb1587d135020c7333235cbqhuang IN UINT64 DataRecordClass, 4583f6d1a03b9037663fb1587d135020c7333235cbqhuang IN VOID *RawData, 4683f6d1a03b9037663fb1587d135020c7333235cbqhuang IN UINT32 RawDataSize 4783f6d1a03b9037663fb1587d135020c7333235cbqhuang ) 4883f6d1a03b9037663fb1587d135020c7333235cbqhuang{ 4983f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_STATUS Status; 5083f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_INSTANCE *Private; 5183f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_ENTRY *LogEntry; 5283f6d1a03b9037663fb1587d135020c7333235cbqhuang UINT32 TotalSize; 5383f6d1a03b9037663fb1587d135020c7333235cbqhuang UINT32 RecordSize; 5483f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_RECORD_HEADER *Record; 5583f6d1a03b9037663fb1587d135020c7333235cbqhuang VOID *Raw; 5683f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_FILTER_DRIVER *FilterEntry; 5783f6d1a03b9037663fb1587d135020c7333235cbqhuang LIST_ENTRY *Link; 5883f6d1a03b9037663fb1587d135020c7333235cbqhuang LIST_ENTRY *Head; 59b4c900588691090ae931a630b93f5c8753677e68lgao EFI_TIME LogTime; 6083f6d1a03b9037663fb1587d135020c7333235cbqhuang 6183f6d1a03b9037663fb1587d135020c7333235cbqhuang Private = DATA_HUB_INSTANCE_FROM_THIS (This); 6283f6d1a03b9037663fb1587d135020c7333235cbqhuang 6383f6d1a03b9037663fb1587d135020c7333235cbqhuang // 6483f6d1a03b9037663fb1587d135020c7333235cbqhuang // Combine the storage for the internal structs and a copy of the log record. 6583f6d1a03b9037663fb1587d135020c7333235cbqhuang // Record follows PrivateLogEntry. The consumer will be returned a pointer 6683f6d1a03b9037663fb1587d135020c7333235cbqhuang // to Record so we don't what it to be the thing that was allocated from 6783f6d1a03b9037663fb1587d135020c7333235cbqhuang // pool, so the consumer can't free an data record by mistake. 6883f6d1a03b9037663fb1587d135020c7333235cbqhuang // 6983f6d1a03b9037663fb1587d135020c7333235cbqhuang RecordSize = sizeof (EFI_DATA_RECORD_HEADER) + RawDataSize; 7083f6d1a03b9037663fb1587d135020c7333235cbqhuang TotalSize = sizeof (EFI_DATA_ENTRY) + RecordSize; 71b4c900588691090ae931a630b93f5c8753677e68lgao 72b4c900588691090ae931a630b93f5c8753677e68lgao // 73b4c900588691090ae931a630b93f5c8753677e68lgao // First try to get log time at TPL level <= TPL_CALLBACK. 74b4c900588691090ae931a630b93f5c8753677e68lgao // 75b4c900588691090ae931a630b93f5c8753677e68lgao ZeroMem (&LogTime, sizeof (LogTime)); 76b4c900588691090ae931a630b93f5c8753677e68lgao if (EfiGetCurrentTpl() <= TPL_CALLBACK) { 77b4c900588691090ae931a630b93f5c8753677e68lgao gRT->GetTime (&LogTime, NULL); 78b4c900588691090ae931a630b93f5c8753677e68lgao } 7983f6d1a03b9037663fb1587d135020c7333235cbqhuang 8083f6d1a03b9037663fb1587d135020c7333235cbqhuang // 8183f6d1a03b9037663fb1587d135020c7333235cbqhuang // The Logging action is the critical section, so it is locked. 82b4c900588691090ae931a630b93f5c8753677e68lgao // The MTC asignment & update and logging must be an 8383f6d1a03b9037663fb1587d135020c7333235cbqhuang // atomic operation, so use the lock. 8483f6d1a03b9037663fb1587d135020c7333235cbqhuang // 8583f6d1a03b9037663fb1587d135020c7333235cbqhuang Status = EfiAcquireLockOrFail (&Private->DataLock); 8683f6d1a03b9037663fb1587d135020c7333235cbqhuang if (EFI_ERROR (Status)) { 8783f6d1a03b9037663fb1587d135020c7333235cbqhuang // 8883f6d1a03b9037663fb1587d135020c7333235cbqhuang // Reentrancy detected so exit! 8983f6d1a03b9037663fb1587d135020c7333235cbqhuang // 9083f6d1a03b9037663fb1587d135020c7333235cbqhuang return Status; 9183f6d1a03b9037663fb1587d135020c7333235cbqhuang } 9283f6d1a03b9037663fb1587d135020c7333235cbqhuang 9383f6d1a03b9037663fb1587d135020c7333235cbqhuang LogEntry = AllocatePool (TotalSize); 9483f6d1a03b9037663fb1587d135020c7333235cbqhuang 9583f6d1a03b9037663fb1587d135020c7333235cbqhuang if (LogEntry == NULL) { 9683f6d1a03b9037663fb1587d135020c7333235cbqhuang EfiReleaseLock (&Private->DataLock); 9783f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_OUT_OF_RESOURCES; 9883f6d1a03b9037663fb1587d135020c7333235cbqhuang } 9983f6d1a03b9037663fb1587d135020c7333235cbqhuang 10083f6d1a03b9037663fb1587d135020c7333235cbqhuang ZeroMem (LogEntry, TotalSize); 10183f6d1a03b9037663fb1587d135020c7333235cbqhuang 10283f6d1a03b9037663fb1587d135020c7333235cbqhuang Record = (EFI_DATA_RECORD_HEADER *) (LogEntry + 1); 10383f6d1a03b9037663fb1587d135020c7333235cbqhuang Raw = (VOID *) (Record + 1); 10483f6d1a03b9037663fb1587d135020c7333235cbqhuang 10583f6d1a03b9037663fb1587d135020c7333235cbqhuang // 10683f6d1a03b9037663fb1587d135020c7333235cbqhuang // Build Standard Log Header 10783f6d1a03b9037663fb1587d135020c7333235cbqhuang // 10883f6d1a03b9037663fb1587d135020c7333235cbqhuang Record->Version = EFI_DATA_RECORD_HEADER_VERSION; 10913314ba32a0b7eadda3c2340090b66bc0b99cd26xli Record->HeaderSize = (UINT16) sizeof (EFI_DATA_RECORD_HEADER); 11083f6d1a03b9037663fb1587d135020c7333235cbqhuang Record->RecordSize = RecordSize; 11183f6d1a03b9037663fb1587d135020c7333235cbqhuang CopyMem (&Record->DataRecordGuid, DataRecordGuid, sizeof (EFI_GUID)); 11283f6d1a03b9037663fb1587d135020c7333235cbqhuang CopyMem (&Record->ProducerName, ProducerName, sizeof (EFI_GUID)); 11383f6d1a03b9037663fb1587d135020c7333235cbqhuang Record->DataRecordClass = DataRecordClass; 11483f6d1a03b9037663fb1587d135020c7333235cbqhuang 11541e4912f2932985647927229118179d1f5eb0283eric_tian // 11641e4912f2932985647927229118179d1f5eb0283eric_tian // Ensure LogMonotonicCount is not zero 11741e4912f2932985647927229118179d1f5eb0283eric_tian // 11841e4912f2932985647927229118179d1f5eb0283eric_tian Record->LogMonotonicCount = ++Private->GlobalMonotonicCount; 11983f6d1a03b9037663fb1587d135020c7333235cbqhuang 120b4c900588691090ae931a630b93f5c8753677e68lgao CopyMem (&Record->LogTime, &LogTime, sizeof (LogTime)); 12183f6d1a03b9037663fb1587d135020c7333235cbqhuang 12283f6d1a03b9037663fb1587d135020c7333235cbqhuang // 12383f6d1a03b9037663fb1587d135020c7333235cbqhuang // Insert log into the internal linked list. 12483f6d1a03b9037663fb1587d135020c7333235cbqhuang // 12583f6d1a03b9037663fb1587d135020c7333235cbqhuang LogEntry->Signature = EFI_DATA_ENTRY_SIGNATURE; 12683f6d1a03b9037663fb1587d135020c7333235cbqhuang LogEntry->Record = Record; 12783f6d1a03b9037663fb1587d135020c7333235cbqhuang LogEntry->RecordSize = sizeof (EFI_DATA_ENTRY) + RawDataSize; 12883f6d1a03b9037663fb1587d135020c7333235cbqhuang InsertTailList (&Private->DataListHead, &LogEntry->Link); 12983f6d1a03b9037663fb1587d135020c7333235cbqhuang 13083f6d1a03b9037663fb1587d135020c7333235cbqhuang CopyMem (Raw, RawData, RawDataSize); 13183f6d1a03b9037663fb1587d135020c7333235cbqhuang 13283f6d1a03b9037663fb1587d135020c7333235cbqhuang EfiReleaseLock (&Private->DataLock); 13383f6d1a03b9037663fb1587d135020c7333235cbqhuang 13483f6d1a03b9037663fb1587d135020c7333235cbqhuang // 13583f6d1a03b9037663fb1587d135020c7333235cbqhuang // Send Signal to all the filter drivers which are interested 13683f6d1a03b9037663fb1587d135020c7333235cbqhuang // in the record's class and guid. 13783f6d1a03b9037663fb1587d135020c7333235cbqhuang // 13883f6d1a03b9037663fb1587d135020c7333235cbqhuang Head = &Private->FilterDriverListHead; 1392ab239290ded075c540a463815dae5e74fea52c6klu for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { 14083f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterEntry = FILTER_ENTRY_FROM_LINK (Link); 14183f6d1a03b9037663fb1587d135020c7333235cbqhuang if (((FilterEntry->ClassFilter & DataRecordClass) != 0) && 14283f6d1a03b9037663fb1587d135020c7333235cbqhuang (CompareGuid (&FilterEntry->FilterDataRecordGuid, &gZeroGuid) || 14383f6d1a03b9037663fb1587d135020c7333235cbqhuang CompareGuid (&FilterEntry->FilterDataRecordGuid, DataRecordGuid))) { 14483f6d1a03b9037663fb1587d135020c7333235cbqhuang gBS->SignalEvent (FilterEntry->Event); 14583f6d1a03b9037663fb1587d135020c7333235cbqhuang } 14683f6d1a03b9037663fb1587d135020c7333235cbqhuang } 14783f6d1a03b9037663fb1587d135020c7333235cbqhuang 14883f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_SUCCESS; 14983f6d1a03b9037663fb1587d135020c7333235cbqhuang} 15083f6d1a03b9037663fb1587d135020c7333235cbqhuang 151a73d0c743b5192b1038a24711525eed71dfa300fklu/** 1528b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu Search the Head doubly linked list for the passed in MTC. Return the 1538b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu matching element in Head and the MTC on the next entry. 1548b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 1558b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @param Head Head of Data Log linked list. 1568b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @param ClassFilter Only match the MTC if it is in the same Class as the 1578b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu ClassFilter. 1588b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @param PtrCurrentMTC On IN contians MTC to search for. On OUT contians next 1598b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu MTC in the data log list or zero if at end of the list. 1608b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 1618b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @retval EFI_DATA_LOG_ENTRY Return pointer to data log data from Head list. 1628b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @retval NULL If no data record exists. 1638b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 1648b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu**/ 1658b7a3578165b14ebbadc08e80fdfdf88fd2afde4kluEFI_DATA_RECORD_HEADER * 1668b7a3578165b14ebbadc08e80fdfdf88fd2afde4kluGetNextDataRecord ( 1678b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu IN LIST_ENTRY *Head, 1688b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu IN UINT64 ClassFilter, 1698b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu IN OUT UINT64 *PtrCurrentMTC 1708b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu ) 1718b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 1728b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu{ 1738b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu EFI_DATA_ENTRY *LogEntry; 1748b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu LIST_ENTRY *Link; 1758b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu BOOLEAN ReturnFirstEntry; 1768b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu EFI_DATA_RECORD_HEADER *Record; 1778b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu EFI_DATA_ENTRY *NextLogEntry; 1788b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 1798b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 1808b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // If MonotonicCount == 0 just return the first one 1818b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 1828b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu ReturnFirstEntry = (BOOLEAN) (*PtrCurrentMTC == 0); 1838b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 1848b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu Record = NULL; 1858b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { 1868b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu LogEntry = DATA_ENTRY_FROM_LINK (Link); 1878b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu if ((LogEntry->Record->DataRecordClass & ClassFilter) == 0) { 1888b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 1898b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // Skip any entry that does not have the correct ClassFilter 1908b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 1918b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu continue; 1928b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu } 1938b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 1948b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu if ((LogEntry->Record->LogMonotonicCount == *PtrCurrentMTC) || ReturnFirstEntry) { 1958b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 1968b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // Return record to the user 1978b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 1988b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu Record = LogEntry->Record; 1998b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2008b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 2018b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // Calculate the next MTC value. If there is no next entry set 2028b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // MTC to zero. 2038b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 2048b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu *PtrCurrentMTC = 0; 2058b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu for (Link = GetNextNode(Head, Link); Link != Head; Link = GetNextNode(Head, Link)) { 2068b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu NextLogEntry = DATA_ENTRY_FROM_LINK (Link); 2078b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu if ((NextLogEntry->Record->DataRecordClass & ClassFilter) != 0) { 2088b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 2098b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // Return the MTC of the next thing to search for if found 2108b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 2118b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu *PtrCurrentMTC = NextLogEntry->Record->LogMonotonicCount; 2128b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu break; 2138b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu } 2148b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu } 2158b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 2168b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // Record found exit loop and return 2178b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu // 2188b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu break; 2198b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu } 2208b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu } 2218b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2228b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu return Record; 2238b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu} 2248b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2258b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu/** 2268b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu Search the Head list for a EFI_DATA_HUB_FILTER_DRIVER member that 2278b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu represents Event and return it. 2288b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2298b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @param Head Pointer to head of dual linked list of EFI_DATA_HUB_FILTER_DRIVER structures. 2308b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @param Event Event to be search for in the Head list. 2318b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2328b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @retval EFI_DATA_HUB_FILTER_DRIVER Returned if Event stored in the Head doubly linked list. 2338b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu @retval NULL If Event is not in the list 2348b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2358b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu**/ 2368b7a3578165b14ebbadc08e80fdfdf88fd2afde4kluDATA_HUB_FILTER_DRIVER * 2378b7a3578165b14ebbadc08e80fdfdf88fd2afde4kluFindFilterDriverByEvent ( 2388b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu IN LIST_ENTRY *Head, 2398b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu IN EFI_EVENT Event 2408b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu ) 2418b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu{ 2428b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu DATA_HUB_FILTER_DRIVER *FilterEntry; 2438b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu LIST_ENTRY *Link; 2448b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2458b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu for (Link = GetFirstNode(Head); Link != Head; Link = GetNextNode(Head, Link)) { 2468b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu FilterEntry = FILTER_ENTRY_FROM_LINK (Link); 2478b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu if (FilterEntry->Event == Event) { 2488b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu return FilterEntry; 2498b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu } 2508b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu } 2518b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2528b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu return NULL; 2538b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu} 2548b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu 2558b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu/** 25683f6d1a03b9037663fb1587d135020c7333235cbqhuang 25783f6d1a03b9037663fb1587d135020c7333235cbqhuang Get a previously logged data record and the MonotonicCount for the next 25883f6d1a03b9037663fb1587d135020c7333235cbqhuang availible Record. This allows all records or all records later 25983f6d1a03b9037663fb1587d135020c7333235cbqhuang than a give MonotonicCount to be returned. If an optional FilterDriverEvent 26083f6d1a03b9037663fb1587d135020c7333235cbqhuang is passed in with a MonotonicCout of zero return the first record 26183f6d1a03b9037663fb1587d135020c7333235cbqhuang not yet read by the filter driver. If FilterDriverEvent is NULL and 26283f6d1a03b9037663fb1587d135020c7333235cbqhuang MonotonicCount is zero return the first data record. 26383f6d1a03b9037663fb1587d135020c7333235cbqhuang 2642ab239290ded075c540a463815dae5e74fea52c6klu @param This Pointer to the EFI_DATA_HUB_PROTOCOL instance. 2652ab239290ded075c540a463815dae5e74fea52c6klu @param MonotonicCount Specifies the Record to return. On input, zero means 2662ab239290ded075c540a463815dae5e74fea52c6klu return the first record. On output, contains the next 2672ab239290ded075c540a463815dae5e74fea52c6klu record to availible. Zero indicates no more records. 2682ab239290ded075c540a463815dae5e74fea52c6klu @param FilterDriverEvent If FilterDriverEvent is not passed in a MonotonicCount 2692ab239290ded075c540a463815dae5e74fea52c6klu of zero, it means to return the first data record. 2702ab239290ded075c540a463815dae5e74fea52c6klu If FilterDriverEvent is passed in, then a MonotonicCount 2712ab239290ded075c540a463815dae5e74fea52c6klu of zero means to return the first data not yet read by 2722ab239290ded075c540a463815dae5e74fea52c6klu FilterDriverEvent. 2732ab239290ded075c540a463815dae5e74fea52c6klu @param Record Returns a dynamically allocated memory buffer with a data 2742ab239290ded075c540a463815dae5e74fea52c6klu record that matches MonotonicCount. 2752ab239290ded075c540a463815dae5e74fea52c6klu 2762ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_SUCCESS Data was returned in Record. 2772ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_INVALID_PARAMETER FilterDriverEvent was passed in but does not exist. 2782ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_NOT_FOUND MonotonicCount does not match any data record in the 2792ab239290ded075c540a463815dae5e74fea52c6klu system. If a MonotonicCount of zero was passed in, then 2802ab239290ded075c540a463815dae5e74fea52c6klu no data records exist in the system. 2812ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_OUT_OF_RESOURCES Record was not returned due to lack of system resources. 28283f6d1a03b9037663fb1587d135020c7333235cbqhuang 283a73d0c743b5192b1038a24711525eed71dfa300fklu**/ 284a73d0c743b5192b1038a24711525eed71dfa300fkluEFI_STATUS 285a73d0c743b5192b1038a24711525eed71dfa300fkluEFIAPI 286a73d0c743b5192b1038a24711525eed71dfa300fkluDataHubGetNextRecord ( 287a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_DATA_HUB_PROTOCOL *This, 288a73d0c743b5192b1038a24711525eed71dfa300fklu IN OUT UINT64 *MonotonicCount, 289a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_EVENT *FilterDriverEvent, OPTIONAL 290a73d0c743b5192b1038a24711525eed71dfa300fklu OUT EFI_DATA_RECORD_HEADER **Record 291a73d0c743b5192b1038a24711525eed71dfa300fklu ) 29283f6d1a03b9037663fb1587d135020c7333235cbqhuang{ 29383f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_INSTANCE *Private; 29483f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_FILTER_DRIVER *FilterDriver; 29583f6d1a03b9037663fb1587d135020c7333235cbqhuang UINT64 ClassFilter; 29683f6d1a03b9037663fb1587d135020c7333235cbqhuang 29783f6d1a03b9037663fb1587d135020c7333235cbqhuang Private = DATA_HUB_INSTANCE_FROM_THIS (This); 29883f6d1a03b9037663fb1587d135020c7333235cbqhuang 29983f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver = NULL; 30083f6d1a03b9037663fb1587d135020c7333235cbqhuang ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG | 30183f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_RECORD_CLASS_ERROR | 30283f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_RECORD_CLASS_DATA | 30383f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_RECORD_CLASS_PROGRESS_CODE; 30483f6d1a03b9037663fb1587d135020c7333235cbqhuang 305d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 306d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // If FilterDriverEvent is NULL, then return the next record 307d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 308d2720e0ce8fc47df268f7b494469114391115ec9mdkinney if (FilterDriverEvent == NULL) { 309d2720e0ce8fc47df268f7b494469114391115ec9mdkinney *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); 310d2720e0ce8fc47df268f7b494469114391115ec9mdkinney if (*Record == NULL) { 311d2720e0ce8fc47df268f7b494469114391115ec9mdkinney return EFI_NOT_FOUND; 31283f6d1a03b9037663fb1587d135020c7333235cbqhuang } 313d2720e0ce8fc47df268f7b494469114391115ec9mdkinney return EFI_SUCCESS; 314d2720e0ce8fc47df268f7b494469114391115ec9mdkinney } 315d2720e0ce8fc47df268f7b494469114391115ec9mdkinney 316d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 317d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // For events the beginning is the last unread record. This info is 318d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // stored in the instance structure, so we must look up the event 319d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // to get the data. 320d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 321d2720e0ce8fc47df268f7b494469114391115ec9mdkinney FilterDriver = FindFilterDriverByEvent ( 322d2720e0ce8fc47df268f7b494469114391115ec9mdkinney &Private->FilterDriverListHead, 323d2720e0ce8fc47df268f7b494469114391115ec9mdkinney *FilterDriverEvent 324d2720e0ce8fc47df268f7b494469114391115ec9mdkinney ); 325d2720e0ce8fc47df268f7b494469114391115ec9mdkinney if (FilterDriver == NULL) { 326d2720e0ce8fc47df268f7b494469114391115ec9mdkinney return EFI_INVALID_PARAMETER; 327d2720e0ce8fc47df268f7b494469114391115ec9mdkinney } 328d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 329d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // Use the Class filter the event was created with. 330d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 331d2720e0ce8fc47df268f7b494469114391115ec9mdkinney ClassFilter = FilterDriver->ClassFilter; 33283f6d1a03b9037663fb1587d135020c7333235cbqhuang 333d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 334d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // Retrieve the next record or the first record. 335d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 336d2720e0ce8fc47df268f7b494469114391115ec9mdkinney if (*MonotonicCount != 0 || FilterDriver->GetNextMonotonicCount == 0) { 337d2720e0ce8fc47df268f7b494469114391115ec9mdkinney *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); 338d2720e0ce8fc47df268f7b494469114391115ec9mdkinney if (*Record == NULL) { 339d2720e0ce8fc47df268f7b494469114391115ec9mdkinney return EFI_NOT_FOUND; 340d2720e0ce8fc47df268f7b494469114391115ec9mdkinney } 341d2720e0ce8fc47df268f7b494469114391115ec9mdkinney 342d2720e0ce8fc47df268f7b494469114391115ec9mdkinney if (*MonotonicCount != 0) { 34383f6d1a03b9037663fb1587d135020c7333235cbqhuang // 344d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // If this was not the last record then update the count associated with the filter 34583f6d1a03b9037663fb1587d135020c7333235cbqhuang // 346d2720e0ce8fc47df268f7b494469114391115ec9mdkinney FilterDriver->GetNextMonotonicCount = *MonotonicCount; 347d2720e0ce8fc47df268f7b494469114391115ec9mdkinney } else { 3482ebbe08cb6f2e1a52b672c220275bcde401a4413gikidy // 349d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // Save the MonotonicCount of the last record which has been read 3502ebbe08cb6f2e1a52b672c220275bcde401a4413gikidy // 351d2720e0ce8fc47df268f7b494469114391115ec9mdkinney FilterDriver->GetNextMonotonicCount = (*Record)->LogMonotonicCount; 35283f6d1a03b9037663fb1587d135020c7333235cbqhuang } 353d2720e0ce8fc47df268f7b494469114391115ec9mdkinney return EFI_SUCCESS; 35483f6d1a03b9037663fb1587d135020c7333235cbqhuang } 355d2720e0ce8fc47df268f7b494469114391115ec9mdkinney 356d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 357d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // This is a request to read the first record that has not been read yet. 358d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // Set MonotoicCount to the last record successfuly read 359d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 360d2720e0ce8fc47df268f7b494469114391115ec9mdkinney *MonotonicCount = FilterDriver->GetNextMonotonicCount; 361d2720e0ce8fc47df268f7b494469114391115ec9mdkinney 36283f6d1a03b9037663fb1587d135020c7333235cbqhuang // 363d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // Retrieve the last record successfuly read again, but do not return it since 364d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // it has already been returned before. 36583f6d1a03b9037663fb1587d135020c7333235cbqhuang // 36683f6d1a03b9037663fb1587d135020c7333235cbqhuang *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); 36783f6d1a03b9037663fb1587d135020c7333235cbqhuang if (*Record == NULL) { 36883f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_NOT_FOUND; 36983f6d1a03b9037663fb1587d135020c7333235cbqhuang } 370d2720e0ce8fc47df268f7b494469114391115ec9mdkinney 371d2720e0ce8fc47df268f7b494469114391115ec9mdkinney if (*MonotonicCount != 0) { 37283f6d1a03b9037663fb1587d135020c7333235cbqhuang // 373d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // Update the count associated with the filter 37483f6d1a03b9037663fb1587d135020c7333235cbqhuang // 375d2720e0ce8fc47df268f7b494469114391115ec9mdkinney FilterDriver->GetNextMonotonicCount = *MonotonicCount; 376d2720e0ce8fc47df268f7b494469114391115ec9mdkinney 377d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 378d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // Retrieve the record after the last record successfuly read 379d2720e0ce8fc47df268f7b494469114391115ec9mdkinney // 380d2720e0ce8fc47df268f7b494469114391115ec9mdkinney *Record = GetNextDataRecord (&Private->DataListHead, ClassFilter, MonotonicCount); 381d2720e0ce8fc47df268f7b494469114391115ec9mdkinney if (*Record == NULL) { 382d2720e0ce8fc47df268f7b494469114391115ec9mdkinney return EFI_NOT_FOUND; 38383f6d1a03b9037663fb1587d135020c7333235cbqhuang } 38483f6d1a03b9037663fb1587d135020c7333235cbqhuang } 385d2720e0ce8fc47df268f7b494469114391115ec9mdkinney 38683f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_SUCCESS; 38783f6d1a03b9037663fb1587d135020c7333235cbqhuang} 38883f6d1a03b9037663fb1587d135020c7333235cbqhuang 389a73d0c743b5192b1038a24711525eed71dfa300fklu/** 39083f6d1a03b9037663fb1587d135020c7333235cbqhuang This function registers the data hub filter driver that is represented 39183f6d1a03b9037663fb1587d135020c7333235cbqhuang by FilterEvent. Only one instance of each FilterEvent can be registered. 39283f6d1a03b9037663fb1587d135020c7333235cbqhuang After the FilterEvent is registered, it will be signaled so it can sync 39383f6d1a03b9037663fb1587d135020c7333235cbqhuang with data records that have been recorded prior to the FilterEvent being 39483f6d1a03b9037663fb1587d135020c7333235cbqhuang registered. 39583f6d1a03b9037663fb1587d135020c7333235cbqhuang 3962ab239290ded075c540a463815dae5e74fea52c6klu @param This Pointer to The EFI_DATA_HUB_PROTOCOL instance. 3972ab239290ded075c540a463815dae5e74fea52c6klu @param FilterEvent The EFI_EVENT to signal whenever data that matches 3982ab239290ded075c540a463815dae5e74fea52c6klu FilterClass is logged in the system. 3992ab239290ded075c540a463815dae5e74fea52c6klu @param FilterTpl The maximum EFI_TPL at which FilterEvent can be 4002ab239290ded075c540a463815dae5e74fea52c6klu signaled. It is strongly recommended that you use the 4012ab239290ded075c540a463815dae5e74fea52c6klu lowest EFI_TPL possible. 4022ab239290ded075c540a463815dae5e74fea52c6klu @param FilterClass FilterEvent will be signaled whenever a bit in 4032ab239290ded075c540a463815dae5e74fea52c6klu EFI_DATA_RECORD_HEADER.DataRecordClass is also set in 4042ab239290ded075c540a463815dae5e74fea52c6klu FilterClass. If FilterClass is zero, no class-based 4052ab239290ded075c540a463815dae5e74fea52c6klu filtering will be performed. 4062ab239290ded075c540a463815dae5e74fea52c6klu @param FilterDataRecordGuid FilterEvent will be signaled whenever FilterDataRecordGuid 4072ab239290ded075c540a463815dae5e74fea52c6klu matches EFI_DATA_RECORD_HEADER.DataRecordGuid. If 4082ab239290ded075c540a463815dae5e74fea52c6klu FilterDataRecordGuid is NULL, then no GUID-based filtering 4092ab239290ded075c540a463815dae5e74fea52c6klu will be performed. 4102ab239290ded075c540a463815dae5e74fea52c6klu 4112ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_SUCCESS The filter driver event was registered. 4122ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_ALREADY_STARTED FilterEvent was previously registered and cannot be 4132ab239290ded075c540a463815dae5e74fea52c6klu registered again. 4142ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_OUT_OF_RESOURCES The filter driver event was not registered due to lack of 4152ab239290ded075c540a463815dae5e74fea52c6klu system resources. 41683f6d1a03b9037663fb1587d135020c7333235cbqhuang 417a73d0c743b5192b1038a24711525eed71dfa300fklu**/ 418a73d0c743b5192b1038a24711525eed71dfa300fkluEFI_STATUS 419a73d0c743b5192b1038a24711525eed71dfa300fkluEFIAPI 420a73d0c743b5192b1038a24711525eed71dfa300fkluDataHubRegisterFilterDriver ( 421a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_DATA_HUB_PROTOCOL * This, 422a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_EVENT FilterEvent, 423a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_TPL FilterTpl, 424a73d0c743b5192b1038a24711525eed71dfa300fklu IN UINT64 FilterClass, 425a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_GUID * FilterDataRecordGuid OPTIONAL 426a73d0c743b5192b1038a24711525eed71dfa300fklu ) 427a73d0c743b5192b1038a24711525eed71dfa300fklu 42883f6d1a03b9037663fb1587d135020c7333235cbqhuang{ 42983f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_INSTANCE *Private; 43083f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_FILTER_DRIVER *FilterDriver; 43183f6d1a03b9037663fb1587d135020c7333235cbqhuang 43283f6d1a03b9037663fb1587d135020c7333235cbqhuang Private = DATA_HUB_INSTANCE_FROM_THIS (This); 43383f6d1a03b9037663fb1587d135020c7333235cbqhuang 43483f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver = (DATA_HUB_FILTER_DRIVER *) AllocateZeroPool (sizeof (DATA_HUB_FILTER_DRIVER)); 43583f6d1a03b9037663fb1587d135020c7333235cbqhuang if (FilterDriver == NULL) { 43683f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_OUT_OF_RESOURCES; 43783f6d1a03b9037663fb1587d135020c7333235cbqhuang } 43883f6d1a03b9037663fb1587d135020c7333235cbqhuang // 43983f6d1a03b9037663fb1587d135020c7333235cbqhuang // Initialize filter driver info 44083f6d1a03b9037663fb1587d135020c7333235cbqhuang // 44183f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver->Signature = EFI_DATA_HUB_FILTER_DRIVER_SIGNATURE; 44283f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver->Event = FilterEvent; 44383f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver->Tpl = FilterTpl; 44483f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver->GetNextMonotonicCount = 0; 44583f6d1a03b9037663fb1587d135020c7333235cbqhuang if (FilterClass == 0) { 44683f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver->ClassFilter = EFI_DATA_RECORD_CLASS_DEBUG | 44783f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_RECORD_CLASS_ERROR | 44883f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_RECORD_CLASS_DATA | 44983f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_RECORD_CLASS_PROGRESS_CODE; 45083f6d1a03b9037663fb1587d135020c7333235cbqhuang } else { 45183f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver->ClassFilter = FilterClass; 45283f6d1a03b9037663fb1587d135020c7333235cbqhuang } 45383f6d1a03b9037663fb1587d135020c7333235cbqhuang 45483f6d1a03b9037663fb1587d135020c7333235cbqhuang if (FilterDataRecordGuid != NULL) { 45583f6d1a03b9037663fb1587d135020c7333235cbqhuang CopyMem (&FilterDriver->FilterDataRecordGuid, FilterDataRecordGuid, sizeof (EFI_GUID)); 45683f6d1a03b9037663fb1587d135020c7333235cbqhuang } 45783f6d1a03b9037663fb1587d135020c7333235cbqhuang // 45883f6d1a03b9037663fb1587d135020c7333235cbqhuang // Search for duplicate entries 45983f6d1a03b9037663fb1587d135020c7333235cbqhuang // 46083f6d1a03b9037663fb1587d135020c7333235cbqhuang if (FindFilterDriverByEvent (&Private->FilterDriverListHead, FilterEvent) != NULL) { 46183f6d1a03b9037663fb1587d135020c7333235cbqhuang FreePool (FilterDriver); 46283f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_ALREADY_STARTED; 46383f6d1a03b9037663fb1587d135020c7333235cbqhuang } 46483f6d1a03b9037663fb1587d135020c7333235cbqhuang // 46583f6d1a03b9037663fb1587d135020c7333235cbqhuang // Make insertion an atomic operation with the lock. 46683f6d1a03b9037663fb1587d135020c7333235cbqhuang // 46783f6d1a03b9037663fb1587d135020c7333235cbqhuang EfiAcquireLock (&Private->DataLock); 46883f6d1a03b9037663fb1587d135020c7333235cbqhuang InsertTailList (&Private->FilterDriverListHead, &FilterDriver->Link); 46983f6d1a03b9037663fb1587d135020c7333235cbqhuang EfiReleaseLock (&Private->DataLock); 47083f6d1a03b9037663fb1587d135020c7333235cbqhuang 47183f6d1a03b9037663fb1587d135020c7333235cbqhuang // 47283f6d1a03b9037663fb1587d135020c7333235cbqhuang // Signal the Filter driver we just loaded so they will recieve all the 47383f6d1a03b9037663fb1587d135020c7333235cbqhuang // previous history. If we did not signal here we would have to wait until 47483f6d1a03b9037663fb1587d135020c7333235cbqhuang // the next data was logged to get the history. In a case where no next 47583f6d1a03b9037663fb1587d135020c7333235cbqhuang // data was logged we would never get synced up. 47683f6d1a03b9037663fb1587d135020c7333235cbqhuang // 47783f6d1a03b9037663fb1587d135020c7333235cbqhuang gBS->SignalEvent (FilterEvent); 47883f6d1a03b9037663fb1587d135020c7333235cbqhuang 47983f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_SUCCESS; 48083f6d1a03b9037663fb1587d135020c7333235cbqhuang} 48183f6d1a03b9037663fb1587d135020c7333235cbqhuang 482a73d0c743b5192b1038a24711525eed71dfa300fklu/** 48383f6d1a03b9037663fb1587d135020c7333235cbqhuang Remove a Filter Driver, so it no longer gets called when data 48483f6d1a03b9037663fb1587d135020c7333235cbqhuang information is logged. 48583f6d1a03b9037663fb1587d135020c7333235cbqhuang 4862ab239290ded075c540a463815dae5e74fea52c6klu @param This Protocol instance structure 48783f6d1a03b9037663fb1587d135020c7333235cbqhuang 4882ab239290ded075c540a463815dae5e74fea52c6klu @param FilterEvent Event that represents a filter driver that is to be 4892ab239290ded075c540a463815dae5e74fea52c6klu Unregistered. 49083f6d1a03b9037663fb1587d135020c7333235cbqhuang 4912ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_SUCCESS If FilterEvent was unregistered 4922ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_NOT_FOUND If FilterEvent does not exist 493a73d0c743b5192b1038a24711525eed71dfa300fklu**/ 494a73d0c743b5192b1038a24711525eed71dfa300fkluEFI_STATUS 495a73d0c743b5192b1038a24711525eed71dfa300fkluEFIAPI 496a73d0c743b5192b1038a24711525eed71dfa300fkluDataHubUnregisterFilterDriver ( 497a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_DATA_HUB_PROTOCOL *This, 498a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_EVENT FilterEvent 499a73d0c743b5192b1038a24711525eed71dfa300fklu ) 50083f6d1a03b9037663fb1587d135020c7333235cbqhuang{ 50183f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_INSTANCE *Private; 50283f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_FILTER_DRIVER *FilterDriver; 50383f6d1a03b9037663fb1587d135020c7333235cbqhuang 50483f6d1a03b9037663fb1587d135020c7333235cbqhuang Private = DATA_HUB_INSTANCE_FROM_THIS (This); 50583f6d1a03b9037663fb1587d135020c7333235cbqhuang 50683f6d1a03b9037663fb1587d135020c7333235cbqhuang // 50783f6d1a03b9037663fb1587d135020c7333235cbqhuang // Search for duplicate entries 50883f6d1a03b9037663fb1587d135020c7333235cbqhuang // 50983f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterDriver = FindFilterDriverByEvent ( 51083f6d1a03b9037663fb1587d135020c7333235cbqhuang &Private->FilterDriverListHead, 51183f6d1a03b9037663fb1587d135020c7333235cbqhuang FilterEvent 51283f6d1a03b9037663fb1587d135020c7333235cbqhuang ); 51383f6d1a03b9037663fb1587d135020c7333235cbqhuang if (FilterDriver == NULL) { 51483f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_NOT_FOUND; 51583f6d1a03b9037663fb1587d135020c7333235cbqhuang } 51683f6d1a03b9037663fb1587d135020c7333235cbqhuang // 51783f6d1a03b9037663fb1587d135020c7333235cbqhuang // Make removal an atomic operation with the lock 51883f6d1a03b9037663fb1587d135020c7333235cbqhuang // 51983f6d1a03b9037663fb1587d135020c7333235cbqhuang EfiAcquireLock (&Private->DataLock); 52083f6d1a03b9037663fb1587d135020c7333235cbqhuang RemoveEntryList (&FilterDriver->Link); 52183f6d1a03b9037663fb1587d135020c7333235cbqhuang EfiReleaseLock (&Private->DataLock); 52283f6d1a03b9037663fb1587d135020c7333235cbqhuang 52383f6d1a03b9037663fb1587d135020c7333235cbqhuang return EFI_SUCCESS; 52483f6d1a03b9037663fb1587d135020c7333235cbqhuang} 52583f6d1a03b9037663fb1587d135020c7333235cbqhuang 52683f6d1a03b9037663fb1587d135020c7333235cbqhuang 52783f6d1a03b9037663fb1587d135020c7333235cbqhuang 528a73d0c743b5192b1038a24711525eed71dfa300fklu/** 5292ab239290ded075c540a463815dae5e74fea52c6klu Driver's Entry point routine that install Driver to produce Data Hub protocol. 53083f6d1a03b9037663fb1587d135020c7333235cbqhuang 5312ab239290ded075c540a463815dae5e74fea52c6klu @param ImageHandle Module's image handle 5322ab239290ded075c540a463815dae5e74fea52c6klu @param SystemTable Pointer of EFI_SYSTEM_TABLE 53383f6d1a03b9037663fb1587d135020c7333235cbqhuang 5342ab239290ded075c540a463815dae5e74fea52c6klu @retval EFI_SUCCESS Logging Hub protocol installed 5352ab239290ded075c540a463815dae5e74fea52c6klu @retval Other No protocol installed, unload driver. 53683f6d1a03b9037663fb1587d135020c7333235cbqhuang 537a73d0c743b5192b1038a24711525eed71dfa300fklu**/ 538a73d0c743b5192b1038a24711525eed71dfa300fkluEFI_STATUS 539a73d0c743b5192b1038a24711525eed71dfa300fkluEFIAPI 540a73d0c743b5192b1038a24711525eed71dfa300fkluDataHubInstall ( 541a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_HANDLE ImageHandle, 542a73d0c743b5192b1038a24711525eed71dfa300fklu IN EFI_SYSTEM_TABLE *SystemTable 543a73d0c743b5192b1038a24711525eed71dfa300fklu ) 54483f6d1a03b9037663fb1587d135020c7333235cbqhuang{ 54583f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_STATUS Status; 54683f6d1a03b9037663fb1587d135020c7333235cbqhuang UINT32 HighMontonicCount; 54783f6d1a03b9037663fb1587d135020c7333235cbqhuang 54883f6d1a03b9037663fb1587d135020c7333235cbqhuang mPrivateData.Signature = DATA_HUB_INSTANCE_SIGNATURE; 54983f6d1a03b9037663fb1587d135020c7333235cbqhuang mPrivateData.DataHub.LogData = DataHubLogData; 55083f6d1a03b9037663fb1587d135020c7333235cbqhuang mPrivateData.DataHub.GetNextRecord = DataHubGetNextRecord; 55183f6d1a03b9037663fb1587d135020c7333235cbqhuang mPrivateData.DataHub.RegisterFilterDriver = DataHubRegisterFilterDriver; 55283f6d1a03b9037663fb1587d135020c7333235cbqhuang mPrivateData.DataHub.UnregisterFilterDriver = DataHubUnregisterFilterDriver; 55383f6d1a03b9037663fb1587d135020c7333235cbqhuang 55483f6d1a03b9037663fb1587d135020c7333235cbqhuang // 55583f6d1a03b9037663fb1587d135020c7333235cbqhuang // Initialize Private Data in CORE_LOGGING_HUB_INSTANCE that is 5562ab239290ded075c540a463815dae5e74fea52c6klu // required by this protocol 55783f6d1a03b9037663fb1587d135020c7333235cbqhuang // 55883f6d1a03b9037663fb1587d135020c7333235cbqhuang InitializeListHead (&mPrivateData.DataListHead); 55983f6d1a03b9037663fb1587d135020c7333235cbqhuang InitializeListHead (&mPrivateData.FilterDriverListHead); 56083f6d1a03b9037663fb1587d135020c7333235cbqhuang 561b4c900588691090ae931a630b93f5c8753677e68lgao EfiInitializeLock (&mPrivateData.DataLock, TPL_NOTIFY); 56283f6d1a03b9037663fb1587d135020c7333235cbqhuang 56383f6d1a03b9037663fb1587d135020c7333235cbqhuang // 56483f6d1a03b9037663fb1587d135020c7333235cbqhuang // Make sure we get a bigger MTC number on every boot! 56583f6d1a03b9037663fb1587d135020c7333235cbqhuang // 56683f6d1a03b9037663fb1587d135020c7333235cbqhuang Status = gRT->GetNextHighMonotonicCount (&HighMontonicCount); 56783f6d1a03b9037663fb1587d135020c7333235cbqhuang if (EFI_ERROR (Status)) { 56883f6d1a03b9037663fb1587d135020c7333235cbqhuang // 56983f6d1a03b9037663fb1587d135020c7333235cbqhuang // if system service fails pick a sane value. 57083f6d1a03b9037663fb1587d135020c7333235cbqhuang // 57183f6d1a03b9037663fb1587d135020c7333235cbqhuang mPrivateData.GlobalMonotonicCount = 0; 57283f6d1a03b9037663fb1587d135020c7333235cbqhuang } else { 57383f6d1a03b9037663fb1587d135020c7333235cbqhuang mPrivateData.GlobalMonotonicCount = LShiftU64 ((UINT64) HighMontonicCount, 32); 57483f6d1a03b9037663fb1587d135020c7333235cbqhuang } 57583f6d1a03b9037663fb1587d135020c7333235cbqhuang // 57683f6d1a03b9037663fb1587d135020c7333235cbqhuang // Make a new handle and install the protocol 57783f6d1a03b9037663fb1587d135020c7333235cbqhuang // 57883f6d1a03b9037663fb1587d135020c7333235cbqhuang mPrivateData.Handle = NULL; 57983f6d1a03b9037663fb1587d135020c7333235cbqhuang Status = gBS->InstallProtocolInterface ( 58083f6d1a03b9037663fb1587d135020c7333235cbqhuang &mPrivateData.Handle, 58183f6d1a03b9037663fb1587d135020c7333235cbqhuang &gEfiDataHubProtocolGuid, 58283f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_NATIVE_INTERFACE, 58383f6d1a03b9037663fb1587d135020c7333235cbqhuang &mPrivateData.DataHub 58483f6d1a03b9037663fb1587d135020c7333235cbqhuang ); 58583f6d1a03b9037663fb1587d135020c7333235cbqhuang return Status; 58683f6d1a03b9037663fb1587d135020c7333235cbqhuang} 587a73d0c743b5192b1038a24711525eed71dfa300fklu 588