18b7a3578165b14ebbadc08e80fdfdf88fd2afde4klu/** @file 23db510989eb500296c3f4839c427325a02aea2e3klu Data Hub filter driver that takes DEBUG () info from Data Hub and writes it 33db510989eb500296c3f4839c427325a02aea2e3klu to StdErr if it exists. 483f6d1a03b9037663fb1587d135020c7333235cbqhuang 5180a5a35cb49699bd249dee19e41cee34c856a58hhtianCopyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> 6180a5a35cb49699bd249dee19e41cee34c856a58hhtianThis program and the accompanying materials 783f6d1a03b9037663fb1587d135020c7333235cbqhuangare licensed and made available under the terms and conditions of the BSD License 883f6d1a03b9037663fb1587d135020c7333235cbqhuangwhich accompanies this distribution. The full text of the license may be found at 983f6d1a03b9037663fb1587d135020c7333235cbqhuanghttp://opensource.org/licenses/bsd-license.php 1083f6d1a03b9037663fb1587d135020c7333235cbqhuang 1183f6d1a03b9037663fb1587d135020c7333235cbqhuangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 1283f6d1a03b9037663fb1587d135020c7333235cbqhuangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 1383f6d1a03b9037663fb1587d135020c7333235cbqhuang 143db510989eb500296c3f4839c427325a02aea2e3klu**/ 1583f6d1a03b9037663fb1587d135020c7333235cbqhuang 16694b922c0b238c7e358bd48ddbd835fd48a29f33bxing#include <FrameworkDxe.h> 1729941df6a66ffb78925fe3baba566571607405beklu#include <Guid/DataHubStatusCodeRecord.h> 1883f6d1a03b9037663fb1587d135020c7333235cbqhuang#include <Guid/StatusCodeDataTypeId.h> 193a6064fa3b4b371476cce682d298923b06bd2745mdkinney#include <Guid/StatusCodeDataTypeDebug.h> 2083f6d1a03b9037663fb1587d135020c7333235cbqhuang#include <Protocol/DataHub.h> 2183f6d1a03b9037663fb1587d135020c7333235cbqhuang#include <Protocol/SimpleTextOut.h> 22ed7748fe4a5575adea8055c6da5948fbee65fd7avanjeff 2383f6d1a03b9037663fb1587d135020c7333235cbqhuang#include <Library/DebugLib.h> 2483f6d1a03b9037663fb1587d135020c7333235cbqhuang#include <Library/UefiDriverEntryPoint.h> 2583f6d1a03b9037663fb1587d135020c7333235cbqhuang#include <Library/BaseMemoryLib.h> 2683f6d1a03b9037663fb1587d135020c7333235cbqhuang#include <Library/UefiBootServicesTableLib.h> 2783f6d1a03b9037663fb1587d135020c7333235cbqhuang 2883f6d1a03b9037663fb1587d135020c7333235cbqhuangEFI_DATA_HUB_PROTOCOL *mDataHub = NULL; 2983f6d1a03b9037663fb1587d135020c7333235cbqhuang 3083f6d1a03b9037663fb1587d135020c7333235cbqhuangEFI_EVENT mDataHubStdErrEvent; 3183f6d1a03b9037663fb1587d135020c7333235cbqhuang 32a73d0c743b5192b1038a24711525eed71dfa300fklu/** 33a73d0c743b5192b1038a24711525eed71dfa300fklu Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This 34a73d0c743b5192b1038a24711525eed71dfa300fklu handler reads the Data Hub and sends any DEBUG info to StdErr. 35a73d0c743b5192b1038a24711525eed71dfa300fklu 360aa85c4a6bc040fdb85da96112172b68748cfd9cklu @param Event The event that occured, not used 370aa85c4a6bc040fdb85da96112172b68748cfd9cklu @param Context DataHub Protocol Pointer 38a73d0c743b5192b1038a24711525eed71dfa300fklu**/ 3983f6d1a03b9037663fb1587d135020c7333235cbqhuangVOID 4083f6d1a03b9037663fb1587d135020c7333235cbqhuangEFIAPI 4183f6d1a03b9037663fb1587d135020c7333235cbqhuangDataHubStdErrEventHandler ( 4283f6d1a03b9037663fb1587d135020c7333235cbqhuang IN EFI_EVENT Event, 4383f6d1a03b9037663fb1587d135020c7333235cbqhuang IN VOID *Context 4483f6d1a03b9037663fb1587d135020c7333235cbqhuang ) 4583f6d1a03b9037663fb1587d135020c7333235cbqhuang{ 4683f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_STATUS Status; 4783f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_HUB_PROTOCOL *DataHub; 4883f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_DATA_RECORD_HEADER *Record; 4983f6d1a03b9037663fb1587d135020c7333235cbqhuang DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord; 5083f6d1a03b9037663fb1587d135020c7333235cbqhuang UINT64 Mtc; 5183f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto; 5283f6d1a03b9037663fb1587d135020c7333235cbqhuang INT32 OldAttribute; 5383f6d1a03b9037663fb1587d135020c7333235cbqhuang 5483f6d1a03b9037663fb1587d135020c7333235cbqhuang DataHub = (EFI_DATA_HUB_PROTOCOL *) Context; 5583f6d1a03b9037663fb1587d135020c7333235cbqhuang 5683f6d1a03b9037663fb1587d135020c7333235cbqhuang // 5783f6d1a03b9037663fb1587d135020c7333235cbqhuang // If StdErr is not yet initialized just return a DEBUG print in the BDS 5883f6d1a03b9037663fb1587d135020c7333235cbqhuang // after consoles are connect will make sure data gets flushed properly 5970d3fe9dad1d7b2944a2653b3895a11863fb674eGary Lin // when StdErr is available. 6083f6d1a03b9037663fb1587d135020c7333235cbqhuang // 6183f6d1a03b9037663fb1587d135020c7333235cbqhuang if (gST == NULL) { 6283f6d1a03b9037663fb1587d135020c7333235cbqhuang return ; 6383f6d1a03b9037663fb1587d135020c7333235cbqhuang } 6483f6d1a03b9037663fb1587d135020c7333235cbqhuang 6583f6d1a03b9037663fb1587d135020c7333235cbqhuang if (gST->StdErr == NULL) { 6683f6d1a03b9037663fb1587d135020c7333235cbqhuang return ; 6783f6d1a03b9037663fb1587d135020c7333235cbqhuang } 680aa85c4a6bc040fdb85da96112172b68748cfd9cklu 6983f6d1a03b9037663fb1587d135020c7333235cbqhuang // 7083f6d1a03b9037663fb1587d135020c7333235cbqhuang // Mtc of zero means return the next record that has not been read by the 7183f6d1a03b9037663fb1587d135020c7333235cbqhuang // event handler. 7283f6d1a03b9037663fb1587d135020c7333235cbqhuang // 7383f6d1a03b9037663fb1587d135020c7333235cbqhuang Mtc = 0; 7483f6d1a03b9037663fb1587d135020c7333235cbqhuang do { 7583f6d1a03b9037663fb1587d135020c7333235cbqhuang Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record); 7683f6d1a03b9037663fb1587d135020c7333235cbqhuang if (!EFI_ERROR (Status)) { 7729941df6a66ffb78925fe3baba566571607405beklu if (CompareGuid (&Record->DataRecordGuid, &gEfiDataHubStatusCodeRecordGuid)) { 7883f6d1a03b9037663fb1587d135020c7333235cbqhuang DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize); 7983f6d1a03b9037663fb1587d135020c7333235cbqhuang 8083f6d1a03b9037663fb1587d135020c7333235cbqhuang if (DataRecord->Data.HeaderSize > 0) { 8183f6d1a03b9037663fb1587d135020c7333235cbqhuang if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) { 8283f6d1a03b9037663fb1587d135020c7333235cbqhuang // 8383f6d1a03b9037663fb1587d135020c7333235cbqhuang // If the Data record is from a DEBUG () then send it to Standard Error 8483f6d1a03b9037663fb1587d135020c7333235cbqhuang // 8583f6d1a03b9037663fb1587d135020c7333235cbqhuang Sto = gST->StdErr; 8683f6d1a03b9037663fb1587d135020c7333235cbqhuang OldAttribute = Sto->Mode->Attribute; 8783f6d1a03b9037663fb1587d135020c7333235cbqhuang Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK)); 8883f6d1a03b9037663fb1587d135020c7333235cbqhuang Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1)); 8983f6d1a03b9037663fb1587d135020c7333235cbqhuang Sto->SetAttribute (Sto, OldAttribute); 9083f6d1a03b9037663fb1587d135020c7333235cbqhuang } 9183f6d1a03b9037663fb1587d135020c7333235cbqhuang } 9283f6d1a03b9037663fb1587d135020c7333235cbqhuang } 9383f6d1a03b9037663fb1587d135020c7333235cbqhuang } 9483f6d1a03b9037663fb1587d135020c7333235cbqhuang } while ((Mtc != 0) && !EFI_ERROR (Status)); 9583f6d1a03b9037663fb1587d135020c7333235cbqhuang} 9683f6d1a03b9037663fb1587d135020c7333235cbqhuang 97a73d0c743b5192b1038a24711525eed71dfa300fklu/** 98a73d0c743b5192b1038a24711525eed71dfa300fklu Register an event handler with the Data Hub to parse EFI_DEBUG_CODE. This 99a73d0c743b5192b1038a24711525eed71dfa300fklu handler reads the Data Hub and sends any DEBUG info to StdErr. 100a73d0c743b5192b1038a24711525eed71dfa300fklu 1010aa85c4a6bc040fdb85da96112172b68748cfd9cklu @param ImageHandle Image handle of this driver. 1020aa85c4a6bc040fdb85da96112172b68748cfd9cklu @param SystemTable Pointer to EFI system table. 103a73d0c743b5192b1038a24711525eed71dfa300fklu 1040aa85c4a6bc040fdb85da96112172b68748cfd9cklu @retval EFI_SUCCESS The event handler was registered. 1050aa85c4a6bc040fdb85da96112172b68748cfd9cklu @retval EFI_OUT_OF_RESOURCES The event hadler was not registered due to lack of system resources. 106a73d0c743b5192b1038a24711525eed71dfa300fklu**/ 10783f6d1a03b9037663fb1587d135020c7333235cbqhuangEFI_STATUS 10883f6d1a03b9037663fb1587d135020c7333235cbqhuangEFIAPI 10983f6d1a03b9037663fb1587d135020c7333235cbqhuangDataHubStdErrInitialize ( 11083f6d1a03b9037663fb1587d135020c7333235cbqhuang IN EFI_HANDLE ImageHandle, 11183f6d1a03b9037663fb1587d135020c7333235cbqhuang IN EFI_SYSTEM_TABLE *SystemTable 11283f6d1a03b9037663fb1587d135020c7333235cbqhuang ) 11383f6d1a03b9037663fb1587d135020c7333235cbqhuang{ 11483f6d1a03b9037663fb1587d135020c7333235cbqhuang EFI_STATUS Status; 11583f6d1a03b9037663fb1587d135020c7333235cbqhuang UINT64 DataClass; 11683f6d1a03b9037663fb1587d135020c7333235cbqhuang 11783f6d1a03b9037663fb1587d135020c7333235cbqhuang gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub); 11883f6d1a03b9037663fb1587d135020c7333235cbqhuang // 11983f6d1a03b9037663fb1587d135020c7333235cbqhuang // Should never fail due to Depex grammer. 12083f6d1a03b9037663fb1587d135020c7333235cbqhuang // 12183f6d1a03b9037663fb1587d135020c7333235cbqhuang ASSERT (mDataHub != NULL); 12283f6d1a03b9037663fb1587d135020c7333235cbqhuang 12383f6d1a03b9037663fb1587d135020c7333235cbqhuang // 12483f6d1a03b9037663fb1587d135020c7333235cbqhuang // Create an event and register it with the filter driver 12583f6d1a03b9037663fb1587d135020c7333235cbqhuang // 12683f6d1a03b9037663fb1587d135020c7333235cbqhuang Status = gBS->CreateEvent ( 12783f6d1a03b9037663fb1587d135020c7333235cbqhuang EVT_NOTIFY_SIGNAL, 12883f6d1a03b9037663fb1587d135020c7333235cbqhuang TPL_CALLBACK, 12983f6d1a03b9037663fb1587d135020c7333235cbqhuang DataHubStdErrEventHandler, 13083f6d1a03b9037663fb1587d135020c7333235cbqhuang mDataHub, 13183f6d1a03b9037663fb1587d135020c7333235cbqhuang &mDataHubStdErrEvent 13283f6d1a03b9037663fb1587d135020c7333235cbqhuang ); 13383f6d1a03b9037663fb1587d135020c7333235cbqhuang if (EFI_ERROR (Status)) { 13483f6d1a03b9037663fb1587d135020c7333235cbqhuang return Status; 13583f6d1a03b9037663fb1587d135020c7333235cbqhuang } 13683f6d1a03b9037663fb1587d135020c7333235cbqhuang 13783f6d1a03b9037663fb1587d135020c7333235cbqhuang DataClass = EFI_DATA_RECORD_CLASS_DEBUG | EFI_DATA_RECORD_CLASS_ERROR; 13883f6d1a03b9037663fb1587d135020c7333235cbqhuang Status = mDataHub->RegisterFilterDriver ( 13983f6d1a03b9037663fb1587d135020c7333235cbqhuang mDataHub, 14083f6d1a03b9037663fb1587d135020c7333235cbqhuang mDataHubStdErrEvent, 14183f6d1a03b9037663fb1587d135020c7333235cbqhuang TPL_CALLBACK, 14283f6d1a03b9037663fb1587d135020c7333235cbqhuang DataClass, 14383f6d1a03b9037663fb1587d135020c7333235cbqhuang NULL 14483f6d1a03b9037663fb1587d135020c7333235cbqhuang ); 14583f6d1a03b9037663fb1587d135020c7333235cbqhuang if (EFI_ERROR (Status)) { 14683f6d1a03b9037663fb1587d135020c7333235cbqhuang gBS->CloseEvent (mDataHubStdErrEvent); 14783f6d1a03b9037663fb1587d135020c7333235cbqhuang } 14883f6d1a03b9037663fb1587d135020c7333235cbqhuang 14983f6d1a03b9037663fb1587d135020c7333235cbqhuang return Status; 15083f6d1a03b9037663fb1587d135020c7333235cbqhuang} 151a73d0c743b5192b1038a24711525eed71dfa300fklu 152