Home | History | Annotate | Download | only in RtMemoryStatusCode
      1 /*++
      2 
      3 Copyright (c) 2004 - 2010, 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   RtMemoryStatusCode.c
     15 
     16 Abstract:
     17 
     18   EFI lib to provide memory journal status code reporting routines.
     19 
     20 --*/
     21 
     22 #include "RtMemoryStatusCode.h"
     23 
     24 //
     25 // Global variables
     26 //
     27 PEI_STATUS_CODE_MEMORY_PPI  mStatusCodeMemoryPpi = { 0, 0, 0, 0 };
     28 
     29 //
     30 // Function implementations
     31 //
     32 EFI_STATUS
     33 EFIAPI
     34 RtMemoryReportStatusCode (
     35   IN EFI_STATUS_CODE_TYPE     CodeType,
     36   IN EFI_STATUS_CODE_VALUE    Value,
     37   IN UINT32                   Instance,
     38   IN EFI_GUID                 * CallerId,
     39   IN EFI_STATUS_CODE_DATA     * Data OPTIONAL
     40   )
     41 /*++
     42 
     43 Routine Description:
     44 
     45   Log a status code to a memory journal.  If no memory journal exists,
     46   we will just return.
     47 
     48 Arguments:
     49 
     50   Same as ReportStatusCode AP
     51 
     52 Returns:
     53 
     54   EFI_SUCCESS   This function always returns success
     55 
     56 --*/
     57 {
     58   EFI_STATUS_CODE_ENTRY *CurrentEntry;
     59   UINTN                 MaxEntry;
     60 
     61   //
     62   // We don't care to log debug codes.
     63   //
     64   if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {
     65     return EFI_SUCCESS;
     66   }
     67   //
     68   // Update the latest entry in the journal.
     69   //
     70   MaxEntry = mStatusCodeMemoryPpi.Length / sizeof (EFI_STATUS_CODE_ENTRY);
     71   if (!MaxEntry) {
     72     //
     73     // If we don't have any entries, then we can return.
     74     // This effectively means that no memory buffer was passed forward from PEI.
     75     //
     76     return EFI_SUCCESS;
     77   }
     78 
     79   CurrentEntry = (EFI_STATUS_CODE_ENTRY *) (UINTN) (mStatusCodeMemoryPpi.Address + (mStatusCodeMemoryPpi.LastEntry * sizeof (EFI_STATUS_CODE_ENTRY)));
     80 
     81   mStatusCodeMemoryPpi.LastEntry = (mStatusCodeMemoryPpi.LastEntry + 1) % MaxEntry;
     82   if (mStatusCodeMemoryPpi.LastEntry == mStatusCodeMemoryPpi.FirstEntry) {
     83     mStatusCodeMemoryPpi.FirstEntry = (mStatusCodeMemoryPpi.FirstEntry + 1) % MaxEntry;
     84   }
     85 
     86   CurrentEntry->Type      = CodeType;
     87   CurrentEntry->Value     = Value;
     88   CurrentEntry->Instance  = Instance;
     89 
     90   return EFI_SUCCESS;
     91 }
     92 
     93 VOID
     94 EFIAPI
     95 RtMemoryInitializeStatusCode (
     96   IN EFI_HANDLE         ImageHandle,
     97   IN EFI_SYSTEM_TABLE   *SystemTable
     98   )
     99 /*++
    100 
    101 Routine Description:
    102 
    103   Initialization routine.
    104   Allocates heap space for storing Status Codes.
    105   Installs a PPI to point to that heap space.
    106   Installs a callback to switch to memory.
    107   Installs a callback to
    108 
    109 Arguments:
    110 
    111   (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
    112 
    113 Returns:
    114 
    115   None
    116 
    117 --*/
    118 {
    119   EFI_STATUS                  Status;
    120   VOID                        *HobList;
    121   PEI_STATUS_CODE_MEMORY_PPI  **StatusCodeMemoryPpi;
    122 
    123   //
    124   // Locate the HOB that contains the PPI structure for the memory journal
    125   // We don't check for more than one.
    126   //
    127   StatusCodeMemoryPpi = NULL;
    128   EfiLibGetSystemConfigurationTable (
    129     &gEfiHobListGuid,
    130     &HobList
    131     );
    132   Status = GetNextGuidHob (
    133             &HobList,
    134             &gPeiStatusCodeMemoryPpiGuid,
    135             (VOID **) &StatusCodeMemoryPpi,
    136             NULL
    137             );
    138   if (EFI_ERROR (Status) || (StatusCodeMemoryPpi == NULL)) {
    139     return ;
    140   }
    141   //
    142   // Copy data to our structure since the HOB will go away at runtime
    143   //
    144   // BUGBUG: Virtualize for RT
    145   //
    146   mStatusCodeMemoryPpi.FirstEntry = (*StatusCodeMemoryPpi)->FirstEntry;
    147   mStatusCodeMemoryPpi.LastEntry  = (*StatusCodeMemoryPpi)->LastEntry;
    148   mStatusCodeMemoryPpi.Address    = (*StatusCodeMemoryPpi)->Address;
    149   mStatusCodeMemoryPpi.Length     = (*StatusCodeMemoryPpi)->Length;
    150 }
    151 
    152 VOID
    153 EFIAPI
    154 PlaybackStatusCodes (
    155   IN EFI_REPORT_STATUS_CODE   ReportStatusCode
    156   )
    157 /*++
    158 
    159 Routine Description:
    160 
    161   Call the input ReportStatusCode function with every status code recorded in
    162   the journal.
    163 
    164 Arguments:
    165 
    166   ReportStatusCode    ReportStatusCode function to call.
    167 
    168 Returns:
    169 
    170   None
    171 
    172 --*/
    173 {
    174   UINTN                 MaxEntry;
    175   EFI_STATUS_CODE_ENTRY *CurrentEntry;
    176   UINTN                 Counter;
    177 
    178   if (ReportStatusCode == RtMemoryReportStatusCode) {
    179     return ;
    180   }
    181   //
    182   // Playback prior status codes to current listeners
    183   //
    184   MaxEntry = mStatusCodeMemoryPpi.Length / sizeof (EFI_STATUS_CODE_ENTRY);
    185   for (Counter = mStatusCodeMemoryPpi.FirstEntry; Counter != mStatusCodeMemoryPpi.LastEntry; Counter++) {
    186     //
    187     // Check if we have to roll back to beginning of queue buffer
    188     //
    189     if (Counter == MaxEntry) {
    190       Counter = 0;
    191     }
    192     //
    193     // Play current entry
    194     //
    195     CurrentEntry = (EFI_STATUS_CODE_ENTRY *) (UINTN) (mStatusCodeMemoryPpi.Address + (Counter * sizeof (EFI_STATUS_CODE_ENTRY)));
    196     ReportStatusCode (
    197       CurrentEntry->Type,
    198       CurrentEntry->Value,
    199       CurrentEntry->Instance,
    200       NULL,
    201       NULL
    202       );
    203   }
    204 }
    205