12800cd8eSLawrence Tang /**
22800cd8eSLawrence Tang  * Describes functions for converting ARM CPER sections from binary and JSON format
32800cd8eSLawrence Tang  * into an intermediate format.
42800cd8eSLawrence Tang  *
52800cd8eSLawrence Tang  * Author: Lawrence.Tang@arm.com
62800cd8eSLawrence Tang  **/
72800cd8eSLawrence Tang 
82800cd8eSLawrence Tang #include <stdio.h>
92800cd8eSLawrence Tang #include "json.h"
102800cd8eSLawrence Tang #include "../edk/Cper.h"
112800cd8eSLawrence Tang #include "../cper-utils.h"
122800cd8eSLawrence Tang #include "cper-section-arm.h"
132800cd8eSLawrence Tang 
143d0e4f24SLawrence Tang //Private pre-definitions.
15*7f21db6cSLawrence Tang json_object* cper_arm_error_info_to_ir(EFI_ARM_ERROR_INFORMATION_ENTRY* error_info);
16*7f21db6cSLawrence Tang json_object* cper_arm_processor_context_to_ir(EFI_ARM_CONTEXT_INFORMATION_HEADER* header, void** cur_pos);
17*7f21db6cSLawrence Tang json_object* cper_arm_cache_tlb_error_to_ir(EFI_ARM_CACHE_ERROR_STRUCTURE* cache_tlb_error, EFI_ARM_ERROR_INFORMATION_ENTRY* error_info);
18*7f21db6cSLawrence Tang json_object* cper_arm_bus_error_to_ir(EFI_ARM_BUS_ERROR_STRUCTURE* bus_error);
19*7f21db6cSLawrence Tang json_object* cper_arm_misc_register_array_to_ir(EFI_ARM_MISC_CONTEXT_REGISTER* misc_register);
203d0e4f24SLawrence Tang 
212800cd8eSLawrence Tang //Converts the given processor-generic CPER section into JSON IR.
222800cd8eSLawrence Tang json_object* cper_section_arm_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
232800cd8eSLawrence Tang {
24*7f21db6cSLawrence Tang     EFI_ARM_ERROR_RECORD* record = (EFI_ARM_ERROR_RECORD*)section;
252800cd8eSLawrence Tang     json_object* section_ir = json_object_new_object();
262800cd8eSLawrence Tang 
272800cd8eSLawrence Tang     //Validation bits.
28*7f21db6cSLawrence Tang     json_object* validation = bitfield_to_ir(record->ValidFields, 4, ARM_ERROR_VALID_BITFIELD_NAMES);
292800cd8eSLawrence Tang     json_object_object_add(section_ir, "validationBits", validation);
302800cd8eSLawrence Tang 
312800cd8eSLawrence Tang     //Number of error info and context info structures, and length.
322800cd8eSLawrence Tang     json_object_object_add(section_ir, "errorInfoNum", json_object_new_int(record->ErrInfoNum));
332800cd8eSLawrence Tang     json_object_object_add(section_ir, "contextInfoNum", json_object_new_int(record->ContextInfoNum));
342800cd8eSLawrence Tang     json_object_object_add(section_ir, "sectionLength", json_object_new_int(record->SectionLength));
352800cd8eSLawrence Tang 
362800cd8eSLawrence Tang     //Error affinity.
372800cd8eSLawrence Tang     json_object* error_affinity = json_object_new_object();
382800cd8eSLawrence Tang     json_object_object_add(error_affinity, "value", json_object_new_int(record->ErrorAffinityLevel));
392800cd8eSLawrence Tang     json_object_object_add(error_affinity, "type",
402800cd8eSLawrence Tang         json_object_new_string(record->ErrorAffinityLevel < 4 ? "Vendor Defined" : "Reserved"));
412800cd8eSLawrence Tang     json_object_object_add(section_ir, "errorAffinity", error_affinity);
422800cd8eSLawrence Tang 
432800cd8eSLawrence Tang     //Processor ID (MPIDR_EL1) and chip ID (MIDR_EL1).
442800cd8eSLawrence Tang     json_object_object_add(section_ir, "mpidrEl1", json_object_new_uint64(record->MPIDR_EL1));
452800cd8eSLawrence Tang     json_object_object_add(section_ir, "midrEl1", json_object_new_uint64(record->MIDR_EL1));
462800cd8eSLawrence Tang 
472800cd8eSLawrence Tang     //Whether the processor is running, and the state of it if so.
482800cd8eSLawrence Tang     json_object_object_add(section_ir, "running", json_object_new_boolean(record->RunningState));
493d0e4f24SLawrence Tang     if (record->RunningState >> 31)
502800cd8eSLawrence Tang     {
513d0e4f24SLawrence Tang         //Bit 32 of running state is on, so PSCI state information is included.
523d0e4f24SLawrence Tang         //todo: Look at how to make this human readable from the ARM PSCI document.
533d0e4f24SLawrence Tang         json_object_object_add(section_ir, "psciState", json_object_new_int(record->PsciState));
542800cd8eSLawrence Tang     }
552800cd8eSLawrence Tang 
563d0e4f24SLawrence Tang     //Processor error structures.
573d0e4f24SLawrence Tang     json_object* error_info_array = json_object_new_array();
58*7f21db6cSLawrence Tang     EFI_ARM_ERROR_INFORMATION_ENTRY* cur_error = (EFI_ARM_ERROR_INFORMATION_ENTRY*)(record + 1);
593d0e4f24SLawrence Tang     for (int i=0; i<record->ErrInfoNum; i++)
603d0e4f24SLawrence Tang     {
61*7f21db6cSLawrence Tang         json_object_array_add(error_info_array, cper_arm_error_info_to_ir(cur_error));
62*7f21db6cSLawrence Tang         cur_error++;
633d0e4f24SLawrence Tang     }
64*7f21db6cSLawrence Tang     json_object_object_add(section_ir, "errorInfo", error_info_array);
65*7f21db6cSLawrence Tang 
66*7f21db6cSLawrence Tang     //Processor context structures.
67*7f21db6cSLawrence Tang     //The current position is moved within the processing, as it is a dynamic size structure.
68*7f21db6cSLawrence Tang     void* cur_pos = (void*)cur_error;
69*7f21db6cSLawrence Tang     EFI_ARM_CONTEXT_INFORMATION_HEADER* header = (EFI_ARM_CONTEXT_INFORMATION_HEADER*)cur_error;
70*7f21db6cSLawrence Tang     json_object* processor_context = cper_arm_processor_context_to_ir(header, &cur_pos);
71*7f21db6cSLawrence Tang 
72*7f21db6cSLawrence Tang     //Is there any vendor-specific information following?
73*7f21db6cSLawrence Tang     if (cur_pos < section + record->SectionLength)
74*7f21db6cSLawrence Tang     {
75*7f21db6cSLawrence Tang         //todo: b64 and tag on vendor-specific binary info.
76*7f21db6cSLawrence Tang     }
77*7f21db6cSLawrence Tang 
782800cd8eSLawrence Tang     return section_ir;
792800cd8eSLawrence Tang }
803d0e4f24SLawrence Tang 
813d0e4f24SLawrence Tang //Converts a single ARM Process Error Information structure into JSON IR.
82*7f21db6cSLawrence Tang json_object* cper_arm_error_info_to_ir(EFI_ARM_ERROR_INFORMATION_ENTRY* error_info)
833d0e4f24SLawrence Tang {
843d0e4f24SLawrence Tang     json_object* error_info_ir = json_object_new_object();
853d0e4f24SLawrence Tang 
863d0e4f24SLawrence Tang     //Version, length.
873d0e4f24SLawrence Tang     json_object_object_add(error_info_ir, "version", json_object_new_int(error_info->Version));
88*7f21db6cSLawrence Tang     json_object_object_add(error_info_ir, "length", json_object_new_int(error_info->Length));
893d0e4f24SLawrence Tang 
903d0e4f24SLawrence Tang     //Validation bitfield.
91*7f21db6cSLawrence Tang     json_object* validation = bitfield_to_ir(error_info->ValidationBits, 5, ARM_ERROR_INFO_ENTRY_VALID_BITFIELD_NAMES);
923d0e4f24SLawrence Tang     json_object_object_add(error_info_ir, "validationBits", validation);
933d0e4f24SLawrence Tang 
943d0e4f24SLawrence Tang     //The type of error information in this log.
953d0e4f24SLawrence Tang     //todo: The UEFI spec is ambiguous, what are the values for these??
963d0e4f24SLawrence Tang     json_object* error_type = integer_to_readable_pair(error_info->Type, 4,
97*7f21db6cSLawrence Tang         ARM_ERROR_INFO_ENTRY_INFO_TYPES_KEYS,
98*7f21db6cSLawrence Tang         ARM_ERROR_INFO_ENTRY_INFO_TYPES_VALUES,
993d0e4f24SLawrence Tang         "Unknown (Reserved)");
1003d0e4f24SLawrence Tang     json_object_object_add(error_info_ir, "errorType", error_type);
1013d0e4f24SLawrence Tang 
1023d0e4f24SLawrence Tang     //Multiple error count.
10322a467ceSLawrence Tang     json_object* multiple_error = json_object_new_object();
1043d0e4f24SLawrence Tang     json_object_object_add(multiple_error, "value", json_object_new_int(error_info->MultipleError));
1053d0e4f24SLawrence Tang     json_object_object_add(multiple_error, "type",
1063d0e4f24SLawrence Tang         json_object_new_string(error_info->MultipleError < 1 ? "Single Error" : "Multiple Errors"));
1073d0e4f24SLawrence Tang     json_object_object_add(error_info_ir, "multipleError", multiple_error);
1083d0e4f24SLawrence Tang 
1093d0e4f24SLawrence Tang     //Flags.
110*7f21db6cSLawrence Tang     json_object* flags = bitfield_to_ir(error_info->Flags, 4, ARM_ERROR_INFO_ENTRY_FLAGS_NAMES);
1113d0e4f24SLawrence Tang     json_object_object_add(error_info_ir, "flags", flags);
1123d0e4f24SLawrence Tang 
1133d0e4f24SLawrence Tang     //Error information, split by type.
1143d0e4f24SLawrence Tang     json_object* error_subinfo = NULL;
1153d0e4f24SLawrence Tang     switch (error_info->Type)
1163d0e4f24SLawrence Tang     {
1173d0e4f24SLawrence Tang         case 0: //Cache
1183d0e4f24SLawrence Tang         case 1: //TLB
119*7f21db6cSLawrence Tang             error_subinfo = cper_arm_cache_tlb_error_to_ir((EFI_ARM_CACHE_ERROR_STRUCTURE*)&error_info->ErrorInformation, error_info);
1203d0e4f24SLawrence Tang             break;
1213d0e4f24SLawrence Tang         case 2: //Bus
122*7f21db6cSLawrence Tang             error_subinfo = cper_arm_bus_error_to_ir((EFI_ARM_BUS_ERROR_STRUCTURE*)&error_info->ErrorInformation);
1233d0e4f24SLawrence Tang             break;
1243d0e4f24SLawrence Tang     }
1253d0e4f24SLawrence Tang     json_object_object_add(error_info_ir, "errorInformation", error_subinfo);
1263d0e4f24SLawrence Tang 
1273d0e4f24SLawrence Tang     return error_info_ir;
1283d0e4f24SLawrence Tang }
1293d0e4f24SLawrence Tang 
130*7f21db6cSLawrence Tang //Converts a single ARM cache/TLB error information structure into JSON IR format.
131*7f21db6cSLawrence Tang json_object* cper_arm_cache_tlb_error_to_ir(EFI_ARM_CACHE_ERROR_STRUCTURE* cache_tlb_error, EFI_ARM_ERROR_INFORMATION_ENTRY* error_info)
1323d0e4f24SLawrence Tang {
133*7f21db6cSLawrence Tang     json_object* cache_tlb_error_ir = json_object_new_object();
1343d0e4f24SLawrence Tang 
135*7f21db6cSLawrence Tang     //Validation bitfield.
136*7f21db6cSLawrence Tang     json_object* validation = bitfield_to_ir(cache_tlb_error->ValidationBits, 7, ARM_CACHE_TLB_ERROR_VALID_BITFIELD_NAMES);
137*7f21db6cSLawrence Tang     json_object_object_add(cache_tlb_error_ir, "validationBits", validation);
138*7f21db6cSLawrence Tang 
139*7f21db6cSLawrence Tang     //Transaction type.
140*7f21db6cSLawrence Tang     json_object* transaction_type = integer_to_readable_pair(cache_tlb_error->TransactionType, 3,
141*7f21db6cSLawrence Tang         ARM_ERROR_TRANSACTION_TYPES_KEYS,
142*7f21db6cSLawrence Tang         ARM_ERROR_TRANSACTION_TYPES_VALUES,
143*7f21db6cSLawrence Tang         "Unknown (Reserved)");
144*7f21db6cSLawrence Tang     json_object_object_add(cache_tlb_error_ir, "transactionType", transaction_type);
145*7f21db6cSLawrence Tang 
146*7f21db6cSLawrence Tang     //Operation.
147*7f21db6cSLawrence Tang     //todo: What are the types' numeric values? UEFI spec is ambiguous
148*7f21db6cSLawrence Tang     json_object* operation;
149*7f21db6cSLawrence Tang     if (error_info->Type == 0)
1503d0e4f24SLawrence Tang     {
151*7f21db6cSLawrence Tang         //Cache operation.
152*7f21db6cSLawrence Tang         operation = integer_to_readable_pair(cache_tlb_error->Operation, 11,
153*7f21db6cSLawrence Tang             ARM_CACHE_BUS_OPERATION_TYPES_KEYS,
154*7f21db6cSLawrence Tang             ARM_CACHE_BUS_OPERATION_TYPES_VALUES,
155*7f21db6cSLawrence Tang             "Unknown (Reserved)");
156*7f21db6cSLawrence Tang     }
157*7f21db6cSLawrence Tang     else
158*7f21db6cSLawrence Tang     {
159*7f21db6cSLawrence Tang         //TLB operation.
160*7f21db6cSLawrence Tang         operation = integer_to_readable_pair(cache_tlb_error->Operation, 9,
161*7f21db6cSLawrence Tang             ARM_TLB_OPERATION_TYPES_KEYS,
162*7f21db6cSLawrence Tang             ARM_TLB_OPERATION_TYPES_VALUES,
163*7f21db6cSLawrence Tang             "Unknown (Reserved)");
164*7f21db6cSLawrence Tang     }
165*7f21db6cSLawrence Tang     json_object_object_add(cache_tlb_error_ir, "operation", operation);
166*7f21db6cSLawrence Tang 
167*7f21db6cSLawrence Tang     //Miscellaneous remaining fields.
168*7f21db6cSLawrence Tang     json_object_object_add(cache_tlb_error_ir, "level", json_object_new_int(cache_tlb_error->Level));
169*7f21db6cSLawrence Tang     json_object_object_add(cache_tlb_error_ir, "processorContextCorrupt", json_object_new_boolean(cache_tlb_error->ProcessorContextCorrupt));
170*7f21db6cSLawrence Tang     json_object_object_add(cache_tlb_error_ir, "corrected", json_object_new_boolean(cache_tlb_error->Corrected));
171*7f21db6cSLawrence Tang     json_object_object_add(cache_tlb_error_ir, "precisePC", json_object_new_boolean(cache_tlb_error->PrecisePC));
172*7f21db6cSLawrence Tang     json_object_object_add(cache_tlb_error_ir, "restartablePC", json_object_new_boolean(cache_tlb_error->RestartablePC));
173*7f21db6cSLawrence Tang     return cache_tlb_error_ir;
1743d0e4f24SLawrence Tang }
1753d0e4f24SLawrence Tang 
1763d0e4f24SLawrence Tang //Converts a single ARM bus error information structure into JSON IR format.
177*7f21db6cSLawrence Tang json_object* cper_arm_bus_error_to_ir(EFI_ARM_BUS_ERROR_STRUCTURE* bus_error)
1783d0e4f24SLawrence Tang {
179*7f21db6cSLawrence Tang     json_object* bus_error_ir = json_object_new_object();
180*7f21db6cSLawrence Tang 
181*7f21db6cSLawrence Tang     //Validation bits.
182*7f21db6cSLawrence Tang     json_object* validation = bitfield_to_ir(bus_error->ValidationBits, 7, ARM_BUS_ERROR_VALID_BITFIELD_NAMES);
183*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "validationBits", validation);
184*7f21db6cSLawrence Tang 
185*7f21db6cSLawrence Tang     //Transaction type.
186*7f21db6cSLawrence Tang     json_object* transaction_type = integer_to_readable_pair(bus_error->TransactionType, 3,
187*7f21db6cSLawrence Tang         ARM_ERROR_TRANSACTION_TYPES_KEYS,
188*7f21db6cSLawrence Tang         ARM_ERROR_TRANSACTION_TYPES_VALUES,
189*7f21db6cSLawrence Tang         "Unknown (Reserved)");
190*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "transactionType", transaction_type);
191*7f21db6cSLawrence Tang 
192*7f21db6cSLawrence Tang     //Operation.
193*7f21db6cSLawrence Tang     json_object* operation = integer_to_readable_pair(bus_error->Operation, 7,
194*7f21db6cSLawrence Tang         ARM_CACHE_BUS_OPERATION_TYPES_KEYS,
195*7f21db6cSLawrence Tang         ARM_CACHE_BUS_OPERATION_TYPES_VALUES,
196*7f21db6cSLawrence Tang         "Unknown (Reserved)");
197*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "operation", operation);
198*7f21db6cSLawrence Tang 
199*7f21db6cSLawrence Tang     //Affinity level of bus error, + miscellaneous fields.
200*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "level", json_object_new_int(bus_error->Level));
201*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "processorContextCorrupt", json_object_new_boolean(bus_error->ProcessorContextCorrupt));
202*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "corrected", json_object_new_boolean(bus_error->Corrected));
203*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "precisePC", json_object_new_boolean(bus_error->PrecisePC));
204*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "restartablePC", json_object_new_boolean(bus_error->RestartablePC));
205*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "timedOut", json_object_new_boolean(bus_error->TimeOut));
206*7f21db6cSLawrence Tang 
207*7f21db6cSLawrence Tang     //Participation type.
208*7f21db6cSLawrence Tang     json_object* participation_type = integer_to_readable_pair(bus_error->ParticipationType, 4,
209*7f21db6cSLawrence Tang         ARM_BUS_PARTICIPATION_TYPES_KEYS,
210*7f21db6cSLawrence Tang         ARM_BUS_PARTICIPATION_TYPES_VALUES,
211*7f21db6cSLawrence Tang         "Unknown");
212*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "participationType", participation_type);
213*7f21db6cSLawrence Tang 
214*7f21db6cSLawrence Tang     //Address space.
215*7f21db6cSLawrence Tang     json_object* address_space = integer_to_readable_pair(bus_error->AddressSpace, 3,
216*7f21db6cSLawrence Tang         ARM_BUS_ADDRESS_SPACE_TYPES_KEYS,
217*7f21db6cSLawrence Tang         ARM_BUS_ADDRESS_SPACE_TYPES_VALUES,
218*7f21db6cSLawrence Tang         "Unknown");
219*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "addressSpace", address_space);
220*7f21db6cSLawrence Tang 
221*7f21db6cSLawrence Tang     //Memory access attributes.
222*7f21db6cSLawrence Tang     //todo: find the specification of these in the ARM ARM
223*7f21db6cSLawrence Tang     //...
224*7f21db6cSLawrence Tang 
225*7f21db6cSLawrence Tang     //Access Mode
226*7f21db6cSLawrence Tang     json_object* access_mode = json_object_new_object();
227*7f21db6cSLawrence Tang     json_object_object_add(access_mode, "value", json_object_new_int(bus_error->AccessMode));
228*7f21db6cSLawrence Tang     json_object_object_add(access_mode, "name", json_object_new_string(bus_error->AccessMode == 0 ? "Secure" : "Normal"));
229*7f21db6cSLawrence Tang     json_object_object_add(bus_error_ir, "accessMode", access_mode);
230*7f21db6cSLawrence Tang 
231*7f21db6cSLawrence Tang     return bus_error_ir;
232*7f21db6cSLawrence Tang }
233*7f21db6cSLawrence Tang 
234*7f21db6cSLawrence Tang //Converts a single ARM processor context block into JSON IR.
235*7f21db6cSLawrence Tang json_object* cper_arm_processor_context_to_ir(EFI_ARM_CONTEXT_INFORMATION_HEADER* header, void** cur_pos)
236*7f21db6cSLawrence Tang {
237*7f21db6cSLawrence Tang     json_object* context_ir = json_object_new_object();
238*7f21db6cSLawrence Tang 
239*7f21db6cSLawrence Tang     //Add the context type.
240*7f21db6cSLawrence Tang     json_object* context_type = integer_to_readable_pair(header->RegisterContextType, 9,
241*7f21db6cSLawrence Tang         ARM_PROCESSOR_INFO_REGISTER_CONTEXT_TYPES_KEYS,
242*7f21db6cSLawrence Tang         ARM_PROCESSOR_INFO_REGISTER_CONTEXT_TYPES_VALUES,
243*7f21db6cSLawrence Tang         "Unknown (Reserved)");
244*7f21db6cSLawrence Tang     json_object_object_add(context_ir, "registerContextType", context_type);
245*7f21db6cSLawrence Tang 
246*7f21db6cSLawrence Tang     //Register array size (bytes).
247*7f21db6cSLawrence Tang     json_object_object_add(context_ir, "registerArraySize", json_object_new_uint64(header->RegisterArraySize));
248*7f21db6cSLawrence Tang 
249*7f21db6cSLawrence Tang     //The register array itself.
250*7f21db6cSLawrence Tang     *cur_pos = (void*)(header + 1);
251*7f21db6cSLawrence Tang     json_object* register_array = NULL;
252*7f21db6cSLawrence Tang     switch (header->RegisterContextType)
253*7f21db6cSLawrence Tang     {
254*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_AARCH32_GPR:
255*7f21db6cSLawrence Tang             register_array = uniform_struct_to_ir((UINT32*)cur_pos,
256*7f21db6cSLawrence Tang                 sizeof(EFI_ARM_V8_AARCH32_GPR) / sizeof(UINT32), ARM_AARCH32_GPR_NAMES);
257*7f21db6cSLawrence Tang             break;
258*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_AARCH32_EL1:
259*7f21db6cSLawrence Tang             register_array = uniform_struct_to_ir((UINT32*)cur_pos,
260*7f21db6cSLawrence Tang                 sizeof(EFI_ARM_AARCH32_EL1_CONTEXT_REGISTERS) / sizeof(UINT32), ARM_AARCH32_EL1_REGISTER_NAMES);
261*7f21db6cSLawrence Tang             break;
262*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_AARCH32_EL2:
263*7f21db6cSLawrence Tang             register_array = uniform_struct_to_ir((UINT32*)cur_pos,
264*7f21db6cSLawrence Tang                 sizeof(EFI_ARM_AARCH32_EL2_CONTEXT_REGISTERS) / sizeof(UINT32), ARM_AARCH32_EL2_REGISTER_NAMES);
265*7f21db6cSLawrence Tang             break;
266*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_AARCH32_SECURE:
267*7f21db6cSLawrence Tang             register_array = uniform_struct_to_ir((UINT32*)cur_pos,
268*7f21db6cSLawrence Tang                 sizeof(EFI_ARM_AARCH32_SECURE_CONTEXT_REGISTERS) / sizeof(UINT32), ARM_AARCH32_SECURE_REGISTER_NAMES);
269*7f21db6cSLawrence Tang             break;
270*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_AARCH64_GPR:
271*7f21db6cSLawrence Tang             register_array = uniform_struct64_to_ir((UINT64*)cur_pos,
272*7f21db6cSLawrence Tang                 sizeof(EFI_ARM_V8_AARCH64_GPR) / sizeof(UINT64), ARM_AARCH64_GPR_NAMES);
273*7f21db6cSLawrence Tang             break;
274*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_AARCH64_EL1:
275*7f21db6cSLawrence Tang             register_array = uniform_struct64_to_ir((UINT64*)cur_pos,
276*7f21db6cSLawrence Tang                 sizeof(EFI_ARM_AARCH64_EL1_CONTEXT_REGISTERS) / sizeof(UINT64), ARM_AARCH64_EL1_REGISTER_NAMES);
277*7f21db6cSLawrence Tang             break;
278*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_AARCH64_EL2:
279*7f21db6cSLawrence Tang             register_array = uniform_struct64_to_ir((UINT64*)cur_pos,
280*7f21db6cSLawrence Tang                 sizeof(EFI_ARM_AARCH64_EL2_CONTEXT_REGISTERS) / sizeof(UINT64), ARM_AARCH64_EL2_REGISTER_NAMES);
281*7f21db6cSLawrence Tang             break;
282*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_AARCH64_EL3:
283*7f21db6cSLawrence Tang             register_array = uniform_struct64_to_ir((UINT64*)cur_pos,
284*7f21db6cSLawrence Tang                 sizeof(EFI_ARM_AARCH64_EL3_CONTEXT_REGISTERS) / sizeof(UINT64), ARM_AARCH64_EL3_REGISTER_NAMES);
285*7f21db6cSLawrence Tang             break;
286*7f21db6cSLawrence Tang         case EFI_ARM_CONTEXT_TYPE_MISC:
287*7f21db6cSLawrence Tang             register_array = cper_arm_misc_register_array_to_ir((EFI_ARM_MISC_CONTEXT_REGISTER*)cur_pos);
288*7f21db6cSLawrence Tang             break;
289*7f21db6cSLawrence Tang         default:
290*7f21db6cSLawrence Tang             //Unknown register array type.
291*7f21db6cSLawrence Tang             //todo: Format raw binary data and add instead of blank.
292*7f21db6cSLawrence Tang             register_array = json_object_new_object();
293*7f21db6cSLawrence Tang             break;
294*7f21db6cSLawrence Tang     }
295*7f21db6cSLawrence Tang 
296*7f21db6cSLawrence Tang     //Set the current position to after the processor context structure.
297*7f21db6cSLawrence Tang     *cur_pos = (UINT8*)(*cur_pos) + header->RegisterArraySize;
298*7f21db6cSLawrence Tang 
299*7f21db6cSLawrence Tang     return context_ir;
300*7f21db6cSLawrence Tang }
301*7f21db6cSLawrence Tang 
302*7f21db6cSLawrence Tang //Converts a single CPER ARM miscellaneous register array to JSON IR format.
303*7f21db6cSLawrence Tang json_object* cper_arm_misc_register_array_to_ir(EFI_ARM_MISC_CONTEXT_REGISTER* misc_register)
304*7f21db6cSLawrence Tang {
305*7f21db6cSLawrence Tang     json_object* register_array = json_object_new_object();
306*7f21db6cSLawrence Tang     json_object* mrs_encoding = json_object_new_object();
307*7f21db6cSLawrence Tang     json_object_object_add(mrs_encoding, "op2", json_object_new_int(misc_register->MrsOp2));
308*7f21db6cSLawrence Tang     json_object_object_add(mrs_encoding, "crm", json_object_new_int(misc_register->MrsOp2));
309*7f21db6cSLawrence Tang     json_object_object_add(mrs_encoding, "crn", json_object_new_int(misc_register->MrsOp2));
310*7f21db6cSLawrence Tang     json_object_object_add(mrs_encoding, "op1", json_object_new_int(misc_register->MrsOp2));
311*7f21db6cSLawrence Tang     json_object_object_add(mrs_encoding, "o0", json_object_new_int(misc_register->MrsOp2));
312*7f21db6cSLawrence Tang     json_object_object_add(register_array, "mrsEncoding", mrs_encoding);
313*7f21db6cSLawrence Tang     json_object_object_add(register_array, "value", json_object_new_uint64(misc_register->Value));
314*7f21db6cSLawrence Tang 
315*7f21db6cSLawrence Tang     return register_array;
3163d0e4f24SLawrence Tang }