1 /** 2 * Describes functions for converting memory error CPER sections from binary and JSON format 3 * into an intermediate format. 4 * 5 * Author: Lawrence.Tang@arm.com 6 **/ 7 #include <stdio.h> 8 #include <json.h> 9 #include "../edk/Cper.h" 10 #include "../cper-utils.h" 11 #include "cper-section-memory.h" 12 13 //Converts a single memory error CPER section into JSON IR. 14 json_object * 15 cper_section_platform_memory_to_ir(void *section, 16 EFI_ERROR_SECTION_DESCRIPTOR *descriptor) 17 { 18 EFI_PLATFORM_MEMORY_ERROR_DATA *memory_error = 19 (EFI_PLATFORM_MEMORY_ERROR_DATA *)section; 20 json_object *section_ir = json_object_new_object(); 21 22 //Validation bitfield. 23 json_object *validation = 24 bitfield_to_ir(memory_error->ValidFields, 22, 25 MEMORY_ERROR_VALID_BITFIELD_NAMES); 26 json_object_object_add(section_ir, "validationBits", validation); 27 28 //Error status. 29 json_object *error_status = 30 cper_generic_error_status_to_ir(&memory_error->ErrorStatus); 31 json_object_object_add(section_ir, "errorStatus", error_status); 32 33 //Bank. 34 json_object *bank = json_object_new_object(); 35 if ((memory_error->ValidFields >> 5) & 0x1) { 36 //Entire bank address mode. 37 json_object_object_add( 38 bank, "value", 39 json_object_new_uint64(memory_error->Bank)); 40 } else { 41 //Address/group address mode. 42 json_object_object_add( 43 bank, "address", 44 json_object_new_uint64(memory_error->Bank & 0xFF)); 45 json_object_object_add( 46 bank, "group", 47 json_object_new_uint64(memory_error->Bank >> 8)); 48 } 49 json_object_object_add(section_ir, "bank", bank); 50 51 //Memory error type. 52 json_object *memory_error_type = integer_to_readable_pair( 53 memory_error->ErrorType, 16, MEMORY_ERROR_TYPES_KEYS, 54 MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)"); 55 json_object_object_add(section_ir, "memoryErrorType", 56 memory_error_type); 57 58 //"Extended" row/column indication field + misc. 59 json_object *extended = json_object_new_object(); 60 json_object_object_add(extended, "rowBit16", 61 json_object_new_boolean(memory_error->Extended & 62 0b1)); 63 json_object_object_add( 64 extended, "rowBit17", 65 json_object_new_boolean((memory_error->Extended >> 1) & 0b1)); 66 json_object_object_add(extended, "chipIdentification", 67 json_object_new_int(memory_error->Extended >> 68 5)); 69 json_object_object_add(section_ir, "extended", extended); 70 71 //Miscellaneous numeric fields. 72 json_object_object_add( 73 section_ir, "physicalAddress", 74 json_object_new_uint64(memory_error->PhysicalAddress)); 75 json_object_object_add( 76 section_ir, "physicalAddressMask", 77 json_object_new_uint64(memory_error->PhysicalAddressMask)); 78 json_object_object_add(section_ir, "node", 79 json_object_new_uint64(memory_error->Node)); 80 json_object_object_add(section_ir, "card", 81 json_object_new_uint64(memory_error->Card)); 82 json_object_object_add( 83 section_ir, "moduleRank", 84 json_object_new_uint64(memory_error->ModuleRank)); 85 json_object_object_add(section_ir, "device", 86 json_object_new_uint64(memory_error->Device)); 87 json_object_object_add(section_ir, "row", 88 json_object_new_uint64(memory_error->Row)); 89 json_object_object_add(section_ir, "column", 90 json_object_new_uint64(memory_error->Column)); 91 json_object_object_add( 92 section_ir, "bitPosition", 93 json_object_new_uint64(memory_error->BitPosition)); 94 json_object_object_add( 95 section_ir, "requestorID", 96 json_object_new_uint64(memory_error->RequestorId)); 97 json_object_object_add( 98 section_ir, "responderID", 99 json_object_new_uint64(memory_error->ResponderId)); 100 json_object_object_add(section_ir, "targetID", 101 json_object_new_uint64(memory_error->TargetId)); 102 json_object_object_add(section_ir, "rankNumber", 103 json_object_new_uint64(memory_error->RankNum)); 104 json_object_object_add( 105 section_ir, "cardSmbiosHandle", 106 json_object_new_uint64(memory_error->CardHandle)); 107 json_object_object_add( 108 section_ir, "moduleSmbiosHandle", 109 json_object_new_uint64(memory_error->ModuleHandle)); 110 111 return section_ir; 112 } 113 114 //Converts a single memory error 2 CPER section into JSON IR. 115 json_object * 116 cper_section_platform_memory2_to_ir(void *section, 117 EFI_ERROR_SECTION_DESCRIPTOR *descriptor) 118 { 119 EFI_PLATFORM_MEMORY2_ERROR_DATA *memory_error = 120 (EFI_PLATFORM_MEMORY2_ERROR_DATA *)section; 121 json_object *section_ir = json_object_new_object(); 122 123 //Validation bits. 124 json_object *validation = 125 bitfield_to_ir(memory_error->ValidFields, 22, 126 MEMORY_ERROR_2_VALID_BITFIELD_NAMES); 127 json_object_object_add(section_ir, "validationBits", validation); 128 129 //Error status. 130 json_object *error_status = 131 cper_generic_error_status_to_ir(&memory_error->ErrorStatus); 132 json_object_object_add(section_ir, "errorStatus", error_status); 133 134 //Bank. 135 json_object *bank = json_object_new_object(); 136 if ((memory_error->ValidFields >> 5) & 0x1) { 137 //Entire bank address mode. 138 json_object_object_add( 139 bank, "value", 140 json_object_new_uint64(memory_error->Bank)); 141 } else { 142 //Address/group address mode. 143 json_object_object_add( 144 bank, "address", 145 json_object_new_uint64(memory_error->Bank & 0xFF)); 146 json_object_object_add( 147 bank, "group", 148 json_object_new_uint64(memory_error->Bank >> 8)); 149 } 150 json_object_object_add(section_ir, "bank", bank); 151 152 //Memory error type. 153 json_object *memory_error_type = integer_to_readable_pair( 154 memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS, 155 MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)"); 156 json_object_object_add(section_ir, "memoryErrorType", 157 memory_error_type); 158 159 //Status. 160 json_object *status = json_object_new_object(); 161 json_object_object_add(status, "value", 162 json_object_new_int(memory_error->Status)); 163 json_object_object_add(status, "state", 164 json_object_new_string(memory_error->Status & 165 0b1 == 0 ? 166 "Corrected" : 167 "Uncorrected")); 168 json_object_object_add(section_ir, "status", status); 169 170 //Miscellaneous numeric fields. 171 json_object_object_add( 172 section_ir, "physicalAddress", 173 json_object_new_uint64(memory_error->PhysicalAddress)); 174 json_object_object_add( 175 section_ir, "physicalAddressMask", 176 json_object_new_uint64(memory_error->PhysicalAddressMask)); 177 json_object_object_add(section_ir, "node", 178 json_object_new_uint64(memory_error->Node)); 179 json_object_object_add(section_ir, "card", 180 json_object_new_uint64(memory_error->Card)); 181 json_object_object_add(section_ir, "module", 182 json_object_new_uint64(memory_error->Module)); 183 json_object_object_add(section_ir, "device", 184 json_object_new_uint64(memory_error->Device)); 185 json_object_object_add(section_ir, "row", 186 json_object_new_uint64(memory_error->Row)); 187 json_object_object_add(section_ir, "column", 188 json_object_new_uint64(memory_error->Column)); 189 json_object_object_add(section_ir, "rank", 190 json_object_new_uint64(memory_error->Rank)); 191 json_object_object_add( 192 section_ir, "bitPosition", 193 json_object_new_uint64(memory_error->BitPosition)); 194 json_object_object_add(section_ir, "chipID", 195 json_object_new_uint64(memory_error->ChipId)); 196 json_object_object_add( 197 section_ir, "requestorID", 198 json_object_new_uint64(memory_error->RequestorId)); 199 json_object_object_add( 200 section_ir, "responderID", 201 json_object_new_uint64(memory_error->ResponderId)); 202 json_object_object_add(section_ir, "targetID", 203 json_object_new_uint64(memory_error->TargetId)); 204 json_object_object_add( 205 section_ir, "cardSmbiosHandle", 206 json_object_new_uint64(memory_error->CardHandle)); 207 json_object_object_add( 208 section_ir, "moduleSmbiosHandle", 209 json_object_new_uint64(memory_error->ModuleHandle)); 210 211 return section_ir; 212 } 213 214 //Converts a single Memory Error IR section into CPER binary, outputting to the provided stream. 215 void ir_section_memory_to_cper(json_object *section, FILE *out) 216 { 217 EFI_PLATFORM_MEMORY_ERROR_DATA *section_cper = 218 (EFI_PLATFORM_MEMORY_ERROR_DATA *)calloc( 219 1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA)); 220 221 //Validation bits. 222 section_cper->ValidFields = ir_to_bitfield( 223 json_object_object_get(section, "validationBits"), 22, 224 MEMORY_ERROR_VALID_BITFIELD_NAMES); 225 226 //Error status. 227 ir_generic_error_status_to_cper(json_object_object_get(section, 228 "errorStatus"), 229 §ion_cper->ErrorStatus); 230 231 //Bank. 232 json_object *bank = json_object_object_get(section, "bank"); 233 if ((section_cper->ValidFields >> 5) & 0x1) { 234 //Bank just uses simple address. 235 section_cper->Bank = (UINT16)json_object_get_uint64( 236 json_object_object_get(bank, "value")); 237 } else { 238 //Bank uses address/group style address. 239 UINT16 address = (UINT8)json_object_get_uint64( 240 json_object_object_get(bank, "address")); 241 UINT16 group = (UINT8)json_object_get_uint64( 242 json_object_object_get(bank, "group")); 243 section_cper->Bank = address + (group << 8); 244 } 245 246 //"Extended" field. 247 json_object *extended = json_object_object_get(section, "extended"); 248 section_cper->Extended = 0; 249 section_cper->Extended |= json_object_get_boolean( 250 json_object_object_get(extended, "rowBit16")); 251 section_cper->Extended |= 252 json_object_get_boolean( 253 json_object_object_get(extended, "rowBit17")) 254 << 1; 255 section_cper->Extended |= json_object_get_int(json_object_object_get( 256 extended, "chipIdentification")) 257 << 5; 258 259 //Miscellaneous value fields. 260 section_cper->ErrorType = (UINT8)readable_pair_to_integer( 261 json_object_object_get(section, "memoryErrorType")); 262 section_cper->PhysicalAddress = json_object_get_uint64( 263 json_object_object_get(section, "physicalAddress")); 264 section_cper->PhysicalAddressMask = json_object_get_uint64( 265 json_object_object_get(section, "physicalAddressMask")); 266 section_cper->Node = (UINT16)json_object_get_uint64( 267 json_object_object_get(section, "node")); 268 section_cper->Card = (UINT16)json_object_get_uint64( 269 json_object_object_get(section, "card")); 270 section_cper->ModuleRank = (UINT16)json_object_get_uint64( 271 json_object_object_get(section, "moduleRank")); 272 section_cper->Device = (UINT16)json_object_get_uint64( 273 json_object_object_get(section, "device")); 274 section_cper->Row = (UINT16)json_object_get_uint64( 275 json_object_object_get(section, "row")); 276 section_cper->Column = (UINT16)json_object_get_uint64( 277 json_object_object_get(section, "column")); 278 section_cper->BitPosition = (UINT16)json_object_get_uint64( 279 json_object_object_get(section, "bitPosition")); 280 section_cper->RequestorId = json_object_get_uint64( 281 json_object_object_get(section, "requestorID")); 282 section_cper->ResponderId = json_object_get_uint64( 283 json_object_object_get(section, "responderID")); 284 section_cper->TargetId = json_object_get_uint64( 285 json_object_object_get(section, "targetID")); 286 section_cper->RankNum = (UINT16)json_object_get_uint64( 287 json_object_object_get(section, "rankNumber")); 288 section_cper->CardHandle = (UINT16)json_object_get_uint64( 289 json_object_object_get(section, "cardSmbiosHandle")); 290 section_cper->ModuleHandle = (UINT16)json_object_get_uint64( 291 json_object_object_get(section, "moduleSmbiosHandle")); 292 293 //Write to stream, free up resources. 294 fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out); 295 fflush(out); 296 free(section_cper); 297 } 298 299 //Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream. 300 void ir_section_memory2_to_cper(json_object *section, FILE *out) 301 { 302 EFI_PLATFORM_MEMORY2_ERROR_DATA *section_cper = 303 (EFI_PLATFORM_MEMORY2_ERROR_DATA *)calloc( 304 1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA)); 305 306 //Validation bits. 307 section_cper->ValidFields = ir_to_bitfield( 308 json_object_object_get(section, "validationBits"), 22, 309 MEMORY_ERROR_2_VALID_BITFIELD_NAMES); 310 311 //Error status. 312 ir_generic_error_status_to_cper(json_object_object_get(section, 313 "errorStatus"), 314 §ion_cper->ErrorStatus); 315 316 //Bank. 317 json_object *bank = json_object_object_get(section, "bank"); 318 if ((section_cper->ValidFields >> 5) & 0x1) { 319 //Bank just uses simple address. 320 section_cper->Bank = (UINT16)json_object_get_uint64( 321 json_object_object_get(bank, "value")); 322 } else { 323 //Bank uses address/group style address. 324 UINT16 address = (UINT8)json_object_get_uint64( 325 json_object_object_get(bank, "address")); 326 UINT16 group = (UINT8)json_object_get_uint64( 327 json_object_object_get(bank, "group")); 328 section_cper->Bank = address + (group << 8); 329 } 330 331 //Miscellaneous value fields. 332 section_cper->MemErrorType = readable_pair_to_integer( 333 json_object_object_get(section, "memoryErrorType")); 334 section_cper->Status = (UINT8)readable_pair_to_integer( 335 json_object_object_get(section, "status")); 336 section_cper->PhysicalAddress = json_object_get_uint64( 337 json_object_object_get(section, "physicalAddress")); 338 section_cper->PhysicalAddressMask = json_object_get_uint64( 339 json_object_object_get(section, "physicalAddressMask")); 340 section_cper->Node = (UINT16)json_object_get_uint64( 341 json_object_object_get(section, "node")); 342 section_cper->Card = (UINT16)json_object_get_uint64( 343 json_object_object_get(section, "card")); 344 section_cper->Module = (UINT32)json_object_get_uint64( 345 json_object_object_get(section, "module")); 346 section_cper->Device = (UINT32)json_object_get_uint64( 347 json_object_object_get(section, "device")); 348 section_cper->Row = (UINT32)json_object_get_uint64( 349 json_object_object_get(section, "row")); 350 section_cper->Column = (UINT32)json_object_get_uint64( 351 json_object_object_get(section, "column")); 352 section_cper->Rank = (UINT32)json_object_get_uint64( 353 json_object_object_get(section, "rank")); 354 section_cper->BitPosition = (UINT32)json_object_get_uint64( 355 json_object_object_get(section, "bitPosition")); 356 section_cper->ChipId = (UINT8)json_object_get_uint64( 357 json_object_object_get(section, "chipID")); 358 section_cper->RequestorId = json_object_get_uint64( 359 json_object_object_get(section, "requestorID")); 360 section_cper->ResponderId = json_object_get_uint64( 361 json_object_object_get(section, "responderID")); 362 section_cper->TargetId = json_object_get_uint64( 363 json_object_object_get(section, "targetID")); 364 section_cper->CardHandle = (UINT32)json_object_get_uint64( 365 json_object_object_get(section, "cardSmbiosHandle")); 366 section_cper->ModuleHandle = (UINT32)json_object_get_uint64( 367 json_object_object_get(section, "moduleSmbiosHandle")); 368 369 //Write to stream, free up resources. 370 fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out); 371 fflush(out); 372 free(section_cper); 373 }