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