1cc0f5f38SLawrence Tang /**
2cc0f5f38SLawrence Tang  * Describes functions for converting Intel IPF CPER sections from binary and JSON format
3cc0f5f38SLawrence Tang  * into an intermediate format.
4cc0f5f38SLawrence Tang  *
5cc0f5f38SLawrence Tang  * Author: Lawrence.Tang@arm.com
6cc0f5f38SLawrence Tang  **/
7cc0f5f38SLawrence Tang #include <stdio.h>
8cc0f5f38SLawrence Tang #include "json.h"
9cc0f5f38SLawrence Tang #include "../edk/Cper.h"
10cc0f5f38SLawrence Tang #include "../cper-utils.h"
11cc0f5f38SLawrence Tang #include "cper-section-ipf.h"
12cc0f5f38SLawrence Tang 
13*e407b4c8SLawrence Tang json_object *cper_ipf_mod_error_read_array(EFI_IPF_MOD_ERROR_INFO **cur_error,
14*e407b4c8SLawrence Tang 					   int num_to_read);
15e18aaee9SLawrence Tang json_object *cper_ipf_mod_error_to_ir(EFI_IPF_MOD_ERROR_INFO *mod_error);
16e18aaee9SLawrence Tang 
17cc0f5f38SLawrence Tang //Converts a single Intel IPF error CPER section into JSON IR.
18*e407b4c8SLawrence Tang json_object *cper_section_ipf_to_ir(void *section,
19*e407b4c8SLawrence Tang 				    EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
20cc0f5f38SLawrence Tang {
21*e407b4c8SLawrence Tang 	EFI_IPF_ERROR_INFO_HEADER *ipf_error =
22*e407b4c8SLawrence Tang 		(EFI_IPF_ERROR_INFO_HEADER *)section;
23e18aaee9SLawrence Tang 	json_object *section_ir = json_object_new_object();
24e18aaee9SLawrence Tang 
25e18aaee9SLawrence Tang 	//Validation bits.
26e18aaee9SLawrence Tang 	json_object *validation = json_object_new_object();
27*e407b4c8SLawrence Tang 	json_object_object_add(validation, "errorMapValid",
28*e407b4c8SLawrence Tang 			       json_object_new_boolean(
29*e407b4c8SLawrence Tang 				       ipf_error->ValidBits.ProcErrorMapValid));
30*e407b4c8SLawrence Tang 	json_object_object_add(validation, "stateParameterValid",
31*e407b4c8SLawrence Tang 			       json_object_new_boolean(
32*e407b4c8SLawrence Tang 				       ipf_error->ValidBits.ProcErrorMapValid));
33*e407b4c8SLawrence Tang 	json_object_object_add(
34*e407b4c8SLawrence Tang 		validation, "crLIDValid",
35*e407b4c8SLawrence Tang 		json_object_new_boolean(ipf_error->ValidBits.ProcCrLidValid));
36*e407b4c8SLawrence Tang 	json_object_object_add(
37*e407b4c8SLawrence Tang 		validation, "psiStaticStructValid",
38*e407b4c8SLawrence Tang 		json_object_new_boolean(
39*e407b4c8SLawrence Tang 			ipf_error->ValidBits.PsiStaticStructValid));
40*e407b4c8SLawrence Tang 	json_object_object_add(
41*e407b4c8SLawrence Tang 		validation, "cpuInfoValid",
42*e407b4c8SLawrence Tang 		json_object_new_boolean(ipf_error->ValidBits.CpuIdInfoValid));
43e18aaee9SLawrence Tang 	json_object_object_add(section_ir, "validationBits", validation);
44e18aaee9SLawrence Tang 
45e18aaee9SLawrence Tang 	//Numbers of various variable length segments.
46*e407b4c8SLawrence Tang 	json_object_object_add(
47*e407b4c8SLawrence Tang 		section_ir, "cacheCheckNum",
48*e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.CacheCheckNum));
49*e407b4c8SLawrence Tang 	json_object_object_add(
50*e407b4c8SLawrence Tang 		section_ir, "tlbCheckNum",
51*e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.TlbCheckNum));
52*e407b4c8SLawrence Tang 	json_object_object_add(
53*e407b4c8SLawrence Tang 		section_ir, "busCheckNum",
54*e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.BusCheckNum));
55*e407b4c8SLawrence Tang 	json_object_object_add(
56*e407b4c8SLawrence Tang 		section_ir, "regFileCheckNum",
57*e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.RegFileCheckNum));
58*e407b4c8SLawrence Tang 	json_object_object_add(
59*e407b4c8SLawrence Tang 		section_ir, "msCheckNum",
60*e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.MsCheckNum));
61e18aaee9SLawrence Tang 
62e18aaee9SLawrence Tang 	//Process error map, state params/CR LID.
63*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "procErrorMap",
64*e407b4c8SLawrence Tang 			       json_object_new_uint64(ipf_error->ProcErrorMap));
65*e407b4c8SLawrence Tang 	json_object_object_add(
66*e407b4c8SLawrence Tang 		section_ir, "procStateParameter",
67*e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ProcStateParameter));
68*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "procCRLID",
69*e407b4c8SLawrence Tang 			       json_object_new_uint64(ipf_error->ProcCrLid));
70e18aaee9SLawrence Tang 
71e18aaee9SLawrence Tang 	//Read cache, TLB, bus, register file, MS errors.
72*e407b4c8SLawrence Tang 	EFI_IPF_MOD_ERROR_INFO *cur_error =
73*e407b4c8SLawrence Tang 		(EFI_IPF_MOD_ERROR_INFO *)(ipf_error + 1);
74*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "cacheErrors",
75*e407b4c8SLawrence Tang 			       cper_ipf_mod_error_read_array(
76*e407b4c8SLawrence Tang 				       &cur_error,
77*e407b4c8SLawrence Tang 				       ipf_error->ValidBits.CacheCheckNum));
78*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "tlbErrors",
79*e407b4c8SLawrence Tang 			       cper_ipf_mod_error_read_array(
80*e407b4c8SLawrence Tang 				       &cur_error,
81*e407b4c8SLawrence Tang 				       ipf_error->ValidBits.TlbCheckNum));
82*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "busErrors",
83*e407b4c8SLawrence Tang 			       cper_ipf_mod_error_read_array(
84*e407b4c8SLawrence Tang 				       &cur_error,
85*e407b4c8SLawrence Tang 				       ipf_error->ValidBits.BusCheckNum));
86*e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "regFileErrors",
87*e407b4c8SLawrence Tang 			       cper_ipf_mod_error_read_array(
88*e407b4c8SLawrence Tang 				       &cur_error,
89*e407b4c8SLawrence Tang 				       ipf_error->ValidBits.RegFileCheckNum));
90*e407b4c8SLawrence Tang 	json_object_object_add(
91*e407b4c8SLawrence Tang 		section_ir, "msErrors",
92*e407b4c8SLawrence Tang 		cper_ipf_mod_error_read_array(&cur_error,
93*e407b4c8SLawrence Tang 					      ipf_error->ValidBits.MsCheckNum));
94e18aaee9SLawrence Tang 
95e18aaee9SLawrence Tang 	//CPU ID information.
96e18aaee9SLawrence Tang 	EFI_IPF_CPU_INFO *cpu_info = (EFI_IPF_CPU_INFO *)cur_error;
97151c6cabSLawrence Tang 	//stretch: find out how this is represented
98e18aaee9SLawrence Tang 
99e18aaee9SLawrence Tang 	//Processor static information.
100e18aaee9SLawrence Tang 	EFI_IPF_PSI_STATIC *psi_static = (EFI_IPF_PSI_STATIC *)(cpu_info + 1);
101e18aaee9SLawrence Tang 	json_object *psi_static_ir = json_object_new_object();
102e18aaee9SLawrence Tang 
103e18aaee9SLawrence Tang 	//PSI validation bits.
104*e407b4c8SLawrence Tang 	json_object *psi_validation =
105*e407b4c8SLawrence Tang 		bitfield_to_ir(psi_static->ValidBits, 6,
106*e407b4c8SLawrence Tang 			       IPF_PSI_STATIC_INFO_VALID_BITFIELD_NAMES);
107e18aaee9SLawrence Tang 	json_object_object_add(psi_static_ir, "validationBits", psi_validation);
108e18aaee9SLawrence Tang 
109e18aaee9SLawrence Tang 	//PSI minimal state save info.
110151c6cabSLawrence Tang 	//stretch: structure min save state area as in Intel Itanium Architecture Software Developer's Manual.
111e18aaee9SLawrence Tang 
112e18aaee9SLawrence Tang 	//BRs, CRs, ARs, RRs, FRs.
113*e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "brs",
114*e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Brs, 8));
115*e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "crs",
116*e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Crs, 128));
117*e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "ars",
118*e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Ars, 128));
119*e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "rrs",
120*e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Rrs, 8));
121*e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "frs",
122*e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Frs, 256));
123e18aaee9SLawrence Tang 	json_object_object_add(section_ir, "psiStaticInfo", psi_static_ir);
124e18aaee9SLawrence Tang 
125e18aaee9SLawrence Tang 	return section_ir;
126e18aaee9SLawrence Tang }
127e18aaee9SLawrence Tang 
128e18aaee9SLawrence Tang //Reads a continuous stream of CPER IPF mod errors beginning from the given pointer, for n entries.
129e18aaee9SLawrence Tang //Returns an array containing all read entries as JSON IR.
130*e407b4c8SLawrence Tang json_object *cper_ipf_mod_error_read_array(EFI_IPF_MOD_ERROR_INFO **cur_error,
131*e407b4c8SLawrence Tang 					   int num_to_read)
132e18aaee9SLawrence Tang {
133e18aaee9SLawrence Tang 	json_object *error_array = json_object_new_array();
134*e407b4c8SLawrence Tang 	for (int i = 0; i < num_to_read; i++) {
135*e407b4c8SLawrence Tang 		json_object_array_add(error_array,
136*e407b4c8SLawrence Tang 				      cper_ipf_mod_error_to_ir(*cur_error));
137e18aaee9SLawrence Tang 		*cur_error = *cur_error + 1;
138e18aaee9SLawrence Tang 	}
139e18aaee9SLawrence Tang 
140e18aaee9SLawrence Tang 	return error_array;
141e18aaee9SLawrence Tang }
142e18aaee9SLawrence Tang 
143e18aaee9SLawrence Tang //Converts a single CPER IPF mod error info structure into JSON IR.
144e18aaee9SLawrence Tang json_object *cper_ipf_mod_error_to_ir(EFI_IPF_MOD_ERROR_INFO *mod_error)
145e18aaee9SLawrence Tang {
146e18aaee9SLawrence Tang 	json_object *mod_error_ir = json_object_new_object();
147e18aaee9SLawrence Tang 
148e18aaee9SLawrence Tang 	//Validation bits.
149*e407b4c8SLawrence Tang 	json_object *validation = bitfield_to_ir(
150*e407b4c8SLawrence Tang 		mod_error->ValidBits, 5, IPF_MOD_ERROR_VALID_BITFIELD_NAMES);
151e18aaee9SLawrence Tang 	json_object_object_add(mod_error_ir, "validationBits", validation);
152e18aaee9SLawrence Tang 
153e18aaee9SLawrence Tang 	//Numeric fields.
154*e407b4c8SLawrence Tang 	json_object_object_add(mod_error_ir, "modCheckInfo",
155*e407b4c8SLawrence Tang 			       json_object_new_uint64(mod_error->ModCheckInfo));
156*e407b4c8SLawrence Tang 	json_object_object_add(mod_error_ir, "modTargetID",
157*e407b4c8SLawrence Tang 			       json_object_new_uint64(mod_error->ModTargetId));
158*e407b4c8SLawrence Tang 	json_object_object_add(
159*e407b4c8SLawrence Tang 		mod_error_ir, "modRequestorID",
160*e407b4c8SLawrence Tang 		json_object_new_uint64(mod_error->ModRequestorId));
161*e407b4c8SLawrence Tang 	json_object_object_add(
162*e407b4c8SLawrence Tang 		mod_error_ir, "modResponderID",
163*e407b4c8SLawrence Tang 		json_object_new_uint64(mod_error->ModResponderId));
164*e407b4c8SLawrence Tang 	json_object_object_add(mod_error_ir, "modPreciseIP",
165*e407b4c8SLawrence Tang 			       json_object_new_uint64(mod_error->ModPreciseIp));
166e18aaee9SLawrence Tang 
167e18aaee9SLawrence Tang 	return mod_error_ir;
168cc0f5f38SLawrence Tang }