1 /**
2 * Describes functions for converting processor-generic CPER sections from binary and JSON format
3 * into an intermediate format.
4 *
5 * Author: Lawrence.Tang@arm.com
6 **/
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <json.h>
11 #include "../edk/Cper.h"
12 #include "../cper-utils.h"
13 #include "cper-section-generic.h"
14
15 //Converts the given processor-generic CPER section into JSON IR.
cper_section_generic_to_ir(void * section)16 json_object *cper_section_generic_to_ir(void *section)
17 {
18 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic =
19 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
20 json_object *section_ir = json_object_new_object();
21
22 //Validation bits.
23 json_object *validation =
24 bitfield_to_ir(section_generic->ValidFields, 13,
25 GENERIC_VALIDATION_BITFIELD_NAMES);
26 json_object_object_add(section_ir, "validationBits", validation);
27
28 //Processor type, with human readable name if possible.
29 json_object *processor_type = integer_to_readable_pair(
30 section_generic->Type,
31 sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
32 GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES,
33 "Unknown (Reserved)");
34 json_object_object_add(section_ir, "processorType", processor_type);
35
36 //Processor ISA, with human readable name if possible.
37 json_object *processor_isa = integer_to_readable_pair(
38 section_generic->Isa,
39 sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
40 GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES,
41 "Unknown (Reserved)");
42 json_object_object_add(section_ir, "processorISA", processor_isa);
43
44 //Processor error type, with human readable name if possible.
45 json_object *processor_error_type = integer_to_readable_pair(
46 section_generic->ErrorType,
47 sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
48 GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES,
49 "Unknown (Reserved)");
50 json_object_object_add(section_ir, "errorType", processor_error_type);
51
52 //The operation performed, with a human readable name if possible.
53 json_object *operation = integer_to_readable_pair(
54 section_generic->Operation,
55 sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
56 GENERIC_OPERATION_TYPES_KEYS, GENERIC_OPERATION_TYPES_VALUES,
57 "Unknown (Reserved)");
58 json_object_object_add(section_ir, "operation", operation);
59
60 //Flags, additional information about the error.
61 json_object *flags = bitfield_to_ir(section_generic->Flags, 4,
62 GENERIC_FLAGS_BITFIELD_NAMES);
63 json_object_object_add(section_ir, "flags", flags);
64
65 //The level of the error.
66 json_object_object_add(section_ir, "level",
67 json_object_new_int(section_generic->Level));
68
69 //CPU version information.
70 json_object_object_add(
71 section_ir, "cpuVersionInfo",
72 json_object_new_uint64(section_generic->VersionInfo));
73
74 //CPU brand string. May not exist if on ARM.
75 json_object_object_add(
76 section_ir, "cpuBrandString",
77 json_object_new_string(section_generic->BrandString));
78
79 //Remaining 64-bit fields.
80 json_object_object_add(section_ir, "processorID",
81 json_object_new_uint64(section_generic->ApicId));
82 json_object_object_add(
83 section_ir, "targetAddress",
84 json_object_new_uint64(section_generic->TargetAddr));
85 json_object_object_add(
86 section_ir, "requestorID",
87 json_object_new_uint64(section_generic->RequestorId));
88 json_object_object_add(
89 section_ir, "responderID",
90 json_object_new_uint64(section_generic->ResponderId));
91 json_object_object_add(
92 section_ir, "instructionIP",
93 json_object_new_uint64(section_generic->InstructionIP));
94
95 return section_ir;
96 }
97
98 //Converts the given CPER-JSON processor-generic error section into CPER binary,
99 //outputting to the provided stream.
ir_section_generic_to_cper(json_object * section,FILE * out)100 void ir_section_generic_to_cper(json_object *section, FILE *out)
101 {
102 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper =
103 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc(
104 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));
105
106 //Validation bits.
107 section_cper->ValidFields = ir_to_bitfield(
108 json_object_object_get(section, "validationBits"), 13,
109 GENERIC_VALIDATION_BITFIELD_NAMES);
110
111 //Various name/value pair fields.
112 section_cper->Type = (UINT8)readable_pair_to_integer(
113 json_object_object_get(section, "processorType"));
114 section_cper->Isa = (UINT8)readable_pair_to_integer(
115 json_object_object_get(section, "processorISA"));
116 section_cper->ErrorType = (UINT8)readable_pair_to_integer(
117 json_object_object_get(section, "errorType"));
118 section_cper->Operation = (UINT8)readable_pair_to_integer(
119 json_object_object_get(section, "operation"));
120
121 //Flags.
122 section_cper->Flags =
123 (UINT8)ir_to_bitfield(json_object_object_get(section, "flags"),
124 4, GENERIC_FLAGS_BITFIELD_NAMES);
125
126 //Various numeric/string fields.
127 section_cper->Level = (UINT8)json_object_get_int(
128 json_object_object_get(section, "level"));
129 section_cper->VersionInfo = json_object_get_uint64(
130 json_object_object_get(section, "cpuVersionInfo"));
131 section_cper->ApicId = json_object_get_uint64(
132 json_object_object_get(section, "processorID"));
133 section_cper->TargetAddr = json_object_get_uint64(
134 json_object_object_get(section, "targetAddress"));
135 section_cper->RequestorId = json_object_get_uint64(
136 json_object_object_get(section, "requestorID"));
137 section_cper->ResponderId = json_object_get_uint64(
138 json_object_object_get(section, "responderID"));
139 section_cper->InstructionIP = json_object_get_uint64(
140 json_object_object_get(section, "instructionIP"));
141
142 //CPU brand string.
143 const char *brand_string = json_object_get_string(
144 json_object_object_get(section, "cpuBrandString"));
145 if (brand_string != NULL) {
146 strncpy(section_cper->BrandString, brand_string,
147 sizeof(section_cper->BrandString) - 1);
148 section_cper
149 ->BrandString[sizeof(section_cper->BrandString) - 1] =
150 '\0';
151 }
152
153 //Write & flush out to file, free memory.
154 fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out);
155 fflush(out);
156 free(section_cper);
157 }
158