]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c
Add DataHub & DataHubStdErr modules
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / DataHub / DataHubStdErr / Dxe / DataHubStdErr.c
diff --git a/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c b/IntelFrameworkModulePkg/Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.c
new file mode 100644 (file)
index 0000000..50e40c0
--- /dev/null
@@ -0,0 +1,181 @@
+/*++\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