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