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