xref: /openbmc/libcper/sections/cper-section-generic.c (revision e42fb487839b242371b0150ab5b0b89c2d232976)
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 <libcper/Cper.h>
12  #include <libcper/cper-utils.h>
13  #include <libcper/sections/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