1/** @file 2 Data Hub filter driver that takes DEBUG () info from Data Hub and writes it 3 to StdErr if it exists. 4 5Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> 6This program and the accompanying materials 7are licensed and made available under the terms and conditions of the BSD License 8which accompanies this distribution. The full text of the license may be found at 9http://opensource.org/licenses/bsd-license.php 10 11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14**/ 15 16#include <FrameworkDxe.h> 17#include <Guid/DataHubStatusCodeRecord.h> 18#include <Guid/StatusCodeDataTypeId.h> 19#include <Guid/StatusCodeDataTypeDebug.h> 20#include <Protocol/DataHub.h> 21#include <Protocol/SimpleTextOut.h> 22 23#include <Library/DebugLib.h> 24#include <Library/UefiDriverEntryPoint.h> 25#include <Library/BaseMemoryLib.h> 26#include <Library/UefiBootServicesTableLib.h> 27 28EFI_DATA_HUB_PROTOCOL *mDataHub = NULL; 29 30EFI_EVENT mDataHubStdErrEvent; 31 32/** 33 Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This 34 handler reads the Data Hub and sends any DEBUG info to StdErr. 35 36 @param Event The event that occured, not used 37 @param Context DataHub Protocol Pointer 38**/ 39VOID 40EFIAPI 41DataHubStdErrEventHandler ( 42 IN EFI_EVENT Event, 43 IN VOID *Context 44 ) 45{ 46 EFI_STATUS Status; 47 EFI_DATA_HUB_PROTOCOL *DataHub; 48 EFI_DATA_RECORD_HEADER *Record; 49 DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord; 50 UINT64 Mtc; 51 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto; 52 INT32 OldAttribute; 53 54 DataHub = (EFI_DATA_HUB_PROTOCOL *) Context; 55 56 // 57 // If StdErr is not yet initialized just return a DEBUG print in the BDS 58 // after consoles are connect will make sure data gets flushed properly 59 // when StdErr is availible. 60 // 61 if (gST == NULL) { 62 return ; 63 } 64 65 if (gST->StdErr == NULL) { 66 return ; 67 } 68 69 // 70 // Mtc of zero means return the next record that has not been read by the 71 // event handler. 72 // 73 Mtc = 0; 74 do { 75 Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record); 76 if (!EFI_ERROR (Status)) { 77 if (CompareGuid (&Record->DataRecordGuid, &gEfiDataHubStatusCodeRecordGuid)) { 78 DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize); 79 80 if (DataRecord->Data.HeaderSize > 0) { 81 if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) { 82 // 83 // If the Data record is from a DEBUG () then send it to Standard Error 84 // 85 Sto = gST->StdErr; 86 OldAttribute = Sto->Mode->Attribute; 87 Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK)); 88 Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1)); 89 Sto->SetAttribute (Sto, OldAttribute); 90 } 91 } 92 } 93 } 94 } while ((Mtc != 0) && !EFI_ERROR (Status)); 95} 96 97/** 98 Register an event handler with the Data Hub to parse EFI_DEBUG_CODE. This 99 handler reads the Data Hub and sends any DEBUG info to StdErr. 100 101 @param ImageHandle Image handle of this driver. 102 @param SystemTable Pointer to EFI system table. 103 104 @retval EFI_SUCCESS The event handler was registered. 105 @retval EFI_OUT_OF_RESOURCES The event hadler was not registered due to lack of system resources. 106**/ 107EFI_STATUS 108EFIAPI 109DataHubStdErrInitialize ( 110 IN EFI_HANDLE ImageHandle, 111 IN EFI_SYSTEM_TABLE *SystemTable 112 ) 113{ 114 EFI_STATUS Status; 115 UINT64 DataClass; 116 117 gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub); 118 // 119 // Should never fail due to Depex grammer. 120 // 121 ASSERT (mDataHub != NULL); 122 123 // 124 // Create an event and register it with the filter driver 125 // 126 Status = gBS->CreateEvent ( 127 EVT_NOTIFY_SIGNAL, 128 TPL_CALLBACK, 129 DataHubStdErrEventHandler, 130 mDataHub, 131 &mDataHubStdErrEvent 132 ); 133 if (EFI_ERROR (Status)) { 134 return Status; 135 } 136 137 DataClass = EFI_DATA_RECORD_CLASS_DEBUG | EFI_DATA_RECORD_CLASS_ERROR; 138 Status = mDataHub->RegisterFilterDriver ( 139 mDataHub, 140 mDataHubStdErrEvent, 141 TPL_CALLBACK, 142 DataClass, 143 NULL 144 ); 145 if (EFI_ERROR (Status)) { 146 gBS->CloseEvent (mDataHubStdErrEvent); 147 } 148 149 return Status; 150} 151 152