blob: 2029a2220c89963b29775c75e18417da8dff1854 [file] [log] [blame]
Lawrence Tangcc0f5f32022-07-06 17:17:26 +01001/**
2 * Describes functions for converting Intel IPF CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tangcc0f5f32022-07-06 17:17:26 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7#include <stdio.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01008#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +00009#include <libcper/Cper.h>
10#include <libcper/cper-utils.h>
11#include <libcper/sections/cper-section-ipf.h>
Ed Tanous50b966f2025-03-11 09:06:19 -070012#include <libcper/log.h>
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070013#include <string.h>
Lawrence Tangcc0f5f32022-07-06 17:17:26 +010014
Lawrence Tange407b4c2022-07-21 13:54:01 +010015json_object *cper_ipf_mod_error_read_array(EFI_IPF_MOD_ERROR_INFO **cur_error,
16 int num_to_read);
17json_object *cper_ipf_mod_error_to_ir(EFI_IPF_MOD_ERROR_INFO *mod_error);
Lawrence Tange18aaee2022-07-07 09:01:30 +010018
Lawrence Tangcc0f5f32022-07-06 17:17:26 +010019//Converts a single Intel IPF error CPER section into JSON IR.
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070020json_object *cper_section_ipf_to_ir(const UINT8 *section, UINT32 size,
21 char **desc_string)
Lawrence Tangcc0f5f32022-07-06 17:17:26 +010022{
Aushim Nagarkattiad6c8802025-06-18 16:45:28 -070023 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
Ed Tanous12dbd4f2025-03-08 19:05:01 -080034 if (size < sizeof(EFI_IPF_ERROR_INFO_HEADER)) {
35 return NULL;
36 }
37
Lawrence Tange407b4c2022-07-21 13:54:01 +010038 EFI_IPF_ERROR_INFO_HEADER *ipf_error =
39 (EFI_IPF_ERROR_INFO_HEADER *)section;
40 json_object *section_ir = json_object_new_object();
Lawrence Tange18aaee2022-07-07 09:01:30 +010041
Lawrence Tange407b4c2022-07-21 13:54:01 +010042 //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);
Lawrence Tange18aaee2022-07-07 09:01:30 +010061
Lawrence Tange407b4c2022-07-21 13:54:01 +010062 //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));
Lawrence Tange18aaee2022-07-07 09:01:30 +010078
Lawrence Tange407b4c2022-07-21 13:54:01 +010079 //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));
Lawrence Tange18aaee2022-07-07 09:01:30 +010087
Lawrence Tange407b4c2022-07-21 13:54:01 +010088 //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));
Lawrence Tange18aaee2022-07-07 09:01:30 +0100111
Lawrence Tange407b4c2022-07-21 13:54:01 +0100112 //CPU ID information.
113 EFI_IPF_CPU_INFO *cpu_info = (EFI_IPF_CPU_INFO *)cur_error;
114 //stretch: find out how this is represented
Lawrence Tange18aaee2022-07-07 09:01:30 +0100115
Lawrence Tange407b4c2022-07-21 13:54:01 +0100116 //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();
Lawrence Tange18aaee2022-07-07 09:01:30 +0100119
Lawrence Tange407b4c2022-07-21 13:54:01 +0100120 //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);
Lawrence Tange18aaee2022-07-07 09:01:30 +0100125
Lawrence Tange407b4c2022-07-21 13:54:01 +0100126 //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;
Lawrence Tange18aaee2022-07-07 09:01:30 +0100143}
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.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100147json_object *cper_ipf_mod_error_read_array(EFI_IPF_MOD_ERROR_INFO **cur_error,
148 int num_to_read)
Lawrence Tange18aaee2022-07-07 09:01:30 +0100149{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100150 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 }
Lawrence Tange18aaee2022-07-07 09:01:30 +0100156
Lawrence Tange407b4c2022-07-21 13:54:01 +0100157 return error_array;
Lawrence Tange18aaee2022-07-07 09:01:30 +0100158}
159
160//Converts a single CPER IPF mod error info structure into JSON IR.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100161json_object *cper_ipf_mod_error_to_ir(EFI_IPF_MOD_ERROR_INFO *mod_error)
Lawrence Tange18aaee2022-07-07 09:01:30 +0100162{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100163 json_object *mod_error_ir = json_object_new_object();
Lawrence Tange18aaee2022-07-07 09:01:30 +0100164
Lawrence Tange407b4c2022-07-21 13:54:01 +0100165 //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);
Lawrence Tange18aaee2022-07-07 09:01:30 +0100169
Lawrence Tange407b4c2022-07-21 13:54:01 +0100170 //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;
John Chungf8fc7052024-05-03 20:05:29 +0800185}