1 /** @file 2 Data Hub filter driver that takes DEBUG () info from Data Hub and writes it 3 to StdErr if it exists. 4 5 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT 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 28 EFI_DATA_HUB_PROTOCOL *mDataHub = NULL; 29 30 EFI_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 **/ 39 VOID 40 EFIAPI 41 DataHubStdErrEventHandler ( 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 **/ 107 EFI_STATUS 108 EFIAPI 109 DataHubStdErrInitialize ( 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