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