blob: 2206d2aa4fdefd49ea8166fc9731f89dea2f9313 [file] [log] [blame]
Lawrence Tang794312c2022-07-05 14:46:10 +01001/**
2 * Describes functions for converting IA32/x64 CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang794312c2022-07-05 14:46:10 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7
8#include <stdio.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01009#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +000010#include <libcper/base64.h>
11#include <libcper/Cper.h>
12#include <libcper/cper-utils.h>
13#include <libcper/sections/cper-section-ia32x64.h>
Ed Tanous50b966f2025-03-11 09:06:19 -070014#include <libcper/log.h>
Lawrence Tang794312c2022-07-05 14:46:10 +010015
16//Private pre-definitions.
Lawrence Tange407b4c2022-07-21 13:54:01 +010017json_object *cper_ia32x64_processor_error_info_to_ir(
18 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info);
19json_object *cper_ia32x64_cache_tlb_check_to_ir(
20 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check);
21json_object *
22cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check);
23json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check);
24json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -080025 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
26 UINT32 *remaining_size);
Lawrence Tange407b4c2022-07-21 13:54:01 +010027json_object *
28cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers);
29json_object *
30cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers);
31void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out);
32void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out);
33void ir_ia32x64_cache_tlb_check_error_to_cper(
34 json_object *check_info,
35 EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper);
36void ir_ia32x64_bus_check_error_to_cper(
37 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper);
38void ir_ia32x64_ms_check_error_to_cper(
39 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper);
40void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out);
41void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out);
Lawrence Tangd0c88842022-07-13 14:51:17 +010042
43//////////////////
44/// CPER TO IR ///
45//////////////////
Lawrence Tang794312c2022-07-05 14:46:10 +010046
47//Converts the IA32/x64 error section described in the given descriptor into intermediate format.
Ed Tanous12dbd4f2025-03-08 19:05:01 -080048json_object *cper_section_ia32x64_to_ir(const UINT8 *section, UINT32 size)
Lawrence Tang794312c2022-07-05 14:46:10 +010049{
Ed Tanous12dbd4f2025-03-08 19:05:01 -080050 if (size < sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD)) {
51 return NULL;
52 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010053 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *record =
54 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)section;
Ed Tanous12dbd4f2025-03-08 19:05:01 -080055 UINT32 remaining_size =
56 size - sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD);
Lawrence Tange407b4c2022-07-21 13:54:01 +010057 json_object *record_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +010058
Lawrence Tange407b4c2022-07-21 13:54:01 +010059 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080060 //validation bits contain information
61 //about processorErrorInfoNum and processorContextInfoNum.
62 //Ensure this is decoded properly in IR->CPER
John Chungf8fc7052024-05-03 20:05:29 +080063 int processor_error_info_num = (record->ValidFields >> 2) & 0x3F;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080064 json_object_object_add(record_ir, "processorErrorInfoNum",
Lawrence Tange407b4c2022-07-21 13:54:01 +010065 json_object_new_int(processor_error_info_num));
John Chungf8fc7052024-05-03 20:05:29 +080066 int processor_context_info_num = (record->ValidFields >> 8) & 0x3F;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080067 json_object_object_add(record_ir, "processorContextInfoNum",
Lawrence Tange407b4c2022-07-21 13:54:01 +010068 json_object_new_int(processor_context_info_num));
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080069
70 ValidationTypes ui64Type = { UINT_64T,
71 .value.ui64 = record->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +010072
Lawrence Tange407b4c2022-07-21 13:54:01 +010073 //APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080074 if (isvalid_prop_to_ir(&ui64Type, 0)) {
75 json_object_object_add(record_ir, "localAPICID",
76 json_object_new_uint64(record->ApicId));
77 }
Lawrence Tang794312c2022-07-05 14:46:10 +010078
Lawrence Tange407b4c2022-07-21 13:54:01 +010079 //CPUID information.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -080080 if (isvalid_prop_to_ir(&ui64Type, 1)) {
81 json_object *cpuid_info_ir = json_object_new_object();
82 EFI_IA32_X64_CPU_ID *cpuid_info =
83 (EFI_IA32_X64_CPU_ID *)record->CpuIdInfo;
84 json_object_object_add(cpuid_info_ir, "eax",
85 json_object_new_uint64(cpuid_info->Eax));
86 json_object_object_add(cpuid_info_ir, "ebx",
87 json_object_new_uint64(cpuid_info->Ebx));
88 json_object_object_add(cpuid_info_ir, "ecx",
89 json_object_new_uint64(cpuid_info->Ecx));
90 json_object_object_add(cpuid_info_ir, "edx",
91 json_object_new_uint64(cpuid_info->Edx));
92 json_object_object_add(record_ir, "cpuidInfo", cpuid_info_ir);
93 }
Lawrence Tang794312c2022-07-05 14:46:10 +010094
Lawrence Tange407b4c2022-07-21 13:54:01 +010095 //Processor error information, of the amount described above.
96 EFI_IA32_X64_PROCESS_ERROR_INFO *current_error_info =
97 (EFI_IA32_X64_PROCESS_ERROR_INFO *)(record + 1);
98 json_object *error_info_array = json_object_new_array();
Ed Tanous12dbd4f2025-03-08 19:05:01 -080099 if (remaining_size < (processor_error_info_num *
100 sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO))) {
101 json_object_put(error_info_array);
102 json_object_put(record_ir);
Ed Tanous50b966f2025-03-11 09:06:19 -0700103 cper_print_log(
104 "Invalid CPER file: Invalid processor error info num.\n");
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800105 return NULL;
106 }
107
Lawrence Tange407b4c2022-07-21 13:54:01 +0100108 for (int i = 0; i < processor_error_info_num; i++) {
109 json_object_array_add(error_info_array,
110 cper_ia32x64_processor_error_info_to_ir(
111 current_error_info));
112 current_error_info++;
113 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800114 remaining_size -= processor_error_info_num *
115 sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO);
116
Lawrence Tange407b4c2022-07-21 13:54:01 +0100117 json_object_object_add(record_ir, "processorErrorInfo",
118 error_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100119
Lawrence Tange407b4c2022-07-21 13:54:01 +0100120 //Processor context information, of the amount described above.
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800121 if (remaining_size < (processor_context_info_num *
122 sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO))) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800123 json_object_put(record_ir);
Ed Tanous50b966f2025-03-11 09:06:19 -0700124 cper_print_log(
125 "Invalid CPER file: Invalid processor context info num.\n");
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800126 return NULL;
127 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100128 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *current_context_info =
129 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)current_error_info;
130 void *cur_pos = (void *)current_context_info;
131 json_object *context_info_array = json_object_new_array();
132 for (int i = 0; i < processor_context_info_num; i++) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700133 json_object *context_info =
134 cper_ia32x64_processor_context_info_to_ir(
135 current_context_info, &cur_pos,
136 &remaining_size);
137 if (context_info == NULL) {
138 context_info = json_object_new_object();
139 }
140 json_object_array_add(context_info_array, context_info);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100141 current_context_info =
142 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)cur_pos;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800143
Lawrence Tange407b4c2022-07-21 13:54:01 +0100144 //The context array is a non-fixed size, pointer is shifted within the above function.
145 }
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800146
Lawrence Tange407b4c2022-07-21 13:54:01 +0100147 json_object_object_add(record_ir, "processorContextInfo",
148 context_info_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100149
Lawrence Tange407b4c2022-07-21 13:54:01 +0100150 return record_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100151}
152
Ed Tanous1a648562025-03-10 15:23:38 -0700153EFI_GUID *gEfiIa32x64ErrorTypeGuids[] = {
154 &gEfiIa32x64ErrorTypeCacheCheckGuid,
155 &gEfiIa32x64ErrorTypeTlbCheckGuid,
156 &gEfiIa32x64ErrorTypeBusCheckGuid,
157 &gEfiIa32x64ErrorTypeMsCheckGuid,
158};
159
Lawrence Tang794312c2022-07-05 14:46:10 +0100160//Converts a single IA32/x64 processor error info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100161json_object *cper_ia32x64_processor_error_info_to_ir(
162 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info)
Lawrence Tang794312c2022-07-05 14:46:10 +0100163{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100164 json_object *error_info_ir = json_object_new_object();
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700165 json_object *type = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100166
Lawrence Tange407b4c2022-07-21 13:54:01 +0100167 //Error structure type (as GUID).
Ed Tanousc2ebddd2025-03-09 10:07:01 -0700168 add_guid(type, "guid", &error_info->ErrorType);
Lawrence Tang794312c2022-07-05 14:46:10 +0100169
Lawrence Tang3592da72022-07-21 16:50:07 +0100170 //Get the error structure type as a readable string.
171 const char *readable_type = "Unknown";
Ed Tanous1a648562025-03-10 15:23:38 -0700172
173 const char *readable_names[] = {
174 "Cache Check Error",
175 "TLB Check Error",
176 "Bus Check Error",
177 "MS Check Error",
178 };
179
180 int index = select_guid_from_list(
181 &error_info->ErrorType, gEfiIa32x64ErrorTypeGuids,
182 sizeof(gEfiIa32x64ErrorTypeGuids) / sizeof(EFI_GUID *));
183
184 if (index < (int)(sizeof(readable_names) / sizeof(char *))) {
185 readable_type = readable_names[index];
John Chungf8fc7052024-05-03 20:05:29 +0800186 }
Ed Tanous1a648562025-03-10 15:23:38 -0700187
John Chungf8fc7052024-05-03 20:05:29 +0800188 json_object_object_add(type, "name",
189 json_object_new_string(readable_type));
Lawrence Tang3592da72022-07-21 16:50:07 +0100190 json_object_object_add(error_info_ir, "type", type);
191
Lawrence Tange407b4c2022-07-21 13:54:01 +0100192 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800193 ValidationTypes ui64Type = { UINT_64T,
194 .value.ui64 = error_info->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100195
Lawrence Tange407b4c2022-07-21 13:54:01 +0100196 //Add the check information on a per-structure basis.
197 //Cache and TLB check information are identical, so can be equated.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800198 if (isvalid_prop_to_ir(&ui64Type, 0)) {
199 json_object *check_information = NULL;
Ed Tanous1a648562025-03-10 15:23:38 -0700200
201 switch (index) {
202 case 0:
203 case 1:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800204 check_information = cper_ia32x64_cache_tlb_check_to_ir(
205 (EFI_IA32_X64_CACHE_CHECK_INFO *)&error_info
206 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700207 break;
208 case 2:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800209 check_information = cper_ia32x64_bus_check_to_ir(
210 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info
211 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700212 break;
213 case 3:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800214 check_information = cper_ia32x64_ms_check_to_ir(
215 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info
216 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700217 break;
218 default:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800219 //Unknown check information.
Ed Tanous50b966f2025-03-11 09:06:19 -0700220 cper_print_log(
221 "WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
Ed Tanous1a648562025-03-10 15:23:38 -0700222 break;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800223 }
Ed Tanous1a648562025-03-10 15:23:38 -0700224
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800225 json_object_object_add(error_info_ir, "checkInfo",
226 check_information);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100227 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100228
Lawrence Tange407b4c2022-07-21 13:54:01 +0100229 //Target, requestor, and responder identifiers.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800230 if (isvalid_prop_to_ir(&ui64Type, 1)) {
231 json_object_object_add(
232 error_info_ir, "targetAddressID",
233 json_object_new_uint64(error_info->TargetId));
234 }
235 if (isvalid_prop_to_ir(&ui64Type, 2)) {
236 json_object_object_add(
237 error_info_ir, "requestorID",
238 json_object_new_uint64(error_info->RequestorId));
239 }
240 if (isvalid_prop_to_ir(&ui64Type, 3)) {
241 json_object_object_add(
242 error_info_ir, "responderID",
243 json_object_new_uint64(error_info->ResponderId));
244 }
245 if (isvalid_prop_to_ir(&ui64Type, 4)) {
246 json_object_object_add(
247 error_info_ir, "instructionPointer",
248 json_object_new_uint64(error_info->InstructionIP));
249 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100250
Lawrence Tange407b4c2022-07-21 13:54:01 +0100251 return error_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100252}
253
254//Converts a single IA32/x64 cache or TLB check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100255json_object *cper_ia32x64_cache_tlb_check_to_ir(
256 EFI_IA32_X64_CACHE_CHECK_INFO *cache_tlb_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100257{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100258 json_object *cache_tlb_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100259
Lawrence Tange407b4c2022-07-21 13:54:01 +0100260 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800261 ValidationTypes ui64Type = {
262 UINT_64T, .value.ui64 = cache_tlb_check->ValidFields
263 };
Lawrence Tang794312c2022-07-05 14:46:10 +0100264
Lawrence Tange407b4c2022-07-21 13:54:01 +0100265 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800266 if (isvalid_prop_to_ir(&ui64Type, 0)) {
267 json_object *transaction_type = integer_to_readable_pair(
268 cache_tlb_check->TransactionType, 3,
269 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
270 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
271 "Unknown (Reserved)");
272 json_object_object_add(cache_tlb_check_ir, "transactionType",
273 transaction_type);
274 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100275
Lawrence Tange407b4c2022-07-21 13:54:01 +0100276 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800277 if (isvalid_prop_to_ir(&ui64Type, 1)) {
278 json_object *operation = integer_to_readable_pair(
279 cache_tlb_check->Operation, 9,
280 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
281 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
282 "Unknown (Reserved)");
283 json_object_object_add(cache_tlb_check_ir, "operation",
284 operation);
285 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100286
Lawrence Tange407b4c2022-07-21 13:54:01 +0100287 //Affected cache/TLB level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800288 if (isvalid_prop_to_ir(&ui64Type, 2)) {
289 json_object_object_add(
290 cache_tlb_check_ir, "level",
291 json_object_new_uint64(cache_tlb_check->Level));
292 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100293
Lawrence Tange407b4c2022-07-21 13:54:01 +0100294 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800295 if (isvalid_prop_to_ir(&ui64Type, 3)) {
296 json_object_object_add(
297 cache_tlb_check_ir, "processorContextCorrupt",
298 json_object_new_boolean(
299 cache_tlb_check->ContextCorrupt));
300 }
301 if (isvalid_prop_to_ir(&ui64Type, 4)) {
302 json_object_object_add(
303 cache_tlb_check_ir, "uncorrected",
304 json_object_new_boolean(
305 cache_tlb_check->ErrorUncorrected));
306 }
307 if (isvalid_prop_to_ir(&ui64Type, 5)) {
308 json_object_object_add(
309 cache_tlb_check_ir, "preciseIP",
310 json_object_new_boolean(cache_tlb_check->PreciseIp));
311 }
312 if (isvalid_prop_to_ir(&ui64Type, 6)) {
313 json_object_object_add(cache_tlb_check_ir, "restartableIP",
314 json_object_new_boolean(
315 cache_tlb_check->RestartableIp));
316 }
317 if (isvalid_prop_to_ir(&ui64Type, 7)) {
318 json_object_object_add(
319 cache_tlb_check_ir, "overflow",
320 json_object_new_boolean(cache_tlb_check->Overflow));
321 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100322
Lawrence Tange407b4c2022-07-21 13:54:01 +0100323 return cache_tlb_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100324}
325
326//Converts a single IA32/x64 bus check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100327json_object *
328cper_ia32x64_bus_check_to_ir(EFI_IA32_X64_BUS_CHECK_INFO *bus_check)
329{
330 json_object *bus_check_ir = json_object_new_object();
Lawrence Tang794312c2022-07-05 14:46:10 +0100331
Lawrence Tange407b4c2022-07-21 13:54:01 +0100332 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800333 ValidationTypes ui64Type = { UINT_64T,
334 .value.ui64 = bus_check->ValidFields };
Lawrence Tang794312c2022-07-05 14:46:10 +0100335
Lawrence Tange407b4c2022-07-21 13:54:01 +0100336 //Transaction type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800337 if (isvalid_prop_to_ir(&ui64Type, 0)) {
338 json_object *transaction_type = integer_to_readable_pair(
339 bus_check->TransactionType, 3,
340 IA32X64_CHECK_INFO_TRANSACTION_TYPES_KEYS,
341 IA32X64_CHECK_INFO_TRANSACTION_TYPES_VALUES,
342 "Unknown (Reserved)");
343 json_object_object_add(bus_check_ir, "transactionType",
344 transaction_type);
345 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100346
Lawrence Tange407b4c2022-07-21 13:54:01 +0100347 //Operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800348 if (isvalid_prop_to_ir(&ui64Type, 1)) {
349 json_object *operation = integer_to_readable_pair(
350 bus_check->Operation, 9,
351 IA32X64_CHECK_INFO_OPERATION_TYPES_KEYS,
352 IA32X64_CHECK_INFO_OPERATION_TYPES_VALUES,
353 "Unknown (Reserved)");
354 json_object_object_add(bus_check_ir, "operation", operation);
355 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100356
Lawrence Tange407b4c2022-07-21 13:54:01 +0100357 //Affected bus level.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800358 if (isvalid_prop_to_ir(&ui64Type, 2)) {
359 json_object_object_add(
360 bus_check_ir, "level",
361 json_object_new_uint64(bus_check->Level));
362 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100363
Lawrence Tange407b4c2022-07-21 13:54:01 +0100364 //Miscellaneous boolean fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800365 if (isvalid_prop_to_ir(&ui64Type, 3)) {
366 json_object_object_add(
367 bus_check_ir, "processorContextCorrupt",
368 json_object_new_boolean(bus_check->ContextCorrupt));
369 }
370 if (isvalid_prop_to_ir(&ui64Type, 4)) {
371 json_object_object_add(
372 bus_check_ir, "uncorrected",
373 json_object_new_boolean(bus_check->ErrorUncorrected));
374 }
375 if (isvalid_prop_to_ir(&ui64Type, 5)) {
376 json_object_object_add(
377 bus_check_ir, "preciseIP",
378 json_object_new_boolean(bus_check->PreciseIp));
379 }
380 if (isvalid_prop_to_ir(&ui64Type, 6)) {
381 json_object_object_add(
382 bus_check_ir, "restartableIP",
383 json_object_new_boolean(bus_check->RestartableIp));
384 }
385 if (isvalid_prop_to_ir(&ui64Type, 7)) {
386 json_object_object_add(
387 bus_check_ir, "overflow",
388 json_object_new_boolean(bus_check->Overflow));
389 }
390 if (isvalid_prop_to_ir(&ui64Type, 9)) {
391 json_object_object_add(
392 bus_check_ir, "timedOut",
393 json_object_new_boolean(bus_check->TimeOut));
394 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100395
Lawrence Tange407b4c2022-07-21 13:54:01 +0100396 //Participation type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800397 if (isvalid_prop_to_ir(&ui64Type, 8)) {
398 json_object *participation_type = integer_to_readable_pair(
399 bus_check->ParticipationType, 4,
400 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_KEYS,
401 IA32X64_BUS_CHECK_INFO_PARTICIPATION_TYPES_VALUES,
402 "Unknown");
403 json_object_object_add(bus_check_ir, "participationType",
404 participation_type);
405 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100406
Lawrence Tange407b4c2022-07-21 13:54:01 +0100407 //Address space.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800408 if (isvalid_prop_to_ir(&ui64Type, 10)) {
409 json_object *address_space = integer_to_readable_pair(
410 bus_check->AddressSpace, 4,
411 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_KEYS,
412 IA32X64_BUS_CHECK_INFO_ADDRESS_SPACE_TYPES_VALUES,
413 "Unknown");
414 json_object_object_add(bus_check_ir, "addressSpace",
415 address_space);
416 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100417
418 return bus_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100419}
420
421//Converts a single IA32/x64 MS check check info block into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100422json_object *cper_ia32x64_ms_check_to_ir(EFI_IA32_X64_MS_CHECK_INFO *ms_check)
Lawrence Tang794312c2022-07-05 14:46:10 +0100423{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100424 json_object *ms_check_ir = json_object_new_object();
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800425 ValidationTypes ui64Type = { UINT_64T,
426 .value.ui64 = ms_check->ValidFields };
Lawrence Tange407b4c2022-07-21 13:54:01 +0100427 //Validation bits.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100428 //Error type (operation that caused the error).
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800429 if (isvalid_prop_to_ir(&ui64Type, 0)) {
430 json_object *error_type = integer_to_readable_pair(
431 ms_check->ErrorType, 4,
432 IA32X64_MS_CHECK_INFO_ERROR_TYPES_KEYS,
433 IA32X64_MS_CHECK_INFO_ERROR_TYPES_VALUES,
434 "Unknown (Processor Specific)");
435 json_object_object_add(ms_check_ir, "errorType", error_type);
436 }
Lawrence Tang794312c2022-07-05 14:46:10 +0100437
Lawrence Tange407b4c2022-07-21 13:54:01 +0100438 //Miscellaneous fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800439 if (isvalid_prop_to_ir(&ui64Type, 1)) {
440 json_object_object_add(
441 ms_check_ir, "processorContextCorrupt",
442 json_object_new_boolean(ms_check->ContextCorrupt));
443 }
444 if (isvalid_prop_to_ir(&ui64Type, 2)) {
445 json_object_object_add(
446 ms_check_ir, "uncorrected",
447 json_object_new_boolean(ms_check->ErrorUncorrected));
448 }
449 if (isvalid_prop_to_ir(&ui64Type, 3)) {
450 json_object_object_add(
451 ms_check_ir, "preciseIP",
452 json_object_new_boolean(ms_check->PreciseIp));
453 }
454 if (isvalid_prop_to_ir(&ui64Type, 4)) {
455 json_object_object_add(
456 ms_check_ir, "restartableIP",
457 json_object_new_boolean(ms_check->RestartableIp));
458 }
459 if (isvalid_prop_to_ir(&ui64Type, 5)) {
460 json_object_object_add(
461 ms_check_ir, "overflow",
462 json_object_new_boolean(ms_check->Overflow));
463 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100464
465 return ms_check_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100466}
467
468//Converts a single IA32/x64 processor context info entry into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100469json_object *cper_ia32x64_processor_context_info_to_ir(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800470 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info, void **cur_pos,
471 UINT32 *remaining_size)
Lawrence Tang794312c2022-07-05 14:46:10 +0100472{
Ed Tanousd6b62632025-03-14 15:30:07 -0700473 json_object *context_info_ir = json_object_new_object();
474
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800475 if (*remaining_size < sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO)) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700476 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800477 }
478 *remaining_size -= sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO);
Lawrence Tang794312c2022-07-05 14:46:10 +0100479
Lawrence Tange407b4c2022-07-21 13:54:01 +0100480 //Register context type.
481 json_object *context_type = integer_to_readable_pair(
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800482 context_info->RegisterType, IA32X64_REGISTER_CONTEXT_TYPES_SIZE,
Lawrence Tange407b4c2022-07-21 13:54:01 +0100483 IA32X64_REGISTER_CONTEXT_TYPES_KEYS,
484 IA32X64_REGISTER_CONTEXT_TYPES_VALUES, "Unknown (Reserved)");
485 json_object_object_add(context_info_ir, "registerContextType",
486 context_type);
Lawrence Tang794312c2022-07-05 14:46:10 +0100487
Lawrence Tange407b4c2022-07-21 13:54:01 +0100488 //Register array size, MSR and MM address.
489 json_object_object_add(context_info_ir, "registerArraySize",
490 json_object_new_uint64(context_info->ArraySize));
491 json_object_object_add(
492 context_info_ir, "msrAddress",
493 json_object_new_uint64(context_info->MsrAddress));
494 json_object_object_add(
495 context_info_ir, "mmRegisterAddress",
496 json_object_new_uint64(context_info->MmRegisterAddress));
Lawrence Tang794312c2022-07-05 14:46:10 +0100497
Lawrence Tange407b4c2022-07-21 13:54:01 +0100498 //Register array.
499 json_object *register_array = NULL;
500 if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800501 if (*remaining_size < sizeof(EFI_CONTEXT_IA32_REGISTER_STATE)) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700502 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800503 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100504 EFI_CONTEXT_IA32_REGISTER_STATE *register_state =
505 (EFI_CONTEXT_IA32_REGISTER_STATE *)(context_info + 1);
506 register_array =
507 cper_ia32x64_register_32bit_to_ir(register_state);
508 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800509 *remaining_size -= sizeof(EFI_CONTEXT_IA32_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100510 } else if (context_info->RegisterType == EFI_REG_CONTEXT_TYPE_X64) {
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800511 if (*remaining_size < sizeof(EFI_CONTEXT_X64_REGISTER_STATE)) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700512 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800513 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100514 EFI_CONTEXT_X64_REGISTER_STATE *register_state =
515 (EFI_CONTEXT_X64_REGISTER_STATE *)(context_info + 1);
516 register_array =
517 cper_ia32x64_register_64bit_to_ir(register_state);
518 *cur_pos = (void *)(register_state + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800519 *remaining_size -= sizeof(EFI_CONTEXT_X64_REGISTER_STATE);
Lawrence Tange407b4c2022-07-21 13:54:01 +0100520 } else {
521 //No parseable data, just dump as base64 and shift the head to the next item.
522 *cur_pos = (void *)(context_info + 1);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800523 if (*remaining_size < context_info->ArraySize) {
Ed Tanousd6b62632025-03-14 15:30:07 -0700524 return context_info_ir;
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800525 }
Ed Tanousa7d2cdd2024-07-15 11:07:27 -0700526 int32_t encoded_len = 0;
527 char *encoded = base64_encode((UINT8 *)*cur_pos,
528 context_info->ArraySize,
529 &encoded_len);
530 if (encoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -0700531 cper_print_log(
532 "Failed to allocate encode output buffer. \n");
John Chungf8fc7052024-05-03 20:05:29 +0800533 } else {
John Chungf8fc7052024-05-03 20:05:29 +0800534 register_array = json_object_new_object();
535 json_object_object_add(register_array, "data",
536 json_object_new_string_len(
537 encoded, encoded_len));
538 free(encoded);
539 }
Lawrence Tangd7e8ca32022-07-07 10:25:53 +0100540
Lawrence Tange407b4c2022-07-21 13:54:01 +0100541 *cur_pos =
542 (void *)(((char *)*cur_pos) + context_info->ArraySize);
Ed Tanous12dbd4f2025-03-08 19:05:01 -0800543 *remaining_size -= context_info->ArraySize;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100544 }
545 json_object_object_add(context_info_ir, "registerArray",
546 register_array);
Lawrence Tang794312c2022-07-05 14:46:10 +0100547
Lawrence Tange407b4c2022-07-21 13:54:01 +0100548 return context_info_ir;
Lawrence Tang794312c2022-07-05 14:46:10 +0100549}
550
551//Converts a single CPER IA32 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100552json_object *
553cper_ia32x64_register_32bit_to_ir(EFI_CONTEXT_IA32_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100554{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100555 json_object *ia32_registers = json_object_new_object();
556 json_object_object_add(ia32_registers, "eax",
557 json_object_new_uint64(registers->Eax));
558 json_object_object_add(ia32_registers, "ebx",
559 json_object_new_uint64(registers->Ebx));
560 json_object_object_add(ia32_registers, "ecx",
561 json_object_new_uint64(registers->Ecx));
562 json_object_object_add(ia32_registers, "edx",
563 json_object_new_uint64(registers->Edx));
564 json_object_object_add(ia32_registers, "esi",
565 json_object_new_uint64(registers->Esi));
566 json_object_object_add(ia32_registers, "edi",
567 json_object_new_uint64(registers->Edi));
568 json_object_object_add(ia32_registers, "ebp",
569 json_object_new_uint64(registers->Ebp));
570 json_object_object_add(ia32_registers, "esp",
571 json_object_new_uint64(registers->Esp));
572 json_object_object_add(ia32_registers, "cs",
573 json_object_new_uint64(registers->Cs));
574 json_object_object_add(ia32_registers, "ds",
575 json_object_new_uint64(registers->Ds));
576 json_object_object_add(ia32_registers, "ss",
577 json_object_new_uint64(registers->Ss));
578 json_object_object_add(ia32_registers, "es",
579 json_object_new_uint64(registers->Es));
580 json_object_object_add(ia32_registers, "fs",
581 json_object_new_uint64(registers->Fs));
582 json_object_object_add(ia32_registers, "gs",
583 json_object_new_uint64(registers->Gs));
584 json_object_object_add(ia32_registers, "eflags",
585 json_object_new_uint64(registers->Eflags));
586 json_object_object_add(ia32_registers, "eip",
587 json_object_new_uint64(registers->Eip));
588 json_object_object_add(ia32_registers, "cr0",
589 json_object_new_uint64(registers->Cr0));
590 json_object_object_add(ia32_registers, "cr1",
591 json_object_new_uint64(registers->Cr1));
592 json_object_object_add(ia32_registers, "cr2",
593 json_object_new_uint64(registers->Cr2));
594 json_object_object_add(ia32_registers, "cr3",
595 json_object_new_uint64(registers->Cr3));
596 json_object_object_add(ia32_registers, "cr4",
597 json_object_new_uint64(registers->Cr4));
598 json_object_object_add(
599 ia32_registers, "gdtr",
600 json_object_new_uint64(registers->Gdtr[0] +
601 ((UINT64)registers->Gdtr[1] << 32)));
602 json_object_object_add(
603 ia32_registers, "idtr",
604 json_object_new_uint64(registers->Idtr[0] +
605 ((UINT64)registers->Idtr[1] << 32)));
606 json_object_object_add(ia32_registers, "ldtr",
607 json_object_new_uint64(registers->Ldtr));
608 json_object_object_add(ia32_registers, "tr",
609 json_object_new_uint64(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100610
Lawrence Tange407b4c2022-07-21 13:54:01 +0100611 return ia32_registers;
Lawrence Tang794312c2022-07-05 14:46:10 +0100612}
613
614//Converts a single CPER x64 register state into JSON IR format.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100615json_object *
616cper_ia32x64_register_64bit_to_ir(EFI_CONTEXT_X64_REGISTER_STATE *registers)
Lawrence Tang794312c2022-07-05 14:46:10 +0100617{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100618 json_object *x64_registers = json_object_new_object();
619 json_object_object_add(x64_registers, "rax",
620 json_object_new_uint64(registers->Rax));
621 json_object_object_add(x64_registers, "rbx",
622 json_object_new_uint64(registers->Rbx));
623 json_object_object_add(x64_registers, "rcx",
624 json_object_new_uint64(registers->Rcx));
625 json_object_object_add(x64_registers, "rdx",
626 json_object_new_uint64(registers->Rdx));
627 json_object_object_add(x64_registers, "rsi",
628 json_object_new_uint64(registers->Rsi));
629 json_object_object_add(x64_registers, "rdi",
630 json_object_new_uint64(registers->Rdi));
631 json_object_object_add(x64_registers, "rbp",
632 json_object_new_uint64(registers->Rbp));
633 json_object_object_add(x64_registers, "rsp",
634 json_object_new_uint64(registers->Rsp));
635 json_object_object_add(x64_registers, "r8",
636 json_object_new_uint64(registers->R8));
637 json_object_object_add(x64_registers, "r9",
638 json_object_new_uint64(registers->R9));
639 json_object_object_add(x64_registers, "r10",
640 json_object_new_uint64(registers->R10));
641 json_object_object_add(x64_registers, "r11",
642 json_object_new_uint64(registers->R11));
643 json_object_object_add(x64_registers, "r12",
644 json_object_new_uint64(registers->R12));
645 json_object_object_add(x64_registers, "r13",
646 json_object_new_uint64(registers->R13));
647 json_object_object_add(x64_registers, "r14",
648 json_object_new_uint64(registers->R14));
649 json_object_object_add(x64_registers, "r15",
650 json_object_new_uint64(registers->R15));
651 json_object_object_add(x64_registers, "cs",
652 json_object_new_int(registers->Cs));
653 json_object_object_add(x64_registers, "ds",
654 json_object_new_int(registers->Ds));
655 json_object_object_add(x64_registers, "ss",
656 json_object_new_int(registers->Ss));
657 json_object_object_add(x64_registers, "es",
658 json_object_new_int(registers->Es));
659 json_object_object_add(x64_registers, "fs",
660 json_object_new_int(registers->Fs));
661 json_object_object_add(x64_registers, "gs",
662 json_object_new_int(registers->Gs));
663 json_object_object_add(x64_registers, "rflags",
664 json_object_new_uint64(registers->Rflags));
665 json_object_object_add(x64_registers, "eip",
666 json_object_new_uint64(registers->Rip));
667 json_object_object_add(x64_registers, "cr0",
668 json_object_new_uint64(registers->Cr0));
669 json_object_object_add(x64_registers, "cr1",
670 json_object_new_uint64(registers->Cr1));
671 json_object_object_add(x64_registers, "cr2",
672 json_object_new_uint64(registers->Cr2));
673 json_object_object_add(x64_registers, "cr3",
674 json_object_new_uint64(registers->Cr3));
675 json_object_object_add(x64_registers, "cr4",
676 json_object_new_uint64(registers->Cr4));
677 json_object_object_add(x64_registers, "cr8",
678 json_object_new_uint64(registers->Cr8));
679 json_object_object_add(x64_registers, "gdtr_0",
680 json_object_new_uint64(registers->Gdtr[0]));
681 json_object_object_add(x64_registers, "gdtr_1",
682 json_object_new_uint64(registers->Gdtr[1]));
683 json_object_object_add(x64_registers, "idtr_0",
684 json_object_new_uint64(registers->Idtr[0]));
685 json_object_object_add(x64_registers, "idtr_1",
686 json_object_new_uint64(registers->Idtr[1]));
687 json_object_object_add(x64_registers, "ldtr",
688 json_object_new_int(registers->Ldtr));
689 json_object_object_add(x64_registers, "tr",
690 json_object_new_int(registers->Tr));
Lawrence Tang794312c2022-07-05 14:46:10 +0100691
Lawrence Tange407b4c2022-07-21 13:54:01 +0100692 return x64_registers;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100693}
694
695//////////////////
696/// IR TO CPER ///
697//////////////////
698
699//Converts a single IA32/x64 CPER-JSON section into CPER binary, outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100700void ir_section_ia32x64_to_cper(json_object *section, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100701{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100702 EFI_IA32_X64_PROCESSOR_ERROR_RECORD *section_cper =
703 (EFI_IA32_X64_PROCESSOR_ERROR_RECORD *)calloc(
704 1, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100705
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800706 uint64_t valid = 0x0;
707
708 int proc_error_info_num = json_object_get_int(json_object_object_get(
709 section, "processorErrorInfoNum")) &
710 0x3F;
711 int proc_ctx_info_num = json_object_get_int(json_object_object_get(
712 section, "processorContextInfoNum")) &
713 0x3F;
714 valid |= proc_error_info_num << 2;
715 valid |= proc_ctx_info_num << 8;
716
717 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = valid };
718 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100719
Lawrence Tange407b4c2022-07-21 13:54:01 +0100720 //Local APIC ID.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800721 if (json_object_object_get_ex(section, "localAPICID", &obj)) {
722 section_cper->ApicId = json_object_get_uint64(obj);
723 add_to_valid_bitfield(&ui64Type, 0);
724 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100725
Lawrence Tange407b4c2022-07-21 13:54:01 +0100726 //CPUID info.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800727 if (json_object_object_get_ex(section, "cpuidInfo", &obj)) {
728 json_object *cpuid_info = obj;
729 EFI_IA32_X64_CPU_ID *cpuid_info_cper =
730 (EFI_IA32_X64_CPU_ID *)section_cper->CpuIdInfo;
731 cpuid_info_cper->Eax = json_object_get_uint64(
732 json_object_object_get(cpuid_info, "eax"));
733 cpuid_info_cper->Ebx = json_object_get_uint64(
734 json_object_object_get(cpuid_info, "ebx"));
735 cpuid_info_cper->Ecx = json_object_get_uint64(
736 json_object_object_get(cpuid_info, "ecx"));
737 cpuid_info_cper->Edx = json_object_get_uint64(
738 json_object_object_get(cpuid_info, "edx"));
739 add_to_valid_bitfield(&ui64Type, 1);
740 }
741 section_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100742
Lawrence Tange407b4c2022-07-21 13:54:01 +0100743 //Flush the header to file before dealing w/ info sections.
744 fwrite(section_cper, sizeof(EFI_IA32_X64_PROCESSOR_ERROR_RECORD), 1,
745 out);
746 fflush(out);
747 free(section_cper);
748
749 //Iterate and deal with sections.
750 json_object *error_info =
751 json_object_object_get(section, "processorErrorInfo");
752 json_object *context_info =
753 json_object_object_get(section, "processorContextInfo");
John Chungf8fc7052024-05-03 20:05:29 +0800754 for (int i = 0; i < proc_error_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100755 ir_ia32x64_error_info_to_cper(
756 json_object_array_get_idx(error_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800757 }
758 for (int i = 0; i < proc_ctx_info_num; i++) {
Lawrence Tange407b4c2022-07-21 13:54:01 +0100759 ir_ia32x64_context_info_to_cper(
760 json_object_array_get_idx(context_info, i), out);
John Chungf8fc7052024-05-03 20:05:29 +0800761 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100762}
763
764//Converts a single CPER-JSON IA32/x64 error information structure into CPER binary, outputting to the
765//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100766void ir_ia32x64_error_info_to_cper(json_object *error_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100767{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100768 EFI_IA32_X64_PROCESS_ERROR_INFO *error_info_cper =
769 (EFI_IA32_X64_PROCESS_ERROR_INFO *)calloc(
770 1, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100771
Lawrence Tange407b4c2022-07-21 13:54:01 +0100772 //Error structure type.
Lawrence Tang3592da72022-07-21 16:50:07 +0100773 json_object *type = json_object_object_get(error_info, "type");
774 string_to_guid(
775 &error_info_cper->ErrorType,
776 json_object_get_string(json_object_object_get(type, "guid")));
Lawrence Tangd0c88842022-07-13 14:51:17 +0100777
Lawrence Tange407b4c2022-07-21 13:54:01 +0100778 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800779 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
780 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100781
Lawrence Tange407b4c2022-07-21 13:54:01 +0100782 //Check information, parsed based on the error type.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800783 if (json_object_object_get_ex(error_info, "checkInfo", &obj)) {
784 json_object *check_info = obj;
Ed Tanous1a648562025-03-10 15:23:38 -0700785
786 int index = select_guid_from_list(
787 &error_info_cper->ErrorType, gEfiIa32x64ErrorTypeGuids,
788 sizeof(gEfiIa32x64ErrorTypeGuids) / sizeof(EFI_GUID *));
789
790 switch (index) {
791 case 0:
792 case 1:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800793 ir_ia32x64_cache_tlb_check_error_to_cper(
794 check_info,
795 (EFI_IA32_X64_CACHE_CHECK_INFO
796 *)&error_info_cper->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700797 break;
798 case 2:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800799 ir_ia32x64_bus_check_error_to_cper(
800 check_info,
801 (EFI_IA32_X64_BUS_CHECK_INFO *)&error_info_cper
802 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700803 break;
804 case 3:
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800805 ir_ia32x64_ms_check_error_to_cper(
806 check_info,
807 (EFI_IA32_X64_MS_CHECK_INFO *)&error_info_cper
808 ->CheckInfo);
Ed Tanous1a648562025-03-10 15:23:38 -0700809 break;
810 default:
811 //Unknown check information.
Ed Tanous50b966f2025-03-11 09:06:19 -0700812 cper_print_log(
813 "WARN: Invalid/unknown check information GUID found in IA32/x64 CPER section. Ignoring.\n");
Ed Tanous1a648562025-03-10 15:23:38 -0700814 break;
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800815 }
816 add_to_valid_bitfield(&ui64Type, 0);
John Chungf8fc7052024-05-03 20:05:29 +0800817 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100818
Lawrence Tange407b4c2022-07-21 13:54:01 +0100819 //Miscellaneous numeric fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800820 if (json_object_object_get_ex(error_info, "targetAddressID", &obj)) {
821 error_info_cper->TargetId = json_object_get_uint64(obj);
822 add_to_valid_bitfield(&ui64Type, 1);
823 }
824 if (json_object_object_get_ex(error_info, "requestorID", &obj)) {
825 error_info_cper->RequestorId = json_object_get_uint64(obj);
826 add_to_valid_bitfield(&ui64Type, 2);
827 }
828 if (json_object_object_get_ex(error_info, "responderID", &obj)) {
829 error_info_cper->ResponderId = json_object_get_uint64(obj);
830 add_to_valid_bitfield(&ui64Type, 3);
831 }
832 if (json_object_object_get_ex(error_info, "instructionPointer", &obj)) {
833 error_info_cper->InstructionIP = json_object_get_uint64(obj);
834 add_to_valid_bitfield(&ui64Type, 4);
835 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100836
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800837 error_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tange407b4c2022-07-21 13:54:01 +0100838 //Write out to stream, then free resources.
839 fwrite(error_info_cper, sizeof(EFI_IA32_X64_PROCESS_ERROR_INFO), 1,
840 out);
841 fflush(out);
842 free(error_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +0100843}
844
845//Converts a single CPER-JSON IA32/x64 cache/TLB check error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100846void ir_ia32x64_cache_tlb_check_error_to_cper(
847 json_object *check_info, EFI_IA32_X64_CACHE_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100848{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100849 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800850 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
851 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100852
Lawrence Tange407b4c2022-07-21 13:54:01 +0100853 //Transaction type, operation.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800854 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
855 check_info_cper->TransactionType =
856 readable_pair_to_integer(obj);
857 add_to_valid_bitfield(&ui64Type, 0);
858 }
859 if (json_object_object_get_ex(check_info, "operation", &obj)) {
860 check_info_cper->Operation = readable_pair_to_integer(obj);
861 add_to_valid_bitfield(&ui64Type, 1);
862 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100863
Lawrence Tange407b4c2022-07-21 13:54:01 +0100864 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800865 if (json_object_object_get_ex(check_info, "level", &obj)) {
866 check_info_cper->Level = json_object_get_uint64(obj);
867 add_to_valid_bitfield(&ui64Type, 2);
868 }
869 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
870 &obj)) {
871 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
872 add_to_valid_bitfield(&ui64Type, 3);
873 }
874 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
875 check_info_cper->ErrorUncorrected =
876 json_object_get_boolean(obj);
877 add_to_valid_bitfield(&ui64Type, 4);
878 }
879 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
880 check_info_cper->PreciseIp = json_object_get_boolean(obj);
881 add_to_valid_bitfield(&ui64Type, 5);
882 }
883 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
884 check_info_cper->RestartableIp = json_object_get_boolean(obj);
885 add_to_valid_bitfield(&ui64Type, 6);
886 }
887 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
888 check_info_cper->Overflow = json_object_get_boolean(obj);
889 add_to_valid_bitfield(&ui64Type, 7);
890 }
891 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100892}
893
894//Converts a single CPER-JSON IA32/x64 bus error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100895void ir_ia32x64_bus_check_error_to_cper(
896 json_object *check_info, EFI_IA32_X64_BUS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100897{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100898 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800899 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
900 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100901
Lawrence Tange407b4c2022-07-21 13:54:01 +0100902 //Readable pair fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800903 if (json_object_object_get_ex(check_info, "transactionType", &obj)) {
904 check_info_cper->TransactionType =
905 readable_pair_to_integer(obj);
906 add_to_valid_bitfield(&ui64Type, 0);
907 }
908 if (json_object_object_get_ex(check_info, "operation", &obj)) {
909 check_info_cper->Operation = readable_pair_to_integer(obj);
910 add_to_valid_bitfield(&ui64Type, 1);
911 }
912 if (json_object_object_get_ex(check_info, "participationType", &obj)) {
913 check_info_cper->ParticipationType =
914 readable_pair_to_integer(obj);
915 add_to_valid_bitfield(&ui64Type, 8);
916 }
917
918 if (json_object_object_get_ex(check_info, "addressSpace", &obj)) {
919 check_info_cper->AddressSpace = readable_pair_to_integer(obj);
920 add_to_valid_bitfield(&ui64Type, 10);
921 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100922
Lawrence Tange407b4c2022-07-21 13:54:01 +0100923 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800924 if (json_object_object_get_ex(check_info, "level", &obj)) {
925 check_info_cper->Level = json_object_get_uint64(obj);
926 add_to_valid_bitfield(&ui64Type, 2);
927 }
928 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
929 &obj)) {
930 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
931 add_to_valid_bitfield(&ui64Type, 3);
932 }
933 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
934 check_info_cper->ErrorUncorrected =
935 json_object_get_boolean(obj);
936 add_to_valid_bitfield(&ui64Type, 4);
937 }
938 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
939 check_info_cper->PreciseIp = json_object_get_boolean(obj);
940 add_to_valid_bitfield(&ui64Type, 5);
941 }
942 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
943 check_info_cper->RestartableIp = json_object_get_boolean(obj);
944 add_to_valid_bitfield(&ui64Type, 6);
945 }
946 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
947 check_info_cper->Overflow = json_object_get_boolean(obj);
948 add_to_valid_bitfield(&ui64Type, 7);
949 }
950 if (json_object_object_get_ex(check_info, "timedOut", &obj)) {
951 check_info_cper->TimeOut = json_object_get_boolean(obj);
952 add_to_valid_bitfield(&ui64Type, 9);
953 }
954 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100955}
956
957//Converts a single CPER-JSON IA32/x64 MS error info structure to CPER binary.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100958void ir_ia32x64_ms_check_error_to_cper(
959 json_object *check_info, EFI_IA32_X64_MS_CHECK_INFO *check_info_cper)
Lawrence Tangd0c88842022-07-13 14:51:17 +0100960{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100961 //Validation bits.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800962 ValidationTypes ui64Type = { UINT_64T, .value.ui64 = 0 };
963 struct json_object *obj = NULL;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100964
Lawrence Tange407b4c2022-07-21 13:54:01 +0100965 //Type of MS check error.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800966 if (json_object_object_get_ex(check_info, "errorType", &obj)) {
967 check_info_cper->ErrorType = readable_pair_to_integer(obj);
968 add_to_valid_bitfield(&ui64Type, 0);
969 }
Lawrence Tangd0c88842022-07-13 14:51:17 +0100970
Lawrence Tange407b4c2022-07-21 13:54:01 +0100971 //Miscellaneous raw value fields.
Aushim Nagarkattiae8f6d92025-01-29 17:34:44 -0800972 if (json_object_object_get_ex(check_info, "processorContextCorrupt",
973 &obj)) {
974 check_info_cper->ContextCorrupt = json_object_get_boolean(obj);
975 add_to_valid_bitfield(&ui64Type, 1);
976 }
977 if (json_object_object_get_ex(check_info, "uncorrected", &obj)) {
978 check_info_cper->ErrorUncorrected =
979 json_object_get_boolean(obj);
980 add_to_valid_bitfield(&ui64Type, 2);
981 }
982 if (json_object_object_get_ex(check_info, "preciseIP", &obj)) {
983 check_info_cper->PreciseIp = json_object_get_boolean(obj);
984 add_to_valid_bitfield(&ui64Type, 3);
985 }
986 if (json_object_object_get_ex(check_info, "restartableIP", &obj)) {
987 check_info_cper->RestartableIp = json_object_get_boolean(obj);
988 add_to_valid_bitfield(&ui64Type, 4);
989 }
990 if (json_object_object_get_ex(check_info, "overflow", &obj)) {
991 check_info_cper->Overflow = json_object_get_boolean(obj);
992 add_to_valid_bitfield(&ui64Type, 5);
993 }
994 check_info_cper->ValidFields = ui64Type.value.ui64;
Lawrence Tangd0c88842022-07-13 14:51:17 +0100995}
996
997//Converts a single CPER-JSON IA32/x64 context information structure into CPER binary, outputting to the
998//provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100999void ir_ia32x64_context_info_to_cper(json_object *context_info, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001000{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001001 EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *context_info_cper =
1002 (EFI_IA32_X64_PROCESSOR_CONTEXT_INFO *)calloc(
1003 1, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001004
Lawrence Tange407b4c2022-07-21 13:54:01 +01001005 //Register context type.
1006 context_info_cper->RegisterType = (UINT16)readable_pair_to_integer(
1007 json_object_object_get(context_info, "registerContextType"));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001008
Lawrence Tange407b4c2022-07-21 13:54:01 +01001009 //Miscellaneous numeric fields.
1010 context_info_cper->ArraySize = (UINT16)json_object_get_uint64(
1011 json_object_object_get(context_info, "registerArraySize"));
1012 context_info_cper->MsrAddress = (UINT32)json_object_get_uint64(
1013 json_object_object_get(context_info, "msrAddress"));
1014 context_info_cper->MmRegisterAddress = json_object_get_uint64(
1015 json_object_object_get(context_info, "mmRegisterAddress"));
Lawrence Tangd0c88842022-07-13 14:51:17 +01001016
Lawrence Tange407b4c2022-07-21 13:54:01 +01001017 //Flush header to stream.
1018 fwrite(context_info_cper, sizeof(EFI_IA32_X64_PROCESSOR_CONTEXT_INFO),
1019 1, out);
1020 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001021
Lawrence Tange407b4c2022-07-21 13:54:01 +01001022 //Handle the register array, depending on type provided.
1023 json_object *register_array =
1024 json_object_object_get(context_info, "registerArray");
1025 if (context_info_cper->RegisterType == EFI_REG_CONTEXT_TYPE_IA32) {
1026 ir_ia32x64_ia32_registers_to_cper(register_array, out);
1027 } else if (context_info_cper->RegisterType ==
1028 EFI_REG_CONTEXT_TYPE_X64) {
1029 ir_ia32x64_x64_registers_to_cper(register_array, out);
1030 } else {
1031 //Unknown/structure is not defined.
1032 json_object *encoded =
1033 json_object_object_get(register_array, "data");
Ed Tanousa7d2cdd2024-07-15 11:07:27 -07001034 int32_t decoded_len = 0;
1035 const char *j_string = json_object_get_string(encoded);
1036 int j_size = json_object_get_string_len(encoded);
1037 UINT8 *decoded = base64_decode(j_string, j_size, &decoded_len);
1038 if (decoded == NULL) {
Ed Tanous50b966f2025-03-11 09:06:19 -07001039 cper_print_log(
1040 "Failed to allocate decode output buffer. \n");
John Chungf8fc7052024-05-03 20:05:29 +08001041 } else {
John Chungf8fc7052024-05-03 20:05:29 +08001042 fwrite(decoded, decoded_len, 1, out);
1043 fflush(out);
1044 free(decoded);
1045 }
Lawrence Tange407b4c2022-07-21 13:54:01 +01001046 }
Lawrence Tangd0c88842022-07-13 14:51:17 +01001047
Lawrence Tange407b4c2022-07-21 13:54:01 +01001048 //Free remaining resources.
1049 free(context_info_cper);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001050}
1051
1052//Converts a single CPER-JSON IA32 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001053void ir_ia32x64_ia32_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001054{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001055 EFI_CONTEXT_IA32_REGISTER_STATE register_state;
1056 register_state.Eax = (UINT32)json_object_get_uint64(
1057 json_object_object_get(registers, "eax"));
1058 register_state.Ebx = (UINT32)json_object_get_uint64(
1059 json_object_object_get(registers, "ebx"));
1060 register_state.Ecx = (UINT32)json_object_get_uint64(
1061 json_object_object_get(registers, "ecx"));
1062 register_state.Edx = (UINT32)json_object_get_uint64(
1063 json_object_object_get(registers, "edx"));
1064 register_state.Esi = (UINT32)json_object_get_uint64(
1065 json_object_object_get(registers, "esi"));
1066 register_state.Edi = (UINT32)json_object_get_uint64(
1067 json_object_object_get(registers, "edi"));
1068 register_state.Ebp = (UINT32)json_object_get_uint64(
1069 json_object_object_get(registers, "ebp"));
1070 register_state.Esp = (UINT32)json_object_get_uint64(
1071 json_object_object_get(registers, "esp"));
1072 register_state.Cs = (UINT16)json_object_get_uint64(
1073 json_object_object_get(registers, "cs"));
1074 register_state.Ds = (UINT32)json_object_get_uint64(
1075 json_object_object_get(registers, "ds"));
1076 register_state.Ss = (UINT16)json_object_get_uint64(
1077 json_object_object_get(registers, "ss"));
1078 register_state.Es = (UINT16)json_object_get_uint64(
1079 json_object_object_get(registers, "es"));
1080 register_state.Fs = (UINT16)json_object_get_uint64(
1081 json_object_object_get(registers, "fs"));
1082 register_state.Gs = (UINT16)json_object_get_uint64(
1083 json_object_object_get(registers, "gs"));
1084 register_state.Eflags = (UINT32)json_object_get_uint64(
1085 json_object_object_get(registers, "eflags"));
1086 register_state.Eip = (UINT32)json_object_get_uint64(
1087 json_object_object_get(registers, "eip"));
1088 register_state.Cr0 = (UINT32)json_object_get_uint64(
1089 json_object_object_get(registers, "cr0"));
1090 register_state.Cr1 = (UINT32)json_object_get_uint64(
1091 json_object_object_get(registers, "cr1"));
1092 register_state.Cr2 = (UINT32)json_object_get_uint64(
1093 json_object_object_get(registers, "cr2"));
1094 register_state.Cr3 = (UINT32)json_object_get_uint64(
1095 json_object_object_get(registers, "cr3"));
1096 register_state.Cr4 = (UINT32)json_object_get_uint64(
1097 json_object_object_get(registers, "cr4"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001098
Lawrence Tange407b4c2022-07-21 13:54:01 +01001099 //64-bit registers are split into two 32-bit parts.
1100 UINT64 gdtr = json_object_get_uint64(
1101 json_object_object_get(registers, "gdtr"));
1102 register_state.Gdtr[0] = gdtr & 0xFFFFFFFF;
1103 register_state.Gdtr[1] = gdtr >> 32;
1104 UINT64 idtr = json_object_get_uint64(
1105 json_object_object_get(registers, "idtr"));
1106 register_state.Idtr[0] = idtr & 0xFFFFFFFF;
1107 register_state.Idtr[1] = idtr >> 32;
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001108
Lawrence Tange407b4c2022-07-21 13:54:01 +01001109 //16-bit registers.
1110 register_state.Ldtr = (UINT16)json_object_get_uint64(
1111 json_object_object_get(registers, "ldtr"));
1112 register_state.Tr = (UINT16)json_object_get_uint64(
1113 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001114
Lawrence Tange407b4c2022-07-21 13:54:01 +01001115 //Write out to stream.
1116 fwrite(&register_state, sizeof(EFI_CONTEXT_IA32_REGISTER_STATE), 1,
1117 out);
1118 fflush(out);
Lawrence Tangd0c88842022-07-13 14:51:17 +01001119}
1120
1121//Converts a single CPER-JSON x64 register array into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +01001122void ir_ia32x64_x64_registers_to_cper(json_object *registers, FILE *out)
Lawrence Tangd0c88842022-07-13 14:51:17 +01001123{
Lawrence Tange407b4c2022-07-21 13:54:01 +01001124 EFI_CONTEXT_X64_REGISTER_STATE register_state;
1125 register_state.Rax = json_object_get_uint64(
1126 json_object_object_get(registers, "rax"));
1127 register_state.Rbx = json_object_get_uint64(
1128 json_object_object_get(registers, "rbx"));
1129 register_state.Rcx = json_object_get_uint64(
1130 json_object_object_get(registers, "rcx"));
1131 register_state.Rdx = json_object_get_uint64(
1132 json_object_object_get(registers, "rdx"));
1133 register_state.Rsi = json_object_get_uint64(
1134 json_object_object_get(registers, "rsi"));
1135 register_state.Rdi = json_object_get_uint64(
1136 json_object_object_get(registers, "rdi"));
1137 register_state.Rbp = json_object_get_uint64(
1138 json_object_object_get(registers, "rbp"));
1139 register_state.Rsp = json_object_get_uint64(
1140 json_object_object_get(registers, "rsp"));
1141 register_state.R8 =
1142 json_object_get_uint64(json_object_object_get(registers, "r8"));
1143 register_state.R9 =
1144 json_object_get_uint64(json_object_object_get(registers, "r9"));
1145 register_state.R10 = json_object_get_uint64(
1146 json_object_object_get(registers, "r10"));
1147 register_state.R11 = json_object_get_uint64(
1148 json_object_object_get(registers, "r11"));
1149 register_state.R12 = json_object_get_uint64(
1150 json_object_object_get(registers, "r12"));
1151 register_state.R13 = json_object_get_uint64(
1152 json_object_object_get(registers, "r13"));
1153 register_state.R14 = json_object_get_uint64(
1154 json_object_object_get(registers, "r14"));
1155 register_state.R15 = json_object_get_uint64(
1156 json_object_object_get(registers, "r15"));
1157 register_state.Cs = (UINT16)json_object_get_int(
1158 json_object_object_get(registers, "cs"));
1159 register_state.Ds = (UINT16)json_object_get_int(
1160 json_object_object_get(registers, "ds"));
1161 register_state.Ss = (UINT16)json_object_get_int(
1162 json_object_object_get(registers, "ss"));
1163 register_state.Es = (UINT16)json_object_get_int(
1164 json_object_object_get(registers, "es"));
1165 register_state.Fs = (UINT16)json_object_get_int(
1166 json_object_object_get(registers, "fs"));
1167 register_state.Gs = (UINT16)json_object_get_int(
1168 json_object_object_get(registers, "gs"));
1169 register_state.Resv1 = 0;
1170 register_state.Rflags = json_object_get_uint64(
1171 json_object_object_get(registers, "rflags"));
1172 register_state.Rip = json_object_get_uint64(
1173 json_object_object_get(registers, "eip"));
1174 register_state.Cr0 = json_object_get_uint64(
1175 json_object_object_get(registers, "cr0"));
1176 register_state.Cr1 = json_object_get_uint64(
1177 json_object_object_get(registers, "cr1"));
1178 register_state.Cr2 = json_object_get_uint64(
1179 json_object_object_get(registers, "cr2"));
1180 register_state.Cr3 = json_object_get_uint64(
1181 json_object_object_get(registers, "cr3"));
1182 register_state.Cr4 = json_object_get_uint64(
1183 json_object_object_get(registers, "cr4"));
1184 register_state.Cr8 = json_object_get_uint64(
1185 json_object_object_get(registers, "cr8"));
1186 register_state.Gdtr[0] = json_object_get_uint64(
1187 json_object_object_get(registers, "gdtr_0"));
1188 register_state.Gdtr[1] = json_object_get_uint64(
1189 json_object_object_get(registers, "gdtr_1"));
1190 register_state.Idtr[0] = json_object_get_uint64(
1191 json_object_object_get(registers, "idtr_0"));
1192 register_state.Idtr[1] = json_object_get_uint64(
1193 json_object_object_get(registers, "idtr_1"));
1194 register_state.Ldtr = (UINT16)json_object_get_int(
1195 json_object_object_get(registers, "ldtr"));
1196 register_state.Tr = (UINT16)json_object_get_int(
1197 json_object_object_get(registers, "tr"));
Lawrence Tangbd9a84a2022-07-13 15:41:16 +01001198
Lawrence Tange407b4c2022-07-21 13:54:01 +01001199 //Write out to stream.
1200 fwrite(&register_state, sizeof(EFI_CONTEXT_X64_REGISTER_STATE), 1, out);
1201 fflush(out);
John Chungf8fc7052024-05-03 20:05:29 +08001202}