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 #include <libcper/log.h>
13 #include <string.h>
14
15 //Converts a single memory error CPER section into JSON IR.
cper_section_platform_memory_to_ir(const UINT8 * section,UINT32 size,char ** desc_string)16 json_object *cper_section_platform_memory_to_ir(const UINT8 *section,
17 UINT32 size, char **desc_string)
18 {
19 int outstr_len = 0;
20
21 *desc_string = NULL;
22 if (size < sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA)) {
23 cper_print_log("Error: Platform memory section too small\n");
24 return NULL;
25 }
26
27 *desc_string = calloc(1, SECTION_DESC_STRING_SIZE);
28 if (*desc_string == NULL) {
29 cper_print_log(
30 "Error: Failed to allocate Platform memory desc string\n");
31 return NULL;
32 }
33
34 EFI_PLATFORM_MEMORY_ERROR_DATA *memory_error =
35 (EFI_PLATFORM_MEMORY_ERROR_DATA *)section;
36 json_object *section_ir = json_object_new_object();
37
38 ValidationTypes ui64Type = { UINT_64T,
39 .value.ui64 = memory_error->ValidFields };
40
41 //Error status.
42 if (isvalid_prop_to_ir(&ui64Type, 0)) {
43 json_object *error_status = cper_generic_error_status_to_ir(
44 &memory_error->ErrorStatus);
45 json_object_object_add(section_ir, "errorStatus", error_status);
46 }
47
48 //Bank
49 json_object *bank = json_object_new_object();
50 if (isvalid_prop_to_ir(&ui64Type, 6)) {
51 //Entire bank address mode.
52 json_object_object_add(
53 bank, "value",
54 json_object_new_uint64(memory_error->Bank));
55 } else {
56 //Address/group address mode.
57 json_object_object_add(
58 bank, "address",
59 json_object_new_uint64(memory_error->Bank & 0xFF));
60 json_object_object_add(
61 bank, "group",
62 json_object_new_uint64(memory_error->Bank >> 8));
63 }
64 json_object_object_add(section_ir, "bank", bank);
65
66 //Memory error type.
67 const char *mem_type_str = NULL;
68 if (isvalid_prop_to_ir(&ui64Type, 14)) {
69 json_object *memory_error_type = integer_to_readable_pair(
70 memory_error->ErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
71 MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
72 json_object_object_add(section_ir, "memoryErrorType",
73 memory_error_type);
74 mem_type_str = json_object_get_string(
75 json_object_object_get(memory_error_type, "name"));
76 }
77 if (mem_type_str != NULL) {
78 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
79 "A %s Memory Error occurred",
80 mem_type_str);
81 } else {
82 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
83 "An Unknown Memory Error occurred");
84 }
85 if (outstr_len < 0) {
86 cper_print_log(
87 "Error: Could not write to Memory description string\n");
88 } else if (outstr_len > SECTION_DESC_STRING_SIZE) {
89 cper_print_log(
90 "Error: Memory description string truncated: %s\n",
91 *desc_string);
92 }
93 //"Extended" row/column indication field + misc.
94 if (isvalid_prop_to_ir(&ui64Type, 18)) {
95 json_object *extended = json_object_new_object();
96 json_object_object_add(
97 extended, "rowBit16",
98 json_object_new_boolean(memory_error->Extended & 0x1));
99 json_object_object_add(
100 extended, "rowBit17",
101 json_object_new_boolean((memory_error->Extended >> 1) &
102 0x1));
103 if (isvalid_prop_to_ir(&ui64Type, 21)) {
104 json_object_object_add(
105 extended, "chipIdentification",
106 json_object_new_int(memory_error->Extended >>
107 5));
108 }
109 json_object_object_add(section_ir, "extended", extended);
110 }
111
112 if (isvalid_prop_to_ir(&ui64Type, 16)) {
113 json_object_object_add(
114 section_ir, "cardSmbiosHandle",
115 json_object_new_uint64(memory_error->CardHandle));
116 }
117 if (isvalid_prop_to_ir(&ui64Type, 17)) {
118 json_object_object_add(
119 section_ir, "moduleSmbiosHandle",
120 json_object_new_uint64(memory_error->ModuleHandle));
121 }
122
123 //Miscellaneous numeric fields.
124 if (isvalid_prop_to_ir(&ui64Type, 1)) {
125 json_object_object_add(
126 section_ir, "physicalAddress",
127 json_object_new_uint64(memory_error->PhysicalAddress));
128
129 char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
130 snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
131 memory_error->PhysicalAddress);
132 json_object_object_add(section_ir, "physicalAddressHex",
133 json_object_new_string(hexstring_buf));
134 char physical_address_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
135 outstr_len = snprintf(physical_address_desc,
136 EFI_ERROR_DESCRIPTION_STRING_LEN,
137 " at address 0x%016llX",
138 memory_error->PhysicalAddress);
139 if (outstr_len < 0) {
140 cper_print_log(
141 "Error: Could not write to physical address description string\n");
142 } else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
143 cper_print_log(
144 "Error: Physical address description string truncated: %s\n",
145 physical_address_desc);
146 } else {
147 if (strlen(physical_address_desc) +
148 strlen(*desc_string) <
149 SECTION_DESC_STRING_SIZE) {
150 strncat(*desc_string, physical_address_desc,
151 outstr_len);
152 } else {
153 cper_print_log(
154 "Error: Memory description string too long, not added to description string: %s\n",
155 physical_address_desc);
156 }
157 }
158 }
159 if (isvalid_prop_to_ir(&ui64Type, 2)) {
160 json_object_object_add(
161 section_ir, "physicalAddressMask",
162 json_object_new_uint64(
163 memory_error->PhysicalAddressMask));
164 }
165 if (isvalid_prop_to_ir(&ui64Type, 3)) {
166 json_object_object_add(
167 section_ir, "node",
168 json_object_new_uint64(memory_error->Node));
169 char node_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
170 outstr_len = snprintf(node_desc,
171 EFI_ERROR_DESCRIPTION_STRING_LEN,
172 " at node %d", memory_error->Node);
173 if (outstr_len < 0) {
174 cper_print_log(
175 "Error: Could not write to node description string\n");
176 } else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
177 cper_print_log(
178 "Error: Node description string truncated: %s\n",
179 node_desc);
180 } else {
181 if (strlen(node_desc) + strlen(*desc_string) <
182 SECTION_DESC_STRING_SIZE) {
183 strncat(*desc_string, node_desc, outstr_len);
184 } else {
185 cper_print_log(
186 "Error: Memory description string too long, not added to description string: %s\n",
187 node_desc);
188 }
189 }
190 }
191
192 if (isvalid_prop_to_ir(&ui64Type, 4)) {
193 json_object_object_add(
194 section_ir, "card",
195 json_object_new_uint64(memory_error->Card));
196 }
197 if (isvalid_prop_to_ir(&ui64Type, 5)) {
198 json_object_object_add(
199 section_ir, "moduleRank",
200 json_object_new_uint64(memory_error->ModuleRank));
201 }
202 if (isvalid_prop_to_ir(&ui64Type, 7)) {
203 json_object_object_add(
204 section_ir, "device",
205 json_object_new_uint64(memory_error->Device));
206 }
207 if (isvalid_prop_to_ir(&ui64Type, 8)) {
208 json_object_object_add(
209 section_ir, "row",
210 json_object_new_uint64(memory_error->Row));
211 }
212 if (isvalid_prop_to_ir(&ui64Type, 9)) {
213 json_object_object_add(
214 section_ir, "column",
215 json_object_new_uint64(memory_error->Column));
216 }
217 if (isvalid_prop_to_ir(&ui64Type, 10)) {
218 json_object_object_add(
219 section_ir, "bitPosition",
220 json_object_new_uint64(memory_error->BitPosition));
221 }
222 if (isvalid_prop_to_ir(&ui64Type, 11)) {
223 json_object_object_add(
224 section_ir, "requestorID",
225 json_object_new_uint64(memory_error->RequestorId));
226 }
227 if (isvalid_prop_to_ir(&ui64Type, 12)) {
228 json_object_object_add(
229 section_ir, "responderID",
230 json_object_new_uint64(memory_error->ResponderId));
231 }
232 if (isvalid_prop_to_ir(&ui64Type, 13)) {
233 json_object_object_add(
234 section_ir, "targetID",
235 json_object_new_uint64(memory_error->TargetId));
236 }
237 if (isvalid_prop_to_ir(&ui64Type, 15)) {
238 json_object_object_add(
239 section_ir, "rankNumber",
240 json_object_new_uint64(memory_error->RankNum));
241 }
242
243 return section_ir;
244 }
245
246 //Converts a single memory error 2 CPER section into JSON IR.
cper_section_platform_memory2_to_ir(const UINT8 * section,UINT32 size,char ** desc_string)247 json_object *cper_section_platform_memory2_to_ir(const UINT8 *section,
248 UINT32 size,
249 char **desc_string)
250 {
251 int outstr_len = 0;
252 *desc_string = NULL;
253 if (size < sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA)) {
254 cper_print_log("Error: Platform memory2 section too small\n");
255 return NULL;
256 }
257
258 *desc_string = calloc(1, SECTION_DESC_STRING_SIZE);
259 if (*desc_string == NULL) {
260 cper_print_log(
261 "Error: Failed to allocate Platform memory2 desc string\n");
262 return NULL;
263 }
264
265 EFI_PLATFORM_MEMORY2_ERROR_DATA *memory_error =
266 (EFI_PLATFORM_MEMORY2_ERROR_DATA *)section;
267 json_object *section_ir = json_object_new_object();
268
269 ValidationTypes ui64Type = { UINT_64T,
270 .value.ui64 = memory_error->ValidFields };
271
272 //Error status.
273 if (isvalid_prop_to_ir(&ui64Type, 0)) {
274 json_object *error_status = cper_generic_error_status_to_ir(
275 &memory_error->ErrorStatus);
276 json_object_object_add(section_ir, "errorStatus", error_status);
277 }
278
279 //Bank.
280 json_object *bank = json_object_new_object();
281 if (isvalid_prop_to_ir(&ui64Type, 6)) {
282 //Entire bank address mode.
283 json_object_object_add(
284 bank, "value",
285 json_object_new_uint64(memory_error->Bank));
286 } else {
287 //Address/group address mode.
288 json_object_object_add(
289 bank, "address",
290 json_object_new_uint64(memory_error->Bank & 0xFF));
291 json_object_object_add(
292 bank, "group",
293 json_object_new_uint64(memory_error->Bank >> 8));
294 }
295 json_object_object_add(section_ir, "bank", bank);
296
297 //Memory error type.
298 const char *mem_type_str = NULL;
299 if (isvalid_prop_to_ir(&ui64Type, 13)) {
300 json_object *memory_error_type = integer_to_readable_pair(
301 memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
302 MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
303 json_object_object_add(section_ir, "memoryErrorType",
304 memory_error_type);
305 mem_type_str = json_object_get_string(
306 json_object_object_get(memory_error_type, "name"));
307 }
308 if (mem_type_str != NULL) {
309 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
310 "A %s Memory Error occurred",
311 mem_type_str);
312 } else {
313 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
314 "An Unknown Memory Error occurred");
315 }
316 if (outstr_len < 0) {
317 cper_print_log(
318 "Error: Could not write to Memory2 description string\n");
319 } else if (outstr_len > SECTION_DESC_STRING_SIZE) {
320 cper_print_log(
321 "Error: Memory2 description string truncated: %s\n",
322 *desc_string);
323 }
324 //Status.
325 if (isvalid_prop_to_ir(&ui64Type, 14)) {
326 json_object *status = json_object_new_object();
327 json_object_object_add(
328 status, "value",
329 json_object_new_int(memory_error->Status));
330 json_object_object_add(
331 status, "state",
332 json_object_new_string((memory_error->Status & 0x1) ==
333 0 ?
334 "Corrected" :
335 "Uncorrected"));
336 json_object_object_add(section_ir, "status", status);
337 }
338
339 //Miscellaneous numeric fields.
340 if (isvalid_prop_to_ir(&ui64Type, 0)) {
341 json_object_object_add(
342 section_ir, "physicalAddress",
343 json_object_new_uint64(memory_error->PhysicalAddress));
344 char physical_address_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
345 outstr_len = snprintf(physical_address_desc,
346 EFI_ERROR_DESCRIPTION_STRING_LEN,
347 " at address 0x%016llX",
348 memory_error->PhysicalAddress);
349 if (outstr_len < 0) {
350 cper_print_log(
351 "Error: Could not write to physical address description string\n");
352 } else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
353 cper_print_log(
354 "Error: Physical address description string truncated: %s\n",
355 physical_address_desc);
356 } else {
357 if (strlen(physical_address_desc) +
358 strlen(*desc_string) <
359 SECTION_DESC_STRING_SIZE) {
360 strncat(*desc_string, physical_address_desc,
361 outstr_len);
362 } else {
363 cper_print_log(
364 "Error: Memory2 description string too long, not added to description string: %s\n",
365 physical_address_desc);
366 }
367 }
368 }
369
370 char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
371 snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
372 memory_error->PhysicalAddress);
373 json_object_object_add(section_ir, "physicalAddressHex",
374 json_object_new_string(hexstring_buf));
375
376 if (isvalid_prop_to_ir(&ui64Type, 2)) {
377 json_object_object_add(
378 section_ir, "physicalAddressMask",
379 json_object_new_uint64(
380 memory_error->PhysicalAddressMask));
381 }
382 if (isvalid_prop_to_ir(&ui64Type, 3)) {
383 json_object_object_add(
384 section_ir, "node",
385 json_object_new_uint64(memory_error->Node));
386 char node_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
387 outstr_len = snprintf(node_desc,
388 EFI_ERROR_DESCRIPTION_STRING_LEN,
389 " on node %d", memory_error->Node);
390 if (outstr_len < 0) {
391 cper_print_log(
392 "Error: Could not write to node description string\n");
393 } else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
394 cper_print_log(
395 "Error: Node description string truncated: %s\n",
396 node_desc);
397 } else {
398 if (strlen(node_desc) + strlen(*desc_string) <
399 SECTION_DESC_STRING_SIZE) {
400 strncat(*desc_string, node_desc, outstr_len);
401 } else {
402 cper_print_log(
403 "Error: Memory2 description string too long, not added to description string: %s\n",
404 node_desc);
405 }
406 }
407 }
408 if (isvalid_prop_to_ir(&ui64Type, 4)) {
409 json_object_object_add(
410 section_ir, "card",
411 json_object_new_uint64(memory_error->Card));
412 }
413 if (isvalid_prop_to_ir(&ui64Type, 5)) {
414 json_object_object_add(
415 section_ir, "module",
416 json_object_new_uint64(memory_error->Module));
417 }
418 if (isvalid_prop_to_ir(&ui64Type, 7)) {
419 json_object_object_add(
420 section_ir, "device",
421 json_object_new_uint64(memory_error->Device));
422 }
423 if (isvalid_prop_to_ir(&ui64Type, 8)) {
424 json_object_object_add(
425 section_ir, "row",
426 json_object_new_uint64(memory_error->Row));
427 }
428 if (isvalid_prop_to_ir(&ui64Type, 9)) {
429 json_object_object_add(
430 section_ir, "column",
431 json_object_new_uint64(memory_error->Column));
432 }
433 if (isvalid_prop_to_ir(&ui64Type, 10)) {
434 json_object_object_add(
435 section_ir, "rank",
436 json_object_new_uint64(memory_error->Rank));
437 }
438 if (isvalid_prop_to_ir(&ui64Type, 11)) {
439 json_object_object_add(
440 section_ir, "bitPosition",
441 json_object_new_uint64(memory_error->BitPosition));
442 }
443 if (isvalid_prop_to_ir(&ui64Type, 12)) {
444 json_object_object_add(
445 section_ir, "chipID",
446 json_object_new_uint64(memory_error->ChipId));
447 }
448 if (isvalid_prop_to_ir(&ui64Type, 15)) {
449 json_object_object_add(
450 section_ir, "requestorID",
451 json_object_new_uint64(memory_error->RequestorId));
452 }
453 if (isvalid_prop_to_ir(&ui64Type, 16)) {
454 json_object_object_add(
455 section_ir, "responderID",
456 json_object_new_uint64(memory_error->ResponderId));
457 }
458 if (isvalid_prop_to_ir(&ui64Type, 17)) {
459 json_object_object_add(
460 section_ir, "targetID",
461 json_object_new_uint64(memory_error->TargetId));
462 }
463 if (isvalid_prop_to_ir(&ui64Type, 18)) {
464 json_object_object_add(
465 section_ir, "cardSmbiosHandle",
466 json_object_new_uint64(memory_error->CardHandle));
467 }
468 if (isvalid_prop_to_ir(&ui64Type, 19)) {
469 json_object_object_add(
470 section_ir, "moduleSmbiosHandle",
471 json_object_new_uint64(memory_error->ModuleHandle));
472 }
473
474 return section_ir;
475 }
476
477 //Converts a single Memory Error IR section into CPER binary, outputting to the provided stream.
ir_section_memory_to_cper(json_object * section,FILE * out)478 void ir_section_memory_to_cper(json_object *section, FILE *out)
479 {
480 EFI_PLATFORM_MEMORY_ERROR_DATA *section_cper =
481 (EFI_PLATFORM_MEMORY_ERROR_DATA *)calloc(
482 1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
483
484 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
485 struct json_object *obj = NULL;
486
487 //Error status.
488 if (json_object_object_get_ex(section, "errorStatus", &obj)) {
489 ir_generic_error_status_to_cper(obj,
490 §ion_cper->ErrorStatus);
491 add_to_valid_bitfield(&ui64Type, 0);
492 }
493
494 //Bank.
495 if (json_object_object_get_ex(section, "bank", &obj)) {
496 json_object *bank = obj;
497 if (json_object_object_get_ex(bank, "value", &obj)) {
498 //Bank just uses simple address.
499 section_cper->Bank =
500 (UINT16)json_object_get_uint64(obj);
501 add_to_valid_bitfield(&ui64Type, 6);
502 } else {
503 //Bank uses address/group style address.
504 UINT16 address = (UINT8)json_object_get_uint64(
505 json_object_object_get(bank, "address"));
506 UINT16 group = (UINT8)json_object_get_uint64(
507 json_object_object_get(bank, "group"));
508 section_cper->Bank = address + (group << 8);
509 add_to_valid_bitfield(&ui64Type, 19);
510 add_to_valid_bitfield(&ui64Type, 20);
511 }
512 }
513
514 //"Extended" field.
515 if (json_object_object_get_ex(section, "extended", &obj)) {
516 json_object *extended = obj;
517 section_cper->Extended = 0;
518 section_cper->Extended |= json_object_get_boolean(
519 json_object_object_get(extended, "rowBit16"));
520 section_cper->Extended |=
521 json_object_get_boolean(
522 json_object_object_get(extended, "rowBit17"))
523 << 1;
524 if (json_object_object_get_ex(extended, "chipIdentification",
525 &obj)) {
526 section_cper->Extended |= json_object_get_int(obj) << 5;
527 add_to_valid_bitfield(&ui64Type, 21);
528 }
529 add_to_valid_bitfield(&ui64Type, 18);
530 }
531
532 //Miscellaneous value fields.
533 if (json_object_object_get_ex(section, "memoryErrorType", &obj)) {
534 section_cper->ErrorType = (UINT8)readable_pair_to_integer(obj);
535 add_to_valid_bitfield(&ui64Type, 14);
536 }
537 if (json_object_object_get_ex(section, "physicalAddress", &obj)) {
538 section_cper->PhysicalAddress = json_object_get_uint64(obj);
539 add_to_valid_bitfield(&ui64Type, 1);
540 }
541 if (json_object_object_get_ex(section, "physicalAddressMask", &obj)) {
542 section_cper->PhysicalAddressMask = json_object_get_uint64(obj);
543 add_to_valid_bitfield(&ui64Type, 2);
544 }
545 if (json_object_object_get_ex(section, "node", &obj)) {
546 section_cper->Node = (UINT16)json_object_get_uint64(obj);
547 add_to_valid_bitfield(&ui64Type, 3);
548 }
549 if (json_object_object_get_ex(section, "card", &obj)) {
550 section_cper->Card = (UINT16)json_object_get_uint64(obj);
551 add_to_valid_bitfield(&ui64Type, 4);
552 }
553 if (json_object_object_get_ex(section, "moduleRank", &obj)) {
554 section_cper->ModuleRank = (UINT16)json_object_get_uint64(obj);
555 add_to_valid_bitfield(&ui64Type, 5);
556 }
557 if (json_object_object_get_ex(section, "device", &obj)) {
558 section_cper->Device = (UINT16)json_object_get_uint64(obj);
559 add_to_valid_bitfield(&ui64Type, 7);
560 }
561 if (json_object_object_get_ex(section, "row", &obj)) {
562 section_cper->Row = (UINT16)json_object_get_uint64(obj);
563 add_to_valid_bitfield(&ui64Type, 8);
564 }
565 if (json_object_object_get_ex(section, "column", &obj)) {
566 section_cper->Column = (UINT16)json_object_get_uint64(obj);
567 add_to_valid_bitfield(&ui64Type, 9);
568 }
569 if (json_object_object_get_ex(section, "bitPosition", &obj)) {
570 section_cper->BitPosition = (UINT16)json_object_get_uint64(obj);
571 add_to_valid_bitfield(&ui64Type, 10);
572 }
573 if (json_object_object_get_ex(section, "requestorID", &obj)) {
574 section_cper->RequestorId = json_object_get_uint64(obj);
575 add_to_valid_bitfield(&ui64Type, 11);
576 }
577 if (json_object_object_get_ex(section, "responderID", &obj)) {
578 section_cper->ResponderId = json_object_get_uint64(obj);
579 add_to_valid_bitfield(&ui64Type, 12);
580 }
581 if (json_object_object_get_ex(section, "targetID", &obj)) {
582 section_cper->TargetId = json_object_get_uint64(obj);
583 add_to_valid_bitfield(&ui64Type, 13);
584 }
585 if (json_object_object_get_ex(section, "rankNumber", &obj)) {
586 section_cper->RankNum = (UINT16)json_object_get_uint64(
587 json_object_object_get(section, "rankNumber"));
588 add_to_valid_bitfield(&ui64Type, 15);
589 }
590 if (json_object_object_get_ex(section, "cardSmbiosHandle", &obj)) {
591 section_cper->CardHandle = (UINT16)json_object_get_uint64(obj);
592 add_to_valid_bitfield(&ui64Type, 16);
593 }
594 if (json_object_object_get_ex(section, "moduleSmbiosHandle", &obj)) {
595 section_cper->ModuleHandle =
596 (UINT16)json_object_get_uint64(obj);
597 add_to_valid_bitfield(&ui64Type, 17);
598 }
599 section_cper->ValidFields = ui64Type.value.ui64;
600
601 //Write to stream, free up resources.
602 fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out);
603 fflush(out);
604 free(section_cper);
605 }
606
607 //Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream.
ir_section_memory2_to_cper(json_object * section,FILE * out)608 void ir_section_memory2_to_cper(json_object *section, FILE *out)
609 {
610 EFI_PLATFORM_MEMORY2_ERROR_DATA *section_cper =
611 (EFI_PLATFORM_MEMORY2_ERROR_DATA *)calloc(
612 1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
613
614 //Validation bits.
615 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
616 struct json_object *obj = NULL;
617
618 //Error status.
619 if (json_object_object_get_ex(section, "errorStatus", &obj)) {
620 ir_generic_error_status_to_cper(obj,
621 §ion_cper->ErrorStatus);
622 add_to_valid_bitfield(&ui64Type, 0);
623 }
624
625 //Bank.
626 json_object *bank = json_object_object_get(section, "bank");
627 if (json_object_object_get_ex(bank, "value", &obj)) {
628 //Bank just uses simple address.
629 section_cper->Bank = (UINT16)json_object_get_uint64(obj);
630 add_to_valid_bitfield(&ui64Type, 6);
631 } else {
632 //Bank uses address/group style address.
633 UINT16 address = (UINT8)json_object_get_uint64(
634 json_object_object_get(bank, "address"));
635 UINT16 group = (UINT8)json_object_get_uint64(
636 json_object_object_get(bank, "group"));
637 section_cper->Bank = address + (group << 8);
638 add_to_valid_bitfield(&ui64Type, 20);
639 add_to_valid_bitfield(&ui64Type, 21);
640 }
641
642 //Miscellaneous value fields.
643 if (json_object_object_get_ex(section, "memoryErrorType", &obj)) {
644 section_cper->MemErrorType = readable_pair_to_integer(obj);
645 add_to_valid_bitfield(&ui64Type, 13);
646 }
647 if (json_object_object_get_ex(section, "status", &obj)) {
648 section_cper->Status = (UINT8)readable_pair_to_integer(obj);
649 add_to_valid_bitfield(&ui64Type, 14);
650 }
651 if (json_object_object_get_ex(section, "physicalAddress", &obj)) {
652 section_cper->PhysicalAddress = json_object_get_uint64(obj);
653 add_to_valid_bitfield(&ui64Type, 1);
654 }
655 if (json_object_object_get_ex(section, "physicalAddressMask", &obj)) {
656 section_cper->PhysicalAddressMask = json_object_get_uint64(obj);
657 add_to_valid_bitfield(&ui64Type, 2);
658 }
659 if (json_object_object_get_ex(section, "node", &obj)) {
660 section_cper->Node = (UINT16)json_object_get_uint64(obj);
661 add_to_valid_bitfield(&ui64Type, 3);
662 }
663 if (json_object_object_get_ex(section, "card", &obj)) {
664 section_cper->Card = (UINT16)json_object_get_uint64(obj);
665 add_to_valid_bitfield(&ui64Type, 4);
666 }
667 if (json_object_object_get_ex(section, "module", &obj)) {
668 section_cper->Module = (UINT32)json_object_get_uint64(obj);
669 add_to_valid_bitfield(&ui64Type, 5);
670 }
671 if (json_object_object_get_ex(section, "device", &obj)) {
672 section_cper->Device = (UINT32)json_object_get_uint64(obj);
673 add_to_valid_bitfield(&ui64Type, 7);
674 }
675 if (json_object_object_get_ex(section, "row", &obj)) {
676 section_cper->Row = (UINT32)json_object_get_uint64(obj);
677 add_to_valid_bitfield(&ui64Type, 8);
678 }
679 if (json_object_object_get_ex(section, "column", &obj)) {
680 section_cper->Column = (UINT32)json_object_get_uint64(obj);
681 add_to_valid_bitfield(&ui64Type, 9);
682 }
683 if (json_object_object_get_ex(section, "rank", &obj)) {
684 section_cper->Rank = (UINT32)json_object_get_uint64(obj);
685 add_to_valid_bitfield(&ui64Type, 10);
686 }
687 if (json_object_object_get_ex(section, "bitPosition", &obj)) {
688 section_cper->BitPosition = (UINT32)json_object_get_uint64(obj);
689 add_to_valid_bitfield(&ui64Type, 11);
690 }
691 if (json_object_object_get_ex(section, "chipID", &obj)) {
692 section_cper->ChipId = (UINT8)json_object_get_uint64(obj);
693 add_to_valid_bitfield(&ui64Type, 12);
694 }
695 if (json_object_object_get_ex(section, "requestorID", &obj)) {
696 section_cper->RequestorId = json_object_get_uint64(obj);
697 add_to_valid_bitfield(&ui64Type, 15);
698 }
699 if (json_object_object_get_ex(section, "responderID", &obj)) {
700 section_cper->ResponderId = json_object_get_uint64(obj);
701 add_to_valid_bitfield(&ui64Type, 16);
702 }
703 if (json_object_object_get_ex(section, "targetID", &obj)) {
704 section_cper->TargetId = json_object_get_uint64(obj);
705 add_to_valid_bitfield(&ui64Type, 17);
706 }
707 if (json_object_object_get_ex(section, "cardSmbiosHandle", &obj)) {
708 section_cper->CardHandle = (UINT32)json_object_get_uint64(obj);
709 add_to_valid_bitfield(&ui64Type, 18);
710 }
711 if (json_object_object_get_ex(section, "moduleSmbiosHandle", &obj)) {
712 section_cper->ModuleHandle =
713 (UINT32)json_object_get_uint64(obj);
714 add_to_valid_bitfield(&ui64Type, 19);
715 }
716
717 section_cper->ValidFields = ui64Type.value.ui64;
718
719 //Write to stream, free up resources.
720 fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out);
721 fflush(out);
722 free(section_cper);
723 }
724