blob: 1ed2b9bb220bec1e382917764bdeb1b0d86117fa [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.
4 *
5 * Author: Lawrence.Tang@arm.com
6 **/
7#include <stdio.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01008#include <json.h>
Lawrence Tang7f21db62022-07-06 11:09:39 +01009#include "../edk/Cper.h"
10#include "../cper-utils.h"
11#include "cper-section-memory.h"
12
13//Converts a single memory error CPER section into JSON IR.
Lawrence Tange407b4c2022-07-21 13:54:01 +010014json_object *
15cper_section_platform_memory_to_ir(void *section,
16 EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
Lawrence Tang7f21db62022-07-06 11:09:39 +010017{
Lawrence Tange407b4c2022-07-21 13:54:01 +010018 EFI_PLATFORM_MEMORY_ERROR_DATA *memory_error =
19 (EFI_PLATFORM_MEMORY_ERROR_DATA *)section;
20 json_object *section_ir = json_object_new_object();
Lawrence Tang7f21db62022-07-06 11:09:39 +010021
Lawrence Tange407b4c2022-07-21 13:54:01 +010022 //Validation bitfield.
23 json_object *validation =
24 bitfield_to_ir(memory_error->ValidFields, 22,
25 MEMORY_ERROR_VALID_BITFIELD_NAMES);
26 json_object_object_add(section_ir, "validationBits", validation);
Lawrence Tang7f21db62022-07-06 11:09:39 +010027
Lawrence Tange407b4c2022-07-21 13:54:01 +010028 //Error status.
29 json_object *error_status =
30 cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
31 json_object_object_add(section_ir, "errorStatus", error_status);
Lawrence Tanga0865e32022-07-06 11:59:52 +010032
Lawrence Tange407b4c2022-07-21 13:54:01 +010033 //Bank.
34 json_object *bank = json_object_new_object();
35 if ((memory_error->ValidFields >> 5) & 0x1) {
36 //Entire bank address mode.
37 json_object_object_add(
38 bank, "value",
39 json_object_new_uint64(memory_error->Bank));
40 } else {
41 //Address/group address mode.
42 json_object_object_add(
43 bank, "address",
44 json_object_new_uint64(memory_error->Bank & 0xFF));
45 json_object_object_add(
46 bank, "group",
47 json_object_new_uint64(memory_error->Bank >> 8));
48 }
49 json_object_object_add(section_ir, "bank", bank);
Lawrence Tanga0865e32022-07-06 11:59:52 +010050
Lawrence Tange407b4c2022-07-21 13:54:01 +010051 //Memory error type.
52 json_object *memory_error_type = integer_to_readable_pair(
53 memory_error->ErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
54 MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
55 json_object_object_add(section_ir, "memoryErrorType",
56 memory_error_type);
Lawrence Tanga0865e32022-07-06 11:59:52 +010057
Lawrence Tange407b4c2022-07-21 13:54:01 +010058 //"Extended" row/column indication field + misc.
59 json_object *extended = json_object_new_object();
60 json_object_object_add(extended, "rowBit16",
61 json_object_new_boolean(memory_error->Extended &
62 0b1));
63 json_object_object_add(
64 extended, "rowBit17",
65 json_object_new_boolean((memory_error->Extended >> 1) & 0b1));
66 json_object_object_add(extended, "chipIdentification",
67 json_object_new_int(memory_error->Extended >>
68 5));
69 json_object_object_add(section_ir, "extended", extended);
Lawrence Tanga0865e32022-07-06 11:59:52 +010070
Lawrence Tange407b4c2022-07-21 13:54:01 +010071 //Miscellaneous numeric fields.
72 json_object_object_add(
73 section_ir, "physicalAddress",
74 json_object_new_uint64(memory_error->PhysicalAddress));
75 json_object_object_add(
76 section_ir, "physicalAddressMask",
77 json_object_new_uint64(memory_error->PhysicalAddressMask));
78 json_object_object_add(section_ir, "node",
79 json_object_new_uint64(memory_error->Node));
80 json_object_object_add(section_ir, "card",
81 json_object_new_uint64(memory_error->Card));
82 json_object_object_add(
83 section_ir, "moduleRank",
84 json_object_new_uint64(memory_error->ModuleRank));
85 json_object_object_add(section_ir, "device",
86 json_object_new_uint64(memory_error->Device));
87 json_object_object_add(section_ir, "row",
88 json_object_new_uint64(memory_error->Row));
89 json_object_object_add(section_ir, "column",
90 json_object_new_uint64(memory_error->Column));
91 json_object_object_add(
92 section_ir, "bitPosition",
93 json_object_new_uint64(memory_error->BitPosition));
94 json_object_object_add(
95 section_ir, "requestorID",
96 json_object_new_uint64(memory_error->RequestorId));
97 json_object_object_add(
98 section_ir, "responderID",
99 json_object_new_uint64(memory_error->ResponderId));
100 json_object_object_add(section_ir, "targetID",
101 json_object_new_uint64(memory_error->TargetId));
102 json_object_object_add(section_ir, "rankNumber",
103 json_object_new_uint64(memory_error->RankNum));
104 json_object_object_add(
105 section_ir, "cardSmbiosHandle",
106 json_object_new_uint64(memory_error->CardHandle));
107 json_object_object_add(
108 section_ir, "moduleSmbiosHandle",
109 json_object_new_uint64(memory_error->ModuleHandle));
Lawrence Tang54da4412022-07-06 13:14:58 +0100110
Lawrence Tange407b4c2022-07-21 13:54:01 +0100111 return section_ir;
Lawrence Tanga0865e32022-07-06 11:59:52 +0100112}
113
114//Converts a single memory error 2 CPER section into JSON IR.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100115json_object *
116cper_section_platform_memory2_to_ir(void *section,
117 EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
Lawrence Tanga0865e32022-07-06 11:59:52 +0100118{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100119 EFI_PLATFORM_MEMORY2_ERROR_DATA *memory_error =
120 (EFI_PLATFORM_MEMORY2_ERROR_DATA *)section;
121 json_object *section_ir = json_object_new_object();
Lawrence Tanga0865e32022-07-06 11:59:52 +0100122
Lawrence Tange407b4c2022-07-21 13:54:01 +0100123 //Validation bits.
124 json_object *validation =
125 bitfield_to_ir(memory_error->ValidFields, 22,
126 MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
127 json_object_object_add(section_ir, "validationBits", validation);
Lawrence Tanga0865e32022-07-06 11:59:52 +0100128
Lawrence Tange407b4c2022-07-21 13:54:01 +0100129 //Error status.
130 json_object *error_status =
131 cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
132 json_object_object_add(section_ir, "errorStatus", error_status);
Lawrence Tang54da4412022-07-06 13:14:58 +0100133
Lawrence Tange407b4c2022-07-21 13:54:01 +0100134 //Bank.
135 json_object *bank = json_object_new_object();
136 if ((memory_error->ValidFields >> 5) & 0x1) {
137 //Entire bank address mode.
138 json_object_object_add(
139 bank, "value",
140 json_object_new_uint64(memory_error->Bank));
141 } else {
142 //Address/group address mode.
143 json_object_object_add(
144 bank, "address",
145 json_object_new_uint64(memory_error->Bank & 0xFF));
146 json_object_object_add(
147 bank, "group",
148 json_object_new_uint64(memory_error->Bank >> 8));
149 }
150 json_object_object_add(section_ir, "bank", bank);
Lawrence Tang54da4412022-07-06 13:14:58 +0100151
Lawrence Tange407b4c2022-07-21 13:54:01 +0100152 //Memory error type.
153 json_object *memory_error_type = integer_to_readable_pair(
154 memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
155 MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
156 json_object_object_add(section_ir, "memoryErrorType",
157 memory_error_type);
Lawrence Tang54da4412022-07-06 13:14:58 +0100158
Lawrence Tange407b4c2022-07-21 13:54:01 +0100159 //Status.
160 json_object *status = json_object_new_object();
161 json_object_object_add(status, "value",
162 json_object_new_int(memory_error->Status));
163 json_object_object_add(status, "state",
164 json_object_new_string(memory_error->Status &
165 0b1 == 0 ?
166 "Corrected" :
167 "Uncorrected"));
168 json_object_object_add(section_ir, "status", status);
Lawrence Tang54da4412022-07-06 13:14:58 +0100169
Lawrence Tange407b4c2022-07-21 13:54:01 +0100170 //Miscellaneous numeric fields.
171 json_object_object_add(
172 section_ir, "physicalAddress",
173 json_object_new_uint64(memory_error->PhysicalAddress));
174 json_object_object_add(
175 section_ir, "physicalAddressMask",
176 json_object_new_uint64(memory_error->PhysicalAddressMask));
177 json_object_object_add(section_ir, "node",
178 json_object_new_uint64(memory_error->Node));
179 json_object_object_add(section_ir, "card",
180 json_object_new_uint64(memory_error->Card));
181 json_object_object_add(section_ir, "module",
182 json_object_new_uint64(memory_error->Module));
183 json_object_object_add(section_ir, "device",
184 json_object_new_uint64(memory_error->Device));
185 json_object_object_add(section_ir, "row",
186 json_object_new_uint64(memory_error->Row));
187 json_object_object_add(section_ir, "column",
188 json_object_new_uint64(memory_error->Column));
189 json_object_object_add(section_ir, "rank",
190 json_object_new_uint64(memory_error->Rank));
191 json_object_object_add(
192 section_ir, "bitPosition",
193 json_object_new_uint64(memory_error->BitPosition));
194 json_object_object_add(section_ir, "chipID",
195 json_object_new_uint64(memory_error->ChipId));
196 json_object_object_add(
197 section_ir, "requestorID",
198 json_object_new_uint64(memory_error->RequestorId));
199 json_object_object_add(
200 section_ir, "responderID",
201 json_object_new_uint64(memory_error->ResponderId));
202 json_object_object_add(section_ir, "targetID",
203 json_object_new_uint64(memory_error->TargetId));
204 json_object_object_add(
205 section_ir, "cardSmbiosHandle",
206 json_object_new_uint64(memory_error->CardHandle));
207 json_object_object_add(
208 section_ir, "moduleSmbiosHandle",
209 json_object_new_uint64(memory_error->ModuleHandle));
210
211 return section_ir;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100212}
213
214//Converts a single Memory Error IR section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100215void ir_section_memory_to_cper(json_object *section, FILE *out)
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100216{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100217 EFI_PLATFORM_MEMORY_ERROR_DATA *section_cper =
218 (EFI_PLATFORM_MEMORY_ERROR_DATA *)calloc(
219 1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100220
Lawrence Tange407b4c2022-07-21 13:54:01 +0100221 //Validation bits.
222 section_cper->ValidFields = ir_to_bitfield(
223 json_object_object_get(section, "validationBits"), 22,
224 MEMORY_ERROR_VALID_BITFIELD_NAMES);
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100225
Lawrence Tange407b4c2022-07-21 13:54:01 +0100226 //Error status.
227 ir_generic_error_status_to_cper(json_object_object_get(section,
228 "errorStatus"),
229 &section_cper->ErrorStatus);
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100230
Lawrence Tange407b4c2022-07-21 13:54:01 +0100231 //Bank.
232 json_object *bank = json_object_object_get(section, "bank");
233 if ((section_cper->ValidFields >> 5) & 0x1) {
234 //Bank just uses simple address.
235 section_cper->Bank = (UINT16)json_object_get_uint64(
236 json_object_object_get(bank, "value"));
237 } else {
238 //Bank uses address/group style address.
239 UINT16 address = (UINT8)json_object_get_uint64(
240 json_object_object_get(bank, "address"));
241 UINT16 group = (UINT8)json_object_get_uint64(
242 json_object_object_get(bank, "group"));
243 section_cper->Bank = address + (group << 8);
244 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100245
Lawrence Tange407b4c2022-07-21 13:54:01 +0100246 //"Extended" field.
247 json_object *extended = json_object_object_get(section, "extended");
248 section_cper->Extended = 0;
249 section_cper->Extended |= json_object_get_boolean(
250 json_object_object_get(extended, "rowBit16"));
251 section_cper->Extended |=
252 json_object_get_boolean(
253 json_object_object_get(extended, "rowBit17"))
254 << 1;
255 section_cper->Extended |= json_object_get_int(json_object_object_get(
256 extended, "chipIdentification"))
257 << 5;
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100258
Lawrence Tange407b4c2022-07-21 13:54:01 +0100259 //Miscellaneous value fields.
260 section_cper->ErrorType = (UINT8)readable_pair_to_integer(
261 json_object_object_get(section, "memoryErrorType"));
262 section_cper->PhysicalAddress = json_object_get_uint64(
263 json_object_object_get(section, "physicalAddress"));
264 section_cper->PhysicalAddressMask = json_object_get_uint64(
265 json_object_object_get(section, "physicalAddressMask"));
266 section_cper->Node = (UINT16)json_object_get_uint64(
267 json_object_object_get(section, "node"));
268 section_cper->Card = (UINT16)json_object_get_uint64(
269 json_object_object_get(section, "card"));
270 section_cper->ModuleRank = (UINT16)json_object_get_uint64(
271 json_object_object_get(section, "moduleRank"));
272 section_cper->Device = (UINT16)json_object_get_uint64(
273 json_object_object_get(section, "device"));
274 section_cper->Row = (UINT16)json_object_get_uint64(
275 json_object_object_get(section, "row"));
276 section_cper->Column = (UINT16)json_object_get_uint64(
277 json_object_object_get(section, "column"));
278 section_cper->BitPosition = (UINT16)json_object_get_uint64(
279 json_object_object_get(section, "bitPosition"));
280 section_cper->RequestorId = json_object_get_uint64(
281 json_object_object_get(section, "requestorID"));
282 section_cper->ResponderId = json_object_get_uint64(
283 json_object_object_get(section, "responderID"));
284 section_cper->TargetId = json_object_get_uint64(
285 json_object_object_get(section, "targetID"));
286 section_cper->RankNum = (UINT16)json_object_get_uint64(
287 json_object_object_get(section, "rankNumber"));
288 section_cper->CardHandle = (UINT16)json_object_get_uint64(
289 json_object_object_get(section, "cardSmbiosHandle"));
290 section_cper->ModuleHandle = (UINT16)json_object_get_uint64(
291 json_object_object_get(section, "moduleSmbiosHandle"));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100292
Lawrence Tange407b4c2022-07-21 13:54:01 +0100293 //Write to stream, free up resources.
294 fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out);
295 fflush(out);
296 free(section_cper);
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100297}
298
299//Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100300void ir_section_memory2_to_cper(json_object *section, FILE *out)
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100301{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100302 EFI_PLATFORM_MEMORY2_ERROR_DATA *section_cper =
303 (EFI_PLATFORM_MEMORY2_ERROR_DATA *)calloc(
304 1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100305
Lawrence Tange407b4c2022-07-21 13:54:01 +0100306 //Validation bits.
307 section_cper->ValidFields = ir_to_bitfield(
308 json_object_object_get(section, "validationBits"), 22,
309 MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100310
Lawrence Tange407b4c2022-07-21 13:54:01 +0100311 //Error status.
312 ir_generic_error_status_to_cper(json_object_object_get(section,
313 "errorStatus"),
314 &section_cper->ErrorStatus);
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100315
Lawrence Tange407b4c2022-07-21 13:54:01 +0100316 //Bank.
317 json_object *bank = json_object_object_get(section, "bank");
318 if ((section_cper->ValidFields >> 5) & 0x1) {
319 //Bank just uses simple address.
320 section_cper->Bank = (UINT16)json_object_get_uint64(
321 json_object_object_get(bank, "value"));
322 } else {
323 //Bank uses address/group style address.
324 UINT16 address = (UINT8)json_object_get_uint64(
325 json_object_object_get(bank, "address"));
326 UINT16 group = (UINT8)json_object_get_uint64(
327 json_object_object_get(bank, "group"));
328 section_cper->Bank = address + (group << 8);
329 }
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100330
Lawrence Tange407b4c2022-07-21 13:54:01 +0100331 //Miscellaneous value fields.
332 section_cper->MemErrorType = readable_pair_to_integer(
333 json_object_object_get(section, "memoryErrorType"));
334 section_cper->Status = (UINT8)readable_pair_to_integer(
335 json_object_object_get(section, "status"));
336 section_cper->PhysicalAddress = json_object_get_uint64(
337 json_object_object_get(section, "physicalAddress"));
338 section_cper->PhysicalAddressMask = json_object_get_uint64(
339 json_object_object_get(section, "physicalAddressMask"));
340 section_cper->Node = (UINT16)json_object_get_uint64(
341 json_object_object_get(section, "node"));
342 section_cper->Card = (UINT16)json_object_get_uint64(
343 json_object_object_get(section, "card"));
344 section_cper->Module = (UINT32)json_object_get_uint64(
345 json_object_object_get(section, "module"));
346 section_cper->Device = (UINT32)json_object_get_uint64(
347 json_object_object_get(section, "device"));
348 section_cper->Row = (UINT32)json_object_get_uint64(
349 json_object_object_get(section, "row"));
350 section_cper->Column = (UINT32)json_object_get_uint64(
351 json_object_object_get(section, "column"));
352 section_cper->Rank = (UINT32)json_object_get_uint64(
353 json_object_object_get(section, "rank"));
354 section_cper->BitPosition = (UINT32)json_object_get_uint64(
355 json_object_object_get(section, "bitPosition"));
356 section_cper->ChipId = (UINT8)json_object_get_uint64(
357 json_object_object_get(section, "chipID"));
358 section_cper->RequestorId = json_object_get_uint64(
359 json_object_object_get(section, "requestorID"));
360 section_cper->ResponderId = json_object_get_uint64(
361 json_object_object_get(section, "responderID"));
362 section_cper->TargetId = json_object_get_uint64(
363 json_object_object_get(section, "targetID"));
364 section_cper->CardHandle = (UINT32)json_object_get_uint64(
365 json_object_object_get(section, "cardSmbiosHandle"));
366 section_cper->ModuleHandle = (UINT32)json_object_get_uint64(
367 json_object_object_get(section, "moduleSmbiosHandle"));
Lawrence Tang3b7f45b2022-07-14 14:14:30 +0100368
Lawrence Tange407b4c2022-07-21 13:54:01 +0100369 //Write to stream, free up resources.
370 fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out);
371 fflush(out);
372 free(section_cper);
Lawrence Tang7f21db62022-07-06 11:09:39 +0100373}