blob: a3b76b676df703e8040fcc7f85b25a9bfeb4eb33 [file] [log] [blame]
Lawrence Tang7f21db62022-07-06 11:09:39 +01001/**
2 * Describes functions for converting memory error CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang7f21db62022-07-06 11:09:39 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7#include <stdio.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01008#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +00009#include <libcper/Cper.h>
10#include <libcper/cper-utils.h>
11#include <libcper/sections/cper-section-memory.h>
Ed Tanous50b966f2025-03-11 09:06:19 -070012#include <libcper/log.h>
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070013#include <string.h>
Lawrence Tang7f21db62022-07-06 11:09:39 +010014
15//Converts a single memory error CPER section into JSON IR.
Ed Tanous12dbd4f2025-03-08 19:05:01 -080016json_object *cper_section_platform_memory_to_ir(const UINT8 *section,
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070017 UINT32 size, char **desc_string)
Lawrence Tang7f21db62022-07-06 11:09:39 +010018{
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070019 int outstr_len = 0;
20 *desc_string = malloc(SECTION_DESC_STRING_SIZE);
Ed Tanous12dbd4f2025-03-08 19:05:01 -080021 if (size < sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA)) {
22 return NULL;
23 }
24
Lawrence Tange407b4c2022-07-21 13:54:01 +010025 EFI_PLATFORM_MEMORY_ERROR_DATA *memory_error =
26 (EFI_PLATFORM_MEMORY_ERROR_DATA *)section;
27 json_object *section_ir = json_object_new_object();
Lawrence Tang7f21db62022-07-06 11:09:39 +010028
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080029 ValidationTypes ui64Type = { UINT_64T,
30 .value.ui64 = memory_error->ValidFields };
Lawrence Tang7f21db62022-07-06 11:09:39 +010031
Lawrence Tange407b4c2022-07-21 13:54:01 +010032 //Error status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080033 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 }
Lawrence Tanga0865e32022-07-06 11:59:52 +010038
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080039 //Bank
Lawrence Tange407b4c2022-07-21 13:54:01 +010040 json_object *bank = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080041 if (isvalid_prop_to_ir(&ui64Type, 6)) {
Lawrence Tange407b4c2022-07-21 13:54:01 +010042 //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);
Lawrence Tanga0865e32022-07-06 11:59:52 +010056
Lawrence Tange407b4c2022-07-21 13:54:01 +010057 //Memory error type.
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070058 const char *mem_type_str = NULL;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080059 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);
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070065 mem_type_str = json_object_get_string(
66 json_object_object_get(memory_error_type, "name"));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080067 }
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070068 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 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010084 //"Extended" row/column indication field + misc.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080085 if (isvalid_prop_to_ir(&ui64Type, 18)) {
86 json_object *extended = json_object_new_object();
87 json_object_object_add(
88 extended, "rowBit16",
89 json_object_new_boolean(memory_error->Extended & 0x1));
90 json_object_object_add(
91 extended, "rowBit17",
92 json_object_new_boolean((memory_error->Extended >> 1) &
93 0x1));
94 if (isvalid_prop_to_ir(&ui64Type, 21)) {
95 json_object_object_add(
96 extended, "chipIdentification",
97 json_object_new_int(memory_error->Extended >>
98 5));
99 }
100 json_object_object_add(section_ir, "extended", extended);
Peter Benitezda751282025-07-28 11:26:11 -0700101 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800102
Peter Benitezda751282025-07-28 11:26:11 -0700103 if (isvalid_prop_to_ir(&ui64Type, 16)) {
104 json_object_object_add(
105 section_ir, "cardSmbiosHandle",
106 json_object_new_uint64(memory_error->CardHandle));
107 }
108 if (isvalid_prop_to_ir(&ui64Type, 17)) {
109 json_object_object_add(
110 section_ir, "moduleSmbiosHandle",
111 json_object_new_uint64(memory_error->ModuleHandle));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800112 }
Lawrence Tanga0865e32022-07-06 11:59:52 +0100113
Lawrence Tange407b4c2022-07-21 13:54:01 +0100114 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800115 if (isvalid_prop_to_ir(&ui64Type, 1)) {
116 json_object_object_add(
117 section_ir, "physicalAddress",
118 json_object_new_uint64(memory_error->PhysicalAddress));
Aushim Nagarkatticc367012024-12-05 18:17:27 -0800119
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800120 char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
121 snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
122 memory_error->PhysicalAddress);
123 json_object_object_add(section_ir, "physicalAddressHex",
124 json_object_new_string(hexstring_buf));
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700125 char physical_address_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
126 outstr_len = snprintf(physical_address_desc,
127 EFI_ERROR_DESCRIPTION_STRING_LEN,
128 " at address 0x%016llX",
129 memory_error->PhysicalAddress);
130 if (outstr_len < 0) {
131 cper_print_log(
132 "Error: Could not write to physical address description string\n");
133 } else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
134 cper_print_log(
135 "Error: Physical address description string truncated: %s\n",
136 physical_address_desc);
137 } else {
138 if (strlen(physical_address_desc) +
139 strlen(*desc_string) <
140 SECTION_DESC_STRING_SIZE) {
141 strncat(*desc_string, physical_address_desc,
142 outstr_len);
143 } else {
144 cper_print_log(
145 "Error: Memory description string too long, not added to description string: %s\n",
146 physical_address_desc);
147 }
148 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800149 }
150 if (isvalid_prop_to_ir(&ui64Type, 2)) {
151 json_object_object_add(
152 section_ir, "physicalAddressMask",
153 json_object_new_uint64(
154 memory_error->PhysicalAddressMask));
155 }
156 if (isvalid_prop_to_ir(&ui64Type, 3)) {
157 json_object_object_add(
158 section_ir, "node",
159 json_object_new_uint64(memory_error->Node));
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700160 char node_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
161 outstr_len = snprintf(node_desc,
162 EFI_ERROR_DESCRIPTION_STRING_LEN,
163 " at node %d", memory_error->Node);
164 if (outstr_len < 0) {
165 cper_print_log(
166 "Error: Could not write to node description string\n");
167 } else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
168 cper_print_log(
169 "Error: Node description string truncated: %s\n",
170 node_desc);
171 } else {
172 if (strlen(node_desc) + strlen(*desc_string) <
173 SECTION_DESC_STRING_SIZE) {
174 strncat(*desc_string, node_desc, outstr_len);
175 } else {
176 cper_print_log(
177 "Error: Memory description string too long, not added to description string: %s\n",
178 node_desc);
179 }
180 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800181 }
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700182
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800183 if (isvalid_prop_to_ir(&ui64Type, 4)) {
184 json_object_object_add(
185 section_ir, "card",
186 json_object_new_uint64(memory_error->Card));
187 }
188 if (isvalid_prop_to_ir(&ui64Type, 5)) {
189 json_object_object_add(
190 section_ir, "moduleRank",
191 json_object_new_uint64(memory_error->ModuleRank));
192 }
193 if (isvalid_prop_to_ir(&ui64Type, 7)) {
194 json_object_object_add(
195 section_ir, "device",
196 json_object_new_uint64(memory_error->Device));
197 }
198 if (isvalid_prop_to_ir(&ui64Type, 8)) {
199 json_object_object_add(
200 section_ir, "row",
201 json_object_new_uint64(memory_error->Row));
202 }
203 if (isvalid_prop_to_ir(&ui64Type, 9)) {
204 json_object_object_add(
205 section_ir, "column",
206 json_object_new_uint64(memory_error->Column));
207 }
208 if (isvalid_prop_to_ir(&ui64Type, 10)) {
209 json_object_object_add(
210 section_ir, "bitPosition",
211 json_object_new_uint64(memory_error->BitPosition));
212 }
213 if (isvalid_prop_to_ir(&ui64Type, 11)) {
214 json_object_object_add(
215 section_ir, "requestorID",
216 json_object_new_uint64(memory_error->RequestorId));
217 }
218 if (isvalid_prop_to_ir(&ui64Type, 12)) {
219 json_object_object_add(
220 section_ir, "responderID",
221 json_object_new_uint64(memory_error->ResponderId));
222 }
223 if (isvalid_prop_to_ir(&ui64Type, 13)) {
224 json_object_object_add(
225 section_ir, "targetID",
226 json_object_new_uint64(memory_error->TargetId));
227 }
228 if (isvalid_prop_to_ir(&ui64Type, 15)) {
229 json_object_object_add(
230 section_ir, "rankNumber",
231 json_object_new_uint64(memory_error->RankNum));
232 }
Lawrence Tang54da4412022-07-06 13:14:58 +0100233
Lawrence Tange407b4c2022-07-21 13:54:01 +0100234 return section_ir;
Lawrence Tanga0865e32022-07-06 11:59:52 +0100235}
236
237//Converts a single memory error 2 CPER section into JSON IR.
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800238json_object *cper_section_platform_memory2_to_ir(const UINT8 *section,
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700239 UINT32 size,
240 char **desc_string)
Lawrence Tanga0865e32022-07-06 11:59:52 +0100241{
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700242 int outstr_len = 0;
243 *desc_string = malloc(SECTION_DESC_STRING_SIZE);
244
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800245 if (size < sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA)) {
246 return NULL;
247 }
248
Lawrence Tange407b4c2022-07-21 13:54:01 +0100249 EFI_PLATFORM_MEMORY2_ERROR_DATA *memory_error =
250 (EFI_PLATFORM_MEMORY2_ERROR_DATA *)section;
251 json_object *section_ir = json_object_new_object();
Lawrence Tanga0865e32022-07-06 11:59:52 +0100252
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800253 ValidationTypes ui64Type = { UINT_64T,
254 .value.ui64 = memory_error->ValidFields };
Lawrence Tanga0865e32022-07-06 11:59:52 +0100255
Lawrence Tange407b4c2022-07-21 13:54:01 +0100256 //Error status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800257 if (isvalid_prop_to_ir(&ui64Type, 0)) {
258 json_object *error_status = cper_generic_error_status_to_ir(
259 &memory_error->ErrorStatus);
260 json_object_object_add(section_ir, "errorStatus", error_status);
261 }
Lawrence Tang54da4412022-07-06 13:14:58 +0100262
Lawrence Tange407b4c2022-07-21 13:54:01 +0100263 //Bank.
264 json_object *bank = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800265 if (isvalid_prop_to_ir(&ui64Type, 6)) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100266 //Entire bank address mode.
267 json_object_object_add(
268 bank, "value",
269 json_object_new_uint64(memory_error->Bank));
270 } else {
271 //Address/group address mode.
272 json_object_object_add(
273 bank, "address",
274 json_object_new_uint64(memory_error->Bank & 0xFF));
275 json_object_object_add(
276 bank, "group",
277 json_object_new_uint64(memory_error->Bank >> 8));
278 }
279 json_object_object_add(section_ir, "bank", bank);
Lawrence Tang54da4412022-07-06 13:14:58 +0100280
Lawrence Tange407b4c2022-07-21 13:54:01 +0100281 //Memory error type.
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700282 const char *mem_type_str = NULL;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800283 if (isvalid_prop_to_ir(&ui64Type, 13)) {
284 json_object *memory_error_type = integer_to_readable_pair(
285 memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
286 MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
287 json_object_object_add(section_ir, "memoryErrorType",
288 memory_error_type);
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700289 mem_type_str = json_object_get_string(
290 json_object_object_get(memory_error_type, "name"));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800291 }
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700292 if (mem_type_str != NULL) {
293 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
294 "A %s Memory Error occurred",
295 mem_type_str);
296 } else {
297 outstr_len = snprintf(*desc_string, SECTION_DESC_STRING_SIZE,
298 "An Unknown Memory Error occurred");
299 }
300 if (outstr_len < 0) {
301 cper_print_log(
302 "Error: Could not write to Memory2 description string\n");
303 } else if (outstr_len > SECTION_DESC_STRING_SIZE) {
304 cper_print_log(
305 "Error: Memory2 description string truncated: %s\n",
306 *desc_string);
307 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100308 //Status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800309 if (isvalid_prop_to_ir(&ui64Type, 14)) {
310 json_object *status = json_object_new_object();
311 json_object_object_add(
312 status, "value",
313 json_object_new_int(memory_error->Status));
314 json_object_object_add(
315 status, "state",
316 json_object_new_string((memory_error->Status & 0x1) ==
317 0 ?
318 "Corrected" :
319 "Uncorrected"));
320 json_object_object_add(section_ir, "status", status);
321 }
Lawrence Tang54da4412022-07-06 13:14:58 +0100322
Lawrence Tange407b4c2022-07-21 13:54:01 +0100323 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800324 if (isvalid_prop_to_ir(&ui64Type, 0)) {
325 json_object_object_add(
326 section_ir, "physicalAddress",
327 json_object_new_uint64(memory_error->PhysicalAddress));
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700328 char physical_address_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
329 outstr_len = snprintf(physical_address_desc,
330 EFI_ERROR_DESCRIPTION_STRING_LEN,
331 " at address 0x%016llX",
332 memory_error->PhysicalAddress);
333 if (outstr_len < 0) {
334 cper_print_log(
335 "Error: Could not write to physical address description string\n");
336 } else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
337 cper_print_log(
338 "Error: Physical address description string truncated: %s\n",
339 physical_address_desc);
340 } else {
341 if (strlen(physical_address_desc) +
342 strlen(*desc_string) <
343 SECTION_DESC_STRING_SIZE) {
344 strncat(*desc_string, physical_address_desc,
345 outstr_len);
346 } else {
347 cper_print_log(
348 "Error: Memory2 description string too long, not added to description string: %s\n",
349 physical_address_desc);
350 }
351 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800352 }
Aushim Nagarkatticc367012024-12-05 18:17:27 -0800353
354 char hexstring_buf[EFI_UINT64_HEX_STRING_LEN];
355 snprintf(hexstring_buf, EFI_UINT64_HEX_STRING_LEN, "0x%016llX",
356 memory_error->PhysicalAddress);
357 json_object_object_add(section_ir, "physicalAddressHex",
358 json_object_new_string(hexstring_buf));
359
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800360 if (isvalid_prop_to_ir(&ui64Type, 2)) {
361 json_object_object_add(
362 section_ir, "physicalAddressMask",
363 json_object_new_uint64(
364 memory_error->PhysicalAddressMask));
365 }
366 if (isvalid_prop_to_ir(&ui64Type, 3)) {
367 json_object_object_add(
368 section_ir, "node",
369 json_object_new_uint64(memory_error->Node));
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -0700370 char node_desc[EFI_ERROR_DESCRIPTION_STRING_LEN];
371 outstr_len = snprintf(node_desc,
372 EFI_ERROR_DESCRIPTION_STRING_LEN,
373 " on node %d", memory_error->Node);
374 if (outstr_len < 0) {
375 cper_print_log(
376 "Error: Could not write to node description string\n");
377 } else if (outstr_len > EFI_ERROR_DESCRIPTION_STRING_LEN) {
378 cper_print_log(
379 "Error: Node description string truncated: %s\n",
380 node_desc);
381 } else {
382 if (strlen(node_desc) + strlen(*desc_string) <
383 SECTION_DESC_STRING_SIZE) {
384 strncat(*desc_string, node_desc, outstr_len);
385 } else {
386 cper_print_log(
387 "Error: Memory2 description string too long, not added to description string: %s\n",
388 node_desc);
389 }
390 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800391 }
392 if (isvalid_prop_to_ir(&ui64Type, 4)) {
393 json_object_object_add(
394 section_ir, "card",
395 json_object_new_uint64(memory_error->Card));
396 }
397 if (isvalid_prop_to_ir(&ui64Type, 5)) {
398 json_object_object_add(
399 section_ir, "module",
400 json_object_new_uint64(memory_error->Module));
401 }
402 if (isvalid_prop_to_ir(&ui64Type, 7)) {
403 json_object_object_add(
404 section_ir, "device",
405 json_object_new_uint64(memory_error->Device));
406 }
407 if (isvalid_prop_to_ir(&ui64Type, 8)) {
408 json_object_object_add(
409 section_ir, "row",
410 json_object_new_uint64(memory_error->Row));
411 }
412 if (isvalid_prop_to_ir(&ui64Type, 9)) {
413 json_object_object_add(
414 section_ir, "column",
415 json_object_new_uint64(memory_error->Column));
416 }
417 if (isvalid_prop_to_ir(&ui64Type, 10)) {
418 json_object_object_add(
419 section_ir, "rank",
420 json_object_new_uint64(memory_error->Rank));
421 }
422 if (isvalid_prop_to_ir(&ui64Type, 11)) {
423 json_object_object_add(
424 section_ir, "bitPosition",
425 json_object_new_uint64(memory_error->BitPosition));
426 }
427 if (isvalid_prop_to_ir(&ui64Type, 12)) {
428 json_object_object_add(
429 section_ir, "chipID",
430 json_object_new_uint64(memory_error->ChipId));
431 }
432 if (isvalid_prop_to_ir(&ui64Type, 15)) {
433 json_object_object_add(
434 section_ir, "requestorID",
435 json_object_new_uint64(memory_error->RequestorId));
436 }
437 if (isvalid_prop_to_ir(&ui64Type, 16)) {
438 json_object_object_add(
439 section_ir, "responderID",
440 json_object_new_uint64(memory_error->ResponderId));
441 }
442 if (isvalid_prop_to_ir(&ui64Type, 17)) {
443 json_object_object_add(
444 section_ir, "targetID",
445 json_object_new_uint64(memory_error->TargetId));
446 }
447 if (isvalid_prop_to_ir(&ui64Type, 18)) {
448 json_object_object_add(
449 section_ir, "cardSmbiosHandle",
450 json_object_new_uint64(memory_error->CardHandle));
451 }
452 if (isvalid_prop_to_ir(&ui64Type, 19)) {
453 json_object_object_add(
454 section_ir, "moduleSmbiosHandle",
455 json_object_new_uint64(memory_error->ModuleHandle));
456 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100457
458 return section_ir;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100459}
460
461//Converts a single Memory Error IR section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100462void ir_section_memory_to_cper(json_object *section, FILE *out)
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100463{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100464 EFI_PLATFORM_MEMORY_ERROR_DATA *section_cper =
465 (EFI_PLATFORM_MEMORY_ERROR_DATA *)calloc(
466 1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100467
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800468 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
469 struct json_object *obj = NULL;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100470
Lawrence Tange407b4c2022-07-21 13:54:01 +0100471 //Error status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800472 if (json_object_object_get_ex(section, "errorStatus", &obj)) {
473 ir_generic_error_status_to_cper(obj,
474 &section_cper->ErrorStatus);
475 add_to_valid_bitfield(&ui64Type, 0);
476 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100477
Lawrence Tange407b4c2022-07-21 13:54:01 +0100478 //Bank.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800479 if (json_object_object_get_ex(section, "bank", &obj)) {
480 json_object *bank = obj;
481 if (json_object_object_get_ex(bank, "value", &obj)) {
482 //Bank just uses simple address.
483 section_cper->Bank =
484 (UINT16)json_object_get_uint64(obj);
485 add_to_valid_bitfield(&ui64Type, 6);
486 } else {
487 //Bank uses address/group style address.
488 UINT16 address = (UINT8)json_object_get_uint64(
489 json_object_object_get(bank, "address"));
490 UINT16 group = (UINT8)json_object_get_uint64(
491 json_object_object_get(bank, "group"));
492 section_cper->Bank = address + (group << 8);
493 add_to_valid_bitfield(&ui64Type, 19);
494 add_to_valid_bitfield(&ui64Type, 20);
495 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100496 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100497
Lawrence Tange407b4c2022-07-21 13:54:01 +0100498 //"Extended" field.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800499 if (json_object_object_get_ex(section, "extended", &obj)) {
500 json_object *extended = obj;
501 section_cper->Extended = 0;
502 section_cper->Extended |= json_object_get_boolean(
503 json_object_object_get(extended, "rowBit16"));
504 section_cper->Extended |=
505 json_object_get_boolean(
506 json_object_object_get(extended, "rowBit17"))
507 << 1;
508 if (json_object_object_get_ex(extended, "chipIdentification",
509 &obj)) {
510 section_cper->Extended |= json_object_get_int(obj) << 5;
511 add_to_valid_bitfield(&ui64Type, 21);
512 }
513 add_to_valid_bitfield(&ui64Type, 18);
514 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100515
Lawrence Tange407b4c2022-07-21 13:54:01 +0100516 //Miscellaneous value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800517 if (json_object_object_get_ex(section, "memoryErrorType", &obj)) {
518 section_cper->ErrorType = (UINT8)readable_pair_to_integer(obj);
519 add_to_valid_bitfield(&ui64Type, 14);
520 }
521 if (json_object_object_get_ex(section, "physicalAddress", &obj)) {
522 section_cper->PhysicalAddress = json_object_get_uint64(obj);
523 add_to_valid_bitfield(&ui64Type, 1);
524 }
525 if (json_object_object_get_ex(section, "physicalAddressMask", &obj)) {
526 section_cper->PhysicalAddressMask = json_object_get_uint64(obj);
527 add_to_valid_bitfield(&ui64Type, 2);
528 }
529 if (json_object_object_get_ex(section, "node", &obj)) {
530 section_cper->Node = (UINT16)json_object_get_uint64(obj);
531 add_to_valid_bitfield(&ui64Type, 3);
532 }
533 if (json_object_object_get_ex(section, "card", &obj)) {
534 section_cper->Card = (UINT16)json_object_get_uint64(obj);
535 add_to_valid_bitfield(&ui64Type, 4);
536 }
537 if (json_object_object_get_ex(section, "moduleRank", &obj)) {
538 section_cper->ModuleRank = (UINT16)json_object_get_uint64(obj);
539 add_to_valid_bitfield(&ui64Type, 5);
540 }
541 if (json_object_object_get_ex(section, "device", &obj)) {
542 section_cper->Device = (UINT16)json_object_get_uint64(obj);
543 add_to_valid_bitfield(&ui64Type, 7);
544 }
545 if (json_object_object_get_ex(section, "row", &obj)) {
546 section_cper->Row = (UINT16)json_object_get_uint64(obj);
547 add_to_valid_bitfield(&ui64Type, 8);
548 }
549 if (json_object_object_get_ex(section, "column", &obj)) {
550 section_cper->Column = (UINT16)json_object_get_uint64(obj);
551 add_to_valid_bitfield(&ui64Type, 9);
552 }
553 if (json_object_object_get_ex(section, "bitPosition", &obj)) {
554 section_cper->BitPosition = (UINT16)json_object_get_uint64(obj);
555 add_to_valid_bitfield(&ui64Type, 10);
556 }
557 if (json_object_object_get_ex(section, "requestorID", &obj)) {
558 section_cper->RequestorId = json_object_get_uint64(obj);
559 add_to_valid_bitfield(&ui64Type, 11);
560 }
561 if (json_object_object_get_ex(section, "responderID", &obj)) {
562 section_cper->ResponderId = json_object_get_uint64(obj);
563 add_to_valid_bitfield(&ui64Type, 12);
564 }
565 if (json_object_object_get_ex(section, "targetID", &obj)) {
566 section_cper->TargetId = json_object_get_uint64(obj);
567 add_to_valid_bitfield(&ui64Type, 13);
568 }
569 if (json_object_object_get_ex(section, "rankNumber", &obj)) {
570 section_cper->RankNum = (UINT16)json_object_get_uint64(
571 json_object_object_get(section, "rankNumber"));
572 add_to_valid_bitfield(&ui64Type, 15);
573 }
574 if (json_object_object_get_ex(section, "cardSmbiosHandle", &obj)) {
575 section_cper->CardHandle = (UINT16)json_object_get_uint64(obj);
576 add_to_valid_bitfield(&ui64Type, 16);
577 }
578 if (json_object_object_get_ex(section, "moduleSmbiosHandle", &obj)) {
579 section_cper->ModuleHandle =
580 (UINT16)json_object_get_uint64(obj);
581 add_to_valid_bitfield(&ui64Type, 17);
582 }
583 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100584
Lawrence Tange407b4c2022-07-21 13:54:01 +0100585 //Write to stream, free up resources.
586 fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out);
587 fflush(out);
588 free(section_cper);
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100589}
590
591//Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100592void ir_section_memory2_to_cper(json_object *section, FILE *out)
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100593{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100594 EFI_PLATFORM_MEMORY2_ERROR_DATA *section_cper =
595 (EFI_PLATFORM_MEMORY2_ERROR_DATA *)calloc(
596 1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100597
Lawrence Tange407b4c2022-07-21 13:54:01 +0100598 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800599 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
600 struct json_object *obj = NULL;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100601
Lawrence Tange407b4c2022-07-21 13:54:01 +0100602 //Error status.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800603 if (json_object_object_get_ex(section, "errorStatus", &obj)) {
604 ir_generic_error_status_to_cper(obj,
605 &section_cper->ErrorStatus);
606 add_to_valid_bitfield(&ui64Type, 0);
607 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100608
Lawrence Tange407b4c2022-07-21 13:54:01 +0100609 //Bank.
610 json_object *bank = json_object_object_get(section, "bank");
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800611 if (json_object_object_get_ex(bank, "value", &obj)) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100612 //Bank just uses simple address.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800613 section_cper->Bank = (UINT16)json_object_get_uint64(obj);
614 add_to_valid_bitfield(&ui64Type, 6);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100615 } else {
616 //Bank uses address/group style address.
617 UINT16 address = (UINT8)json_object_get_uint64(
618 json_object_object_get(bank, "address"));
619 UINT16 group = (UINT8)json_object_get_uint64(
620 json_object_object_get(bank, "group"));
621 section_cper->Bank = address + (group << 8);
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800622 add_to_valid_bitfield(&ui64Type, 20);
623 add_to_valid_bitfield(&ui64Type, 21);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100624 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100625
Lawrence Tange407b4c2022-07-21 13:54:01 +0100626 //Miscellaneous value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800627 if (json_object_object_get_ex(section, "memoryErrorType", &obj)) {
628 section_cper->MemErrorType = readable_pair_to_integer(obj);
629 add_to_valid_bitfield(&ui64Type, 13);
630 }
631 if (json_object_object_get_ex(section, "status", &obj)) {
632 section_cper->Status = (UINT8)readable_pair_to_integer(obj);
633 add_to_valid_bitfield(&ui64Type, 14);
634 }
635 if (json_object_object_get_ex(section, "physicalAddress", &obj)) {
636 section_cper->PhysicalAddress = json_object_get_uint64(obj);
637 add_to_valid_bitfield(&ui64Type, 1);
638 }
639 if (json_object_object_get_ex(section, "physicalAddressMask", &obj)) {
640 section_cper->PhysicalAddressMask = json_object_get_uint64(obj);
641 add_to_valid_bitfield(&ui64Type, 2);
642 }
643 if (json_object_object_get_ex(section, "node", &obj)) {
644 section_cper->Node = (UINT16)json_object_get_uint64(obj);
645 add_to_valid_bitfield(&ui64Type, 3);
646 }
647 if (json_object_object_get_ex(section, "card", &obj)) {
648 section_cper->Card = (UINT16)json_object_get_uint64(obj);
649 add_to_valid_bitfield(&ui64Type, 4);
650 }
651 if (json_object_object_get_ex(section, "module", &obj)) {
652 section_cper->Module = (UINT32)json_object_get_uint64(obj);
653 add_to_valid_bitfield(&ui64Type, 5);
654 }
655 if (json_object_object_get_ex(section, "device", &obj)) {
656 section_cper->Device = (UINT32)json_object_get_uint64(obj);
657 add_to_valid_bitfield(&ui64Type, 7);
658 }
659 if (json_object_object_get_ex(section, "row", &obj)) {
660 section_cper->Row = (UINT32)json_object_get_uint64(obj);
661 add_to_valid_bitfield(&ui64Type, 8);
662 }
663 if (json_object_object_get_ex(section, "column", &obj)) {
664 section_cper->Column = (UINT32)json_object_get_uint64(obj);
665 add_to_valid_bitfield(&ui64Type, 9);
666 }
667 if (json_object_object_get_ex(section, "rank", &obj)) {
668 section_cper->Rank = (UINT32)json_object_get_uint64(obj);
669 add_to_valid_bitfield(&ui64Type, 10);
670 }
671 if (json_object_object_get_ex(section, "bitPosition", &obj)) {
672 section_cper->BitPosition = (UINT32)json_object_get_uint64(obj);
673 add_to_valid_bitfield(&ui64Type, 11);
674 }
675 if (json_object_object_get_ex(section, "chipID", &obj)) {
676 section_cper->ChipId = (UINT8)json_object_get_uint64(obj);
677 add_to_valid_bitfield(&ui64Type, 12);
678 }
679 if (json_object_object_get_ex(section, "requestorID", &obj)) {
680 section_cper->RequestorId = json_object_get_uint64(obj);
681 add_to_valid_bitfield(&ui64Type, 15);
682 }
683 if (json_object_object_get_ex(section, "responderID", &obj)) {
684 section_cper->ResponderId = json_object_get_uint64(obj);
685 add_to_valid_bitfield(&ui64Type, 16);
686 }
687 if (json_object_object_get_ex(section, "targetID", &obj)) {
688 section_cper->TargetId = json_object_get_uint64(obj);
689 add_to_valid_bitfield(&ui64Type, 17);
690 }
691 if (json_object_object_get_ex(section, "cardSmbiosHandle", &obj)) {
692 section_cper->CardHandle = (UINT32)json_object_get_uint64(obj);
693 add_to_valid_bitfield(&ui64Type, 18);
694 }
695 if (json_object_object_get_ex(section, "moduleSmbiosHandle", &obj)) {
696 section_cper->ModuleHandle =
697 (UINT32)json_object_get_uint64(obj);
698 add_to_valid_bitfield(&ui64Type, 19);
699 }
700
701 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100702
Lawrence Tange407b4c2022-07-21 13:54:01 +0100703 //Write to stream, free up resources.
704 fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out);
705 fflush(out);
706 free(section_cper);
John Chungf8fc7052024-05-03 20:05:29 +0800707}