blob: 420dd8dfa7d0f9c1441c97b2d9d6cce172d74321 [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.
4 *
5 * Author: Lawrence.Tang@arm.com
6 **/
7#include <stdio.h>
8#include "json.h"
9#include "../edk/Cper.h"
10#include "../cper-utils.h"
11#include "cper-section-dmar-generic.h"
12
13//Converts a single generic DMAr CPER section into JSON IR.
Lawrence Tange407b4c2022-07-21 13:54:01 +010014json_object *
15cper_section_dmar_generic_to_ir(void *section,
16 EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
Lawrence Tang4795d4a2022-07-06 15:19:31 +010017{
Lawrence Tange407b4c2022-07-21 13:54:01 +010018 EFI_DMAR_GENERIC_ERROR_DATA *firmware_error =
19 (EFI_DMAR_GENERIC_ERROR_DATA *)section;
20 json_object *section_ir = json_object_new_object();
Lawrence Tang4795d4a2022-07-06 15:19:31 +010021
Lawrence Tange407b4c2022-07-21 13:54:01 +010022 //Requester ID, segment.
23 json_object_object_add(
24 section_ir, "requesterID",
25 json_object_new_int(firmware_error->RequesterId));
26 json_object_object_add(
27 section_ir, "segmentNumber",
28 json_object_new_int(firmware_error->SegmentNumber));
Lawrence Tang4795d4a2022-07-06 15:19:31 +010029
Lawrence Tange407b4c2022-07-21 13:54:01 +010030 //Fault reason.
31 json_object *fault_reason = integer_to_readable_pair_with_desc(
32 firmware_error->FaultReason, 11,
33 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_KEYS,
34 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_VALUES,
35 DMAR_GENERIC_ERROR_FAULT_REASON_TYPES_DESCRIPTIONS,
36 "Unknown (Reserved)");
37 json_object_object_add(section_ir, "faultReason", fault_reason);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010038
Lawrence Tange407b4c2022-07-21 13:54:01 +010039 //Access type.
40 json_object *access_type = integer_to_readable_pair(
41 firmware_error->AccessType, 2,
42 DMAR_GENERIC_ERROR_ACCESS_TYPES_KEYS,
43 DMAR_GENERIC_ERROR_ACCESS_TYPES_VALUES, "Unknown (Reserved)");
44 json_object_object_add(section_ir, "accessType", access_type);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010045
Lawrence Tange407b4c2022-07-21 13:54:01 +010046 //Address type.
47 json_object *address_type = integer_to_readable_pair(
48 firmware_error->AddressType, 2,
49 DMAR_GENERIC_ERROR_ADDRESS_TYPES_KEYS,
50 DMAR_GENERIC_ERROR_ADDRESS_TYPES_VALUES, "Unknown (Reserved)");
51 json_object_object_add(section_ir, "addressType", address_type);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010052
Lawrence Tange407b4c2022-07-21 13:54:01 +010053 //Architecture type.
54 json_object *arch_type = integer_to_readable_pair(
55 firmware_error->ArchType, 2, DMAR_GENERIC_ERROR_ARCH_TYPES_KEYS,
56 DMAR_GENERIC_ERROR_ARCH_TYPES_VALUES, "Unknown (Reserved)");
57 json_object_object_add(section_ir, "architectureType", arch_type);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010058
Lawrence Tange407b4c2022-07-21 13:54:01 +010059 //Device address.
60 json_object_object_add(
61 section_ir, "deviceAddress",
62 json_object_new_uint64(firmware_error->DeviceAddr));
63
64 return section_ir;
Lawrence Tang205dd1d2022-07-14 16:23:38 +010065}
66
67//Converts a single generic DMAR CPER-JSON section into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +010068void ir_section_dmar_generic_to_cper(json_object *section, FILE *out)
Lawrence Tang205dd1d2022-07-14 16:23:38 +010069{
Lawrence Tange407b4c2022-07-21 13:54:01 +010070 EFI_DMAR_GENERIC_ERROR_DATA *section_cper =
71 (EFI_DMAR_GENERIC_ERROR_DATA *)calloc(
72 1, sizeof(EFI_DMAR_GENERIC_ERROR_DATA));
Lawrence Tang205dd1d2022-07-14 16:23:38 +010073
Lawrence Tange407b4c2022-07-21 13:54:01 +010074 //Record fields.
75 section_cper->RequesterId = (UINT16)json_object_get_int(
76 json_object_object_get(section, "requesterID"));
77 section_cper->SegmentNumber = (UINT16)json_object_get_int(
78 json_object_object_get(section, "segmentNumber"));
79 section_cper->FaultReason = (UINT8)readable_pair_to_integer(
80 json_object_object_get(section, "faultReason"));
81 section_cper->AccessType = (UINT8)readable_pair_to_integer(
82 json_object_object_get(section, "accessType"));
83 section_cper->AddressType = (UINT8)readable_pair_to_integer(
84 json_object_object_get(section, "addressType"));
85 section_cper->ArchType = (UINT8)readable_pair_to_integer(
86 json_object_object_get(section, "architectureType"));
87 section_cper->DeviceAddr = json_object_get_uint64(
88 json_object_object_get(section, "deviceAddress"));
Lawrence Tang205dd1d2022-07-14 16:23:38 +010089
Lawrence Tange407b4c2022-07-21 13:54:01 +010090 //Write to stream, free resources.
91 fwrite(section_cper, sizeof(EFI_DMAR_GENERIC_ERROR_DATA), 1, out);
92 fflush(out);
93 free(section_cper);
Lawrence Tang4795d4a2022-07-06 15:19:31 +010094}