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