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>
8*5202bbb4SLawrence 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 
13e407b4c8SLawrence Tang json_object *cper_ipf_mod_error_read_array(EFI_IPF_MOD_ERROR_INFO **cur_error,
14e407b4c8SLawrence 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.
18e407b4c8SLawrence Tang json_object *cper_section_ipf_to_ir(void *section,
19e407b4c8SLawrence Tang 				    EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
20cc0f5f38SLawrence Tang {
21e407b4c8SLawrence Tang 	EFI_IPF_ERROR_INFO_HEADER *ipf_error =
22e407b4c8SLawrence 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();
27e407b4c8SLawrence Tang 	json_object_object_add(validation, "errorMapValid",
28e407b4c8SLawrence Tang 			       json_object_new_boolean(
29e407b4c8SLawrence Tang 				       ipf_error->ValidBits.ProcErrorMapValid));
30e407b4c8SLawrence Tang 	json_object_object_add(validation, "stateParameterValid",
31e407b4c8SLawrence Tang 			       json_object_new_boolean(
32e407b4c8SLawrence Tang 				       ipf_error->ValidBits.ProcErrorMapValid));
33e407b4c8SLawrence Tang 	json_object_object_add(
34e407b4c8SLawrence Tang 		validation, "crLIDValid",
35e407b4c8SLawrence Tang 		json_object_new_boolean(ipf_error->ValidBits.ProcCrLidValid));
36e407b4c8SLawrence Tang 	json_object_object_add(
37e407b4c8SLawrence Tang 		validation, "psiStaticStructValid",
38e407b4c8SLawrence Tang 		json_object_new_boolean(
39e407b4c8SLawrence Tang 			ipf_error->ValidBits.PsiStaticStructValid));
40e407b4c8SLawrence Tang 	json_object_object_add(
41e407b4c8SLawrence Tang 		validation, "cpuInfoValid",
42e407b4c8SLawrence 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.
46e407b4c8SLawrence Tang 	json_object_object_add(
47e407b4c8SLawrence Tang 		section_ir, "cacheCheckNum",
48e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.CacheCheckNum));
49e407b4c8SLawrence Tang 	json_object_object_add(
50e407b4c8SLawrence Tang 		section_ir, "tlbCheckNum",
51e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.TlbCheckNum));
52e407b4c8SLawrence Tang 	json_object_object_add(
53e407b4c8SLawrence Tang 		section_ir, "busCheckNum",
54e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.BusCheckNum));
55e407b4c8SLawrence Tang 	json_object_object_add(
56e407b4c8SLawrence Tang 		section_ir, "regFileCheckNum",
57e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.RegFileCheckNum));
58e407b4c8SLawrence Tang 	json_object_object_add(
59e407b4c8SLawrence Tang 		section_ir, "msCheckNum",
60e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ValidBits.MsCheckNum));
61e18aaee9SLawrence Tang 
62e18aaee9SLawrence Tang 	//Process error map, state params/CR LID.
63e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "procErrorMap",
64e407b4c8SLawrence Tang 			       json_object_new_uint64(ipf_error->ProcErrorMap));
65e407b4c8SLawrence Tang 	json_object_object_add(
66e407b4c8SLawrence Tang 		section_ir, "procStateParameter",
67e407b4c8SLawrence Tang 		json_object_new_uint64(ipf_error->ProcStateParameter));
68e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "procCRLID",
69e407b4c8SLawrence Tang 			       json_object_new_uint64(ipf_error->ProcCrLid));
70e18aaee9SLawrence Tang 
71e18aaee9SLawrence Tang 	//Read cache, TLB, bus, register file, MS errors.
72e407b4c8SLawrence Tang 	EFI_IPF_MOD_ERROR_INFO *cur_error =
73e407b4c8SLawrence Tang 		(EFI_IPF_MOD_ERROR_INFO *)(ipf_error + 1);
74e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "cacheErrors",
75e407b4c8SLawrence Tang 			       cper_ipf_mod_error_read_array(
76e407b4c8SLawrence Tang 				       &cur_error,
77e407b4c8SLawrence Tang 				       ipf_error->ValidBits.CacheCheckNum));
78e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "tlbErrors",
79e407b4c8SLawrence Tang 			       cper_ipf_mod_error_read_array(
80e407b4c8SLawrence Tang 				       &cur_error,
81e407b4c8SLawrence Tang 				       ipf_error->ValidBits.TlbCheckNum));
82e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "busErrors",
83e407b4c8SLawrence Tang 			       cper_ipf_mod_error_read_array(
84e407b4c8SLawrence Tang 				       &cur_error,
85e407b4c8SLawrence Tang 				       ipf_error->ValidBits.BusCheckNum));
86e407b4c8SLawrence Tang 	json_object_object_add(section_ir, "regFileErrors",
87e407b4c8SLawrence Tang 			       cper_ipf_mod_error_read_array(
88e407b4c8SLawrence Tang 				       &cur_error,
89e407b4c8SLawrence Tang 				       ipf_error->ValidBits.RegFileCheckNum));
90e407b4c8SLawrence Tang 	json_object_object_add(
91e407b4c8SLawrence Tang 		section_ir, "msErrors",
92e407b4c8SLawrence Tang 		cper_ipf_mod_error_read_array(&cur_error,
93e407b4c8SLawrence 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.
104e407b4c8SLawrence Tang 	json_object *psi_validation =
105e407b4c8SLawrence Tang 		bitfield_to_ir(psi_static->ValidBits, 6,
106e407b4c8SLawrence 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.
113e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "brs",
114e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Brs, 8));
115e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "crs",
116e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Crs, 128));
117e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "ars",
118e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Ars, 128));
119e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "rrs",
120e407b4c8SLawrence Tang 			       uint64_array_to_ir_array(psi_static->Rrs, 8));
121e407b4c8SLawrence Tang 	json_object_object_add(psi_static_ir, "frs",
122e407b4c8SLawrence 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.
130e407b4c8SLawrence Tang json_object *cper_ipf_mod_error_read_array(EFI_IPF_MOD_ERROR_INFO **cur_error,
131e407b4c8SLawrence Tang 					   int num_to_read)
132e18aaee9SLawrence Tang {
133e18aaee9SLawrence Tang 	json_object *error_array = json_object_new_array();
134e407b4c8SLawrence Tang 	for (int i = 0; i < num_to_read; i++) {
135e407b4c8SLawrence Tang 		json_object_array_add(error_array,
136e407b4c8SLawrence 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.
149e407b4c8SLawrence Tang 	json_object *validation = bitfield_to_ir(
150e407b4c8SLawrence 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.
154e407b4c8SLawrence Tang 	json_object_object_add(mod_error_ir, "modCheckInfo",
155e407b4c8SLawrence Tang 			       json_object_new_uint64(mod_error->ModCheckInfo));
156e407b4c8SLawrence Tang 	json_object_object_add(mod_error_ir, "modTargetID",
157e407b4c8SLawrence Tang 			       json_object_new_uint64(mod_error->ModTargetId));
158e407b4c8SLawrence Tang 	json_object_object_add(
159e407b4c8SLawrence Tang 		mod_error_ir, "modRequestorID",
160e407b4c8SLawrence Tang 		json_object_new_uint64(mod_error->ModRequestorId));
161e407b4c8SLawrence Tang 	json_object_object_add(
162e407b4c8SLawrence Tang 		mod_error_ir, "modResponderID",
163e407b4c8SLawrence Tang 		json_object_new_uint64(mod_error->ModResponderId));
164e407b4c8SLawrence Tang 	json_object_object_add(mod_error_ir, "modPreciseIP",
165e407b4c8SLawrence Tang 			       json_object_new_uint64(mod_error->ModPreciseIp));
166e18aaee9SLawrence Tang 
167e18aaee9SLawrence Tang 	return mod_error_ir;
168cc0f5f38SLawrence Tang }