xref: /openbmc/libcper/sections/cper-section-memory.c (revision cc36701137e8ad0e7a537c624cd486fb72fb66de)
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 					&section_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 					&section_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