Home | History | Annotate | Download | only in UefiDebugLibConOut
      1 /** @file
      2   UEFI Debug Library that sends messages to the Console Output Device in the EFI System Table.
      3 
      4   Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php.
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <Uefi.h>
     16 
     17 #include <Library/DebugLib.h>
     18 #include <Library/UefiBootServicesTableLib.h>
     19 #include <Library/PrintLib.h>
     20 #include <Library/PcdLib.h>
     21 #include <Library/BaseLib.h>
     22 #include <Library/BaseMemoryLib.h>
     23 #include <Library/DebugPrintErrorLevelLib.h>
     24 
     25 //
     26 // Define the maximum debug and assert message length that this library supports
     27 //
     28 #define MAX_DEBUG_MESSAGE_LENGTH  0x100
     29 
     30 /**
     31   Prints a debug message to the debug output device if the specified error level is enabled.
     32 
     33   If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
     34   GetDebugPrintErrorLevel (), then print the message specified by Format and the
     35   associated variable argument list to the debug output device.
     36 
     37   If Format is NULL, then ASSERT().
     38 
     39   @param  ErrorLevel  The error level of the debug message.
     40   @param  Format      Format string for the debug message to print.
     41   @param  ...         A variable argument list whose contents are accessed
     42                       based on the format string specified by Format.
     43 
     44 **/
     45 VOID
     46 EFIAPI
     47 DebugPrint (
     48   IN  UINTN        ErrorLevel,
     49   IN  CONST CHAR8  *Format,
     50   ...
     51   )
     52 {
     53   CHAR16   Buffer[MAX_DEBUG_MESSAGE_LENGTH];
     54   VA_LIST  Marker;
     55 
     56   //
     57   // If Format is NULL, then ASSERT().
     58   //
     59   ASSERT (Format != NULL);
     60 
     61   //
     62   // Check driver debug mask value and global mask
     63   //
     64   if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
     65     return;
     66   }
     67 
     68   //
     69   // Convert the DEBUG() message to a Unicode String
     70   //
     71   VA_START (Marker, Format);
     72   UnicodeVSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH,  Format, Marker);
     73   VA_END (Marker);
     74 
     75 
     76   //
     77   // Send the print string to the Console Output device
     78   //
     79   if ((gST != NULL) && (gST->ConOut != NULL)) {
     80     gST->ConOut->OutputString (gST->ConOut, Buffer);
     81   }
     82 }
     83 
     84 
     85 /**
     86   Prints an assert message containing a filename, line number, and description.
     87   This may be followed by a breakpoint or a dead loop.
     88 
     89   Print a message of the form "ASSERT <FileName>(<LineNumber>): <Description>\n"
     90   to the debug output device.  If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
     91   PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if
     92   DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then
     93   CpuDeadLoop() is called.  If neither of these bits are set, then this function
     94   returns immediately after the message is printed to the debug output device.
     95   DebugAssert() must actively prevent recursion.  If DebugAssert() is called while
     96   processing another DebugAssert(), then DebugAssert() must return immediately.
     97 
     98   If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
     99   If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
    100 
    101   @param  FileName     The pointer to the name of the source file that generated
    102                        the assert condition.
    103   @param  LineNumber   The line number in the source file that generated the
    104                        assert condition
    105   @param  Description  The pointer to the description of the assert condition.
    106 
    107 **/
    108 VOID
    109 EFIAPI
    110 DebugAssert (
    111   IN CONST CHAR8  *FileName,
    112   IN UINTN        LineNumber,
    113   IN CONST CHAR8  *Description
    114   )
    115 {
    116   CHAR16  Buffer[MAX_DEBUG_MESSAGE_LENGTH];
    117 
    118   //
    119   // Generate the ASSERT() message in Unicode format
    120   //
    121   UnicodeSPrintAsciiFormat (
    122     Buffer,
    123     sizeof (Buffer),
    124     "ASSERT [%a] %a(%d): %a\n",
    125     gEfiCallerBaseName,
    126     FileName,
    127     LineNumber,
    128     Description
    129     );
    130 
    131   //
    132   // Send the print string to the Console Output device
    133   //
    134   if ((gST != NULL) && (gST->ConOut != NULL)) {
    135     gST->ConOut->OutputString (gST->ConOut, Buffer);
    136   }
    137 
    138   //
    139   // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
    140   //
    141   if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
    142     CpuBreakpoint ();
    143   } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
    144     CpuDeadLoop ();
    145   }
    146 }
    147 
    148 
    149 /**
    150   Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.
    151 
    152   This function fills Length bytes of Buffer with the value specified by
    153   PcdDebugClearMemoryValue, and returns Buffer.
    154 
    155   If Buffer is NULL, then ASSERT().
    156   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
    157 
    158   @param   Buffer  The pointer to the target buffer to be filled with PcdDebugClearMemoryValue.
    159   @param   Length  The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue.
    160 
    161   @return  Buffer  The pointer to the target buffer filled with PcdDebugClearMemoryValue.
    162 
    163 **/
    164 VOID *
    165 EFIAPI
    166 DebugClearMemory (
    167   OUT VOID  *Buffer,
    168   IN UINTN  Length
    169   )
    170 {
    171   //
    172   // If Buffer is NULL, then ASSERT().
    173   //
    174   ASSERT (Buffer != NULL);
    175 
    176   //
    177   // SetMem() checks for the the ASSERT() condition on Length and returns Buffer
    178   //
    179   return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));
    180 }
    181 
    182 
    183 /**
    184   Returns TRUE if ASSERT() macros are enabled.
    185 
    186   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
    187   PcdDebugProperyMask is set.  Otherwise FALSE is returned.
    188 
    189   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set.
    190   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear.
    191 
    192 **/
    193 BOOLEAN
    194 EFIAPI
    195 DebugAssertEnabled (
    196   VOID
    197   )
    198 {
    199   return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
    200 }
    201 
    202 
    203 /**
    204   Returns TRUE if DEBUG() macros are enabled.
    205 
    206   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
    207   PcdDebugProperyMask is set.  Otherwise FALSE is returned.
    208 
    209   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set.
    210   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear.
    211 
    212 **/
    213 BOOLEAN
    214 EFIAPI
    215 DebugPrintEnabled (
    216   VOID
    217   )
    218 {
    219   return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
    220 }
    221 
    222 
    223 /**
    224   Returns TRUE if DEBUG_CODE() macros are enabled.
    225 
    226   This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
    227   PcdDebugProperyMask is set.  Otherwise FALSE is returned.
    228 
    229   @retval  TRUE    The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set.
    230   @retval  FALSE   The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear.
    231 
    232 **/
    233 BOOLEAN
    234 EFIAPI
    235 DebugCodeEnabled (
    236   VOID
    237   )
    238 {
    239   return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
    240 }
    241 
    242 
    243 /**
    244   Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
    245 
    246   This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
    247   PcdDebugProperyMask is set.  Otherwise FALSE is returned.
    248 
    249   @retval  TRUE    The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set.
    250   @retval  FALSE   The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear.
    251 
    252 **/
    253 BOOLEAN
    254 EFIAPI
    255 DebugClearMemoryEnabled (
    256   VOID
    257   )
    258 {
    259   return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
    260 }
    261 
    262 /**
    263   Returns TRUE if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel.
    264 
    265   This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel.
    266 
    267   @retval  TRUE    Current ErrorLevel is supported.
    268   @retval  FALSE   Current ErrorLevel is not supported.
    269 
    270 **/
    271 BOOLEAN
    272 EFIAPI
    273 DebugPrintLevelEnabled (
    274   IN  CONST UINTN        ErrorLevel
    275   )
    276 {
    277   return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);
    278 }
    279