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