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