Home | History | Annotate | Download | only in DataHubStdErrDxe
      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