14795d4aeSLawrence Tang /**
24795d4aeSLawrence Tang  * Describes functions for converting generic DMAr CPER sections from binary and JSON format
34795d4aeSLawrence Tang  * into an intermediate format.
44795d4aeSLawrence Tang  *
54795d4aeSLawrence Tang  * Author: Lawrence.Tang@arm.com
64795d4aeSLawrence Tang  **/
74795d4aeSLawrence Tang #include <stdio.h>
85202bbb4SLawrence Tang #include <json.h>
94795d4aeSLawrence Tang #include "../edk/Cper.h"
104795d4aeSLawrence Tang #include "../cper-utils.h"
114795d4aeSLawrence Tang #include "cper-section-dmar-generic.h"
124795d4aeSLawrence Tang 
134795d4aeSLawrence Tang //Converts a single generic DMAr CPER section into JSON IR.
cper_section_dmar_generic_to_ir(void * section)14*f8fc7052SJohn Chung json_object *cper_section_dmar_generic_to_ir(void *section)
154795d4aeSLawrence Tang {
16e407b4c8SLawrence Tang 	EFI_DMAR_GENERIC_ERROR_DATA *firmware_error =
17e407b4c8SLawrence Tang 		(EFI_DMAR_GENERIC_ERROR_DATA *)section;
184795d4aeSLawrence Tang 	json_object *section_ir = json_object_new_object();
194795d4aeSLawrence Tang 
204795d4aeSLawrence Tang 	//Requester ID, segment.
21e407b4c8SLawrence Tang 	json_object_object_add(
22e407b4c8SLawrence Tang 		section_ir, "requesterID",
23e407b4c8SLawrence Tang 		json_object_new_int(firmware_error->RequesterId));
24e407b4c8SLawrence Tang 	json_object_object_add(
25e407b4c8SLawrence Tang 		section_ir, "segmentNumber",
26e407b4c8SLawrence Tang 		json_object_new_int(firmware_error->SegmentNumber));
274795d4aeSLawrence Tang 
284795d4aeSLawrence Tang 	//Fault reason.
29e407b4c8SLawrence Tang 	json_object *fault_reason = integer_to_readable_pair_with_desc(
30e407b4c8SLawrence Tang 		firmware_error->FaultReason, 11,
314795d4aeSLawrence Tang 		DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_KEYS,
324795d4aeSLawrence Tang 		DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_VALUES,
334795d4aeSLawrence Tang 		DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_DESCRIPTIONS,
344795d4aeSLawrence Tang 		"Unknown (Reserved)");
354795d4aeSLawrence Tang 	json_object_object_add(section_ir, "faultReason", fault_reason);
364795d4aeSLawrence Tang 
374795d4aeSLawrence Tang 	//Access type.
38e407b4c8SLawrence Tang 	json_object *access_type = integer_to_readable_pair(
39e407b4c8SLawrence Tang 		firmware_error->AccessType, 2,
404795d4aeSLawrence Tang 		DMAR_GENERIC_ERROR_ACCESS_TYPES_KEYS,
41e407b4c8SLawrence Tang 		DMAR_GENERIC_ERROR_ACCESS_TYPES_VALUES, "Unknown (Reserved)");
424795d4aeSLawrence Tang 	json_object_object_add(section_ir, "accessType", access_type);
434795d4aeSLawrence Tang 
444795d4aeSLawrence Tang 	//Address type.
45e407b4c8SLawrence Tang 	json_object *address_type = integer_to_readable_pair(
46e407b4c8SLawrence Tang 		firmware_error->AddressType, 2,
474795d4aeSLawrence Tang 		DMAR_GENERIC_ERROR_ADDRESS_TYPES_KEYS,
48e407b4c8SLawrence Tang 		DMAR_GENERIC_ERROR_ADDRESS_TYPES_VALUES, "Unknown (Reserved)");
494795d4aeSLawrence Tang 	json_object_object_add(section_ir, "addressType", address_type);
504795d4aeSLawrence Tang 
514795d4aeSLawrence Tang 	//Architecture type.
52e407b4c8SLawrence Tang 	json_object *arch_type = integer_to_readable_pair(
53e407b4c8SLawrence Tang 		firmware_error->ArchType, 2, DMAR_GENERIC_ERROR_ARCH_TYPES_KEYS,
54e407b4c8SLawrence Tang 		DMAR_GENERIC_ERROR_ARCH_TYPES_VALUES, "Unknown (Reserved)");
554795d4aeSLawrence Tang 	json_object_object_add(section_ir, "architectureType", arch_type);
564795d4aeSLawrence Tang 
574795d4aeSLawrence Tang 	//Device address.
58e407b4c8SLawrence Tang 	json_object_object_add(
59e407b4c8SLawrence Tang 		section_ir, "deviceAddress",
60e407b4c8SLawrence Tang 		json_object_new_uint64(firmware_error->DeviceAddr));
614795d4aeSLawrence Tang 
624795d4aeSLawrence Tang 	return section_ir;
634795d4aeSLawrence Tang }
64205dd1d7SLawrence Tang 
65205dd1d7SLawrence Tang //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)66205dd1d7SLawrence Tang void ir_section_dmar_generic_to_cper(json_object *section, FILE *out)
67205dd1d7SLawrence Tang {
68205dd1d7SLawrence Tang 	EFI_DMAR_GENERIC_ERROR_DATA *section_cper =
69e407b4c8SLawrence Tang 		(EFI_DMAR_GENERIC_ERROR_DATA *)calloc(
70e407b4c8SLawrence Tang 			1, sizeof(EFI_DMAR_GENERIC_ERROR_DATA));
71205dd1d7SLawrence Tang 
72205dd1d7SLawrence Tang 	//Record fields.
73e407b4c8SLawrence Tang 	section_cper->RequesterId = (UINT16)json_object_get_int(
74e407b4c8SLawrence Tang 		json_object_object_get(section, "requesterID"));
75e407b4c8SLawrence Tang 	section_cper->SegmentNumber = (UINT16)json_object_get_int(
76e407b4c8SLawrence Tang 		json_object_object_get(section, "segmentNumber"));
77e407b4c8SLawrence Tang 	section_cper->FaultReason = (UINT8)readable_pair_to_integer(
78e407b4c8SLawrence Tang 		json_object_object_get(section, "faultReason"));
79e407b4c8SLawrence Tang 	section_cper->AccessType = (UINT8)readable_pair_to_integer(
80e407b4c8SLawrence Tang 		json_object_object_get(section, "accessType"));
81e407b4c8SLawrence Tang 	section_cper->AddressType = (UINT8)readable_pair_to_integer(
82e407b4c8SLawrence Tang 		json_object_object_get(section, "addressType"));
83e407b4c8SLawrence Tang 	section_cper->ArchType = (UINT8)readable_pair_to_integer(
84e407b4c8SLawrence Tang 		json_object_object_get(section, "architectureType"));
85e407b4c8SLawrence Tang 	section_cper->DeviceAddr = json_object_get_uint64(
86e407b4c8SLawrence Tang 		json_object_object_get(section, "deviceAddress"));
87205dd1d7SLawrence Tang 
88205dd1d7SLawrence Tang 	//Write to stream, free resources.
893ab351feSLawrence Tang 	fwrite(section_cper, sizeof(EFI_DMAR_GENERIC_ERROR_DATA), 1, out);
90205dd1d7SLawrence Tang 	fflush(out);
91205dd1d7SLawrence Tang 	free(section_cper);
92205dd1d7SLawrence Tang }
93