blob: ec70b850a160d84b7460311908761a3e2d9eff36 [file] [log] [blame]
Lawrence Tang1b0b00e2022-07-05 10:33:10 +01001/**
2 * Describes functions for converting processor-generic CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang1b0b00e2022-07-05 10:33:10 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7
8#include <stdio.h>
Lawrence Tang0cb33792022-07-13 13:51:39 +01009#include <string.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +010010#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +000011#include <libcper/Cper.h>
12#include <libcper/cper-utils.h>
13#include <libcper/sections/cper-section-generic.h>
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010014
15//Converts the given processor-generic CPER section into JSON IR.
Ed Tanous12dbd4f2025-03-08 19:05:01 -080016json_object *cper_section_generic_to_ir(const UINT8 *section, UINT32 size)
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010017{
Ed Tanous12dbd4f2025-03-08 19:05:01 -080018 if (size < sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA)) {
19 return NULL;
20 }
21
Lawrence Tange407b4c2022-07-21 13:54:01 +010022 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic =
23 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
24 json_object *section_ir = json_object_new_object();
Lawrence Tang3c43f742022-07-05 11:37:17 +010025
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080026 ValidationTypes ui64Type = {
27 UINT_64T, .value.ui64 = section_generic->ValidFields
28 };
Lawrence Tang3c43f742022-07-05 11:37:17 +010029
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080030 if (isvalid_prop_to_ir(&ui64Type, 0)) {
31 //Processor type, with human readable name if possible.
32 json_object *processor_type = integer_to_readable_pair(
33 section_generic->Type,
34 sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
35 GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES,
36 "Unknown (Reserved)");
37 json_object_object_add(section_ir, "processorType",
38 processor_type);
39 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010040
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080041 if (isvalid_prop_to_ir(&ui64Type, 1)) {
42 //Processor ISA, with human readable name if possible.
43 json_object *processor_isa = integer_to_readable_pair(
44 section_generic->Isa,
45 sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
46 GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES,
47 "Unknown (Reserved)");
48 json_object_object_add(section_ir, "processorISA",
49 processor_isa);
50 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010051
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080052 if (isvalid_prop_to_ir(&ui64Type, 2)) {
53 //Processor error type, with human readable name if possible.
54 json_object *processor_error_type = integer_to_readable_pair(
55 section_generic->ErrorType,
56 sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
57 GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES,
58 "Unknown (Reserved)");
59 json_object_object_add(section_ir, "errorType",
60 processor_error_type);
61 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010062
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080063 if (isvalid_prop_to_ir(&ui64Type, 3)) {
64 //The operation performed, with a human readable name if possible.
65 json_object *operation = integer_to_readable_pair(
66 section_generic->Operation,
67 sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
68 GENERIC_OPERATION_TYPES_KEYS,
69 GENERIC_OPERATION_TYPES_VALUES, "Unknown (Reserved)");
70 json_object_object_add(section_ir, "operation", operation);
71 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010072
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080073 if (isvalid_prop_to_ir(&ui64Type, 4)) {
74 //Flags, additional information about the error.
75 json_object *flags =
76 bitfield_to_ir(section_generic->Flags, 4,
77 GENERIC_FLAGS_BITFIELD_NAMES);
78 json_object_object_add(section_ir, "flags", flags);
79 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010080
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080081 if (isvalid_prop_to_ir(&ui64Type, 5)) {
82 //The level of the error.
83 json_object_object_add(
84 section_ir, "level",
85 json_object_new_int(section_generic->Level));
86 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010087
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080088 if (isvalid_prop_to_ir(&ui64Type, 6)) {
89 //CPU version information.
90 json_object_object_add(
91 section_ir, "cpuVersionInfo",
92 json_object_new_uint64(section_generic->VersionInfo));
93 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010094
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080095 if (isvalid_prop_to_ir(&ui64Type, 7)) {
96 //CPU brand string. May not exist if on ARM.
97 json_object_object_add(
98 section_ir, "cpuBrandString",
99 json_object_new_string(section_generic->BrandString));
100 }
Lawrence Tang3c43f742022-07-05 11:37:17 +0100101
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800102 if (isvalid_prop_to_ir(&ui64Type, 8)) {
103 //Remaining 64-bit fields.
104 json_object_object_add(
105 section_ir, "processorID",
106 json_object_new_uint64(section_generic->ApicId));
107 }
108
109 if (isvalid_prop_to_ir(&ui64Type, 9)) {
110 json_object_object_add(
111 section_ir, "targetAddress",
112 json_object_new_uint64(section_generic->TargetAddr));
113 }
114
115 if (isvalid_prop_to_ir(&ui64Type, 10)) {
116 json_object_object_add(
117 section_ir, "requestorID",
118 json_object_new_uint64(section_generic->RequestorId));
119 }
120
121 if (isvalid_prop_to_ir(&ui64Type, 11)) {
122 json_object_object_add(
123 section_ir, "responderID",
124 json_object_new_uint64(section_generic->ResponderId));
125 }
126
127 if (isvalid_prop_to_ir(&ui64Type, 12)) {
128 json_object_object_add(
129 section_ir, "instructionIP",
130 json_object_new_uint64(section_generic->InstructionIP));
131 }
Lawrence Tang3c43f742022-07-05 11:37:17 +0100132
Lawrence Tange407b4c2022-07-21 13:54:01 +0100133 return section_ir;
Lawrence Tang0cb33792022-07-13 13:51:39 +0100134}
135
136//Converts the given CPER-JSON processor-generic error section into CPER binary,
137//outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100138void ir_section_generic_to_cper(json_object *section, FILE *out)
Lawrence Tang0cb33792022-07-13 13:51:39 +0100139{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100140 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper =
141 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc(
142 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100143
Lawrence Tange407b4c2022-07-21 13:54:01 +0100144 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800145 //Remove
146 // section_cper->ValidFields = ir_to_bitfield(
147 // json_object_object_get(section, "validationBits"), 13,
148 // GENERIC_VALIDATION_BITFIELD_NAMES);
149 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
150 struct json_object *obj = NULL;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100151 //Various name/value pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800152 if (json_object_object_get_ex(section, "processorType", &obj)) {
153 section_cper->Type = (UINT8)readable_pair_to_integer(obj);
154 add_to_valid_bitfield(&ui64Type, 0);
155 }
156 if (json_object_object_get_ex(section, "processorISA", &obj)) {
157 section_cper->Isa = (UINT8)readable_pair_to_integer(obj);
158 add_to_valid_bitfield(&ui64Type, 1);
159 }
160 if (json_object_object_get_ex(section, "errorType", &obj)) {
161 section_cper->ErrorType = (UINT8)readable_pair_to_integer(obj);
162 add_to_valid_bitfield(&ui64Type, 2);
163 }
164 if (json_object_object_get_ex(section, "operation", &obj)) {
165 section_cper->Operation = (UINT8)readable_pair_to_integer(obj);
166 add_to_valid_bitfield(&ui64Type, 3);
167 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100168 //Flags.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800169 if (json_object_object_get_ex(section, "flags", &obj)) {
170 section_cper->Flags = (UINT8)ir_to_bitfield(
171 obj, 4, GENERIC_FLAGS_BITFIELD_NAMES);
172 add_to_valid_bitfield(&ui64Type, 4);
173 }
Lawrence Tang0cb33792022-07-13 13:51:39 +0100174
Lawrence Tange407b4c2022-07-21 13:54:01 +0100175 //Various numeric/string fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800176 if (json_object_object_get_ex(section, "level", &obj)) {
177 section_cper->Level = (UINT8)json_object_get_int(obj);
178 add_to_valid_bitfield(&ui64Type, 5);
179 }
180 if (json_object_object_get_ex(section, "cpuVersionInfo", &obj)) {
181 section_cper->VersionInfo = json_object_get_uint64(obj);
182 add_to_valid_bitfield(&ui64Type, 6);
183 }
184 if (json_object_object_get_ex(section, "processorID", &obj)) {
185 section_cper->ApicId = json_object_get_uint64(obj);
186 add_to_valid_bitfield(&ui64Type, 8);
187 }
188 if (json_object_object_get_ex(section, "targetAddress", &obj)) {
189 section_cper->TargetAddr = json_object_get_uint64(obj);
190 add_to_valid_bitfield(&ui64Type, 9);
191 }
192 if (json_object_object_get_ex(section, "requestorID", &obj)) {
193 section_cper->RequestorId = json_object_get_uint64(obj);
194 add_to_valid_bitfield(&ui64Type, 10);
195 }
196 if (json_object_object_get_ex(section, "responderID", &obj)) {
197 section_cper->ResponderId = json_object_get_uint64(obj);
198 add_to_valid_bitfield(&ui64Type, 11);
199 }
200 if (json_object_object_get_ex(section, "instructionIP", &obj)) {
201 section_cper->InstructionIP = json_object_get_uint64(obj);
202 add_to_valid_bitfield(&ui64Type, 12);
203 }
Lawrence Tang0cb33792022-07-13 13:51:39 +0100204
Lawrence Tange407b4c2022-07-21 13:54:01 +0100205 //CPU brand string.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800206 if (json_object_object_get_ex(section, "cpuBrandString", &obj)) {
207 const char *brand_string = json_object_get_string(obj);
208 if (brand_string != NULL) {
209 strncpy(section_cper->BrandString, brand_string,
210 sizeof(section_cper->BrandString) - 1);
211 section_cper
212 ->BrandString[sizeof(section_cper->BrandString) -
213 1] = '\0';
214 }
215 add_to_valid_bitfield(&ui64Type, 7);
John Chungf8fc7052024-05-03 20:05:29 +0800216 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800217 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100218
219 //Write & flush out to file, free memory.
220 fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out);
221 fflush(out);
222 free(section_cper);
John Chungf8fc7052024-05-03 20:05:29 +0800223}