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