EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

MdeModulePkg/Library/DxeDebugPrintErrorLevelLib/DxeDebugPrintErrorLevelLib.c

Go to the documentation of this file.
00001 
00018 #include <PiDxe.h>
00019 
00020 #include <Library/DebugPrintErrorLevelLib.h>
00021 #include <Library/PcdLib.h>
00022 #include <Library/HobLib.h>
00023 
00024 #include <Guid/DebugMask.h>
00025 
00029 
00045 EFI_STATUS
00046 EFIAPI
00047 GetDebugMask (
00048   IN EFI_DEBUG_MASK_PROTOCOL  *This,             
00049   IN OUT UINTN                *CurrentDebugMask  
00050   );
00051 
00065 EFI_STATUS
00066 EFIAPI
00067 SetDebugMask (
00068   IN EFI_DEBUG_MASK_PROTOCOL  *This,
00069   IN UINTN                    NewDebugMask
00070   );
00071 
00075 EFI_DEBUG_MASK_PROTOCOL  mDebugMaskProtocol = {
00076   EFI_DEBUG_MASK_REVISION,
00077   GetDebugMask,
00078   SetDebugMask
00079 };
00080 
00087 BOOLEAN           mGlobalErrorLevelInitialized = FALSE;
00088 
00099 UINT32            mDebugPrintErrorLevel        = 0;
00100 
00107 EFI_SYSTEM_TABLE  *mSystemTable                         = NULL;
00108 
00120 EFI_STATUS
00121 EFIAPI
00122 DxeDebugPrintErrorLevelLibConstructor (
00123   IN EFI_HANDLE        ImageHandle,
00124   IN EFI_SYSTEM_TABLE  *SystemTable
00125   )
00126 {
00127   EFI_STATUS                  Status;
00128   
00129   //
00130   // Initialize the error level mask from PCD setting.
00131   //
00132   mDebugPrintErrorLevel = PcdGet32 (PcdDebugPrintErrorLevel);
00133     
00134   //
00135   // Install Debug Mask Protocol onto ImageHandle
00136   //  
00137   mSystemTable = SystemTable;
00138   Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces (
00139                                         &ImageHandle,
00140                                         &gEfiDebugMaskProtocolGuid, &mDebugMaskProtocol,
00141                                         NULL
00142                                         );
00143 
00144   //
00145   // Attempt to retrieve the global debug print error level mask from the EFI Variable
00146   // If the EFI Variable can not be accessed when this module's library constructors are
00147   // executed a HOB can be used to set the global debug print error level. If no value 
00148   // was found then the EFI Variable access will be reattempted on every DEBUG() print
00149   // from this module until the EFI Variable services are available.
00150   //
00151   GetDebugPrintErrorLevel ();
00152   
00153   return Status;
00154 }
00155 
00167 EFI_STATUS
00168 EFIAPI
00169 DxeDebugPrintErrorLevelLibDestructor (
00170   IN EFI_HANDLE        ImageHandle,
00171   IN EFI_SYSTEM_TABLE  *SystemTable
00172   )
00173 {
00174   //
00175   // Uninstall the Debug Mask Protocol from ImageHandle
00176   //  
00177   return SystemTable->BootServices->UninstallMultipleProtocolInterfaces (
00178                                       ImageHandle,
00179                                       &gEfiDebugMaskProtocolGuid, &mDebugMaskProtocol,
00180                                       NULL
00181                                       );
00182 }
00183 
00190 UINT32
00191 EFIAPI
00192 GetDebugPrintErrorLevel (
00193   VOID
00194   )
00195 {
00196   EFI_STATUS  Status;
00197   EFI_TPL     CurrentTpl;
00198   UINTN       Size;
00199   UINTN       GlobalErrorLevel;
00200   VOID        *Hob;
00201 
00202   //
00203   // If the constructor has not been executed yet, then just return the PCD value.
00204   // This case should only occur if debug print is generated by a library
00205   // constructor for this module
00206   //
00207   if (mSystemTable == NULL) {
00208     return PcdGet32 (PcdDebugPrintErrorLevel);
00209   }
00210   
00211   //
00212   // Check to see if an attempt has been made to retrieve the global debug print 
00213   // error level mask.  Since this library instance stores the global debug print
00214   // error level mask in an EFI Variable, the EFI Variable should only be accessed
00215   // once to reduce the overhead of reading the EFI Variable on every debug print
00216   //  
00217   if (!mGlobalErrorLevelInitialized) {
00218     //
00219     // Make sure the TPL Level is low enough for EFI Variable Services to be called
00220     //
00221     CurrentTpl = mSystemTable->BootServices->RaiseTPL (TPL_HIGH_LEVEL);
00222     mSystemTable->BootServices->RestoreTPL (CurrentTpl);
00223     if (CurrentTpl <= TPL_CALLBACK) {
00224       //
00225       // Attempt to retrieve the global debug print error level mask from the 
00226       // EFI Variable
00227       //
00228       Size = sizeof (GlobalErrorLevel);
00229       Status = mSystemTable->RuntimeServices->GetVariable (
00230                                        DEBUG_MASK_VARIABLE_NAME, 
00231                                        &gEfiGenericVariableGuid, 
00232                                        NULL, 
00233                                        &Size, 
00234                                        &GlobalErrorLevel
00235                                        );
00236       if (Status != EFI_NOT_AVAILABLE_YET) {
00237         //
00238         // If EFI Variable Services are available, then set a flag so the EFI
00239         // Variable will not be read again by this module.
00240         //
00241         mGlobalErrorLevelInitialized = TRUE;
00242         if (!EFI_ERROR (Status)) {
00243           //
00244           // If the EFI Varible exists, then set this module's module's mask to
00245           // the global debug print error level mask value.
00246           //
00247           mDebugPrintErrorLevel = (UINT32)GlobalErrorLevel;
00248         }
00249       } else {
00250         //
00251         // If variable services are not yet availible optionally get the global
00252         // debug print error level mask from a HOB.
00253         //
00254         Hob = GetFirstGuidHob (&gEfiGenericVariableGuid);
00255         if (Hob != NULL) {
00256           if (GET_GUID_HOB_DATA_SIZE (Hob) == sizeof (UINT32)) {
00257             mDebugPrintErrorLevel = *(UINT32 *)GET_GUID_HOB_DATA (Hob);
00258             mGlobalErrorLevelInitialized = TRUE;
00259           }
00260         }
00261       }
00262     }
00263   }
00264 
00265   //
00266   // Return the current mask value for this module.
00267   //
00268   return mDebugPrintErrorLevel;
00269 }
00270 
00280 BOOLEAN
00281 EFIAPI
00282 SetDebugPrintErrorLevel (
00283   UINT32  ErrorLevel
00284   )
00285 {
00286   EFI_STATUS  Status;
00287   EFI_TPL     CurrentTpl;
00288   UINTN       Size;
00289   UINTN       GlobalErrorLevel;
00290 
00291   //
00292   // Make sure the constructor has been executed
00293   //
00294   if (mSystemTable != NULL) {
00295     //
00296     // Make sure the TPL Level is low enough for EFI Variable Services
00297     //
00298     CurrentTpl = mSystemTable->BootServices->RaiseTPL (TPL_HIGH_LEVEL);
00299     mSystemTable->BootServices->RestoreTPL (CurrentTpl);
00300     if (CurrentTpl <= TPL_CALLBACK) {
00301       //
00302       // Attempt to store the global debug print error level mask in an EFI Variable
00303       //
00304       GlobalErrorLevel = (UINTN)ErrorLevel;
00305       Size = sizeof (GlobalErrorLevel);
00306       Status = mSystemTable->RuntimeServices->SetVariable (
00307                                        DEBUG_MASK_VARIABLE_NAME, 
00308                                        &gEfiGenericVariableGuid, 
00309                                        (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
00310                                        Size,
00311                                        &GlobalErrorLevel
00312                                        );
00313       if (!EFI_ERROR (Status)) {
00314         //
00315         // If the EFI Variable was updated, then update the mask value for this 
00316         // module and return TRUE.
00317         //
00318         mGlobalErrorLevelInitialized = TRUE;    
00319         mDebugPrintErrorLevel = ErrorLevel;
00320         return TRUE;
00321       }
00322     }
00323   }
00324   //
00325   // Return FALSE since the EFI Variable could not be updated.
00326   //
00327   return FALSE;
00328 }
00329 
00345 EFI_STATUS
00346 EFIAPI
00347 GetDebugMask (
00348   IN EFI_DEBUG_MASK_PROTOCOL  *This,             
00349   IN OUT UINTN                *CurrentDebugMask  
00350   )
00351 {
00352   if (CurrentDebugMask == NULL) {
00353     return EFI_INVALID_PARAMETER;
00354   }
00355   
00356   //
00357   // Retrieve the current debug mask from mDebugPrintErrorLevel
00358   //
00359   *CurrentDebugMask = (UINTN)mDebugPrintErrorLevel;
00360   return EFI_SUCCESS;
00361 }
00362 
00376 EFI_STATUS
00377 EFIAPI
00378 SetDebugMask (
00379   IN EFI_DEBUG_MASK_PROTOCOL  *This,
00380   IN UINTN                    NewDebugMask
00381   )
00382 {
00383   //
00384   // Store the new debug mask into mDebugPrintErrorLevel
00385   //
00386   mDebugPrintErrorLevel = (UINT32)NewDebugMask;
00387   return EFI_SUCCESS;
00388 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines