17f21db6cSLawrence Tang /**
27f21db6cSLawrence Tang  * Describes functions for converting memory error CPER sections from binary and JSON format
37f21db6cSLawrence Tang  * into an intermediate format.
47f21db6cSLawrence Tang  *
57f21db6cSLawrence Tang  * Author: Lawrence.Tang@arm.com
67f21db6cSLawrence Tang  **/
77f21db6cSLawrence Tang #include <stdio.h>
85202bbb4SLawrence Tang #include <json.h>
97f21db6cSLawrence Tang #include "../edk/Cper.h"
107f21db6cSLawrence Tang #include "../cper-utils.h"
117f21db6cSLawrence Tang #include "cper-section-memory.h"
127f21db6cSLawrence Tang 
137f21db6cSLawrence Tang //Converts a single memory error CPER section into JSON IR.
cper_section_platform_memory_to_ir(void * section)14*f8fc7052SJohn Chung json_object *cper_section_platform_memory_to_ir(void *section)
157f21db6cSLawrence Tang {
16e407b4c8SLawrence Tang 	EFI_PLATFORM_MEMORY_ERROR_DATA *memory_error =
17e407b4c8SLawrence Tang 		(EFI_PLATFORM_MEMORY_ERROR_DATA *)section;
187f21db6cSLawrence Tang 	json_object *section_ir = json_object_new_object();
197f21db6cSLawrence Tang 
207f21db6cSLawrence Tang 	//Validation bitfield.
21e407b4c8SLawrence Tang 	json_object *validation =
22e407b4c8SLawrence Tang 		bitfield_to_ir(memory_error->ValidFields, 22,
23e407b4c8SLawrence Tang 			       MEMORY_ERROR_VALID_BITFIELD_NAMES);
247f21db6cSLawrence Tang 	json_object_object_add(section_ir, "validationBits", validation);
257f21db6cSLawrence Tang 
267f21db6cSLawrence Tang 	//Error status.
27e407b4c8SLawrence Tang 	json_object *error_status =
28e407b4c8SLawrence Tang 		cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
29a0865e38SLawrence Tang 	json_object_object_add(section_ir, "errorStatus", error_status);
30a0865e38SLawrence Tang 
31a0865e38SLawrence Tang 	//Bank.
32a0865e38SLawrence Tang 	json_object *bank = json_object_new_object();
33e407b4c8SLawrence Tang 	if ((memory_error->ValidFields >> 5) & 0x1) {
34583cdeeeSLawrence Tang 		//Entire bank address mode.
35e407b4c8SLawrence Tang 		json_object_object_add(
36e407b4c8SLawrence Tang 			bank, "value",
37e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank));
38e407b4c8SLawrence Tang 	} else {
39583cdeeeSLawrence Tang 		//Address/group address mode.
40e407b4c8SLawrence Tang 		json_object_object_add(
41e407b4c8SLawrence Tang 			bank, "address",
42e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank & 0xFF));
43e407b4c8SLawrence Tang 		json_object_object_add(
44e407b4c8SLawrence Tang 			bank, "group",
45e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank >> 8));
46583cdeeeSLawrence Tang 	}
47a0865e38SLawrence Tang 	json_object_object_add(section_ir, "bank", bank);
48a0865e38SLawrence Tang 
49a0865e38SLawrence Tang 	//Memory error type.
50e407b4c8SLawrence Tang 	json_object *memory_error_type = integer_to_readable_pair(
51e407b4c8SLawrence Tang 		memory_error->ErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
52e407b4c8SLawrence Tang 		MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
53e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "memoryErrorType",
54e407b4c8SLawrence Tang 			       memory_error_type);
55a0865e38SLawrence Tang 
56a0865e38SLawrence Tang 	//"Extended" row/column indication field + misc.
57a0865e38SLawrence Tang 	json_object *extended = json_object_new_object();
58e407b4c8SLawrence Tang 	json_object_object_add(extended, "rowBit16",
59e407b4c8SLawrence Tang 			       json_object_new_boolean(memory_error->Extended &
60*f8fc7052SJohn Chung 						       0x1));
61e407b4c8SLawrence Tang 	json_object_object_add(
62e407b4c8SLawrence Tang 		extended, "rowBit17",
63*f8fc7052SJohn Chung 		json_object_new_boolean((memory_error->Extended >> 1) & 0x1));
64e407b4c8SLawrence Tang 	json_object_object_add(extended, "chipIdentification",
65e407b4c8SLawrence Tang 			       json_object_new_int(memory_error->Extended >>
66e407b4c8SLawrence Tang 						   5));
67a0865e38SLawrence Tang 	json_object_object_add(section_ir, "extended", extended);
68a0865e38SLawrence Tang 
6954da4414SLawrence Tang 	//Miscellaneous numeric fields.
70e407b4c8SLawrence Tang 	json_object_object_add(
71e407b4c8SLawrence Tang 		section_ir, "physicalAddress",
72e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->PhysicalAddress));
73e407b4c8SLawrence Tang 	json_object_object_add(
74e407b4c8SLawrence Tang 		section_ir, "physicalAddressMask",
75e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->PhysicalAddressMask));
76e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "node",
77e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Node));
78e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "card",
79e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Card));
80e407b4c8SLawrence Tang 	json_object_object_add(
81e407b4c8SLawrence Tang 		section_ir, "moduleRank",
82e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ModuleRank));
83e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "device",
84e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Device));
85e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "row",
86e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Row));
87e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "column",
88e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Column));
89e407b4c8SLawrence Tang 	json_object_object_add(
90e407b4c8SLawrence Tang 		section_ir, "bitPosition",
91e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->BitPosition));
92e407b4c8SLawrence Tang 	json_object_object_add(
93e407b4c8SLawrence Tang 		section_ir, "requestorID",
94e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->RequestorId));
95e407b4c8SLawrence Tang 	json_object_object_add(
96e407b4c8SLawrence Tang 		section_ir, "responderID",
97e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ResponderId));
98e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "targetID",
99e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->TargetId));
100e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "rankNumber",
101e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->RankNum));
102e407b4c8SLawrence Tang 	json_object_object_add(
103e407b4c8SLawrence Tang 		section_ir, "cardSmbiosHandle",
104e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->CardHandle));
105e407b4c8SLawrence Tang 	json_object_object_add(
106e407b4c8SLawrence Tang 		section_ir, "moduleSmbiosHandle",
107e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ModuleHandle));
10854da4414SLawrence Tang 
109a0865e38SLawrence Tang 	return section_ir;
110a0865e38SLawrence Tang }
111a0865e38SLawrence Tang 
112a0865e38SLawrence Tang //Converts a single memory error 2 CPER section into JSON IR.
cper_section_platform_memory2_to_ir(void * section)113*f8fc7052SJohn Chung json_object *cper_section_platform_memory2_to_ir(void *section)
114a0865e38SLawrence Tang {
115e407b4c8SLawrence Tang 	EFI_PLATFORM_MEMORY2_ERROR_DATA *memory_error =
116e407b4c8SLawrence Tang 		(EFI_PLATFORM_MEMORY2_ERROR_DATA *)section;
117a0865e38SLawrence Tang 	json_object *section_ir = json_object_new_object();
118a0865e38SLawrence Tang 
11954da4414SLawrence Tang 	//Validation bits.
120e407b4c8SLawrence Tang 	json_object *validation =
121e407b4c8SLawrence Tang 		bitfield_to_ir(memory_error->ValidFields, 22,
122e407b4c8SLawrence Tang 			       MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
12354da4414SLawrence Tang 	json_object_object_add(section_ir, "validationBits", validation);
12454da4414SLawrence Tang 
12554da4414SLawrence Tang 	//Error status.
126e407b4c8SLawrence Tang 	json_object *error_status =
127e407b4c8SLawrence Tang 		cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
12854da4414SLawrence Tang 	json_object_object_add(section_ir, "errorStatus", error_status);
12954da4414SLawrence Tang 
13054da4414SLawrence Tang 	//Bank.
13154da4414SLawrence Tang 	json_object *bank = json_object_new_object();
132e407b4c8SLawrence Tang 	if ((memory_error->ValidFields >> 5) & 0x1) {
133583cdeeeSLawrence Tang 		//Entire bank address mode.
134e407b4c8SLawrence Tang 		json_object_object_add(
135e407b4c8SLawrence Tang 			bank, "value",
136e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank));
137e407b4c8SLawrence Tang 	} else {
138583cdeeeSLawrence Tang 		//Address/group address mode.
139e407b4c8SLawrence Tang 		json_object_object_add(
140e407b4c8SLawrence Tang 			bank, "address",
141e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank & 0xFF));
142e407b4c8SLawrence Tang 		json_object_object_add(
143e407b4c8SLawrence Tang 			bank, "group",
144e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank >> 8));
145583cdeeeSLawrence Tang 	}
14654da4414SLawrence Tang 	json_object_object_add(section_ir, "bank", bank);
14754da4414SLawrence Tang 
14854da4414SLawrence Tang 	//Memory error type.
149e407b4c8SLawrence Tang 	json_object *memory_error_type = integer_to_readable_pair(
150e407b4c8SLawrence Tang 		memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
151e407b4c8SLawrence Tang 		MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
152e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "memoryErrorType",
153e407b4c8SLawrence Tang 			       memory_error_type);
15454da4414SLawrence Tang 
15554da4414SLawrence Tang 	//Status.
15654da4414SLawrence Tang 	json_object *status = json_object_new_object();
157e407b4c8SLawrence Tang 	json_object_object_add(status, "value",
158e407b4c8SLawrence Tang 			       json_object_new_int(memory_error->Status));
159*f8fc7052SJohn Chung 	json_object_object_add(
160*f8fc7052SJohn Chung 		status, "state",
161*f8fc7052SJohn Chung 		json_object_new_string((memory_error->Status & 0x1) == 0 ?
162e407b4c8SLawrence Tang 					       "Corrected" :
163e407b4c8SLawrence Tang 					       "Uncorrected"));
16454da4414SLawrence Tang 	json_object_object_add(section_ir, "status", status);
16554da4414SLawrence Tang 
16654da4414SLawrence Tang 	//Miscellaneous numeric fields.
167e407b4c8SLawrence Tang 	json_object_object_add(
168e407b4c8SLawrence Tang 		section_ir, "physicalAddress",
169e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->PhysicalAddress));
170e407b4c8SLawrence Tang 	json_object_object_add(
171e407b4c8SLawrence Tang 		section_ir, "physicalAddressMask",
172e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->PhysicalAddressMask));
173e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "node",
174e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Node));
175e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "card",
176e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Card));
177e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "module",
178e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Module));
179e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "device",
180e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Device));
181e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "row",
182e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Row));
183e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "column",
184e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Column));
185e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "rank",
186e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Rank));
187e407b4c8SLawrence Tang 	json_object_object_add(
188e407b4c8SLawrence Tang 		section_ir, "bitPosition",
189e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->BitPosition));
190e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "chipID",
191e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->ChipId));
192e407b4c8SLawrence Tang 	json_object_object_add(
193e407b4c8SLawrence Tang 		section_ir, "requestorID",
194e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->RequestorId));
195e407b4c8SLawrence Tang 	json_object_object_add(
196e407b4c8SLawrence Tang 		section_ir, "responderID",
197e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ResponderId));
198e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "targetID",
199e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->TargetId));
200e407b4c8SLawrence Tang 	json_object_object_add(
201e407b4c8SLawrence Tang 		section_ir, "cardSmbiosHandle",
202e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->CardHandle));
203e407b4c8SLawrence Tang 	json_object_object_add(
204e407b4c8SLawrence Tang 		section_ir, "moduleSmbiosHandle",
205e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ModuleHandle));
206a0865e38SLawrence Tang 
207a0865e38SLawrence Tang 	return section_ir;
2087f21db6cSLawrence Tang }
2093b7f45b5SLawrence Tang 
2103b7f45b5SLawrence Tang //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)2113b7f45b5SLawrence Tang void ir_section_memory_to_cper(json_object *section, FILE *out)
2123b7f45b5SLawrence Tang {
2133b7f45b5SLawrence Tang 	EFI_PLATFORM_MEMORY_ERROR_DATA *section_cper =
214e407b4c8SLawrence Tang 		(EFI_PLATFORM_MEMORY_ERROR_DATA *)calloc(
215e407b4c8SLawrence Tang 			1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
2163b7f45b5SLawrence Tang 
2173b7f45b5SLawrence Tang 	//Validation bits.
218e407b4c8SLawrence Tang 	section_cper->ValidFields = ir_to_bitfield(
219e407b4c8SLawrence Tang 		json_object_object_get(section, "validationBits"), 22,
220e407b4c8SLawrence Tang 		MEMORY_ERROR_VALID_BITFIELD_NAMES);
2213b7f45b5SLawrence Tang 
2223b7f45b5SLawrence Tang 	//Error status.
223e407b4c8SLawrence Tang 	ir_generic_error_status_to_cper(json_object_object_get(section,
224e407b4c8SLawrence Tang 							       "errorStatus"),
225e407b4c8SLawrence Tang 					&section_cper->ErrorStatus);
2263b7f45b5SLawrence Tang 
2273b7f45b5SLawrence Tang 	//Bank.
2283b7f45b5SLawrence Tang 	json_object *bank = json_object_object_get(section, "bank");
229e407b4c8SLawrence Tang 	if ((section_cper->ValidFields >> 5) & 0x1) {
2303b7f45b5SLawrence Tang 		//Bank just uses simple address.
231e407b4c8SLawrence Tang 		section_cper->Bank = (UINT16)json_object_get_uint64(
232e407b4c8SLawrence Tang 			json_object_object_get(bank, "value"));
233e407b4c8SLawrence Tang 	} else {
2343b7f45b5SLawrence Tang 		//Bank uses address/group style address.
235e407b4c8SLawrence Tang 		UINT16 address = (UINT8)json_object_get_uint64(
236e407b4c8SLawrence Tang 			json_object_object_get(bank, "address"));
237e407b4c8SLawrence Tang 		UINT16 group = (UINT8)json_object_get_uint64(
238e407b4c8SLawrence Tang 			json_object_object_get(bank, "group"));
2393b7f45b5SLawrence Tang 		section_cper->Bank = address + (group << 8);
2403b7f45b5SLawrence Tang 	}
2413b7f45b5SLawrence Tang 
2423b7f45b5SLawrence Tang 	//"Extended" field.
2433b7f45b5SLawrence Tang 	json_object *extended = json_object_object_get(section, "extended");
2443b7f45b5SLawrence Tang 	section_cper->Extended = 0;
245e407b4c8SLawrence Tang 	section_cper->Extended |= json_object_get_boolean(
246e407b4c8SLawrence Tang 		json_object_object_get(extended, "rowBit16"));
247e407b4c8SLawrence Tang 	section_cper->Extended |=
248e407b4c8SLawrence Tang 		json_object_get_boolean(
249e407b4c8SLawrence Tang 			json_object_object_get(extended, "rowBit17"))
250e407b4c8SLawrence Tang 		<< 1;
251e407b4c8SLawrence Tang 	section_cper->Extended |= json_object_get_int(json_object_object_get(
252e407b4c8SLawrence Tang 					  extended, "chipIdentification"))
253e407b4c8SLawrence Tang 				  << 5;
2543b7f45b5SLawrence Tang 
2553b7f45b5SLawrence Tang 	//Miscellaneous value fields.
256e407b4c8SLawrence Tang 	section_cper->ErrorType = (UINT8)readable_pair_to_integer(
257e407b4c8SLawrence Tang 		json_object_object_get(section, "memoryErrorType"));
258e407b4c8SLawrence Tang 	section_cper->PhysicalAddress = json_object_get_uint64(
259e407b4c8SLawrence Tang 		json_object_object_get(section, "physicalAddress"));
260e407b4c8SLawrence Tang 	section_cper->PhysicalAddressMask = json_object_get_uint64(
261e407b4c8SLawrence Tang 		json_object_object_get(section, "physicalAddressMask"));
262e407b4c8SLawrence Tang 	section_cper->Node = (UINT16)json_object_get_uint64(
263e407b4c8SLawrence Tang 		json_object_object_get(section, "node"));
264e407b4c8SLawrence Tang 	section_cper->Card = (UINT16)json_object_get_uint64(
265e407b4c8SLawrence Tang 		json_object_object_get(section, "card"));
266e407b4c8SLawrence Tang 	section_cper->ModuleRank = (UINT16)json_object_get_uint64(
267e407b4c8SLawrence Tang 		json_object_object_get(section, "moduleRank"));
268e407b4c8SLawrence Tang 	section_cper->Device = (UINT16)json_object_get_uint64(
269e407b4c8SLawrence Tang 		json_object_object_get(section, "device"));
270e407b4c8SLawrence Tang 	section_cper->Row = (UINT16)json_object_get_uint64(
271e407b4c8SLawrence Tang 		json_object_object_get(section, "row"));
272e407b4c8SLawrence Tang 	section_cper->Column = (UINT16)json_object_get_uint64(
273e407b4c8SLawrence Tang 		json_object_object_get(section, "column"));
274e407b4c8SLawrence Tang 	section_cper->BitPosition = (UINT16)json_object_get_uint64(
275e407b4c8SLawrence Tang 		json_object_object_get(section, "bitPosition"));
276e407b4c8SLawrence Tang 	section_cper->RequestorId = json_object_get_uint64(
277e407b4c8SLawrence Tang 		json_object_object_get(section, "requestorID"));
278e407b4c8SLawrence Tang 	section_cper->ResponderId = json_object_get_uint64(
279e407b4c8SLawrence Tang 		json_object_object_get(section, "responderID"));
280e407b4c8SLawrence Tang 	section_cper->TargetId = json_object_get_uint64(
281e407b4c8SLawrence Tang 		json_object_object_get(section, "targetID"));
282e407b4c8SLawrence Tang 	section_cper->RankNum = (UINT16)json_object_get_uint64(
283e407b4c8SLawrence Tang 		json_object_object_get(section, "rankNumber"));
284e407b4c8SLawrence Tang 	section_cper->CardHandle = (UINT16)json_object_get_uint64(
285e407b4c8SLawrence Tang 		json_object_object_get(section, "cardSmbiosHandle"));
286e407b4c8SLawrence Tang 	section_cper->ModuleHandle = (UINT16)json_object_get_uint64(
287e407b4c8SLawrence Tang 		json_object_object_get(section, "moduleSmbiosHandle"));
2883b7f45b5SLawrence Tang 
2893b7f45b5SLawrence Tang 	//Write to stream, free up resources.
2903ab351feSLawrence Tang 	fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out);
2913b7f45b5SLawrence Tang 	fflush(out);
2923b7f45b5SLawrence Tang 	free(section_cper);
2933b7f45b5SLawrence Tang }
2943b7f45b5SLawrence Tang 
2953b7f45b5SLawrence Tang //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)2963b7f45b5SLawrence Tang void ir_section_memory2_to_cper(json_object *section, FILE *out)
2973b7f45b5SLawrence Tang {
2983b7f45b5SLawrence Tang 	EFI_PLATFORM_MEMORY2_ERROR_DATA *section_cper =
299e407b4c8SLawrence Tang 		(EFI_PLATFORM_MEMORY2_ERROR_DATA *)calloc(
300e407b4c8SLawrence Tang 			1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
3013b7f45b5SLawrence Tang 
3023b7f45b5SLawrence Tang 	//Validation bits.
303e407b4c8SLawrence Tang 	section_cper->ValidFields = ir_to_bitfield(
304e407b4c8SLawrence Tang 		json_object_object_get(section, "validationBits"), 22,
305e407b4c8SLawrence Tang 		MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
3063b7f45b5SLawrence Tang 
3073b7f45b5SLawrence Tang 	//Error status.
308e407b4c8SLawrence Tang 	ir_generic_error_status_to_cper(json_object_object_get(section,
309e407b4c8SLawrence Tang 							       "errorStatus"),
310e407b4c8SLawrence Tang 					&section_cper->ErrorStatus);
3113b7f45b5SLawrence Tang 
3123b7f45b5SLawrence Tang 	//Bank.
3133b7f45b5SLawrence Tang 	json_object *bank = json_object_object_get(section, "bank");
314e407b4c8SLawrence Tang 	if ((section_cper->ValidFields >> 5) & 0x1) {
3153b7f45b5SLawrence Tang 		//Bank just uses simple address.
316e407b4c8SLawrence Tang 		section_cper->Bank = (UINT16)json_object_get_uint64(
317e407b4c8SLawrence Tang 			json_object_object_get(bank, "value"));
318e407b4c8SLawrence Tang 	} else {
3193b7f45b5SLawrence Tang 		//Bank uses address/group style address.
320e407b4c8SLawrence Tang 		UINT16 address = (UINT8)json_object_get_uint64(
321e407b4c8SLawrence Tang 			json_object_object_get(bank, "address"));
322e407b4c8SLawrence Tang 		UINT16 group = (UINT8)json_object_get_uint64(
323e407b4c8SLawrence Tang 			json_object_object_get(bank, "group"));
3243b7f45b5SLawrence Tang 		section_cper->Bank = address + (group << 8);
3253b7f45b5SLawrence Tang 	}
3263b7f45b5SLawrence Tang 
3273b7f45b5SLawrence Tang 	//Miscellaneous value fields.
328e407b4c8SLawrence Tang 	section_cper->MemErrorType = readable_pair_to_integer(
329e407b4c8SLawrence Tang 		json_object_object_get(section, "memoryErrorType"));
330e407b4c8SLawrence Tang 	section_cper->Status = (UINT8)readable_pair_to_integer(
331e407b4c8SLawrence Tang 		json_object_object_get(section, "status"));
332e407b4c8SLawrence Tang 	section_cper->PhysicalAddress = json_object_get_uint64(
333e407b4c8SLawrence Tang 		json_object_object_get(section, "physicalAddress"));
334e407b4c8SLawrence Tang 	section_cper->PhysicalAddressMask = json_object_get_uint64(
335e407b4c8SLawrence Tang 		json_object_object_get(section, "physicalAddressMask"));
336e407b4c8SLawrence Tang 	section_cper->Node = (UINT16)json_object_get_uint64(
337e407b4c8SLawrence Tang 		json_object_object_get(section, "node"));
338e407b4c8SLawrence Tang 	section_cper->Card = (UINT16)json_object_get_uint64(
339e407b4c8SLawrence Tang 		json_object_object_get(section, "card"));
340e407b4c8SLawrence Tang 	section_cper->Module = (UINT32)json_object_get_uint64(
341e407b4c8SLawrence Tang 		json_object_object_get(section, "module"));
342e407b4c8SLawrence Tang 	section_cper->Device = (UINT32)json_object_get_uint64(
343e407b4c8SLawrence Tang 		json_object_object_get(section, "device"));
344e407b4c8SLawrence Tang 	section_cper->Row = (UINT32)json_object_get_uint64(
345e407b4c8SLawrence Tang 		json_object_object_get(section, "row"));
346e407b4c8SLawrence Tang 	section_cper->Column = (UINT32)json_object_get_uint64(
347e407b4c8SLawrence Tang 		json_object_object_get(section, "column"));
348e407b4c8SLawrence Tang 	section_cper->Rank = (UINT32)json_object_get_uint64(
349e407b4c8SLawrence Tang 		json_object_object_get(section, "rank"));
350e407b4c8SLawrence Tang 	section_cper->BitPosition = (UINT32)json_object_get_uint64(
351e407b4c8SLawrence Tang 		json_object_object_get(section, "bitPosition"));
352e407b4c8SLawrence Tang 	section_cper->ChipId = (UINT8)json_object_get_uint64(
353e407b4c8SLawrence Tang 		json_object_object_get(section, "chipID"));
354e407b4c8SLawrence Tang 	section_cper->RequestorId = json_object_get_uint64(
355e407b4c8SLawrence Tang 		json_object_object_get(section, "requestorID"));
356e407b4c8SLawrence Tang 	section_cper->ResponderId = json_object_get_uint64(
357e407b4c8SLawrence Tang 		json_object_object_get(section, "responderID"));
358e407b4c8SLawrence Tang 	section_cper->TargetId = json_object_get_uint64(
359e407b4c8SLawrence Tang 		json_object_object_get(section, "targetID"));
360e407b4c8SLawrence Tang 	section_cper->CardHandle = (UINT32)json_object_get_uint64(
361e407b4c8SLawrence Tang 		json_object_object_get(section, "cardSmbiosHandle"));
362e407b4c8SLawrence Tang 	section_cper->ModuleHandle = (UINT32)json_object_get_uint64(
363e407b4c8SLawrence Tang 		json_object_object_get(section, "moduleSmbiosHandle"));
3643b7f45b5SLawrence Tang 
3653b7f45b5SLawrence Tang 	//Write to stream, free up resources.
3663ab351feSLawrence Tang 	fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out);
3673b7f45b5SLawrence Tang 	fflush(out);
3683b7f45b5SLawrence Tang 	free(section_cper);
3693b7f45b5SLawrence Tang }
370