--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Module Name:\r
+\r
+ DataHubStdErr.c\r
+\r
+Abstract:\r
+\r
+ Data Hub filter driver that takes DEBUG () info from Data Hub and writes it\r
+ to StdErr if it exists.\r
+\r
+--*/\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiDxe.h>\r
+#include <Common/FrameworkStatusCode.h>\r
+//\r
+// The protocols, PPI and GUID defintions for this module\r
+//\r
+#include <Guid/StatusCode.h>\r
+#include <Guid/StatusCodeDataTypeId.h>\r
+#include <Protocol/DataHub.h>\r
+#include <Protocol/SimpleTextOut.h>\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+EFI_DATA_HUB_PROTOCOL *mDataHub = NULL;\r
+\r
+EFI_EVENT mDataHubStdErrEvent;\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+DataHubStdErrEventHandler (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Event handler registered with the Data Hub to parse EFI_DEBUG_CODE. This\r
+ handler reads the Data Hub and sends any DEBUG info to StdErr.\r
+\r
+Arguments:\r
+ Event - The event that occured, not used\r
+ Context - DataHub Protocol Pointer\r
+\r
+Returns:\r
+ None.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DATA_HUB_PROTOCOL *DataHub;\r
+ EFI_DATA_RECORD_HEADER *Record;\r
+ DATA_HUB_STATUS_CODE_DATA_RECORD *DataRecord;\r
+ UINT64 Mtc;\r
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Sto;\r
+ INT32 OldAttribute;\r
+\r
+ DataHub = (EFI_DATA_HUB_PROTOCOL *) Context;\r
+\r
+ //\r
+ // If StdErr is not yet initialized just return a DEBUG print in the BDS\r
+ // after consoles are connect will make sure data gets flushed properly\r
+ // when StdErr is availible.\r
+ //\r
+ if (gST == NULL) {\r
+ return ;\r
+ }\r
+\r
+ if (gST->StdErr == NULL) {\r
+ return ;\r
+ }\r
+ //\r
+ // Mtc of zero means return the next record that has not been read by the\r
+ // event handler.\r
+ //\r
+ Mtc = 0;\r
+ do {\r
+ Status = DataHub->GetNextRecord (DataHub, &Mtc, &mDataHubStdErrEvent, &Record);\r
+ if (!EFI_ERROR (Status)) {\r
+ if (CompareGuid (&Record->DataRecordGuid, &gEfiStatusCodeGuid)) {\r
+ DataRecord = (DATA_HUB_STATUS_CODE_DATA_RECORD *) (((CHAR8 *) Record) + Record->HeaderSize);\r
+\r
+ if (DataRecord->Data.HeaderSize > 0) {\r
+ if (CompareGuid (&DataRecord->Data.Type, &gEfiStatusCodeDataTypeDebugGuid)) {\r
+ //\r
+ // If the Data record is from a DEBUG () then send it to Standard Error\r
+ //\r
+ Sto = gST->StdErr;\r
+ OldAttribute = Sto->Mode->Attribute;\r
+ Sto->SetAttribute (Sto, EFI_TEXT_ATTR (EFI_MAGENTA, EFI_BLACK));\r
+ Sto->OutputString (Sto, (CHAR16 *) (DataRecord + 1));\r
+ Sto->SetAttribute (Sto, OldAttribute);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } while ((Mtc != 0) && !EFI_ERROR (Status));\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+DataHubStdErrInitialize (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Register an event handler with the Data Hub to parse EFI_DEBUG_CODE. This\r
+ handler reads the Data Hub and sends any DEBUG info to StdErr.\r
+\r
+Arguments:\r
+\r
+ ImageHandle - Image handle of this driver.\r
+ SystemTable - Pointer to EFI system table.\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - The event handler was registered.\r
+ EFI_OUT_OF_RESOURCES - The event hadler was not registered due to lack of\r
+ system resources.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 DataClass;\r
+\r
+ gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **) &mDataHub);\r
+ //\r
+ // Should never fail due to Depex grammer.\r
+ //\r
+ ASSERT (mDataHub != NULL);\r
+\r
+ //\r
+ // Create an event and register it with the filter driver\r
+ //\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ DataHubStdErrEventHandler,\r
+ mDataHub,\r
+ &mDataHubStdErrEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ DataClass = EFI_DATA_RECORD_CLASS_DEBUG | EFI_DATA_RECORD_CLASS_ERROR;\r
+ Status = mDataHub->RegisterFilterDriver (\r
+ mDataHub,\r
+ mDataHubStdErrEvent,\r
+ TPL_CALLBACK,\r
+ DataClass,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->CloseEvent (mDataHubStdErrEvent);\r
+ }\r
+\r
+ return Status;\r
+}\r