1cc0f5f38SLawrence Tang /**
2cc0f5f38SLawrence Tang  * Describes functions for converting Intel IPF CPER sections from binary and JSON format
3cc0f5f38SLawrence Tang  * into an intermediate format.
4cc0f5f38SLawrence Tang  *
5cc0f5f38SLawrence Tang  * Author: Lawrence.Tang@arm.com
6cc0f5f38SLawrence Tang  **/
7cc0f5f38SLawrence Tang #include <stdio.h>
8cc0f5f38SLawrence Tang #include "json.h"
9cc0f5f38SLawrence Tang #include "../edk/Cper.h"
10cc0f5f38SLawrence Tang #include "../cper-utils.h"
11cc0f5f38SLawrence Tang #include "cper-section-ipf.h"
12cc0f5f38SLawrence Tang 
13*e18aaee9SLawrence Tang json_object* cper_ipf_mod_error_read_array(EFI_IPF_MOD_ERROR_INFO** cur_error, int num_to_read);
14*e18aaee9SLawrence Tang json_object* cper_ipf_mod_error_to_ir(EFI_IPF_MOD_ERROR_INFO* mod_error);
15*e18aaee9SLawrence Tang 
16cc0f5f38SLawrence Tang //Converts a single Intel IPF error CPER section into JSON IR.
17cc0f5f38SLawrence Tang json_object* cper_section_ipf_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
18cc0f5f38SLawrence Tang {
19*e18aaee9SLawrence Tang     EFI_IPF_ERROR_INFO_HEADER* ipf_error = (EFI_IPF_ERROR_INFO_HEADER*)section;
20*e18aaee9SLawrence Tang     json_object* section_ir = json_object_new_object();
21*e18aaee9SLawrence Tang 
22*e18aaee9SLawrence Tang     //Validation bits.
23*e18aaee9SLawrence Tang     json_object* validation = json_object_new_object();
24*e18aaee9SLawrence Tang     json_object_object_add(validation, "errorMapValid", json_object_new_boolean(ipf_error->ValidBits.ProcErrorMapValid));
25*e18aaee9SLawrence Tang     json_object_object_add(validation, "stateParameterValid", json_object_new_boolean(ipf_error->ValidBits.ProcErrorMapValid));
26*e18aaee9SLawrence Tang     json_object_object_add(validation, "crLIDValid", json_object_new_boolean(ipf_error->ValidBits.ProcCrLidValid));
27*e18aaee9SLawrence Tang     json_object_object_add(validation, "psiStaticStructValid", json_object_new_boolean(ipf_error->ValidBits.PsiStaticStructValid));
28*e18aaee9SLawrence Tang     json_object_object_add(validation, "cpuInfoValid", json_object_new_boolean(ipf_error->ValidBits.CpuIdInfoValid));
29*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "validationBits", validation);
30*e18aaee9SLawrence Tang 
31*e18aaee9SLawrence Tang     //Numbers of various variable length segments.
32*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "cacheCheckNum", json_object_new_uint64(ipf_error->ValidBits.CacheCheckNum));
33*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "tlbCheckNum", json_object_new_uint64(ipf_error->ValidBits.TlbCheckNum));
34*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "busCheckNum", json_object_new_uint64(ipf_error->ValidBits.BusCheckNum));
35*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "regFileCheckNum", json_object_new_uint64(ipf_error->ValidBits.RegFileCheckNum));
36*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "msCheckNum", json_object_new_uint64(ipf_error->ValidBits.MsCheckNum));
37*e18aaee9SLawrence Tang 
38*e18aaee9SLawrence Tang     //Process error map, state params/CR LID.
39*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "procErrorMap", json_object_new_uint64(ipf_error->ProcErrorMap));
40*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "procStateParameter", json_object_new_uint64(ipf_error->ProcStateParameter));
41*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "procCRLID", json_object_new_uint64(ipf_error->ProcCrLid));
42*e18aaee9SLawrence Tang 
43*e18aaee9SLawrence Tang     //Read cache, TLB, bus, register file, MS errors.
44*e18aaee9SLawrence Tang     EFI_IPF_MOD_ERROR_INFO* cur_error = (EFI_IPF_MOD_ERROR_INFO*)(ipf_error + 1);
45*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "cacheErrors", cper_ipf_mod_error_read_array(&cur_error, ipf_error->ValidBits.CacheCheckNum));
46*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "tlbErrors", cper_ipf_mod_error_read_array(&cur_error, ipf_error->ValidBits.TlbCheckNum));
47*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "busErrors", cper_ipf_mod_error_read_array(&cur_error, ipf_error->ValidBits.BusCheckNum));
48*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "regFileErrors", cper_ipf_mod_error_read_array(&cur_error, ipf_error->ValidBits.RegFileCheckNum));
49*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "msErrors", cper_ipf_mod_error_read_array(&cur_error, ipf_error->ValidBits.MsCheckNum));
50*e18aaee9SLawrence Tang 
51*e18aaee9SLawrence Tang     //CPU ID information.
52*e18aaee9SLawrence Tang     EFI_IPF_CPU_INFO* cpu_info = (EFI_IPF_CPU_INFO*)cur_error;
53*e18aaee9SLawrence Tang     //todo: find out how this is represented
54*e18aaee9SLawrence Tang 
55*e18aaee9SLawrence Tang     //Processor static information.
56*e18aaee9SLawrence Tang     EFI_IPF_PSI_STATIC* psi_static = (EFI_IPF_PSI_STATIC*)(cpu_info + 1);
57*e18aaee9SLawrence Tang     json_object* psi_static_ir = json_object_new_object();
58*e18aaee9SLawrence Tang 
59*e18aaee9SLawrence Tang     //PSI validation bits.
60*e18aaee9SLawrence Tang     json_object* psi_validation = bitfield_to_ir(psi_static->ValidBits, 6, IPF_PSI_STATIC_INFO_VALID_BITFIELD_NAMES);
61*e18aaee9SLawrence Tang     json_object_object_add(psi_static_ir, "validationBits", psi_validation);
62*e18aaee9SLawrence Tang 
63*e18aaee9SLawrence Tang     //PSI minimal state save info.
64*e18aaee9SLawrence Tang     //todo: structure min save state area as in Intel Itanium Architecture Software Developer's Manual.
65*e18aaee9SLawrence Tang 
66*e18aaee9SLawrence Tang     //BRs, CRs, ARs, RRs, FRs.
67*e18aaee9SLawrence Tang     json_object_object_add(psi_static_ir, "brs", uint64_array_to_ir_array(psi_static->Brs, 8));
68*e18aaee9SLawrence Tang     json_object_object_add(psi_static_ir, "crs", uint64_array_to_ir_array(psi_static->Crs, 128));
69*e18aaee9SLawrence Tang     json_object_object_add(psi_static_ir, "ars", uint64_array_to_ir_array(psi_static->Ars, 128));
70*e18aaee9SLawrence Tang     json_object_object_add(psi_static_ir, "rrs", uint64_array_to_ir_array(psi_static->Rrs, 8));
71*e18aaee9SLawrence Tang     json_object_object_add(psi_static_ir, "frs", uint64_array_to_ir_array(psi_static->Frs, 256));
72*e18aaee9SLawrence Tang     json_object_object_add(section_ir, "psiStaticInfo", psi_static_ir);
73*e18aaee9SLawrence Tang 
74*e18aaee9SLawrence Tang     return section_ir;
75*e18aaee9SLawrence Tang }
76*e18aaee9SLawrence Tang 
77*e18aaee9SLawrence Tang //Reads a continuous stream of CPER IPF mod errors beginning from the given pointer, for n entries.
78*e18aaee9SLawrence Tang //Returns an array containing all read entries as JSON IR.
79*e18aaee9SLawrence Tang json_object* cper_ipf_mod_error_read_array(EFI_IPF_MOD_ERROR_INFO** cur_error, int num_to_read)
80*e18aaee9SLawrence Tang {
81*e18aaee9SLawrence Tang     json_object* error_array = json_object_new_array();
82*e18aaee9SLawrence Tang     for (int i=0; i<num_to_read; i++)
83*e18aaee9SLawrence Tang     {
84*e18aaee9SLawrence Tang         json_object_array_add(error_array, cper_ipf_mod_error_to_ir(*cur_error));
85*e18aaee9SLawrence Tang         *cur_error = *cur_error + 1;
86*e18aaee9SLawrence Tang     }
87*e18aaee9SLawrence Tang 
88*e18aaee9SLawrence Tang     return error_array;
89*e18aaee9SLawrence Tang }
90*e18aaee9SLawrence Tang 
91*e18aaee9SLawrence Tang //Converts a single CPER IPF mod error info structure into JSON IR.
92*e18aaee9SLawrence Tang json_object* cper_ipf_mod_error_to_ir(EFI_IPF_MOD_ERROR_INFO* mod_error)
93*e18aaee9SLawrence Tang {
94*e18aaee9SLawrence Tang     json_object* mod_error_ir = json_object_new_object();
95*e18aaee9SLawrence Tang 
96*e18aaee9SLawrence Tang     //Validation bits.
97*e18aaee9SLawrence Tang     json_object* validation = bitfield_to_ir(mod_error->ValidBits, 5, IPF_MOD_ERROR_VALID_BITFIELD_NAMES);
98*e18aaee9SLawrence Tang     json_object_object_add(mod_error_ir, "validationBits", validation);
99*e18aaee9SLawrence Tang 
100*e18aaee9SLawrence Tang     //Numeric fields.
101*e18aaee9SLawrence Tang     json_object_object_add(mod_error_ir, "modCheckInfo", json_object_new_uint64(mod_error->ModCheckInfo));
102*e18aaee9SLawrence Tang     json_object_object_add(mod_error_ir, "modTargetID", json_object_new_uint64(mod_error->ModTargetId));
103*e18aaee9SLawrence Tang     json_object_object_add(mod_error_ir, "modRequestorID", json_object_new_uint64(mod_error->ModRequestorId));
104*e18aaee9SLawrence Tang     json_object_object_add(mod_error_ir, "modResponderID", json_object_new_uint64(mod_error->ModResponderId));
105*e18aaee9SLawrence Tang     json_object_object_add(mod_error_ir, "modPreciseIP", json_object_new_uint64(mod_error->ModPreciseIp));
106*e18aaee9SLawrence Tang 
107*e18aaee9SLawrence Tang     return mod_error_ir;
108cc0f5f38SLawrence Tang }