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