blob: 7bbf56eae427df35e6ecec3c64c7b28e93206e8a [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 Tanous5aedbb22025-03-05 18:02:34 -080016json_object *cper_section_generic_to_ir(const void *section)
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010017{
Lawrence Tange407b4c2022-07-21 13:54:01 +010018 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic =
19 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
20 json_object *section_ir = json_object_new_object();
Lawrence Tang3c43f742022-07-05 11:37:17 +010021
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080022 ValidationTypes ui64Type = {
23 UINT_64T, .value.ui64 = section_generic->ValidFields
24 };
Lawrence Tang3c43f742022-07-05 11:37:17 +010025
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080026 if (isvalid_prop_to_ir(&ui64Type, 0)) {
27 //Processor type, with human readable name if possible.
28 json_object *processor_type = integer_to_readable_pair(
29 section_generic->Type,
30 sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
31 GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES,
32 "Unknown (Reserved)");
33 json_object_object_add(section_ir, "processorType",
34 processor_type);
35 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010036
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080037 if (isvalid_prop_to_ir(&ui64Type, 1)) {
38 //Processor ISA, with human readable name if possible.
39 json_object *processor_isa = integer_to_readable_pair(
40 section_generic->Isa,
41 sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
42 GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES,
43 "Unknown (Reserved)");
44 json_object_object_add(section_ir, "processorISA",
45 processor_isa);
46 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010047
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080048 if (isvalid_prop_to_ir(&ui64Type, 2)) {
49 //Processor error type, with human readable name if possible.
50 json_object *processor_error_type = integer_to_readable_pair(
51 section_generic->ErrorType,
52 sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
53 GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES,
54 "Unknown (Reserved)");
55 json_object_object_add(section_ir, "errorType",
56 processor_error_type);
57 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010058
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080059 if (isvalid_prop_to_ir(&ui64Type, 3)) {
60 //The operation performed, with a human readable name if possible.
61 json_object *operation = integer_to_readable_pair(
62 section_generic->Operation,
63 sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
64 GENERIC_OPERATION_TYPES_KEYS,
65 GENERIC_OPERATION_TYPES_VALUES, "Unknown (Reserved)");
66 json_object_object_add(section_ir, "operation", operation);
67 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010068
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080069 if (isvalid_prop_to_ir(&ui64Type, 4)) {
70 //Flags, additional information about the error.
71 json_object *flags =
72 bitfield_to_ir(section_generic->Flags, 4,
73 GENERIC_FLAGS_BITFIELD_NAMES);
74 json_object_object_add(section_ir, "flags", flags);
75 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010076
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080077 if (isvalid_prop_to_ir(&ui64Type, 5)) {
78 //The level of the error.
79 json_object_object_add(
80 section_ir, "level",
81 json_object_new_int(section_generic->Level));
82 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010083
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080084 if (isvalid_prop_to_ir(&ui64Type, 6)) {
85 //CPU version information.
86 json_object_object_add(
87 section_ir, "cpuVersionInfo",
88 json_object_new_uint64(section_generic->VersionInfo));
89 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010090
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080091 if (isvalid_prop_to_ir(&ui64Type, 7)) {
92 //CPU brand string. May not exist if on ARM.
93 json_object_object_add(
94 section_ir, "cpuBrandString",
95 json_object_new_string(section_generic->BrandString));
96 }
Lawrence Tang3c43f742022-07-05 11:37:17 +010097
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080098 if (isvalid_prop_to_ir(&ui64Type, 8)) {
99 //Remaining 64-bit fields.
100 json_object_object_add(
101 section_ir, "processorID",
102 json_object_new_uint64(section_generic->ApicId));
103 }
104
105 if (isvalid_prop_to_ir(&ui64Type, 9)) {
106 json_object_object_add(
107 section_ir, "targetAddress",
108 json_object_new_uint64(section_generic->TargetAddr));
109 }
110
111 if (isvalid_prop_to_ir(&ui64Type, 10)) {
112 json_object_object_add(
113 section_ir, "requestorID",
114 json_object_new_uint64(section_generic->RequestorId));
115 }
116
117 if (isvalid_prop_to_ir(&ui64Type, 11)) {
118 json_object_object_add(
119 section_ir, "responderID",
120 json_object_new_uint64(section_generic->ResponderId));
121 }
122
123 if (isvalid_prop_to_ir(&ui64Type, 12)) {
124 json_object_object_add(
125 section_ir, "instructionIP",
126 json_object_new_uint64(section_generic->InstructionIP));
127 }
Lawrence Tang3c43f742022-07-05 11:37:17 +0100128
Lawrence Tange407b4c2022-07-21 13:54:01 +0100129 return section_ir;
Lawrence Tang0cb33792022-07-13 13:51:39 +0100130}
131
132//Converts the given CPER-JSON processor-generic error section into CPER binary,
133//outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100134void ir_section_generic_to_cper(json_object *section, FILE *out)
Lawrence Tang0cb33792022-07-13 13:51:39 +0100135{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100136 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper =
137 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc(
138 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100139
Lawrence Tange407b4c2022-07-21 13:54:01 +0100140 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800141 //Remove
142 // section_cper->ValidFields = ir_to_bitfield(
143 // json_object_object_get(section, "validationBits"), 13,
144 // GENERIC_VALIDATION_BITFIELD_NAMES);
145 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
146 struct json_object *obj = NULL;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100147 //Various name/value pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800148 if (json_object_object_get_ex(section, "processorType", &obj)) {
149 section_cper->Type = (UINT8)readable_pair_to_integer(obj);
150 add_to_valid_bitfield(&ui64Type, 0);
151 }
152 if (json_object_object_get_ex(section, "processorISA", &obj)) {
153 section_cper->Isa = (UINT8)readable_pair_to_integer(obj);
154 add_to_valid_bitfield(&ui64Type, 1);
155 }
156 if (json_object_object_get_ex(section, "errorType", &obj)) {
157 section_cper->ErrorType = (UINT8)readable_pair_to_integer(obj);
158 add_to_valid_bitfield(&ui64Type, 2);
159 }
160 if (json_object_object_get_ex(section, "operation", &obj)) {
161 section_cper->Operation = (UINT8)readable_pair_to_integer(obj);
162 add_to_valid_bitfield(&ui64Type, 3);
163 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100164 //Flags.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800165 if (json_object_object_get_ex(section, "flags", &obj)) {
166 section_cper->Flags = (UINT8)ir_to_bitfield(
167 obj, 4, GENERIC_FLAGS_BITFIELD_NAMES);
168 add_to_valid_bitfield(&ui64Type, 4);
169 }
Lawrence Tang0cb33792022-07-13 13:51:39 +0100170
Lawrence Tange407b4c2022-07-21 13:54:01 +0100171 //Various numeric/string fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800172 if (json_object_object_get_ex(section, "level", &obj)) {
173 section_cper->Level = (UINT8)json_object_get_int(obj);
174 add_to_valid_bitfield(&ui64Type, 5);
175 }
176 if (json_object_object_get_ex(section, "cpuVersionInfo", &obj)) {
177 section_cper->VersionInfo = json_object_get_uint64(obj);
178 add_to_valid_bitfield(&ui64Type, 6);
179 }
180 if (json_object_object_get_ex(section, "processorID", &obj)) {
181 section_cper->ApicId = json_object_get_uint64(obj);
182 add_to_valid_bitfield(&ui64Type, 8);
183 }
184 if (json_object_object_get_ex(section, "targetAddress", &obj)) {
185 section_cper->TargetAddr = json_object_get_uint64(obj);
186 add_to_valid_bitfield(&ui64Type, 9);
187 }
188 if (json_object_object_get_ex(section, "requestorID", &obj)) {
189 section_cper->RequestorId = json_object_get_uint64(obj);
190 add_to_valid_bitfield(&ui64Type, 10);
191 }
192 if (json_object_object_get_ex(section, "responderID", &obj)) {
193 section_cper->ResponderId = json_object_get_uint64(obj);
194 add_to_valid_bitfield(&ui64Type, 11);
195 }
196 if (json_object_object_get_ex(section, "instructionIP", &obj)) {
197 section_cper->InstructionIP = json_object_get_uint64(obj);
198 add_to_valid_bitfield(&ui64Type, 12);
199 }
Lawrence Tang0cb33792022-07-13 13:51:39 +0100200
Lawrence Tange407b4c2022-07-21 13:54:01 +0100201 //CPU brand string.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800202 if (json_object_object_get_ex(section, "cpuBrandString", &obj)) {
203 const char *brand_string = json_object_get_string(obj);
204 if (brand_string != NULL) {
205 strncpy(section_cper->BrandString, brand_string,
206 sizeof(section_cper->BrandString) - 1);
207 section_cper
208 ->BrandString[sizeof(section_cper->BrandString) -
209 1] = '\0';
210 }
211 add_to_valid_bitfield(&ui64Type, 7);
John Chungf8fc7052024-05-03 20:05:29 +0800212 }
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800213 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100214
215 //Write & flush out to file, free memory.
216 fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out);
217 fflush(out);
218 free(section_cper);
John Chungf8fc7052024-05-03 20:05:29 +0800219}