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