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