xref: /openbmc/libcper/sections/cper-section-dmar-generic.c (revision e42fb487839b242371b0150ab5b0b89c2d232976)
1  /**
2   * Describes functions for converting generic DMAr CPER sections from binary and JSON format
3   * into an intermediate format.
4   *
5   * Author: Lawrence.Tang@arm.com
6   **/
7  #include <stdio.h>
8  #include <json.h>
9  #include <libcper/Cper.h>
10  #include <libcper/cper-utils.h>
11  #include <libcper/sections/cper-section-dmar-generic.h>
12  
13  //Converts a single generic DMAr CPER section into JSON IR.
cper_section_dmar_generic_to_ir(void * section)14  json_object *cper_section_dmar_generic_to_ir(void *section)
15  {
16  	EFI_DMAR_GENERIC_ERROR_DATA *firmware_error =
17  		(EFI_DMAR_GENERIC_ERROR_DATA *)section;
18  	json_object *section_ir = json_object_new_object();
19  
20  	//Requester ID, segment.
21  	json_object_object_add(
22  		section_ir, "requesterID",
23  		json_object_new_int(firmware_error->RequesterId));
24  	json_object_object_add(
25  		section_ir, "segmentNumber",
26  		json_object_new_int(firmware_error->SegmentNumber));
27  
28  	//Fault reason.
29  	json_object *fault_reason = integer_to_readable_pair_with_desc(
30  		firmware_error->FaultReason, 11,
31  		DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_KEYS,
32  		DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_VALUES,
33  		DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_DESCRIPTIONS,
34  		"Unknown (Reserved)");
35  	json_object_object_add(section_ir, "faultReason", fault_reason);
36  
37  	//Access type.
38  	json_object *access_type = integer_to_readable_pair(
39  		firmware_error->AccessType, 2,
40  		DMAR_GENERIC_ERROR_ACCESS_TYPES_KEYS,
41  		DMAR_GENERIC_ERROR_ACCESS_TYPES_VALUES, "Unknown (Reserved)");
42  	json_object_object_add(section_ir, "accessType", access_type);
43  
44  	//Address type.
45  	json_object *address_type = integer_to_readable_pair(
46  		firmware_error->AddressType, 2,
47  		DMAR_GENERIC_ERROR_ADDRESS_TYPES_KEYS,
48  		DMAR_GENERIC_ERROR_ADDRESS_TYPES_VALUES, "Unknown (Reserved)");
49  	json_object_object_add(section_ir, "addressType", address_type);
50  
51  	//Architecture type.
52  	json_object *arch_type = integer_to_readable_pair(
53  		firmware_error->ArchType, 2, DMAR_GENERIC_ERROR_ARCH_TYPES_KEYS,
54  		DMAR_GENERIC_ERROR_ARCH_TYPES_VALUES, "Unknown (Reserved)");
55  	json_object_object_add(section_ir, "architectureType", arch_type);
56  
57  	//Device address.
58  	json_object_object_add(
59  		section_ir, "deviceAddress",
60  		json_object_new_uint64(firmware_error->DeviceAddr));
61  
62  	return section_ir;
63  }
64  
65  //Converts a single generic DMAR CPER-JSON section into CPER binary, outputting to the given stream.
ir_section_dmar_generic_to_cper(json_object * section,FILE * out)66  void ir_section_dmar_generic_to_cper(json_object *section, FILE *out)
67  {
68  	EFI_DMAR_GENERIC_ERROR_DATA *section_cper =
69  		(EFI_DMAR_GENERIC_ERROR_DATA *)calloc(
70  			1, sizeof(EFI_DMAR_GENERIC_ERROR_DATA));
71  
72  	//Record fields.
73  	section_cper->RequesterId = (UINT16)json_object_get_int(
74  		json_object_object_get(section, "requesterID"));
75  	section_cper->SegmentNumber = (UINT16)json_object_get_int(
76  		json_object_object_get(section, "segmentNumber"));
77  	section_cper->FaultReason = (UINT8)readable_pair_to_integer(
78  		json_object_object_get(section, "faultReason"));
79  	section_cper->AccessType = (UINT8)readable_pair_to_integer(
80  		json_object_object_get(section, "accessType"));
81  	section_cper->AddressType = (UINT8)readable_pair_to_integer(
82  		json_object_object_get(section, "addressType"));
83  	section_cper->ArchType = (UINT8)readable_pair_to_integer(
84  		json_object_object_get(section, "architectureType"));
85  	section_cper->DeviceAddr = json_object_get_uint64(
86  		json_object_object_get(section, "deviceAddress"));
87  
88  	//Write to stream, free resources.
89  	fwrite(section_cper, sizeof(EFI_DMAR_GENERIC_ERROR_DATA), 1, out);
90  	fflush(out);
91  	free(section_cper);
92  }
93