blob: ebbd6283e45cabe7561f63df2eb73759be55c875 [file] [log] [blame]
Lawrence Tang1b0b00e2022-07-05 10:33:10 +01001/**
2 * Describes functions for converting processor-generic CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang1b0b00e2022-07-05 10:33:10 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7
8#include <stdio.h>
Lawrence Tang0cb33792022-07-13 13:51:39 +01009#include <string.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +010010#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +000011#include <libcper/Cper.h>
12#include <libcper/cper-utils.h>
13#include <libcper/sections/cper-section-generic.h>
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010014
15//Converts the given processor-generic CPER section into JSON IR.
John Chungf8fc7052024-05-03 20:05:29 +080016json_object *cper_section_generic_to_ir(void *section)
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010017{
Lawrence Tange407b4c2022-07-21 13:54:01 +010018 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic =
19 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
20 json_object *section_ir = json_object_new_object();
Lawrence Tang3c43f742022-07-05 11:37:17 +010021
Lawrence Tange407b4c2022-07-21 13:54:01 +010022 //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);
Lawrence Tang3c43f742022-07-05 11:37:17 +010027
Lawrence Tange407b4c2022-07-21 13:54:01 +010028 //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);
Lawrence Tang3c43f742022-07-05 11:37:17 +010035
Lawrence Tange407b4c2022-07-21 13:54:01 +010036 //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);
Lawrence Tang3c43f742022-07-05 11:37:17 +010043
Lawrence Tange407b4c2022-07-21 13:54:01 +010044 //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);
Lawrence Tang3c43f742022-07-05 11:37:17 +010051
Lawrence Tange407b4c2022-07-21 13:54:01 +010052 //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);
Lawrence Tang3c43f742022-07-05 11:37:17 +010059
Lawrence Tange407b4c2022-07-21 13:54:01 +010060 //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);
Lawrence Tang3c43f742022-07-05 11:37:17 +010064
Lawrence Tange407b4c2022-07-21 13:54:01 +010065 //The level of the error.
66 json_object_object_add(section_ir, "level",
67 json_object_new_int(section_generic->Level));
Lawrence Tang3c43f742022-07-05 11:37:17 +010068
Lawrence Tange407b4c2022-07-21 13:54:01 +010069 //CPU version information.
70 json_object_object_add(
71 section_ir, "cpuVersionInfo",
72 json_object_new_uint64(section_generic->VersionInfo));
Lawrence Tang3c43f742022-07-05 11:37:17 +010073
Lawrence Tange407b4c2022-07-21 13:54:01 +010074 //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));
Lawrence Tang3c43f742022-07-05 11:37:17 +010078
Lawrence Tange407b4c2022-07-21 13:54:01 +010079 //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));
Lawrence Tang3c43f742022-07-05 11:37:17 +010094
Lawrence Tange407b4c2022-07-21 13:54:01 +010095 return section_ir;
Lawrence Tang0cb33792022-07-13 13:51:39 +010096}
97
98//Converts the given CPER-JSON processor-generic error section into CPER binary,
99//outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100100void ir_section_generic_to_cper(json_object *section, FILE *out)
Lawrence Tang0cb33792022-07-13 13:51:39 +0100101{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100102 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper =
103 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc(
104 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100105
Lawrence Tange407b4c2022-07-21 13:54:01 +0100106 //Validation bits.
107 section_cper->ValidFields = ir_to_bitfield(
108 json_object_object_get(section, "validationBits"), 13,
109 GENERIC_VALIDATION_BITFIELD_NAMES);
Lawrence Tang0cb33792022-07-13 13:51:39 +0100110
Lawrence Tange407b4c2022-07-21 13:54:01 +0100111 //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"));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100120
Lawrence Tange407b4c2022-07-21 13:54:01 +0100121 //Flags.
122 section_cper->Flags =
123 (UINT8)ir_to_bitfield(json_object_object_get(section, "flags"),
124 4, GENERIC_FLAGS_BITFIELD_NAMES);
Lawrence Tang0cb33792022-07-13 13:51:39 +0100125
Lawrence Tange407b4c2022-07-21 13:54:01 +0100126 //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"));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100141
Lawrence Tange407b4c2022-07-21 13:54:01 +0100142 //CPU brand string.
143 const char *brand_string = json_object_get_string(
144 json_object_object_get(section, "cpuBrandString"));
John Chungf8fc7052024-05-03 20:05:29 +0800145 if (brand_string != NULL) {
Patrick Williams379e4922024-08-28 11:14:34 -0400146 strncpy(section_cper->BrandString, brand_string,
147 sizeof(section_cper->BrandString) - 1);
148 section_cper
149 ->BrandString[sizeof(section_cper->BrandString) - 1] =
150 '\0';
John Chungf8fc7052024-05-03 20:05:29 +0800151 }
Lawrence Tange407b4c2022-07-21 13:54:01 +0100152
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);
John Chungf8fc7052024-05-03 20:05:29 +0800157}