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