xref: /openbmc/libcper/sections/cper-section-nvidia.c (revision 50b966f7afa31fe39fda70e10eb9139cce39e025)
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>
72d17acecSEd Tanous #include <stddef.h>
8683e0550SKarthik Rajagopalan #include <string.h>
9683e0550SKarthik Rajagopalan #include <json.h>
10e42fb487SThu Nguyen #include <libcper/Cper.h>
11e42fb487SThu Nguyen #include <libcper/cper-utils.h>
12e42fb487SThu Nguyen #include <libcper/sections/cper-section-nvidia.h>
13*50b966f7SEd Tanous #include <libcper/log.h>
14683e0550SKarthik Rajagopalan 
cper_section_nvidia_to_ir(void * section)15683e0550SKarthik Rajagopalan //Converts a single NVIDIA CPER section into JSON IR.
1612dbd4fdSEd Tanous json_object *cper_section_nvidia_to_ir(const UINT8 *section, UINT32 size)
17683e0550SKarthik Rajagopalan {
1812dbd4fdSEd Tanous 	if (size < sizeof(EFI_NVIDIA_ERROR_DATA)) {
1912dbd4fdSEd Tanous 		return NULL;
2012dbd4fdSEd Tanous 	}
2112dbd4fdSEd Tanous 
22683e0550SKarthik Rajagopalan 	EFI_NVIDIA_ERROR_DATA *nvidia_error = (EFI_NVIDIA_ERROR_DATA *)section;
2312dbd4fdSEd Tanous 	if (size < sizeof(EFI_NVIDIA_ERROR_DATA) +
2412dbd4fdSEd Tanous 			   nvidia_error->NumberRegs *
2512dbd4fdSEd Tanous 				   sizeof(EFI_NVIDIA_REGISTER_DATA)) {
2612dbd4fdSEd Tanous 		return NULL;
2712dbd4fdSEd Tanous 	}
2812dbd4fdSEd Tanous 
29683e0550SKarthik Rajagopalan 	json_object *section_ir = json_object_new_object();
30683e0550SKarthik Rajagopalan 
315e2164a0SEd Tanous 	add_untrusted_string(section_ir, "signature", nvidia_error->Signature,
325e2164a0SEd Tanous 			     sizeof(nvidia_error->Signature));
33683e0550SKarthik Rajagopalan 
342d17acecSEd Tanous 	json_object *severity = json_object_new_object();
352d17acecSEd Tanous 	json_object_object_add(severity, "code",
362d17acecSEd Tanous 			       json_object_new_uint64(nvidia_error->Severity));
372d17acecSEd Tanous 	json_object_object_add(severity, "name",
382d17acecSEd Tanous 			       json_object_new_string(severity_to_string(
392d17acecSEd Tanous 				       nvidia_error->Severity)));
402d17acecSEd Tanous 	json_object_object_add(section_ir, "severity", severity);
412d17acecSEd Tanous 
42683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "errorType",
43683e0550SKarthik Rajagopalan 			       json_object_new_int(nvidia_error->ErrorType));
44683e0550SKarthik Rajagopalan 	json_object_object_add(
45683e0550SKarthik Rajagopalan 		section_ir, "errorInstance",
46683e0550SKarthik Rajagopalan 		json_object_new_int(nvidia_error->ErrorInstance));
47683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "socket",
48683e0550SKarthik Rajagopalan 			       json_object_new_int(nvidia_error->Socket));
492d17acecSEd Tanous 	json_object_object_add(section_ir, "registerCount",
50683e0550SKarthik Rajagopalan 			       json_object_new_int(nvidia_error->NumberRegs));
51683e0550SKarthik Rajagopalan 	json_object_object_add(
52683e0550SKarthik Rajagopalan 		section_ir, "instanceBase",
53683e0550SKarthik Rajagopalan 		json_object_new_uint64(nvidia_error->InstanceBase));
54683e0550SKarthik Rajagopalan 
55683e0550SKarthik Rajagopalan 	// Registers (Address Value pairs).
56683e0550SKarthik Rajagopalan 	json_object *regarr = json_object_new_array();
572d17acecSEd Tanous 	EFI_NVIDIA_REGISTER_DATA *regPtr = nvidia_error->Register;
582d17acecSEd Tanous 	for (int i = 0; i < nvidia_error->NumberRegs; i++, regPtr++) {
59683e0550SKarthik Rajagopalan 		json_object *reg = json_object_new_object();
60683e0550SKarthik Rajagopalan 		json_object_object_add(reg, "address",
612d17acecSEd Tanous 				       json_object_new_uint64(regPtr->Address));
62683e0550SKarthik Rajagopalan 		json_object_object_add(reg, "value",
632d17acecSEd Tanous 				       json_object_new_uint64(regPtr->Value));
64683e0550SKarthik Rajagopalan 		json_object_array_add(regarr, reg);
65683e0550SKarthik Rajagopalan 	}
66683e0550SKarthik Rajagopalan 	json_object_object_add(section_ir, "registers", regarr);
67683e0550SKarthik Rajagopalan 
68683e0550SKarthik Rajagopalan 	return section_ir;
69683e0550SKarthik Rajagopalan }
70683e0550SKarthik Rajagopalan 
71683e0550SKarthik Rajagopalan //Converts a single NVIDIA CPER-JSON section into CPER binary, outputting to the given stream.
72683e0550SKarthik Rajagopalan void ir_section_nvidia_to_cper(json_object *section, FILE *out)
73683e0550SKarthik Rajagopalan {
74683e0550SKarthik Rajagopalan 	json_object *regarr = json_object_object_get(section, "registers");
75683e0550SKarthik Rajagopalan 	int numRegs = json_object_array_length(regarr);
76683e0550SKarthik Rajagopalan 
772d17acecSEd Tanous 	size_t section_sz = offsetof(EFI_NVIDIA_ERROR_DATA, Register) +
782d17acecSEd Tanous 			    numRegs * sizeof(EFI_NVIDIA_REGISTER_DATA);
79683e0550SKarthik Rajagopalan 	EFI_NVIDIA_ERROR_DATA *section_cper =
80683e0550SKarthik Rajagopalan 		(EFI_NVIDIA_ERROR_DATA *)calloc(1, section_sz);
81683e0550SKarthik Rajagopalan 
82683e0550SKarthik Rajagopalan 	//Signature.
83683e0550SKarthik Rajagopalan 	strncpy(section_cper->Signature,
84683e0550SKarthik Rajagopalan 		json_object_get_string(
85683e0550SKarthik Rajagopalan 			json_object_object_get(section, "signature")),
86379e492aSPatrick Williams 		sizeof(section_cper->Signature) - 1);
87379e492aSPatrick Williams 	section_cper->Signature[sizeof(section_cper->Signature) - 1] = '\0';
88683e0550SKarthik Rajagopalan 
89683e0550SKarthik Rajagopalan 	//Fields.
90683e0550SKarthik Rajagopalan 	section_cper->ErrorType = json_object_get_int(
91683e0550SKarthik Rajagopalan 		json_object_object_get(section, "errorType"));
92683e0550SKarthik Rajagopalan 	section_cper->ErrorInstance = json_object_get_int(
93683e0550SKarthik Rajagopalan 		json_object_object_get(section, "errorInstance"));
942d17acecSEd Tanous 	json_object *severity = json_object_object_get(section, "severity");
952d17acecSEd Tanous 	section_cper->Severity = (UINT8)json_object_get_uint64(
962d17acecSEd Tanous 		json_object_object_get(severity, "code"));
97683e0550SKarthik Rajagopalan 	section_cper->Socket =
98683e0550SKarthik Rajagopalan 		json_object_get_int(json_object_object_get(section, "socket"));
99683e0550SKarthik Rajagopalan 	section_cper->NumberRegs = json_object_get_int(
1002d17acecSEd Tanous 		json_object_object_get(section, "registerCount"));
101683e0550SKarthik Rajagopalan 	section_cper->InstanceBase = json_object_get_uint64(
102683e0550SKarthik Rajagopalan 		json_object_object_get(section, "instanceBase"));
103683e0550SKarthik Rajagopalan 
104683e0550SKarthik Rajagopalan 	// Registers (Address Value pairs).
1052d17acecSEd Tanous 	EFI_NVIDIA_REGISTER_DATA *regPtr = section_cper->Register;
1062d17acecSEd Tanous 	for (int i = 0; i < numRegs; i++, regPtr++) {
107683e0550SKarthik Rajagopalan 		json_object *reg = json_object_array_get_idx(regarr, i);
1082d17acecSEd Tanous 		regPtr->Address = json_object_get_uint64(
109683e0550SKarthik Rajagopalan 			json_object_object_get(reg, "address"));
1102d17acecSEd Tanous 		regPtr->Value = json_object_get_uint64(
111683e0550SKarthik Rajagopalan 			json_object_object_get(reg, "value"));
112683e0550SKarthik Rajagopalan 	}
113683e0550SKarthik Rajagopalan 
114683e0550SKarthik Rajagopalan 	//Write to stream, free resources.
115683e0550SKarthik Rajagopalan 	fwrite(section_cper, section_sz, 1, out);
116683e0550SKarthik Rajagopalan 	fflush(out);
117683e0550SKarthik Rajagopalan 	free(section_cper);
118683e0550SKarthik Rajagopalan }
119