blob: f33c4eca5059a2a9f56fc61ce058e6eccda62730 [file] [log] [blame]
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +01001/**
2 * Describes functions for converting IOMMU specific 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>
Lawrence Tang205dd1d2022-07-14 16:23:38 +01008#include <string.h>
Lawrence Tang5202bbb2022-08-12 14:54:36 +01009#include <json.h>
Lawrence Tangd7e8ca32022-07-07 10:25:53 +010010#include "b64.h"
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010011#include "../edk/Cper.h"
12#include "../cper-utils.h"
13#include "cper-section-dmar-iommu.h"
14
15//Converts a single IOMMU specific DMAr CPER section into JSON IR.
Lawrence Tange407b4c2022-07-21 13:54:01 +010016json_object *
17cper_section_dmar_iommu_to_ir(void *section,
18 EFI_ERROR_SECTION_DESCRIPTOR *descriptor)
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010019{
Lawrence Tange407b4c2022-07-21 13:54:01 +010020 EFI_IOMMU_DMAR_ERROR_DATA *iommu_error =
21 (EFI_IOMMU_DMAR_ERROR_DATA *)section;
22 json_object *section_ir = json_object_new_object();
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010023
Lawrence Tange407b4c2022-07-21 13:54:01 +010024 //Revision.
25 json_object_object_add(section_ir, "revision",
26 json_object_new_int(iommu_error->Revision));
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010027
Lawrence Tange407b4c2022-07-21 13:54:01 +010028 //IOMMU registers.
29 json_object_object_add(section_ir, "controlRegister",
30 json_object_new_uint64(iommu_error->Control));
31 json_object_object_add(section_ir, "statusRegister",
32 json_object_new_uint64(iommu_error->Status));
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010033
Lawrence Tange407b4c2022-07-21 13:54:01 +010034 //IOMMU event log entry.
35 //The format of these entries differ widely by the type of error.
36 char *encoded =
37 b64_encode((unsigned char *)iommu_error->EventLogEntry, 16);
38 json_object_object_add(section_ir, "eventLogEntry",
39 json_object_new_string(encoded));
40 free(encoded);
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010041
Lawrence Tange407b4c2022-07-21 13:54:01 +010042 //Device table entry (as base64).
43 encoded =
44 b64_encode((unsigned char *)iommu_error->DeviceTableEntry, 32);
45 json_object_object_add(section_ir, "deviceTableEntry",
46 json_object_new_string(encoded));
47 free(encoded);
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010048
Lawrence Tange407b4c2022-07-21 13:54:01 +010049 //Page table entries.
50 json_object_object_add(section_ir, "pageTableEntry_Level6",
51 json_object_new_uint64(iommu_error->PteL6));
52 json_object_object_add(section_ir, "pageTableEntry_Level5",
53 json_object_new_uint64(iommu_error->PteL5));
54 json_object_object_add(section_ir, "pageTableEntry_Level4",
55 json_object_new_uint64(iommu_error->PteL4));
56 json_object_object_add(section_ir, "pageTableEntry_Level3",
57 json_object_new_uint64(iommu_error->PteL3));
58 json_object_object_add(section_ir, "pageTableEntry_Level2",
59 json_object_new_uint64(iommu_error->PteL2));
60 json_object_object_add(section_ir, "pageTableEntry_Level1",
61 json_object_new_uint64(iommu_error->PteL1));
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010062
Lawrence Tange407b4c2022-07-21 13:54:01 +010063 return section_ir;
Lawrence Tang205dd1d2022-07-14 16:23:38 +010064}
65
66//Converts a single DMAR IOMMU CPER-JSON section into CPER binary, outputting to the given stream.
Lawrence Tange407b4c2022-07-21 13:54:01 +010067void ir_section_dmar_iommu_to_cper(json_object *section, FILE *out)
Lawrence Tang205dd1d2022-07-14 16:23:38 +010068{
Lawrence Tange407b4c2022-07-21 13:54:01 +010069 EFI_IOMMU_DMAR_ERROR_DATA *section_cper =
70 (EFI_IOMMU_DMAR_ERROR_DATA *)calloc(
71 1, sizeof(EFI_IOMMU_DMAR_ERROR_DATA));
Lawrence Tang205dd1d2022-07-14 16:23:38 +010072
Lawrence Tange407b4c2022-07-21 13:54:01 +010073 //Revision, registers.
74 section_cper->Revision = (UINT8)json_object_get_int(
75 json_object_object_get(section, "revision"));
76 section_cper->Control = json_object_get_uint64(
77 json_object_object_get(section, "controlRegister"));
78 section_cper->Status = json_object_get_uint64(
79 json_object_object_get(section, "statusRegister"));
Lawrence Tang205dd1d2022-07-14 16:23:38 +010080
Lawrence Tange407b4c2022-07-21 13:54:01 +010081 //IOMMU event log entry.
82 json_object *encoded = json_object_object_get(section, "eventLogEntry");
83 UINT8 *decoded = b64_decode(json_object_get_string(encoded),
84 json_object_get_string_len(encoded));
85 memcpy(section_cper->EventLogEntry, decoded, 16);
86 free(decoded);
Lawrence Tang205dd1d2022-07-14 16:23:38 +010087
Lawrence Tange407b4c2022-07-21 13:54:01 +010088 //Device table entry.
89 encoded = json_object_object_get(section, "deviceTableEntry");
90 decoded = b64_decode(json_object_get_string(encoded),
91 json_object_get_string_len(encoded));
92 memcpy(section_cper->DeviceTableEntry, decoded, 32);
93 free(decoded);
Lawrence Tang205dd1d2022-07-14 16:23:38 +010094
Lawrence Tange407b4c2022-07-21 13:54:01 +010095 //Page table entries.
96 section_cper->PteL1 = json_object_get_uint64(
97 json_object_object_get(section, "pageTableEntry_Level1"));
98 section_cper->PteL2 = json_object_get_uint64(
99 json_object_object_get(section, "pageTableEntry_Level2"));
100 section_cper->PteL3 = json_object_get_uint64(
101 json_object_object_get(section, "pageTableEntry_Level3"));
102 section_cper->PteL4 = json_object_get_uint64(
103 json_object_object_get(section, "pageTableEntry_Level4"));
104 section_cper->PteL5 = json_object_get_uint64(
105 json_object_object_get(section, "pageTableEntry_Level5"));
106 section_cper->PteL6 = json_object_get_uint64(
107 json_object_object_get(section, "pageTableEntry_Level6"));
Lawrence Tang205dd1d2022-07-14 16:23:38 +0100108
Lawrence Tange407b4c2022-07-21 13:54:01 +0100109 //Write to stream, free resources.
110 fwrite(section_cper, sizeof(EFI_IOMMU_DMAR_ERROR_DATA), 1, out);
111 fflush(out);
112 free(section_cper);
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +0100113}