blob: e745d2b5524a0bed54e70fecff646b38358495a4 [file] [log] [blame]
Lawrence Tang4795d4a2022-07-06 15:19:31 +01001/**
2 * Describes functions for converting generic DMAr CPER sections from binary and JSON format
3 * into an intermediate format.
Ed Tanousfedd4572024-07-12 13:56:00 -07004 *
Lawrence Tang4795d4a2022-07-06 15:19:31 +01005 * Author: Lawrence.Tang@arm.com
6 **/
7#include <stdio.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01008#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +00009#include <libcper/Cper.h>
10#include <libcper/cper-utils.h>
11#include <libcper/sections/cper-section-dmar-generic.h>
Lawrence Tang4795d4a2022-07-06 15:19:31 +010012
13//Converts a single generic DMAr CPER section into JSON IR.
Ed Tanous12dbd4f2025-03-08 19:05:01 -080014json_object *cper_section_dmar_generic_to_ir(const UINT8 *section, UINT32 size)
Lawrence Tang4795d4a2022-07-06 15:19:31 +010015{
Ed Tanous12dbd4f2025-03-08 19:05:01 -080016 if (size < sizeof(EFI_DMAR_GENERIC_ERROR_DATA)) {
17 return NULL;
18 }
19
Lawrence Tange407b4c2022-07-21 13:54:01 +010020 EFI_DMAR_GENERIC_ERROR_DATA *firmware_error =
21 (EFI_DMAR_GENERIC_ERROR_DATA *)section;
22 json_object *section_ir = json_object_new_object();
Lawrence Tang4795d4a2022-07-06 15:19:31 +010023
Lawrence Tange407b4c2022-07-21 13:54:01 +010024 //Requester ID, segment.
25 json_object_object_add(
26 section_ir, "requesterID",
27 json_object_new_int(firmware_error->RequesterId));
28 json_object_object_add(
29 section_ir, "segmentNumber",
30 json_object_new_int(firmware_error->SegmentNumber));
Lawrence Tang4795d4a2022-07-06 15:19:31 +010031
Lawrence Tange407b4c2022-07-21 13:54:01 +010032 //Fault reason.
33 json_object *fault_reason = integer_to_readable_pair_with_desc(
34 firmware_error->FaultReason, 11,
35 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_KEYS,
36 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_VALUES,
37 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_DESCRIPTIONS,
38 "Unknown (Reserved)");
39 json_object_object_add(section_ir, "faultReason", fault_reason);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010040
Lawrence Tange407b4c2022-07-21 13:54:01 +010041 //Access type.
42 json_object *access_type = integer_to_readable_pair(
43 firmware_error->AccessType, 2,
44 DMAR_GENERIC_ERROR_ACCESS_TYPES_KEYS,
45 DMAR_GENERIC_ERROR_ACCESS_TYPES_VALUES, "Unknown (Reserved)");
46 json_object_object_add(section_ir, "accessType", access_type);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010047
Lawrence Tange407b4c2022-07-21 13:54:01 +010048 //Address type.
49 json_object *address_type = integer_to_readable_pair(
50 firmware_error->AddressType, 2,
51 DMAR_GENERIC_ERROR_ADDRESS_TYPES_KEYS,
52 DMAR_GENERIC_ERROR_ADDRESS_TYPES_VALUES, "Unknown (Reserved)");
53 json_object_object_add(section_ir, "addressType", address_type);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010054
Lawrence Tange407b4c2022-07-21 13:54:01 +010055 //Architecture type.
56 json_object *arch_type = integer_to_readable_pair(
57 firmware_error->ArchType, 2, DMAR_GENERIC_ERROR_ARCH_TYPES_KEYS,
58 DMAR_GENERIC_ERROR_ARCH_TYPES_VALUES, "Unknown (Reserved)");
59 json_object_object_add(section_ir, "architectureType", arch_type);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010060
Lawrence Tange407b4c2022-07-21 13:54:01 +010061 //Device address.
62 json_object_object_add(
63 section_ir, "deviceAddress",
64 json_object_new_uint64(firmware_error->DeviceAddr));
65
66 return section_ir;
Lawrence Tang205dd1d2022-07-14 16:23:38 +010067}
68
69//Converts a single generic DMAR CPER-JSON section into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +010070void ir_section_dmar_generic_to_cper(json_object *section, FILE *out)
Lawrence Tang205dd1d2022-07-14 16:23:38 +010071{
Lawrence Tange407b4c2022-07-21 13:54:01 +010072 EFI_DMAR_GENERIC_ERROR_DATA *section_cper =
73 (EFI_DMAR_GENERIC_ERROR_DATA *)calloc(
74 1, sizeof(EFI_DMAR_GENERIC_ERROR_DATA));
Lawrence Tang205dd1d2022-07-14 16:23:38 +010075
Lawrence Tange407b4c2022-07-21 13:54:01 +010076 //Record fields.
77 section_cper->RequesterId = (UINT16)json_object_get_int(
78 json_object_object_get(section, "requesterID"));
79 section_cper->SegmentNumber = (UINT16)json_object_get_int(
80 json_object_object_get(section, "segmentNumber"));
81 section_cper->FaultReason = (UINT8)readable_pair_to_integer(
82 json_object_object_get(section, "faultReason"));
83 section_cper->AccessType = (UINT8)readable_pair_to_integer(
84 json_object_object_get(section, "accessType"));
85 section_cper->AddressType = (UINT8)readable_pair_to_integer(
86 json_object_object_get(section, "addressType"));
87 section_cper->ArchType = (UINT8)readable_pair_to_integer(
88 json_object_object_get(section, "architectureType"));
89 section_cper->DeviceAddr = json_object_get_uint64(
90 json_object_object_get(section, "deviceAddress"));
Lawrence Tang205dd1d2022-07-14 16:23:38 +010091
Lawrence Tange407b4c2022-07-21 13:54:01 +010092 //Write to stream, free resources.
93 fwrite(section_cper, sizeof(EFI_DMAR_GENERIC_ERROR_DATA), 1, out);
94 fflush(out);
95 free(section_cper);
John Chungf8fc7052024-05-03 20:05:29 +080096}