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