blob: 6a0de01eb739402b19285d1abe92719d13ea5aed [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.
4 *
5 * 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>
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010011#include "../edk/Cper.h"
12#include "../cper-utils.h"
Lawrence Tang3c43f742022-07-05 11:37:17 +010013#include "cper-section-generic.h"
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010014
15//Converts the given processor-generic CPER section into JSON IR.
Lawrence Tange407b4c2022-07-21 13:54:01 +010016json_object *
17cper_section_generic_to_ir(void *section,
18 EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
Lawrence Tang1b0b00e2022-07-05 10:33:10 +010019{
Lawrence Tange407b4c2022-07-21 13:54:01 +010020 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_generic =
21 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)section;
22 json_object *section_ir = json_object_new_object();
Lawrence Tang3c43f742022-07-05 11:37:17 +010023
Lawrence Tange407b4c2022-07-21 13:54:01 +010024 //Validation bits.
25 json_object *validation =
26 bitfield_to_ir(section_generic->ValidFields, 13,
27 GENERIC_VALIDATION_BITFIELD_NAMES);
28 json_object_object_add(section_ir, "validationBits", validation);
Lawrence Tang3c43f742022-07-05 11:37:17 +010029
Lawrence Tange407b4c2022-07-21 13:54:01 +010030 //Processor type, with human readable name if possible.
31 json_object *processor_type = integer_to_readable_pair(
32 section_generic->Type,
33 sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
34 GENERIC_PROC_TYPES_KEYS, GENERIC_PROC_TYPES_VALUES,
35 "Unknown (Reserved)");
36 json_object_object_add(section_ir, "processorType", processor_type);
Lawrence Tang3c43f742022-07-05 11:37:17 +010037
Lawrence Tange407b4c2022-07-21 13:54:01 +010038 //Processor ISA, with human readable name if possible.
39 json_object *processor_isa = integer_to_readable_pair(
40 section_generic->Isa,
41 sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
42 GENERIC_ISA_TYPES_KEYS, GENERIC_ISA_TYPES_VALUES,
43 "Unknown (Reserved)");
44 json_object_object_add(section_ir, "processorISA", processor_isa);
Lawrence Tang3c43f742022-07-05 11:37:17 +010045
Lawrence Tange407b4c2022-07-21 13:54:01 +010046 //Processor error type, with human readable name if possible.
47 json_object *processor_error_type = integer_to_readable_pair(
48 section_generic->ErrorType,
49 sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
50 GENERIC_ERROR_TYPES_KEYS, GENERIC_ERROR_TYPES_VALUES,
51 "Unknown (Reserved)");
52 json_object_object_add(section_ir, "errorType", processor_error_type);
Lawrence Tang3c43f742022-07-05 11:37:17 +010053
Lawrence Tange407b4c2022-07-21 13:54:01 +010054 //The operation performed, with a human readable name if possible.
55 json_object *operation = integer_to_readable_pair(
56 section_generic->Operation,
57 sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
58 GENERIC_OPERATION_TYPES_KEYS, GENERIC_OPERATION_TYPES_VALUES,
59 "Unknown (Reserved)");
60 json_object_object_add(section_ir, "operation", operation);
Lawrence Tang3c43f742022-07-05 11:37:17 +010061
Lawrence Tange407b4c2022-07-21 13:54:01 +010062 //Flags, additional information about the error.
63 json_object *flags = bitfield_to_ir(section_generic->Flags, 4,
64 GENERIC_FLAGS_BITFIELD_NAMES);
65 json_object_object_add(section_ir, "flags", flags);
Lawrence Tang3c43f742022-07-05 11:37:17 +010066
Lawrence Tange407b4c2022-07-21 13:54:01 +010067 //The level of the error.
68 json_object_object_add(section_ir, "level",
69 json_object_new_int(section_generic->Level));
Lawrence Tang3c43f742022-07-05 11:37:17 +010070
Lawrence Tange407b4c2022-07-21 13:54:01 +010071 //CPU version information.
72 json_object_object_add(
73 section_ir, "cpuVersionInfo",
74 json_object_new_uint64(section_generic->VersionInfo));
Lawrence Tang3c43f742022-07-05 11:37:17 +010075
Lawrence Tange407b4c2022-07-21 13:54:01 +010076 //CPU brand string. May not exist if on ARM.
77 json_object_object_add(
78 section_ir, "cpuBrandString",
79 json_object_new_string(section_generic->BrandString));
Lawrence Tang3c43f742022-07-05 11:37:17 +010080
Lawrence Tange407b4c2022-07-21 13:54:01 +010081 //Remaining 64-bit fields.
82 json_object_object_add(section_ir, "processorID",
83 json_object_new_uint64(section_generic->ApicId));
84 json_object_object_add(
85 section_ir, "targetAddress",
86 json_object_new_uint64(section_generic->TargetAddr));
87 json_object_object_add(
88 section_ir, "requestorID",
89 json_object_new_uint64(section_generic->RequestorId));
90 json_object_object_add(
91 section_ir, "responderID",
92 json_object_new_uint64(section_generic->ResponderId));
93 json_object_object_add(
94 section_ir, "instructionIP",
95 json_object_new_uint64(section_generic->InstructionIP));
Lawrence Tang3c43f742022-07-05 11:37:17 +010096
Lawrence Tange407b4c2022-07-21 13:54:01 +010097 return section_ir;
Lawrence Tang0cb33792022-07-13 13:51:39 +010098}
99
100//Converts the given CPER-JSON processor-generic error section into CPER binary,
101//outputting to the provided stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100102void ir_section_generic_to_cper(json_object *section, FILE *out)
Lawrence Tang0cb33792022-07-13 13:51:39 +0100103{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100104 EFI_PROCESSOR_GENERIC_ERROR_DATA *section_cper =
105 (EFI_PROCESSOR_GENERIC_ERROR_DATA *)calloc(
106 1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100107
Lawrence Tange407b4c2022-07-21 13:54:01 +0100108 //Validation bits.
109 section_cper->ValidFields = ir_to_bitfield(
110 json_object_object_get(section, "validationBits"), 13,
111 GENERIC_VALIDATION_BITFIELD_NAMES);
Lawrence Tang0cb33792022-07-13 13:51:39 +0100112
Lawrence Tange407b4c2022-07-21 13:54:01 +0100113 //Various name/value pair fields.
114 section_cper->Type = (UINT8)readable_pair_to_integer(
115 json_object_object_get(section, "processorType"));
116 section_cper->Isa = (UINT8)readable_pair_to_integer(
117 json_object_object_get(section, "processorISA"));
118 section_cper->ErrorType = (UINT8)readable_pair_to_integer(
119 json_object_object_get(section, "errorType"));
120 section_cper->Operation = (UINT8)readable_pair_to_integer(
121 json_object_object_get(section, "operation"));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100122
Lawrence Tange407b4c2022-07-21 13:54:01 +0100123 //Flags.
124 section_cper->Flags =
125 (UINT8)ir_to_bitfield(json_object_object_get(section, "flags"),
126 4, GENERIC_FLAGS_BITFIELD_NAMES);
Lawrence Tang0cb33792022-07-13 13:51:39 +0100127
Lawrence Tange407b4c2022-07-21 13:54:01 +0100128 //Various numeric/string fields.
129 section_cper->Level = (UINT8)json_object_get_int(
130 json_object_object_get(section, "level"));
131 section_cper->VersionInfo = json_object_get_uint64(
132 json_object_object_get(section, "cpuVersionInfo"));
133 section_cper->ApicId = json_object_get_uint64(
134 json_object_object_get(section, "processorID"));
135 section_cper->TargetAddr = json_object_get_uint64(
136 json_object_object_get(section, "targetAddress"));
137 section_cper->RequestorId = json_object_get_uint64(
138 json_object_object_get(section, "requestorID"));
139 section_cper->ResponderId = json_object_get_uint64(
140 json_object_object_get(section, "responderID"));
141 section_cper->InstructionIP = json_object_get_uint64(
142 json_object_object_get(section, "instructionIP"));
Lawrence Tang0cb33792022-07-13 13:51:39 +0100143
Lawrence Tange407b4c2022-07-21 13:54:01 +0100144 //CPU brand string.
145 const char *brand_string = json_object_get_string(
146 json_object_object_get(section, "cpuBrandString"));
147 if (brand_string != NULL)
148 strncpy(section_cper->BrandString, brand_string, 127);
149
150 //Write & flush out to file, free memory.
151 fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out);
152 fflush(out);
153 free(section_cper);
Lawrence Tang1b0b00e2022-07-05 10:33:10 +0100154}