blob: c82730b6c1334df70254219a759b807234a78071 [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 Tang1b0b00e2022-07-05 10:33:10 +010010#include "json.h"
11#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.
16json_object* cper_section_generic_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
17{
Lawrence Tang3c43f742022-07-05 11:37:17 +010018 EFI_PROCESSOR_GENERIC_ERROR_DATA* section_generic = (EFI_PROCESSOR_GENERIC_ERROR_DATA*)section;
19 json_object* section_ir = json_object_new_object();
20
21 //Validation bits.
Lawrence Tang22a467c2022-07-05 17:21:06 +010022 json_object* validation = bitfield_to_ir(section_generic->ValidFields, 13, GENERIC_VALIDATION_BITFIELD_NAMES);
Lawrence Tang3c43f742022-07-05 11:37:17 +010023 json_object_object_add(section_ir, "validationBits", validation);
24
25 //Processor type, with human readable name if possible.
26 json_object* processor_type = integer_to_readable_pair(section_generic->Type,
27 sizeof(GENERIC_PROC_TYPES_KEYS) / sizeof(int),
28 GENERIC_PROC_TYPES_KEYS,
29 GENERIC_PROC_TYPES_VALUES,
30 "Unknown (Reserved)");
31 json_object_object_add(section_ir, "processorType", processor_type);
32
33 //Processor ISA, with human readable name if possible.
34 json_object* processor_isa = integer_to_readable_pair(section_generic->Isa,
35 sizeof(GENERIC_ISA_TYPES_KEYS) / sizeof(int),
36 GENERIC_ISA_TYPES_KEYS,
37 GENERIC_ISA_TYPES_VALUES,
Lawrence Tang67cbed62022-07-18 16:44:51 +010038 "Unknown (Reserved)");
Lawrence Tang3c43f742022-07-05 11:37:17 +010039 json_object_object_add(section_ir, "processorISA", processor_isa);
40
41 //Processor error type, with human readable name if possible.
42 json_object* processor_error_type = integer_to_readable_pair(section_generic->ErrorType,
43 sizeof(GENERIC_ERROR_TYPES_KEYS) / sizeof(int),
44 GENERIC_ERROR_TYPES_KEYS,
45 GENERIC_ERROR_TYPES_VALUES,
Lawrence Tang67cbed62022-07-18 16:44:51 +010046 "Unknown (Reserved)");
Lawrence Tang3c43f742022-07-05 11:37:17 +010047 json_object_object_add(section_ir, "errorType", processor_error_type);
48
49 //The operation performed, with a human readable name if possible.
50 json_object* operation = integer_to_readable_pair(section_generic->Operation,
51 sizeof(GENERIC_OPERATION_TYPES_KEYS) / sizeof(int),
52 GENERIC_OPERATION_TYPES_KEYS,
53 GENERIC_OPERATION_TYPES_VALUES,
Lawrence Tang67cbed62022-07-18 16:44:51 +010054 "Unknown (Reserved)");
Lawrence Tang3c43f742022-07-05 11:37:17 +010055 json_object_object_add(section_ir, "operation", operation);
56
57 //Flags, additional information about the error.
Lawrence Tang22a467c2022-07-05 17:21:06 +010058 json_object* flags = bitfield_to_ir(section_generic->Flags, 4, GENERIC_FLAGS_BITFIELD_NAMES);
Lawrence Tang3c43f742022-07-05 11:37:17 +010059 json_object_object_add(section_ir, "flags", flags);
60
61 //The level of the error.
62 json_object_object_add(section_ir, "level", json_object_new_int(section_generic->Level));
63
Lawrence Tang9a785c22022-07-07 15:47:17 +010064 //CPU version information.
65 json_object_object_add(section_ir, "cpuVersionInfo", json_object_new_uint64(section_generic->VersionInfo));
Lawrence Tang3c43f742022-07-05 11:37:17 +010066
67 //CPU brand string. May not exist if on ARM.
68 json_object_object_add(section_ir, "cpuBrandString", json_object_new_string(section_generic->BrandString));
69
70 //Remaining 64-bit fields.
71 json_object_object_add(section_ir, "processorID", json_object_new_uint64(section_generic->ApicId));
72 json_object_object_add(section_ir, "targetAddress", json_object_new_uint64(section_generic->TargetAddr));
73 json_object_object_add(section_ir, "requestorID", json_object_new_uint64(section_generic->RequestorId));
74 json_object_object_add(section_ir, "responderID", json_object_new_uint64(section_generic->ResponderId));
75 json_object_object_add(section_ir, "instructionIP", json_object_new_uint64(section_generic->InstructionIP));
76
77 return section_ir;
Lawrence Tang0cb33792022-07-13 13:51:39 +010078}
79
80//Converts the given CPER-JSON processor-generic error section into CPER binary,
81//outputting to the provided stream.
82void ir_section_generic_to_cper(json_object* section, FILE* out)
83{
84 EFI_PROCESSOR_GENERIC_ERROR_DATA* section_cper =
85 (EFI_PROCESSOR_GENERIC_ERROR_DATA*)calloc(1, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA));
86
87 //Validation bits.
88 section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"),
Lawrence Tangaacf0e22022-07-20 13:28:52 +010089 13, GENERIC_VALIDATION_BITFIELD_NAMES);
Lawrence Tang0cb33792022-07-13 13:51:39 +010090
91 //Various name/value pair fields.
92 section_cper->Type = (UINT8)readable_pair_to_integer(json_object_object_get(section, "processorType"));
93 section_cper->Isa = (UINT8)readable_pair_to_integer(json_object_object_get(section, "processorISA"));
94 section_cper->ErrorType = (UINT8)readable_pair_to_integer(json_object_object_get(section, "errorType"));
95 section_cper->Operation = (UINT8)readable_pair_to_integer(json_object_object_get(section, "operation"));
96
97 //Flags.
98 section_cper->Flags = (UINT8)ir_to_bitfield(json_object_object_get(section, "flags"), 4, GENERIC_FLAGS_BITFIELD_NAMES);
99
100 //Various numeric/string fields.
101 section_cper->Level = (UINT8)json_object_get_int(json_object_object_get(section, "level"));
102 section_cper->VersionInfo = json_object_get_uint64(json_object_object_get(section, "cpuVersionInfo"));
103 section_cper->ApicId = json_object_get_uint64(json_object_object_get(section, "processorID"));
104 section_cper->TargetAddr = json_object_get_uint64(json_object_object_get(section, "targetAddress"));
105 section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID"));
106 section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID"));
107 section_cper->InstructionIP = json_object_get_uint64(json_object_object_get(section, "instructionIP"));
108
109 //CPU brand string.
110 const char* brand_string = json_object_get_string(json_object_object_get(section, "cpuBrandString"));
111 if (brand_string != NULL)
112 strncpy(section_cper->BrandString, brand_string, 127);
113
114 //Write & flush out to file, free memory.
115 fwrite(section_cper, sizeof(EFI_PROCESSOR_GENERIC_ERROR_DATA), 1, out);
116 fflush(out);
117 free(section_cper);
Lawrence Tang1b0b00e2022-07-05 10:33:10 +0100118}