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