blob: 0298df0d7213748be9676698c11277e6f2fab2a5 [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 Tangdb1b7ce2022-07-06 15:40:26 +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.
16json_object* cper_section_dmar_iommu_to_ir(void* section, EFI_ERROR_SECTION_DESCRIPTOR* descriptor)
17{
18 EFI_IOMMU_DMAR_ERROR_DATA* iommu_error = (EFI_IOMMU_DMAR_ERROR_DATA*)section;
19 json_object* section_ir = json_object_new_object();
20
21 //Revision.
22 json_object_object_add(section_ir, "revision", json_object_new_int(iommu_error->Revision));
23
24 //IOMMU registers.
25 json_object_object_add(section_ir, "controlRegister", json_object_new_uint64(iommu_error->Control));
26 json_object_object_add(section_ir, "statusRegister", json_object_new_uint64(iommu_error->Status));
27
28 //IOMMU event log entry.
Lawrence Tangce0f82b2022-07-07 16:14:28 +010029 //The format of these entries differ widely by the type of error.
30 char* encoded = b64_encode((unsigned char*)iommu_error->EventLogEntry, 16);
31 json_object_object_add(section_ir, "eventLogEntry", json_object_new_string(encoded));
32 free(encoded);
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010033
Lawrence Tangd7e8ca32022-07-07 10:25:53 +010034 //Device table entry (as base64).
Lawrence Tangce0f82b2022-07-07 16:14:28 +010035 encoded = b64_encode((unsigned char*)iommu_error->DeviceTableEntry, 32);
Lawrence Tangd7e8ca32022-07-07 10:25:53 +010036 json_object_object_add(section_ir, "deviceTableEntry", json_object_new_string(encoded));
37 free(encoded);
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010038
39 //Page table entries.
40 json_object_object_add(section_ir, "pageTableEntry_Level6", json_object_new_uint64(iommu_error->PteL6));
41 json_object_object_add(section_ir, "pageTableEntry_Level5", json_object_new_uint64(iommu_error->PteL5));
42 json_object_object_add(section_ir, "pageTableEntry_Level4", json_object_new_uint64(iommu_error->PteL4));
43 json_object_object_add(section_ir, "pageTableEntry_Level3", json_object_new_uint64(iommu_error->PteL3));
44 json_object_object_add(section_ir, "pageTableEntry_Level2", json_object_new_uint64(iommu_error->PteL2));
45 json_object_object_add(section_ir, "pageTableEntry_Level1", json_object_new_uint64(iommu_error->PteL1));
46
47 return section_ir;
Lawrence Tang205dd1d2022-07-14 16:23:38 +010048}
49
50//Converts a single DMAR IOMMU CPER-JSON section into CPER binary, outputting to the given stream.
51void ir_section_dmar_iommu_to_cper(json_object* section, FILE* out)
52{
53 EFI_IOMMU_DMAR_ERROR_DATA* section_cper =
54 (EFI_IOMMU_DMAR_ERROR_DATA*)calloc(1, sizeof(EFI_IOMMU_DMAR_ERROR_DATA));
55
56 //Revision, registers.
57 section_cper->Revision = (UINT8)json_object_get_int(json_object_object_get(section, "revision"));
58 section_cper->Control = json_object_get_uint64(json_object_object_get(section, "controlRegister"));
59 section_cper->Status = json_object_get_uint64(json_object_object_get(section, "statusRegister"));
60
61 //IOMMU event log entry.
62 json_object* encoded = json_object_object_get(section, "eventLogEntry");
63 UINT8* decoded = b64_decode(json_object_get_string(encoded), json_object_get_string_len(encoded));
64 memcpy(section_cper->EventLogEntry, decoded, 16);
65 free(decoded);
66
67 //Device table entry.
68 encoded = json_object_object_get(section, "deviceTableEntry");
69 decoded = b64_decode(json_object_get_string(encoded), json_object_get_string_len(encoded));
70 memcpy(section_cper->DeviceTableEntry, decoded, 32);
71 free(decoded);
72
73 //Page table entries.
74 section_cper->PteL1 = json_object_get_uint64(json_object_object_get(section, "pageTableEntry_Level1"));
75 section_cper->PteL2 = json_object_get_uint64(json_object_object_get(section, "pageTableEntry_Level2"));
76 section_cper->PteL3 = json_object_get_uint64(json_object_object_get(section, "pageTableEntry_Level3"));
77 section_cper->PteL4 = json_object_get_uint64(json_object_object_get(section, "pageTableEntry_Level4"));
78 section_cper->PteL5 = json_object_get_uint64(json_object_object_get(section, "pageTableEntry_Level5"));
79 section_cper->PteL6 = json_object_get_uint64(json_object_object_get(section, "pageTableEntry_Level6"));
80
81 //Write to stream, free resources.
82 fwrite(&section_cper, sizeof(section_cper), 1, out);
83 fflush(out);
84 free(section_cper);
Lawrence Tangdb1b7ce2022-07-06 15:40:26 +010085}