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>
87f21db6cSLawrence 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.
14*e407b4c8SLawrence Tang json_object *
15*e407b4c8SLawrence Tang cper_section_platform_memory_to_ir(void *section,
16*e407b4c8SLawrence Tang 				   EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
177f21db6cSLawrence Tang {
18*e407b4c8SLawrence Tang 	EFI_PLATFORM_MEMORY_ERROR_DATA *memory_error =
19*e407b4c8SLawrence Tang 		(EFI_PLATFORM_MEMORY_ERROR_DATA *)section;
207f21db6cSLawrence Tang 	json_object *section_ir = json_object_new_object();
217f21db6cSLawrence Tang 
227f21db6cSLawrence Tang 	//Validation bitfield.
23*e407b4c8SLawrence Tang 	json_object *validation =
24*e407b4c8SLawrence Tang 		bitfield_to_ir(memory_error->ValidFields, 22,
25*e407b4c8SLawrence Tang 			       MEMORY_ERROR_VALID_BITFIELD_NAMES);
267f21db6cSLawrence Tang 	json_object_object_add(section_ir, "validationBits", validation);
277f21db6cSLawrence Tang 
287f21db6cSLawrence Tang 	//Error status.
29*e407b4c8SLawrence Tang 	json_object *error_status =
30*e407b4c8SLawrence Tang 		cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
31a0865e38SLawrence Tang 	json_object_object_add(section_ir, "errorStatus", error_status);
32a0865e38SLawrence Tang 
33a0865e38SLawrence Tang 	//Bank.
34a0865e38SLawrence Tang 	json_object *bank = json_object_new_object();
35*e407b4c8SLawrence Tang 	if ((memory_error->ValidFields >> 5) & 0x1) {
36583cdeeeSLawrence Tang 		//Entire bank address mode.
37*e407b4c8SLawrence Tang 		json_object_object_add(
38*e407b4c8SLawrence Tang 			bank, "value",
39*e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank));
40*e407b4c8SLawrence Tang 	} else {
41583cdeeeSLawrence Tang 		//Address/group address mode.
42*e407b4c8SLawrence Tang 		json_object_object_add(
43*e407b4c8SLawrence Tang 			bank, "address",
44*e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank & 0xFF));
45*e407b4c8SLawrence Tang 		json_object_object_add(
46*e407b4c8SLawrence Tang 			bank, "group",
47*e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank >> 8));
48583cdeeeSLawrence Tang 	}
49a0865e38SLawrence Tang 	json_object_object_add(section_ir, "bank", bank);
50a0865e38SLawrence Tang 
51a0865e38SLawrence Tang 	//Memory error type.
52*e407b4c8SLawrence Tang 	json_object *memory_error_type = integer_to_readable_pair(
53*e407b4c8SLawrence Tang 		memory_error->ErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
54*e407b4c8SLawrence Tang 		MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
55*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "memoryErrorType",
56*e407b4c8SLawrence Tang 			       memory_error_type);
57a0865e38SLawrence Tang 
58a0865e38SLawrence Tang 	//"Extended" row/column indication field + misc.
59a0865e38SLawrence Tang 	json_object *extended = json_object_new_object();
60*e407b4c8SLawrence Tang 	json_object_object_add(extended, "rowBit16",
61*e407b4c8SLawrence Tang 			       json_object_new_boolean(memory_error->Extended &
62*e407b4c8SLawrence Tang 						       0b1));
63*e407b4c8SLawrence Tang 	json_object_object_add(
64*e407b4c8SLawrence Tang 		extended, "rowBit17",
65*e407b4c8SLawrence Tang 		json_object_new_boolean((memory_error->Extended >> 1) & 0b1));
66*e407b4c8SLawrence Tang 	json_object_object_add(extended, "chipIdentification",
67*e407b4c8SLawrence Tang 			       json_object_new_int(memory_error->Extended >>
68*e407b4c8SLawrence Tang 						   5));
69a0865e38SLawrence Tang 	json_object_object_add(section_ir, "extended", extended);
70a0865e38SLawrence Tang 
7154da4414SLawrence Tang 	//Miscellaneous numeric fields.
72*e407b4c8SLawrence Tang 	json_object_object_add(
73*e407b4c8SLawrence Tang 		section_ir, "physicalAddress",
74*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->PhysicalAddress));
75*e407b4c8SLawrence Tang 	json_object_object_add(
76*e407b4c8SLawrence Tang 		section_ir, "physicalAddressMask",
77*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->PhysicalAddressMask));
78*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "node",
79*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Node));
80*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "card",
81*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Card));
82*e407b4c8SLawrence Tang 	json_object_object_add(
83*e407b4c8SLawrence Tang 		section_ir, "moduleRank",
84*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ModuleRank));
85*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "device",
86*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Device));
87*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "row",
88*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Row));
89*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "column",
90*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Column));
91*e407b4c8SLawrence Tang 	json_object_object_add(
92*e407b4c8SLawrence Tang 		section_ir, "bitPosition",
93*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->BitPosition));
94*e407b4c8SLawrence Tang 	json_object_object_add(
95*e407b4c8SLawrence Tang 		section_ir, "requestorID",
96*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->RequestorId));
97*e407b4c8SLawrence Tang 	json_object_object_add(
98*e407b4c8SLawrence Tang 		section_ir, "responderID",
99*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ResponderId));
100*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "targetID",
101*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->TargetId));
102*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "rankNumber",
103*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->RankNum));
104*e407b4c8SLawrence Tang 	json_object_object_add(
105*e407b4c8SLawrence Tang 		section_ir, "cardSmbiosHandle",
106*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->CardHandle));
107*e407b4c8SLawrence Tang 	json_object_object_add(
108*e407b4c8SLawrence Tang 		section_ir, "moduleSmbiosHandle",
109*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ModuleHandle));
11054da4414SLawrence Tang 
111a0865e38SLawrence Tang 	return section_ir;
112a0865e38SLawrence Tang }
113a0865e38SLawrence Tang 
114a0865e38SLawrence Tang //Converts a single memory error 2 CPER section into JSON IR.
115*e407b4c8SLawrence Tang json_object *
116*e407b4c8SLawrence Tang cper_section_platform_memory2_to_ir(void *section,
117*e407b4c8SLawrence Tang 				    EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
118a0865e38SLawrence Tang {
119*e407b4c8SLawrence Tang 	EFI_PLATFORM_MEMORY2_ERROR_DATA *memory_error =
120*e407b4c8SLawrence Tang 		(EFI_PLATFORM_MEMORY2_ERROR_DATA *)section;
121a0865e38SLawrence Tang 	json_object *section_ir = json_object_new_object();
122a0865e38SLawrence Tang 
12354da4414SLawrence Tang 	//Validation bits.
124*e407b4c8SLawrence Tang 	json_object *validation =
125*e407b4c8SLawrence Tang 		bitfield_to_ir(memory_error->ValidFields, 22,
126*e407b4c8SLawrence Tang 			       MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
12754da4414SLawrence Tang 	json_object_object_add(section_ir, "validationBits", validation);
12854da4414SLawrence Tang 
12954da4414SLawrence Tang 	//Error status.
130*e407b4c8SLawrence Tang 	json_object *error_status =
131*e407b4c8SLawrence Tang 		cper_generic_error_status_to_ir(&memory_error->ErrorStatus);
13254da4414SLawrence Tang 	json_object_object_add(section_ir, "errorStatus", error_status);
13354da4414SLawrence Tang 
13454da4414SLawrence Tang 	//Bank.
13554da4414SLawrence Tang 	json_object *bank = json_object_new_object();
136*e407b4c8SLawrence Tang 	if ((memory_error->ValidFields >> 5) & 0x1) {
137583cdeeeSLawrence Tang 		//Entire bank address mode.
138*e407b4c8SLawrence Tang 		json_object_object_add(
139*e407b4c8SLawrence Tang 			bank, "value",
140*e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank));
141*e407b4c8SLawrence Tang 	} else {
142583cdeeeSLawrence Tang 		//Address/group address mode.
143*e407b4c8SLawrence Tang 		json_object_object_add(
144*e407b4c8SLawrence Tang 			bank, "address",
145*e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank & 0xFF));
146*e407b4c8SLawrence Tang 		json_object_object_add(
147*e407b4c8SLawrence Tang 			bank, "group",
148*e407b4c8SLawrence Tang 			json_object_new_uint64(memory_error->Bank >> 8));
149583cdeeeSLawrence Tang 	}
15054da4414SLawrence Tang 	json_object_object_add(section_ir, "bank", bank);
15154da4414SLawrence Tang 
15254da4414SLawrence Tang 	//Memory error type.
153*e407b4c8SLawrence Tang 	json_object *memory_error_type = integer_to_readable_pair(
154*e407b4c8SLawrence Tang 		memory_error->MemErrorType, 16, MEMORY_ERROR_TYPES_KEYS,
155*e407b4c8SLawrence Tang 		MEMORY_ERROR_TYPES_VALUES, "Unknown (Reserved)");
156*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "memoryErrorType",
157*e407b4c8SLawrence Tang 			       memory_error_type);
15854da4414SLawrence Tang 
15954da4414SLawrence Tang 	//Status.
16054da4414SLawrence Tang 	json_object *status = json_object_new_object();
161*e407b4c8SLawrence Tang 	json_object_object_add(status, "value",
162*e407b4c8SLawrence Tang 			       json_object_new_int(memory_error->Status));
163*e407b4c8SLawrence Tang 	json_object_object_add(status, "state",
164*e407b4c8SLawrence Tang 			       json_object_new_string(memory_error->Status &
165*e407b4c8SLawrence Tang 								      0b1 == 0 ?
166*e407b4c8SLawrence Tang 								    "Corrected" :
167*e407b4c8SLawrence Tang 								    "Uncorrected"));
16854da4414SLawrence Tang 	json_object_object_add(section_ir, "status", status);
16954da4414SLawrence Tang 
17054da4414SLawrence Tang 	//Miscellaneous numeric fields.
171*e407b4c8SLawrence Tang 	json_object_object_add(
172*e407b4c8SLawrence Tang 		section_ir, "physicalAddress",
173*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->PhysicalAddress));
174*e407b4c8SLawrence Tang 	json_object_object_add(
175*e407b4c8SLawrence Tang 		section_ir, "physicalAddressMask",
176*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->PhysicalAddressMask));
177*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "node",
178*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Node));
179*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "card",
180*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Card));
181*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "module",
182*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Module));
183*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "device",
184*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Device));
185*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "row",
186*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Row));
187*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "column",
188*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Column));
189*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "rank",
190*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->Rank));
191*e407b4c8SLawrence Tang 	json_object_object_add(
192*e407b4c8SLawrence Tang 		section_ir, "bitPosition",
193*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->BitPosition));
194*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "chipID",
195*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->ChipId));
196*e407b4c8SLawrence Tang 	json_object_object_add(
197*e407b4c8SLawrence Tang 		section_ir, "requestorID",
198*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->RequestorId));
199*e407b4c8SLawrence Tang 	json_object_object_add(
200*e407b4c8SLawrence Tang 		section_ir, "responderID",
201*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ResponderId));
202*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "targetID",
203*e407b4c8SLawrence Tang 			       json_object_new_uint64(memory_error->TargetId));
204*e407b4c8SLawrence Tang 	json_object_object_add(
205*e407b4c8SLawrence Tang 		section_ir, "cardSmbiosHandle",
206*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->CardHandle));
207*e407b4c8SLawrence Tang 	json_object_object_add(
208*e407b4c8SLawrence Tang 		section_ir, "moduleSmbiosHandle",
209*e407b4c8SLawrence Tang 		json_object_new_uint64(memory_error->ModuleHandle));
210a0865e38SLawrence Tang 
211a0865e38SLawrence Tang 	return section_ir;
2127f21db6cSLawrence Tang }
2133b7f45b5SLawrence Tang 
2143b7f45b5SLawrence Tang //Converts a single Memory Error IR section into CPER binary, outputting to the provided stream.
2153b7f45b5SLawrence Tang void ir_section_memory_to_cper(json_object *section, FILE *out)
2163b7f45b5SLawrence Tang {
2173b7f45b5SLawrence Tang 	EFI_PLATFORM_MEMORY_ERROR_DATA *section_cper =
218*e407b4c8SLawrence Tang 		(EFI_PLATFORM_MEMORY_ERROR_DATA *)calloc(
219*e407b4c8SLawrence Tang 			1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
2203b7f45b5SLawrence Tang 
2213b7f45b5SLawrence Tang 	//Validation bits.
222*e407b4c8SLawrence Tang 	section_cper->ValidFields = ir_to_bitfield(
223*e407b4c8SLawrence Tang 		json_object_object_get(section, "validationBits"), 22,
224*e407b4c8SLawrence Tang 		MEMORY_ERROR_VALID_BITFIELD_NAMES);
2253b7f45b5SLawrence Tang 
2263b7f45b5SLawrence Tang 	//Error status.
227*e407b4c8SLawrence Tang 	ir_generic_error_status_to_cper(json_object_object_get(section,
228*e407b4c8SLawrence Tang 							       "errorStatus"),
229*e407b4c8SLawrence Tang 					&section_cper->ErrorStatus);
2303b7f45b5SLawrence Tang 
2313b7f45b5SLawrence Tang 	//Bank.
2323b7f45b5SLawrence Tang 	json_object *bank = json_object_object_get(section, "bank");
233*e407b4c8SLawrence Tang 	if ((section_cper->ValidFields >> 5) & 0x1) {
2343b7f45b5SLawrence Tang 		//Bank just uses simple address.
235*e407b4c8SLawrence Tang 		section_cper->Bank = (UINT16)json_object_get_uint64(
236*e407b4c8SLawrence Tang 			json_object_object_get(bank, "value"));
237*e407b4c8SLawrence Tang 	} else {
2383b7f45b5SLawrence Tang 		//Bank uses address/group style address.
239*e407b4c8SLawrence Tang 		UINT16 address = (UINT8)json_object_get_uint64(
240*e407b4c8SLawrence Tang 			json_object_object_get(bank, "address"));
241*e407b4c8SLawrence Tang 		UINT16 group = (UINT8)json_object_get_uint64(
242*e407b4c8SLawrence Tang 			json_object_object_get(bank, "group"));
2433b7f45b5SLawrence Tang 		section_cper->Bank = address + (group << 8);
2443b7f45b5SLawrence Tang 	}
2453b7f45b5SLawrence Tang 
2463b7f45b5SLawrence Tang 	//"Extended" field.
2473b7f45b5SLawrence Tang 	json_object *extended = json_object_object_get(section, "extended");
2483b7f45b5SLawrence Tang 	section_cper->Extended = 0;
249*e407b4c8SLawrence Tang 	section_cper->Extended |= json_object_get_boolean(
250*e407b4c8SLawrence Tang 		json_object_object_get(extended, "rowBit16"));
251*e407b4c8SLawrence Tang 	section_cper->Extended |=
252*e407b4c8SLawrence Tang 		json_object_get_boolean(
253*e407b4c8SLawrence Tang 			json_object_object_get(extended, "rowBit17"))
254*e407b4c8SLawrence Tang 		<< 1;
255*e407b4c8SLawrence Tang 	section_cper->Extended |= json_object_get_int(json_object_object_get(
256*e407b4c8SLawrence Tang 					  extended, "chipIdentification"))
257*e407b4c8SLawrence Tang 				  << 5;
2583b7f45b5SLawrence Tang 
2593b7f45b5SLawrence Tang 	//Miscellaneous value fields.
260*e407b4c8SLawrence Tang 	section_cper->ErrorType = (UINT8)readable_pair_to_integer(
261*e407b4c8SLawrence Tang 		json_object_object_get(section, "memoryErrorType"));
262*e407b4c8SLawrence Tang 	section_cper->PhysicalAddress = json_object_get_uint64(
263*e407b4c8SLawrence Tang 		json_object_object_get(section, "physicalAddress"));
264*e407b4c8SLawrence Tang 	section_cper->PhysicalAddressMask = json_object_get_uint64(
265*e407b4c8SLawrence Tang 		json_object_object_get(section, "physicalAddressMask"));
266*e407b4c8SLawrence Tang 	section_cper->Node = (UINT16)json_object_get_uint64(
267*e407b4c8SLawrence Tang 		json_object_object_get(section, "node"));
268*e407b4c8SLawrence Tang 	section_cper->Card = (UINT16)json_object_get_uint64(
269*e407b4c8SLawrence Tang 		json_object_object_get(section, "card"));
270*e407b4c8SLawrence Tang 	section_cper->ModuleRank = (UINT16)json_object_get_uint64(
271*e407b4c8SLawrence Tang 		json_object_object_get(section, "moduleRank"));
272*e407b4c8SLawrence Tang 	section_cper->Device = (UINT16)json_object_get_uint64(
273*e407b4c8SLawrence Tang 		json_object_object_get(section, "device"));
274*e407b4c8SLawrence Tang 	section_cper->Row = (UINT16)json_object_get_uint64(
275*e407b4c8SLawrence Tang 		json_object_object_get(section, "row"));
276*e407b4c8SLawrence Tang 	section_cper->Column = (UINT16)json_object_get_uint64(
277*e407b4c8SLawrence Tang 		json_object_object_get(section, "column"));
278*e407b4c8SLawrence Tang 	section_cper->BitPosition = (UINT16)json_object_get_uint64(
279*e407b4c8SLawrence Tang 		json_object_object_get(section, "bitPosition"));
280*e407b4c8SLawrence Tang 	section_cper->RequestorId = json_object_get_uint64(
281*e407b4c8SLawrence Tang 		json_object_object_get(section, "requestorID"));
282*e407b4c8SLawrence Tang 	section_cper->ResponderId = json_object_get_uint64(
283*e407b4c8SLawrence Tang 		json_object_object_get(section, "responderID"));
284*e407b4c8SLawrence Tang 	section_cper->TargetId = json_object_get_uint64(
285*e407b4c8SLawrence Tang 		json_object_object_get(section, "targetID"));
286*e407b4c8SLawrence Tang 	section_cper->RankNum = (UINT16)json_object_get_uint64(
287*e407b4c8SLawrence Tang 		json_object_object_get(section, "rankNumber"));
288*e407b4c8SLawrence Tang 	section_cper->CardHandle = (UINT16)json_object_get_uint64(
289*e407b4c8SLawrence Tang 		json_object_object_get(section, "cardSmbiosHandle"));
290*e407b4c8SLawrence Tang 	section_cper->ModuleHandle = (UINT16)json_object_get_uint64(
291*e407b4c8SLawrence Tang 		json_object_object_get(section, "moduleSmbiosHandle"));
2923b7f45b5SLawrence Tang 
2933b7f45b5SLawrence Tang 	//Write to stream, free up resources.
2943ab351feSLawrence Tang 	fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA), 1, out);
2953b7f45b5SLawrence Tang 	fflush(out);
2963b7f45b5SLawrence Tang 	free(section_cper);
2973b7f45b5SLawrence Tang }
2983b7f45b5SLawrence Tang 
2993b7f45b5SLawrence Tang //Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream.
3003b7f45b5SLawrence Tang void ir_section_memory2_to_cper(json_object *section, FILE *out)
3013b7f45b5SLawrence Tang {
3023b7f45b5SLawrence Tang 	EFI_PLATFORM_MEMORY2_ERROR_DATA *section_cper =
303*e407b4c8SLawrence Tang 		(EFI_PLATFORM_MEMORY2_ERROR_DATA *)calloc(
304*e407b4c8SLawrence Tang 			1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
3053b7f45b5SLawrence Tang 
3063b7f45b5SLawrence Tang 	//Validation bits.
307*e407b4c8SLawrence Tang 	section_cper->ValidFields = ir_to_bitfield(
308*e407b4c8SLawrence Tang 		json_object_object_get(section, "validationBits"), 22,
309*e407b4c8SLawrence Tang 		MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
3103b7f45b5SLawrence Tang 
3113b7f45b5SLawrence Tang 	//Error status.
312*e407b4c8SLawrence Tang 	ir_generic_error_status_to_cper(json_object_object_get(section,
313*e407b4c8SLawrence Tang 							       "errorStatus"),
314*e407b4c8SLawrence Tang 					&section_cper->ErrorStatus);
3153b7f45b5SLawrence Tang 
3163b7f45b5SLawrence Tang 	//Bank.
3173b7f45b5SLawrence Tang 	json_object *bank = json_object_object_get(section, "bank");
318*e407b4c8SLawrence Tang 	if ((section_cper->ValidFields >> 5) & 0x1) {
3193b7f45b5SLawrence Tang 		//Bank just uses simple address.
320*e407b4c8SLawrence Tang 		section_cper->Bank = (UINT16)json_object_get_uint64(
321*e407b4c8SLawrence Tang 			json_object_object_get(bank, "value"));
322*e407b4c8SLawrence Tang 	} else {
3233b7f45b5SLawrence Tang 		//Bank uses address/group style address.
324*e407b4c8SLawrence Tang 		UINT16 address = (UINT8)json_object_get_uint64(
325*e407b4c8SLawrence Tang 			json_object_object_get(bank, "address"));
326*e407b4c8SLawrence Tang 		UINT16 group = (UINT8)json_object_get_uint64(
327*e407b4c8SLawrence Tang 			json_object_object_get(bank, "group"));
3283b7f45b5SLawrence Tang 		section_cper->Bank = address + (group << 8);
3293b7f45b5SLawrence Tang 	}
3303b7f45b5SLawrence Tang 
3313b7f45b5SLawrence Tang 	//Miscellaneous value fields.
332*e407b4c8SLawrence Tang 	section_cper->MemErrorType = readable_pair_to_integer(
333*e407b4c8SLawrence Tang 		json_object_object_get(section, "memoryErrorType"));
334*e407b4c8SLawrence Tang 	section_cper->Status = (UINT8)readable_pair_to_integer(
335*e407b4c8SLawrence Tang 		json_object_object_get(section, "status"));
336*e407b4c8SLawrence Tang 	section_cper->PhysicalAddress = json_object_get_uint64(
337*e407b4c8SLawrence Tang 		json_object_object_get(section, "physicalAddress"));
338*e407b4c8SLawrence Tang 	section_cper->PhysicalAddressMask = json_object_get_uint64(
339*e407b4c8SLawrence Tang 		json_object_object_get(section, "physicalAddressMask"));
340*e407b4c8SLawrence Tang 	section_cper->Node = (UINT16)json_object_get_uint64(
341*e407b4c8SLawrence Tang 		json_object_object_get(section, "node"));
342*e407b4c8SLawrence Tang 	section_cper->Card = (UINT16)json_object_get_uint64(
343*e407b4c8SLawrence Tang 		json_object_object_get(section, "card"));
344*e407b4c8SLawrence Tang 	section_cper->Module = (UINT32)json_object_get_uint64(
345*e407b4c8SLawrence Tang 		json_object_object_get(section, "module"));
346*e407b4c8SLawrence Tang 	section_cper->Device = (UINT32)json_object_get_uint64(
347*e407b4c8SLawrence Tang 		json_object_object_get(section, "device"));
348*e407b4c8SLawrence Tang 	section_cper->Row = (UINT32)json_object_get_uint64(
349*e407b4c8SLawrence Tang 		json_object_object_get(section, "row"));
350*e407b4c8SLawrence Tang 	section_cper->Column = (UINT32)json_object_get_uint64(
351*e407b4c8SLawrence Tang 		json_object_object_get(section, "column"));
352*e407b4c8SLawrence Tang 	section_cper->Rank = (UINT32)json_object_get_uint64(
353*e407b4c8SLawrence Tang 		json_object_object_get(section, "rank"));
354*e407b4c8SLawrence Tang 	section_cper->BitPosition = (UINT32)json_object_get_uint64(
355*e407b4c8SLawrence Tang 		json_object_object_get(section, "bitPosition"));
356*e407b4c8SLawrence Tang 	section_cper->ChipId = (UINT8)json_object_get_uint64(
357*e407b4c8SLawrence Tang 		json_object_object_get(section, "chipID"));
358*e407b4c8SLawrence Tang 	section_cper->RequestorId = json_object_get_uint64(
359*e407b4c8SLawrence Tang 		json_object_object_get(section, "requestorID"));
360*e407b4c8SLawrence Tang 	section_cper->ResponderId = json_object_get_uint64(
361*e407b4c8SLawrence Tang 		json_object_object_get(section, "responderID"));
362*e407b4c8SLawrence Tang 	section_cper->TargetId = json_object_get_uint64(
363*e407b4c8SLawrence Tang 		json_object_object_get(section, "targetID"));
364*e407b4c8SLawrence Tang 	section_cper->CardHandle = (UINT32)json_object_get_uint64(
365*e407b4c8SLawrence Tang 		json_object_object_get(section, "cardSmbiosHandle"));
366*e407b4c8SLawrence Tang 	section_cper->ModuleHandle = (UINT32)json_object_get_uint64(
367*e407b4c8SLawrence Tang 		json_object_object_get(section, "moduleSmbiosHandle"));
3683b7f45b5SLawrence Tang 
3693b7f45b5SLawrence Tang 	//Write to stream, free up resources.
3703ab351feSLawrence Tang 	fwrite(section_cper, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA), 1, out);
3713b7f45b5SLawrence Tang 	fflush(out);
3723b7f45b5SLawrence Tang 	free(section_cper);
3733b7f45b5SLawrence Tang }