Home | History | Annotate | Download | only in EfiDriverLib
      1 /*++
      2 
      3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   ReportStatusCode.c
     15 
     16 Abstract:
     17 
     18 --*/
     19 
     20 #include "Tiano.h"
     21 #include "EfiDriverLib.h"
     22 #include "PeiHob.h"
     23 #include EFI_PROTOCOL_DEFINITION (DevicePath)
     24 #include EFI_GUID_DEFINITION (Hob)
     25 #include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
     26 #include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)
     27 
     28 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
     29 
     30 EFI_REPORT_STATUS_CODE gReportStatusCode = NULL;
     31 
     32 VOID
     33 EFIAPI
     34 OnStatusCodeInstall (
     35   IN EFI_EVENT        Event,
     36   IN VOID             *Context
     37   )
     38 {
     39   EFI_STATUS                Status;
     40   EFI_STATUS_CODE_PROTOCOL  *StatusCode;
     41 
     42   Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **) &StatusCode);
     43   if (!EFI_ERROR (Status)) {
     44     gReportStatusCode = StatusCode->ReportStatusCode;
     45   }
     46 }
     47 
     48 EFI_STATUS
     49 GetPeiProtocol (
     50   IN EFI_GUID  *ProtocolGuid,
     51   IN VOID      **Interface
     52   )
     53 /*++
     54 
     55 Routine Description:
     56 
     57   Searches for a Protocol Interface passed from PEI through a HOB
     58 
     59 Arguments:
     60 
     61   ProtocolGuid - The Protocol GUID to search for in the HOB List
     62   Interface    - A pointer to the interface for the Protocol GUID
     63 
     64 Returns:
     65 
     66   EFI_SUCCESS   - The Protocol GUID was found and its interface is returned in Interface
     67   EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List
     68 
     69 --*/
     70 {
     71   EFI_STATUS            Status;
     72   EFI_PEI_HOB_POINTERS  GuidHob;
     73 
     74   //
     75   // Get Hob list
     76   //
     77   Status = EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **)  &GuidHob.Raw);
     78   if (EFI_ERROR (Status)) {
     79     return Status;
     80   }
     81 
     82   for (Status = EFI_NOT_FOUND; EFI_ERROR (Status);) {
     83     if (END_OF_HOB_LIST (GuidHob)) {
     84       Status = EFI_NOT_FOUND;
     85       break;
     86     }
     87 
     88     if (GET_HOB_TYPE (GuidHob) == EFI_HOB_TYPE_GUID_EXTENSION) {
     89       if (EfiCompareGuid (ProtocolGuid, &GuidHob.Guid->Name)) {
     90         Status     = EFI_SUCCESS;
     91         *Interface = (VOID *) *(UINTN *) (GuidHob.Guid + 1);
     92       }
     93     }
     94 
     95     GuidHob.Raw = GET_NEXT_HOB (GuidHob);
     96   }
     97 
     98   return Status;
     99 }
    100 
    101 #endif
    102 
    103 EFI_STATUS
    104 EfiLibReportStatusCode (
    105   IN EFI_STATUS_CODE_TYPE     Type,
    106   IN EFI_STATUS_CODE_VALUE    Value,
    107   IN UINT32                   Instance,
    108   IN EFI_GUID                 *CallerId OPTIONAL,
    109   IN EFI_STATUS_CODE_DATA     *Data     OPTIONAL
    110   )
    111 /*++
    112 
    113 Routine Description:
    114 
    115   Report device path through status code.
    116 
    117 Arguments:
    118 
    119   Type        - Code type
    120   Value       - Code value
    121   Instance    - Instance number
    122   CallerId    - Caller name
    123   DevicePath  - Device path that to be reported
    124 
    125 Returns:
    126 
    127   Status code.
    128 
    129   EFI_OUT_OF_RESOURCES - No enough buffer could be allocated
    130 
    131 --*/
    132 {
    133   EFI_STATUS  Status;
    134 
    135 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
    136   if (gReportStatusCode == NULL) {
    137     //
    138     // Because we've installed the protocol notification on EfiStatusCodeRuntimeProtocol,
    139     //   running here indicates that the StatusCode driver has not started yet.
    140     //
    141     if (gBS == NULL) {
    142       //
    143       // Running here only when StatusCode driver never starts.
    144       //
    145       return EFI_UNSUPPORTED;
    146     }
    147 
    148     //
    149     // Try to get the PEI version of ReportStatusCode.
    150     //
    151     Status = GetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid, (VOID **) &gReportStatusCode);
    152     if (EFI_ERROR (Status) || (gReportStatusCode == NULL)) {
    153       return EFI_UNSUPPORTED;
    154     }
    155   }
    156   Status = gReportStatusCode (Type, Value, Instance, CallerId, Data);
    157 #else
    158   if (gRT == NULL) {
    159     return EFI_UNSUPPORTED;
    160   }
    161   //
    162   // Check whether EFI_RUNTIME_SERVICES has Tiano Extension
    163   //
    164   Status = EFI_UNSUPPORTED;
    165   if (gRT->Hdr.Revision     == EFI_SPECIFICATION_VERSION     &&
    166       gRT->Hdr.HeaderSize   == sizeof (EFI_RUNTIME_SERVICES) &&
    167       gRT->ReportStatusCode != NULL) {
    168     Status = gRT->ReportStatusCode (Type, Value, Instance, CallerId, Data);
    169   }
    170 #endif
    171   return Status;
    172 }
    173 
    174 EFI_STATUS
    175 ReportStatusCodeWithDevicePath (
    176   IN EFI_STATUS_CODE_TYPE     Type,
    177   IN EFI_STATUS_CODE_VALUE    Value,
    178   IN UINT32                   Instance,
    179   IN EFI_GUID                 * CallerId OPTIONAL,
    180   IN EFI_DEVICE_PATH_PROTOCOL * DevicePath
    181   )
    182 /*++
    183 
    184 Routine Description:
    185 
    186   Report device path through status code.
    187 
    188 Arguments:
    189 
    190   Type        - Code type
    191   Value       - Code value
    192   Instance    - Instance number
    193   CallerId    - Caller name
    194   DevicePath  - Device path that to be reported
    195 
    196 Returns:
    197 
    198   Status code.
    199 
    200   EFI_OUT_OF_RESOURCES - No enough buffer could be allocated
    201 
    202 --*/
    203 {
    204   UINT16                    Size;
    205   UINT16                    DevicePathSize;
    206   EFI_STATUS_CODE_DATA      *ExtendedData;
    207   EFI_DEVICE_PATH_PROTOCOL  *ExtendedDevicePath;
    208   EFI_STATUS                Status;
    209 
    210   DevicePathSize  = (UINT16) EfiDevicePathSize (DevicePath);
    211   Size            = (UINT16) (DevicePathSize + sizeof (EFI_STATUS_CODE_DATA));
    212   ExtendedData    = (EFI_STATUS_CODE_DATA *) EfiLibAllocatePool (Size);
    213   if (ExtendedData == NULL) {
    214     return EFI_OUT_OF_RESOURCES;
    215   }
    216 
    217   ExtendedDevicePath = EfiConstructStatusCodeData (Size, &gEfiStatusCodeSpecificDataGuid, ExtendedData);
    218   EfiCopyMem (ExtendedDevicePath, DevicePath, DevicePathSize);
    219 
    220   Status = EfiLibReportStatusCode (Type, Value, Instance, CallerId, (EFI_STATUS_CODE_DATA *) ExtendedData);
    221 
    222   gBS->FreePool (ExtendedData);
    223   return Status;
    224 }
    225