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