1683e0550SKarthik Rajagopalan /**
2683e0550SKarthik Rajagopalan  * Describes functions for converting NVIDIA CPER sections from binary and JSON format
3683e0550SKarthik Rajagopalan  * into an intermediate format.
4683e0550SKarthik Rajagopalan  **/
5683e0550SKarthik Rajagopalan 
6683e0550SKarthik Rajagopalan #include <stdio.h>
7683e0550SKarthik Rajagopalan #include <string.h>
8683e0550SKarthik Rajagopalan #include <json.h>
9683e0550SKarthik Rajagopalan #include "../edk/Cper.h"
10683e0550SKarthik Rajagopalan #include "../cper-utils.h"
11683e0550SKarthik Rajagopalan #include "cper-section-nvidia.h"
12683e0550SKarthik Rajagopalan 
13683e0550SKarthik Rajagopalan //Converts a single NVIDIA CPER section into JSON IR.
cper_section_nvidia_to_ir(void * section)14683e0550SKarthik Rajagopalan json_object *cper_section_nvidia_to_ir(void *section)
15683e0550SKarthik Rajagopalan {
16683e0550SKarthik Rajagopalan 	EFI_NVIDIA_ERROR_DATA *nvidia_error = (EFI_NVIDIA_ERROR_DATA *)section;
17683e0550SKarthik Rajagopalan 	json_object *section_ir = json_object_new_object();
18683e0550SKarthik Rajagopalan 
19683e0550SKarthik Rajagopalan 	//Signature.
20683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "signature",
21683e0550SKarthik Rajagopalan 			       json_object_new_string(nvidia_error->Signature));
22683e0550SKarthik Rajagopalan 
23683e0550SKarthik Rajagopalan 	//Fields.
24683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "errorType",
25683e0550SKarthik Rajagopalan 			       json_object_new_int(nvidia_error->ErrorType));
26683e0550SKarthik Rajagopalan 	json_object_object_add(
27683e0550SKarthik Rajagopalan 		section_ir, "errorInstance",
28683e0550SKarthik Rajagopalan 		json_object_new_int(nvidia_error->ErrorInstance));
29683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "severity",
30683e0550SKarthik Rajagopalan 			       json_object_new_int(nvidia_error->Severity));
31683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "socket",
32683e0550SKarthik Rajagopalan 			       json_object_new_int(nvidia_error->Socket));
33683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "numberRegs",
34683e0550SKarthik Rajagopalan 			       json_object_new_int(nvidia_error->NumberRegs));
35683e0550SKarthik Rajagopalan 	json_object_object_add(
36683e0550SKarthik Rajagopalan 		section_ir, "instanceBase",
37683e0550SKarthik Rajagopalan 		json_object_new_uint64(nvidia_error->InstanceBase));
38683e0550SKarthik Rajagopalan 
39683e0550SKarthik Rajagopalan 	// Registers (Address Value pairs).
40683e0550SKarthik Rajagopalan 	json_object *regarr = json_object_new_array();
41683e0550SKarthik Rajagopalan 	UINT64 *regPtr = &nvidia_error->InstanceBase;
42683e0550SKarthik Rajagopalan 	for (int i = 0; i < nvidia_error->NumberRegs; i++) {
43683e0550SKarthik Rajagopalan 		json_object *reg = json_object_new_object();
44683e0550SKarthik Rajagopalan 		json_object_object_add(reg, "address",
45683e0550SKarthik Rajagopalan 				       json_object_new_uint64(*++regPtr));
46683e0550SKarthik Rajagopalan 		json_object_object_add(reg, "value",
47683e0550SKarthik Rajagopalan 				       json_object_new_uint64(*++regPtr));
48683e0550SKarthik Rajagopalan 		json_object_array_add(regarr, reg);
49683e0550SKarthik Rajagopalan 	}
50683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "registers", regarr);
51683e0550SKarthik Rajagopalan 
52683e0550SKarthik Rajagopalan 	return section_ir;
53683e0550SKarthik Rajagopalan }
54683e0550SKarthik Rajagopalan 
55683e0550SKarthik Rajagopalan //Converts a single NVIDIA CPER-JSON section into CPER binary, outputting to the given stream.
ir_section_nvidia_to_cper(json_object * section,FILE * out)56683e0550SKarthik Rajagopalan void ir_section_nvidia_to_cper(json_object *section, FILE *out)
57683e0550SKarthik Rajagopalan {
58683e0550SKarthik Rajagopalan 	json_object *regarr = json_object_object_get(section, "registers");
59683e0550SKarthik Rajagopalan 	int numRegs = json_object_array_length(regarr);
60683e0550SKarthik Rajagopalan 
61683e0550SKarthik Rajagopalan 	size_t section_sz =
62683e0550SKarthik Rajagopalan 		sizeof(EFI_NVIDIA_ERROR_DATA) + (numRegs * 2 * sizeof(UINT64));
63683e0550SKarthik Rajagopalan 	EFI_NVIDIA_ERROR_DATA *section_cper =
64683e0550SKarthik Rajagopalan 		(EFI_NVIDIA_ERROR_DATA *)calloc(1, section_sz);
65683e0550SKarthik Rajagopalan 
66683e0550SKarthik Rajagopalan 	//Signature.
67683e0550SKarthik Rajagopalan 	strncpy(section_cper->Signature,
68683e0550SKarthik Rajagopalan 		json_object_get_string(
69683e0550SKarthik Rajagopalan 			json_object_object_get(section, "signature")),
70*379e492aSPatrick Williams 		sizeof(section_cper->Signature) - 1);
71*379e492aSPatrick Williams 	section_cper->Signature[sizeof(section_cper->Signature) - 1] = '\0';
72683e0550SKarthik Rajagopalan 
73683e0550SKarthik Rajagopalan 	//Fields.
74683e0550SKarthik Rajagopalan 	section_cper->ErrorType = json_object_get_int(
75683e0550SKarthik Rajagopalan 		json_object_object_get(section, "errorType"));
76683e0550SKarthik Rajagopalan 	section_cper->ErrorInstance = json_object_get_int(
77683e0550SKarthik Rajagopalan 		json_object_object_get(section, "errorInstance"));
78683e0550SKarthik Rajagopalan 	section_cper->Severity = json_object_get_int(
79683e0550SKarthik Rajagopalan 		json_object_object_get(section, "severity"));
80683e0550SKarthik Rajagopalan 	section_cper->Socket =
81683e0550SKarthik Rajagopalan 		json_object_get_int(json_object_object_get(section, "socket"));
82683e0550SKarthik Rajagopalan 	section_cper->NumberRegs = json_object_get_int(
83683e0550SKarthik Rajagopalan 		json_object_object_get(section, "numberRegs"));
84683e0550SKarthik Rajagopalan 	section_cper->InstanceBase = json_object_get_uint64(
85683e0550SKarthik Rajagopalan 		json_object_object_get(section, "instanceBase"));
86683e0550SKarthik Rajagopalan 
87683e0550SKarthik Rajagopalan 	// Registers (Address Value pairs).
88683e0550SKarthik Rajagopalan 	UINT64 *regPtr = &section_cper->InstanceBase;
89683e0550SKarthik Rajagopalan 	for (int i = 0; i < numRegs; i++) {
90683e0550SKarthik Rajagopalan 		json_object *reg = json_object_array_get_idx(regarr, i);
91683e0550SKarthik Rajagopalan 		*++regPtr = json_object_get_uint64(
92683e0550SKarthik Rajagopalan 			json_object_object_get(reg, "address"));
93683e0550SKarthik Rajagopalan 		*++regPtr = json_object_get_uint64(
94683e0550SKarthik Rajagopalan 			json_object_object_get(reg, "value"));
95683e0550SKarthik Rajagopalan 	}
96683e0550SKarthik Rajagopalan 
97683e0550SKarthik Rajagopalan 	//Write to stream, free resources.
98683e0550SKarthik Rajagopalan 	fwrite(section_cper, section_sz, 1, out);
99683e0550SKarthik Rajagopalan 	fflush(out);
100683e0550SKarthik Rajagopalan 	free(section_cper);
101683e0550SKarthik Rajagopalan }
102