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