1 /** 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> 8 #include <string.h> 9 #include "json.h" 10 #include "b64.h" 11 #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. 16 json_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. 29 //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); 33 34 //Device table entry (as base64). 35 encoded = b64_encode((unsigned char*)iommu_error->DeviceTableEntry, 32); 36 json_object_object_add(section_ir, "deviceTableEntry", json_object_new_string(encoded)); 37 free(encoded); 38 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; 48 } 49 50 //Converts a single DMAR IOMMU CPER-JSON section into CPER binary, outputting to the given stream. 51 void 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(§ion_cper, sizeof(section_cper), 1, out); 83 fflush(out); 84 free(section_cper); 85 }