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