--- /dev/null
+/** @file\r
+\r
+ Debug Mask Protocol.\r
+\r
+Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under \r
+the terms and conditions of the BSD License that accompanies this distribution. \r
+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
+**/\r
+\r
+#ifndef __DEBUG_MASK_H__\r
+#define __DEBUG_MASK_H__\r
+\r
+///\r
+/// Protocol GUID for DXE Phase Debug Mask support\r
+///\r
+#define EFI_DEBUG_MASK_PROTOCOL_GUID \\r
+ { 0x4c8a2451, 0xc207, 0x405b, {0x96, 0x94, 0x99, 0xea, 0x13, 0x25, 0x13, 0x41} }\r
+\r
+///\r
+/// Forward reference for pure ANSI compatability\r
+///\r
+typedef struct _EFI_DEBUG_MASK_PROTOCOL EFI_DEBUG_MASK_PROTOCOL;\r
+\r
+///\r
+///\r
+/// \r
+#define EFI_DEBUG_MASK_REVISION 0x00010000\r
+\r
+//\r
+// DebugMask member functions definition\r
+//\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI * EFI_GET_DEBUG_MASK) (\r
+ IN EFI_DEBUG_MASK_PROTOCOL *This, \r
+ IN OUT UINTN *CurrentDebugMask \r
+ );\r
+\r
+typedef \r
+EFI_STATUS\r
+(EFIAPI *EFI_SET_DEBUG_MASK) (\r
+ IN EFI_DEBUG_MASK_PROTOCOL *This,\r
+ IN UINTN NewDebugMask\r
+ );\r
+\r
+///\r
+/// DebugMask protocol definition\r
+///\r
+struct _EFI_DEBUG_MASK_PROTOCOL {\r
+ INT64 Revision;\r
+ EFI_GET_DEBUG_MASK GetDebugMask;\r
+ EFI_SET_DEBUG_MASK SetDebugMask;\r
+};\r
+\r
+extern EFI_GUID gEfiDebugMaskProtocolGuid;\r
+\r
+///\r
+/// GUID used to store the global debug mask in an the "EFIDebug" EFI Variabe\r
+///\r
+#define EFI_GENERIC_VARIABLE_GUID \\r
+ { 0x59d1c24f, 0x50f1, 0x401a, {0xb1, 0x01, 0xf3, 0x3e, 0x0d, 0xae, 0xd4, 0x43} }\r
+ \r
+#define DEBUG_MASK_VARIABLE_NAME L"EFIDebug"\r
+\r
+extern EFI_GUID gEfiGenericVariableGuid;\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Debug Print Error Level library instance that provide compatibility with the \r
+ "err" shell command. This includes support for the Debug Mask Protocol\r
+ supports for global debug print error level mask stored in an EFI Variable.\r
+ This library instance only support DXE Phase modules.\r
+\r
+ Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+ 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
+**/\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Library/DebugPrintErrorLevelLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <Guid/DebugMask.h>\r
+\r
+///\r
+/// Debug Mask Protocol function prototypes\r
+///\r
+EFI_STATUS\r
+EFIAPI\r
+GetDebugMask (\r
+ IN EFI_DEBUG_MASK_PROTOCOL *This, \r
+ IN OUT UINTN *CurrentDebugMask \r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+SetDebugMask (\r
+ IN EFI_DEBUG_MASK_PROTOCOL *This,\r
+ IN UINTN NewDebugMask\r
+ );\r
+\r
+///\r
+/// Debug Mask Protocol instance\r
+///\r
+EFI_DEBUG_MASK_PROTOCOL mDebugMaskProtocol = {\r
+ EFI_DEBUG_MASK_REVISION,\r
+ GetDebugMask,\r
+ SetDebugMask\r
+};\r
+\r
+///\r
+/// Global variable that is set to TRUE after the first attempt is made to \r
+/// retrieve the global error level mask through the EFI Varibale Services.\r
+/// This variable prevents the EFI Variable Services from being called fort\r
+/// every DEBUG() macro.\r
+///\r
+BOOLEAN mGlobalErrorLevelInitialized = FALSE;\r
+\r
+///\r
+/// Global variable that contains the current debug error level mask for the\r
+/// module that is using this library instance. This variable is initially\r
+/// set to the PcdDebugPrintErrorLevel value. If the EFI Variable exists that\r
+/// contains the global debug print error level mask, then that override the\r
+/// PcdDebugPrintErrorLevel value. If the Debug Mask Protocol SetDebugMask()\r
+/// service is called, then that overrides bit the PcdDebugPrintErrorLevel and\r
+/// the EFI Variable setting.\r
+///\r
+UINT32 mDebugPrintErrorLevel = 0;\r
+\r
+///\r
+/// Global variable that is used to cache a pointer to the EFI System Table\r
+/// that is required to access the EFI Variable Services to get and set\r
+/// the global debug print error level mask value. The UefiBootServicesTableLib\r
+/// is not used to prevent a circular dependency between these libraries.\r
+///\r
+EFI_SYSTEM_TABLE *mST = NULL;\r
+\r
+/**\r
+ The constructor function caches the PCI Express Base Address and creates a \r
+ Set Virtual Address Map event to convert physical address to virtual addresses.\r
+ \r
+ @param ImageHandle The firmware allocated handle for the EFI image.\r
+ @param SystemTable A pointer to the EFI System Table.\r
+ \r
+ @retval EFI_SUCCESS The constructor completed successfully.\r
+ @retval Other value The constructor did not complete successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeDebugPrintErrorLevelLibConstructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Initialize the error level mask from PCD setting.\r
+ //\r
+ mDebugPrintErrorLevel = PcdGet32 (PcdDebugPrintErrorLevel);\r
+ \r
+ //\r
+ // Install Debug Mask Protocol onto ImageHandle\r
+ // \r
+ mST = SystemTable;\r
+ Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces (\r
+ &ImageHandle,\r
+ &gEfiDebugMaskProtocolGuid, &mDebugMaskProtocol,\r
+ NULL\r
+ );\r
+\r
+ //\r
+ // Attempt to retrieve the global debug print error level mask from the EFI Variable\r
+ // If the EFI Variable can not be accessed when this module's library constructors are\r
+ // executed, then the EFI Variable access will be reattempted on every DEBUG() print\r
+ // from this module until the EFI Variable services are available.\r
+ //\r
+ GetDebugPrintErrorLevel ();\r
+ \r
+ return Status;\r
+}\r
+\r
+/**\r
+ The destructor function frees any allocated buffers and closes the Set Virtual \r
+ Address Map event.\r
+ \r
+ @param ImageHandle The firmware allocated handle for the EFI image.\r
+ @param SystemTable A pointer to the EFI System Table.\r
+ \r
+ @retval EFI_SUCCESS The destructor completed successfully.\r
+ @retval Other value The destructor did not complete successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DxeDebugPrintErrorLevelLibDestructor (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ //\r
+ // Uninstall the Debug Mask Protocol from ImageHandle\r
+ // \r
+ return SystemTable->BootServices->UninstallMultipleProtocolInterfaces (\r
+ ImageHandle,\r
+ &gEfiDebugMaskProtocolGuid, &mDebugMaskProtocol,\r
+ NULL\r
+ );\r
+}\r
+\r
+/**\r
+ Returns the debug print error level mask for the current module.\r
+\r
+ @return Debug print error level mask for the current module.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetDebugPrintErrorLevel (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_TPL CurrentTpl;\r
+ UINTN Size;\r
+ UINTN GlobalErrorLevel;\r
+\r
+ //\r
+ // If the constructor has not been executed yet, then just return the PCD value.\r
+ // This case should only occur if debug print is generated by a library\r
+ // constructor for this module\r
+ //\r
+ if (mST == NULL) {\r
+ return PcdGet32 (PcdDebugPrintErrorLevel);\r
+ }\r
+\r
+ //\r
+ // Check to see if an attempt has been mde to retrieve the global debug print \r
+ // error level mask. Since this libtrary instance stores the global debug print\r
+ // error level mask in an EFI Variable, the EFI Variable should only be accessed\r
+ // once to reduce the overhead of reading the EFI Variable on every debug print\r
+ // \r
+ if (!mGlobalErrorLevelInitialized) {\r
+ //\r
+ // Make sure the TPL Level is low enough for EFI Variable Services to be called\r
+ //\r
+ CurrentTpl = mST->BootServices->RaiseTPL (TPL_HIGH_LEVEL);\r
+ mST->BootServices->RestoreTPL (CurrentTpl);\r
+ if (CurrentTpl <= TPL_CALLBACK) {\r
+ //\r
+ // Attempt to retrieve the global debug print error level mask from the \r
+ // EFI Variable\r
+ //\r
+ Size = sizeof (GlobalErrorLevel);\r
+ Status = mST->RuntimeServices->GetVariable (\r
+ DEBUG_MASK_VARIABLE_NAME, \r
+ &gEfiGenericVariableGuid, \r
+ NULL, \r
+ &Size, \r
+ &GlobalErrorLevel\r
+ );\r
+ if (Status != EFI_NOT_AVAILABLE_YET) {\r
+ //\r
+ // If EFI Variable Services are available, then set a flag so the EFI\r
+ // Variable will not be read again by this module.\r
+ //\r
+ mGlobalErrorLevelInitialized = TRUE;\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // If the EFI Varible exists, then set this module's module's mask to\r
+ // the global debug print error level mask value.\r
+ //\r
+ mDebugPrintErrorLevel = (UINT32)GlobalErrorLevel;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Return the current mask value for this module.\r
+ //\r
+ return mDebugPrintErrorLevel;\r
+}\r
+\r
+/**\r
+ Sets the global debug print error level mask fpr the entire platform.\r
+\r
+ @retval TRUE The debug print error level mask was sucessfully set.\r
+ @retval FALSE The debug print error level mask could not be set.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+SetDebugPrintErrorLevel (\r
+ UINT32 ErrorLevel\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_TPL CurrentTpl;\r
+ UINTN Size;\r
+ UINTN GlobalErrorLevel;\r
+\r
+ //\r
+ // Make sure the constructor has been executed\r
+ //\r
+ if (mST != NULL) {\r
+ //\r
+ // Make sure the TPL Level is low enough for EFI Variable Services\r
+ //\r
+ CurrentTpl = mST->BootServices->RaiseTPL (TPL_HIGH_LEVEL);\r
+ mST->BootServices->RestoreTPL (CurrentTpl);\r
+ if (CurrentTpl <= TPL_CALLBACK) {\r
+ //\r
+ // Attempt to store the global debug print error level mask in an EFI Variable\r
+ //\r
+ GlobalErrorLevel = (UINTN)ErrorLevel;\r
+ Size = sizeof (GlobalErrorLevel);\r
+ Status = mST->RuntimeServices->SetVariable (\r
+ DEBUG_MASK_VARIABLE_NAME, \r
+ &gEfiGenericVariableGuid, \r
+ (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),\r
+ Size,\r
+ &GlobalErrorLevel\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // If the EFI Variable was updated, then update the mask value for this \r
+ // module and return TRUE.\r
+ //\r
+ mGlobalErrorLevelInitialized = TRUE; \r
+ mDebugPrintErrorLevel = ErrorLevel;\r
+ return TRUE;\r
+ }\r
+ }\r
+ }\r
+ //\r
+ // Return FALSE since the EFI Variable could not be updated.\r
+ //\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ Retrieves the current debug print error level mask for a module are returns\r
+ it in CurrentDebugMask.\r
+\r
+ @param This The protocol instance pointer.\r
+ @param CurrentDebugMask Pointer to the debug print error level mask that \r
+ is returned.\r
+\r
+ @retval EFI_SUCCESS The current debug print error level mask was\r
+ returned in CurrentDebugMask.\r
+ @retval EFI_INVALID_PARAMETER CurrentDebugMask is NULL.\r
+ @retval EFI_DEVICE_ERROR The current debug print error level mask could\r
+ not be retrieved.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetDebugMask (\r
+ IN EFI_DEBUG_MASK_PROTOCOL *This, \r
+ IN OUT UINTN *CurrentDebugMask \r
+ )\r
+{\r
+ if (CurrentDebugMask == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+ //\r
+ // Retrieve the current debug mask from mDebugPrintErrorLevel\r
+ //\r
+ *CurrentDebugMask = (UINTN)mDebugPrintErrorLevel;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Sets the current debug print error level mask for a module to the value\r
+ specified by NewDebugMask.\r
+\r
+ @param This The protocol instance pointer.\r
+ @param NewDebugMask The new debug print error level mask for this module.\r
+\r
+ @retval EFI_SUCCESS The current debug print error level mask was\r
+ set to the value specified by NewDebugMask.\r
+ @retval EFI_DEVICE_ERROR The current debug print error level mask could\r
+ not be set to the value specified by NewDebugMask.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetDebugMask (\r
+ IN EFI_DEBUG_MASK_PROTOCOL *This,\r
+ IN UINTN NewDebugMask\r
+ )\r
+{\r
+ //\r
+ // Store the new debug mask into mDebugPrintErrorLevel\r
+ //\r
+ mDebugPrintErrorLevel = (UINT32)NewDebugMask;\r
+ return EFI_SUCCESS;\r
+}\r