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