Home | History | Annotate | Download | only in PeiNt32OemHookStatusCodeLib
      1 /** @file
      2   OEM hook status code library functions with no library constructor/destructor
      3 
      4   Copyright (c) 2006 - 2013, 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   Module Name:  Nt32OemHookStatusCodeLib.c
     14 
     15 **/
     16 
     17 //
     18 // The package level header files this module uses
     19 //
     20 #include <WinNtPeim.h>
     21 
     22 //
     23 // The protocols, PPI and GUID defintions for this module
     24 //
     25 #include <Guid/StatusCodeDataTypeId.h>
     26 #include <Guid/StatusCodeDataTypeDebug.h>
     27 #include <Ppi/NtThunk.h>
     28 //
     29 // The Library classes this module consumes
     30 //
     31 #include <Library/OemHookStatusCodeLib.h>
     32 #include <Library/DebugLib.h>
     33 #include <Library/PrintLib.h>
     34 #include <Library/BaseMemoryLib.h>
     35 #include <Library/ReportStatusCodeLib.h>
     36 #include <Library/PeiServicesLib.h>
     37 
     38 //
     39 // Cache of WinNtThunk protocol
     40 //
     41 EFI_WIN_NT_THUNK_PROTOCOL   *mWinNt;
     42 
     43 //
     44 // Cache of standard output handle .
     45 //
     46 HANDLE                      mStdOut;
     47 
     48 /**
     49 
     50   Initialize OEM status code device .
     51 
     52   @return    Always return EFI_SUCCESS.
     53 
     54 **/
     55 EFI_STATUS
     56 EFIAPI
     57 OemHookStatusCodeInitialize (
     58   VOID
     59   )
     60 {
     61   PEI_NT_THUNK_PPI  *NtThunkPpi;
     62   EFI_STATUS        Status;
     63 
     64 
     65   //
     66   // Locate NtThunkPpi for retrieving standard output handle
     67   //
     68   Status = PeiServicesLocatePpi (
     69               &gPeiNtThunkPpiGuid,
     70               0,
     71               NULL,
     72               (VOID **) &NtThunkPpi
     73               );
     74 
     75   ASSERT_EFI_ERROR (Status);
     76 
     77   mWinNt  = (EFI_WIN_NT_THUNK_PROTOCOL *) NtThunkPpi->NtThunk ();
     78 
     79 
     80   //
     81   // Cache standard output handle.
     82   //
     83   mStdOut = mWinNt->GetStdHandle (STD_OUTPUT_HANDLE);
     84 
     85   return EFI_SUCCESS;
     86 }
     87 
     88 /**
     89   Report status code to OEM device.
     90 
     91   @param  CodeType      Indicates the type of status code being reported.  Type EFI_STATUS_CODE_TYPE is defined in "Related Definitions" below.
     92 
     93   @param  Value         Describes the current status of a hardware or software entity.
     94                         This included information about the class and subclass that is used to classify the entity
     95                         as well as an operation.  For progress codes, the operation is the current activity.
     96                         For error codes, it is the exception.  For debug codes, it is not defined at this time.
     97                         Type EFI_STATUS_CODE_VALUE is defined in "Related Definitions" below.
     98                         Specific values are discussed in the Intel? Platform Innovation Framework for EFI Status Code Specification.
     99 
    100   @param  Instance      The enumeration of a hardware or software entity within the system.
    101                         A system may contain multiple entities that match a class/subclass pairing.
    102                         The instance differentiates between them.  An instance of 0 indicates that instance information is unavailable,
    103                         not meaningful, or not relevant.  Valid instance numbers start with 1.
    104 
    105 
    106   @param  CallerId      This optional parameter may be used to identify the caller.
    107                         This parameter allows the status code driver to apply different rules to different callers.
    108                         Type EFI_GUID is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
    109 
    110 
    111   @param  Data          This optional parameter may be used to pass additional data
    112 
    113   @return               The function always return EFI_SUCCESS.
    114 
    115 **/
    116 EFI_STATUS
    117 EFIAPI
    118 OemHookStatusCodeReport (
    119   IN EFI_STATUS_CODE_TYPE     CodeType,
    120   IN EFI_STATUS_CODE_VALUE    Value,
    121   IN UINT32                   Instance,
    122   IN EFI_GUID                 *CallerId, OPTIONAL
    123   IN EFI_STATUS_CODE_DATA     *Data      OPTIONAL
    124   )
    125 {
    126   CHAR8           *Filename;
    127   CHAR8           *Description;
    128   CHAR8           *Format;
    129   CHAR8           Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
    130   UINT32          ErrorLevel;
    131   UINT32          LineNumber;
    132   UINTN           CharCount;
    133   BASE_LIST       Marker;
    134 
    135   Buffer[0] = '\0';
    136 
    137   if (Data != NULL &&
    138       ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
    139     //
    140     // Print ASSERT() information into output buffer.
    141     //
    142     CharCount = AsciiSPrint (
    143                   Buffer,
    144                   sizeof (Buffer),
    145                   "\n\rASSERT!: %a (%d): %a\n\r",
    146                   Filename,
    147                   LineNumber,
    148                   Description
    149                   );
    150 
    151     //
    152     // Callout to standard output.
    153     //
    154     mWinNt->WriteFile (
    155               mStdOut,
    156               Buffer,
    157               (DWORD)CharCount,
    158               (LPDWORD)&CharCount,
    159               NULL
    160               );
    161 
    162     return EFI_SUCCESS;
    163 
    164   } else if (Data != NULL &&
    165              ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
    166     //
    167     // Print DEBUG() information into output buffer.
    168     //
    169     CharCount = AsciiBSPrint (
    170                   Buffer,
    171                   sizeof (Buffer),
    172                   Format,
    173                   Marker
    174                   );
    175   } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
    176     //
    177     // Print ERROR information into output buffer.
    178     //
    179     CharCount = AsciiSPrint (
    180                   Buffer,
    181                   sizeof (Buffer),
    182                   "ERROR: C%x:V%x I%x",
    183                   CodeType,
    184                   Value,
    185                   Instance
    186                   );
    187 
    188     //
    189     // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
    190     //
    191 
    192     if (CallerId != NULL) {
    193       CharCount += AsciiSPrint (
    194                      &Buffer[CharCount - 1],
    195                      (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
    196                      " %g",
    197                      CallerId
    198                      );
    199     }
    200 
    201     if (Data != NULL) {
    202       CharCount += AsciiSPrint (
    203                      &Buffer[CharCount - 1],
    204                      (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
    205                      " %p",
    206                      Data
    207                      );
    208     }
    209 
    210     CharCount += AsciiSPrint (
    211                    &Buffer[CharCount - 1],
    212                    (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
    213                    "\n\r"
    214                    );
    215   } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
    216     CharCount = AsciiSPrint (
    217                   Buffer,
    218                   sizeof (Buffer),
    219                   "PROGRESS CODE: V%x I%x\n\r",
    220                   Value,
    221                   Instance
    222                   );
    223   } else {
    224     CharCount = AsciiSPrint (
    225                   Buffer,
    226                   sizeof (Buffer),
    227                   "Undefined: C%x:V%x I%x\n\r",
    228                   CodeType,
    229                   Value,
    230                   Instance
    231                   );
    232   }
    233 
    234   //
    235   // Callout to standard output.
    236   //
    237   mWinNt->WriteFile (
    238             mStdOut,
    239             Buffer,
    240             (DWORD)CharCount,
    241             (LPDWORD)&CharCount,
    242             NULL
    243             );
    244 
    245   return EFI_SUCCESS;
    246 }
    247 
    248