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