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