1 /** 2 * Describes functions for converting NVIDIA CPER sections from binary and JSON format 3 * into an intermediate format. 4 **/ 5 6 #include <stdio.h> 7 #include <stddef.h> 8 #include <string.h> 9 #include <json.h> 10 #include "../edk/Cper.h" 11 #include "../cper-utils.h" 12 #include "cper-section-nvidia.h" 13 14 //Converts a single NVIDIA CPER section into JSON IR. 15 json_object *cper_section_nvidia_to_ir(void *section) 16 { 17 EFI_NVIDIA_ERROR_DATA *nvidia_error = (EFI_NVIDIA_ERROR_DATA *)section; 18 json_object *section_ir = json_object_new_object(); 19 20 json_object_object_add(section_ir, "signature", 21 json_object_new_string(nvidia_error->Signature)); 22 23 json_object *severity = json_object_new_object(); 24 json_object_object_add(severity, "code", 25 json_object_new_uint64(nvidia_error->Severity)); 26 json_object_object_add(severity, "name", 27 json_object_new_string(severity_to_string( 28 nvidia_error->Severity))); 29 json_object_object_add(section_ir, "severity", severity); 30 31 json_object_object_add(section_ir, "errorType", 32 json_object_new_int(nvidia_error->ErrorType)); 33 json_object_object_add( 34 section_ir, "errorInstance", 35 json_object_new_int(nvidia_error->ErrorInstance)); 36 json_object_object_add(section_ir, "socket", 37 json_object_new_int(nvidia_error->Socket)); 38 json_object_object_add(section_ir, "registerCount", 39 json_object_new_int(nvidia_error->NumberRegs)); 40 json_object_object_add( 41 section_ir, "instanceBase", 42 json_object_new_uint64(nvidia_error->InstanceBase)); 43 44 // Registers (Address Value pairs). 45 json_object *regarr = json_object_new_array(); 46 EFI_NVIDIA_REGISTER_DATA *regPtr = nvidia_error->Register; 47 for (int i = 0; i < nvidia_error->NumberRegs; i++, regPtr++) { 48 json_object *reg = json_object_new_object(); 49 json_object_object_add(reg, "address", 50 json_object_new_uint64(regPtr->Address)); 51 json_object_object_add(reg, "value", 52 json_object_new_uint64(regPtr->Value)); 53 json_object_array_add(regarr, reg); 54 } 55 json_object_object_add(section_ir, "registers", regarr); 56 57 return section_ir; 58 } 59 60 //Converts a single NVIDIA CPER-JSON section into CPER binary, outputting to the given stream. 61 void ir_section_nvidia_to_cper(json_object *section, FILE *out) 62 { 63 json_object *regarr = json_object_object_get(section, "registers"); 64 int numRegs = json_object_array_length(regarr); 65 66 size_t section_sz = offsetof(EFI_NVIDIA_ERROR_DATA, Register) + 67 numRegs * sizeof(EFI_NVIDIA_REGISTER_DATA); 68 EFI_NVIDIA_ERROR_DATA *section_cper = 69 (EFI_NVIDIA_ERROR_DATA *)calloc(1, section_sz); 70 71 //Signature. 72 strncpy(section_cper->Signature, 73 json_object_get_string( 74 json_object_object_get(section, "signature")), 75 sizeof(section_cper->Signature) - 1); 76 section_cper->Signature[sizeof(section_cper->Signature) - 1] = '\0'; 77 78 //Fields. 79 section_cper->ErrorType = json_object_get_int( 80 json_object_object_get(section, "errorType")); 81 section_cper->ErrorInstance = json_object_get_int( 82 json_object_object_get(section, "errorInstance")); 83 json_object *severity = json_object_object_get(section, "severity"); 84 section_cper->Severity = (UINT8)json_object_get_uint64( 85 json_object_object_get(severity, "code")); 86 section_cper->Socket = 87 json_object_get_int(json_object_object_get(section, "socket")); 88 section_cper->NumberRegs = json_object_get_int( 89 json_object_object_get(section, "registerCount")); 90 section_cper->InstanceBase = json_object_get_uint64( 91 json_object_object_get(section, "instanceBase")); 92 93 // Registers (Address Value pairs). 94 EFI_NVIDIA_REGISTER_DATA *regPtr = section_cper->Register; 95 for (int i = 0; i < numRegs; i++, regPtr++) { 96 json_object *reg = json_object_array_get_idx(regarr, i); 97 regPtr->Address = json_object_get_uint64( 98 json_object_object_get(reg, "address")); 99 regPtr->Value = json_object_get_uint64( 100 json_object_object_get(reg, "value")); 101 } 102 103 //Write to stream, free resources. 104 fwrite(section_cper, section_sz, 1, out); 105 fflush(out); 106 free(section_cper); 107 } 108