1 /** @file 2 Report status code lib on top of either SerialLib and/or EFI Serial Protocol. 3 Based on PcdStatusCodeUseEfiSerial & PcdStatusCodeUseHardSerial settings 4 5 There is just a single runtime memory buffer that contans all the data. 6 7 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> 8 Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> 9 This program and the accompanying materials 10 are licensed and made available under the terms and conditions of the BSD License 11 which accompanies this distribution. The full text of the license may be found at 12 http://opensource.org/licenses/bsd-license.php 13 14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 16 17 18 **/ 19 20 //////////#include "DxeStatusCode.h" 21 22 23 EFI_SERIAL_IO_PROTOCOL *mSerialIoProtocol = NULL; 24 25 26 EFI_STATUS 27 LibReportStatusCode ( 28 IN EFI_STATUS_CODE_TYPE CodeType, 29 IN EFI_STATUS_CODE_VALUE Value, 30 IN UINT32 Instance, 31 IN EFI_GUID *CallerId, 32 IN EFI_STATUS_CODE_DATA *Data OPTIONAL 33 ) 34 { 35 CHAR8 *Filename; 36 CHAR8 *Description; 37 CHAR8 *Format; 38 CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE]; 39 UINT32 ErrorLevel; 40 UINT32 LineNumber; 41 UINTN CharCount; 42 VA_LIST Marker; 43 EFI_DEBUG_INFO *DebugInfo; 44 EFI_TPL CurrentTpl; 45 46 47 if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) { 48 if (EfiAtRuntime ()) { 49 return EFI_DEVICE_ERROR; 50 } 51 CurrentTpl = gBS->RaiseTPL (EFI_TPL_HIGH_LEVEL); 52 gBS->RestoreTPL (CurrentTpl); 53 54 if (CurrentTpl > EFI_TPL_CALLBACK ) { 55 return EFI_DEVICE_ERROR; 56 } 57 } 58 59 Buffer[0] = '\0'; 60 61 if (Data != NULL && 62 ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) { 63 // 64 // Print ASSERT() information into output buffer. 65 // 66 CharCount = AsciiSPrint ( 67 Buffer, 68 EFI_STATUS_CODE_DATA_MAX_SIZE, 69 "\n\rDXE_ASSERT!: %a (%d): %a\n\r", 70 Filename, 71 LineNumber, 72 Description 73 ); 74 } else if (Data != NULL && 75 ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) { 76 // 77 // Print DEBUG() information into output buffer. 78 // 79 CharCount = AsciiVSPrint ( 80 Buffer, 81 EFI_STATUS_CODE_DATA_MAX_SIZE, 82 Format, 83 Marker 84 ); 85 } else if (Data != NULL && 86 CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) && 87 (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) { 88 // 89 // Print specific data into output buffer. 90 // 91 DebugInfo = (EFI_DEBUG_INFO *) (Data + 1); 92 Marker = (VA_LIST) (DebugInfo + 1); 93 Format = (CHAR8 *) (((UINT64 *) (DebugInfo + 1)) + 12); 94 95 CharCount = AsciiVSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker); 96 } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) { 97 // 98 // Print ERROR information into output buffer. 99 // 100 CharCount = AsciiSPrint ( 101 Buffer, 102 EFI_STATUS_CODE_DATA_MAX_SIZE, 103 "ERROR: C%x:V%x I%x", 104 CodeType, 105 Value, 106 Instance 107 ); 108 109 // 110 // Make sure we don't try to print values that weren't 111 // intended to be printed, especially NULL GUID pointers. 112 // 113 114 if (CallerId != NULL) { 115 CharCount += AsciiSPrint ( 116 &Buffer[CharCount - 1], 117 (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)), 118 " %g", 119 CallerId 120 ); 121 } 122 123 if (Data != NULL) { 124 CharCount += AsciiSPrint ( 125 &Buffer[CharCount - 1], 126 (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)), 127 " %x", 128 Data 129 ); 130 } 131 132 CharCount += AsciiSPrint ( 133 &Buffer[CharCount - 1], 134 (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)), 135 "\n\r" 136 ); 137 } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) { 138 CharCount = AsciiSPrint ( 139 Buffer, 140 EFI_STATUS_CODE_DATA_MAX_SIZE, 141 "PROGRESS CODE: V%x I%x\n\r", 142 Value, 143 Instance 144 ); 145 } else { 146 CharCount = AsciiSPrint ( 147 Buffer, 148 EFI_STATUS_CODE_DATA_MAX_SIZE, 149 "Undefined: C%x:V%x I%x\n\r", 150 CodeType, 151 Value, 152 Instance 153 ); 154 } 155 156 157 if (FeaturePcdGet (PcdStatusCodeUseHardSerial)) { 158 // 159 // Callout to SerialPort Lib function to do print. 160 // 161 SerialPortWrite ((UINT8 *) Buffer, CharCount); 162 } 163 if (FeaturePcdGet (PcdStatusCodeUseEfiSerial)) { 164 if (mSerialIoProtocol == NULL) { 165 gBS->LocateProtocol (&gEfiSerialIoProtocolGuid, NULL, (VOID **) &mSerialIoProtocol); 166 } 167 168 if (mSerialIoProtocol == NULL) { 169 mSerialIoProtocol->Write ( 170 mSerialIoProtocol, 171 &CharCount, 172 Buffer 173 ); 174 } 175 } 176 177 return EFI_SUCCESS; 178 } 179 180 181 VOID 182 LibReportStatusCodeVirtualAddressChangeEvent ( 183 VOID 184 ) 185 { 186 return; 187 } 188 189 VOID 190 LibReportStatusCodeInitialize ( 191 VOID 192 ) 193 { 194 return; 195 } 196 197 198 199