blob: 874e616128bd4a2603075b1f3c3df7584b0d9f1f [file] [log] [blame]
Karthik Rajagopalan683e0552024-03-07 12:30:43 -08001/**
2 * Describes functions for converting NVIDIA CPER sections from binary and JSON format
3 * into an intermediate format.
4 **/
5
6#include <stdio.h>
Ed Tanous2d17ace2024-08-27 14:45:38 -07007#include <stddef.h>
Karthik Rajagopalan683e0552024-03-07 12:30:43 -08008#include <string.h>
9#include <json.h>
Thu Nguyene42fb482024-10-15 14:43:11 +000010#include <libcper/Cper.h>
11#include <libcper/cper-utils.h>
12#include <libcper/sections/cper-section-nvidia.h>
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080013
14//Converts a single NVIDIA CPER section into JSON IR.
Ed Tanous12dbd4f2025-03-08 19:05:01 -080015json_object *cper_section_nvidia_to_ir(const UINT8 *section, UINT32 size)
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080016{
Ed Tanous12dbd4f2025-03-08 19:05:01 -080017 if (size < sizeof(EFI_NVIDIA_ERROR_DATA)) {
18 return NULL;
19 }
20
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080021 EFI_NVIDIA_ERROR_DATA *nvidia_error = (EFI_NVIDIA_ERROR_DATA *)section;
Ed Tanous12dbd4f2025-03-08 19:05:01 -080022 if (size < sizeof(EFI_NVIDIA_ERROR_DATA) +
23 nvidia_error->NumberRegs *
24 sizeof(EFI_NVIDIA_REGISTER_DATA)) {
25 return NULL;
26 }
27
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080028 json_object *section_ir = json_object_new_object();
29
Ed Tanous5e2164a2025-03-09 09:20:44 -070030 add_untrusted_string(section_ir, "signature", nvidia_error->Signature,
31 sizeof(nvidia_error->Signature));
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080032
Ed Tanous2d17ace2024-08-27 14:45:38 -070033 json_object *severity = json_object_new_object();
34 json_object_object_add(severity, "code",
35 json_object_new_uint64(nvidia_error->Severity));
36 json_object_object_add(severity, "name",
37 json_object_new_string(severity_to_string(
38 nvidia_error->Severity)));
39 json_object_object_add(section_ir, "severity", severity);
40
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080041 json_object_object_add(section_ir, "errorType",
42 json_object_new_int(nvidia_error->ErrorType));
43 json_object_object_add(
44 section_ir, "errorInstance",
45 json_object_new_int(nvidia_error->ErrorInstance));
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080046 json_object_object_add(section_ir, "socket",
47 json_object_new_int(nvidia_error->Socket));
Ed Tanous2d17ace2024-08-27 14:45:38 -070048 json_object_object_add(section_ir, "registerCount",
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080049 json_object_new_int(nvidia_error->NumberRegs));
50 json_object_object_add(
51 section_ir, "instanceBase",
52 json_object_new_uint64(nvidia_error->InstanceBase));
53
54 // Registers (Address Value pairs).
55 json_object *regarr = json_object_new_array();
Ed Tanous2d17ace2024-08-27 14:45:38 -070056 EFI_NVIDIA_REGISTER_DATA *regPtr = nvidia_error->Register;
57 for (int i = 0; i < nvidia_error->NumberRegs; i++, regPtr++) {
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080058 json_object *reg = json_object_new_object();
59 json_object_object_add(reg, "address",
Ed Tanous2d17ace2024-08-27 14:45:38 -070060 json_object_new_uint64(regPtr->Address));
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080061 json_object_object_add(reg, "value",
Ed Tanous2d17ace2024-08-27 14:45:38 -070062 json_object_new_uint64(regPtr->Value));
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080063 json_object_array_add(regarr, reg);
64 }
65 json_object_object_add(section_ir, "registers", regarr);
66
67 return section_ir;
68}
69
70//Converts a single NVIDIA CPER-JSON section into CPER binary, outputting to the given stream.
71void ir_section_nvidia_to_cper(json_object *section, FILE *out)
72{
73 json_object *regarr = json_object_object_get(section, "registers");
74 int numRegs = json_object_array_length(regarr);
75
Ed Tanous2d17ace2024-08-27 14:45:38 -070076 size_t section_sz = offsetof(EFI_NVIDIA_ERROR_DATA, Register) +
77 numRegs * sizeof(EFI_NVIDIA_REGISTER_DATA);
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080078 EFI_NVIDIA_ERROR_DATA *section_cper =
79 (EFI_NVIDIA_ERROR_DATA *)calloc(1, section_sz);
80
81 //Signature.
82 strncpy(section_cper->Signature,
83 json_object_get_string(
84 json_object_object_get(section, "signature")),
Patrick Williams379e4922024-08-28 11:14:34 -040085 sizeof(section_cper->Signature) - 1);
86 section_cper->Signature[sizeof(section_cper->Signature) - 1] = '\0';
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080087
88 //Fields.
89 section_cper->ErrorType = json_object_get_int(
90 json_object_object_get(section, "errorType"));
91 section_cper->ErrorInstance = json_object_get_int(
92 json_object_object_get(section, "errorInstance"));
Ed Tanous2d17ace2024-08-27 14:45:38 -070093 json_object *severity = json_object_object_get(section, "severity");
94 section_cper->Severity = (UINT8)json_object_get_uint64(
95 json_object_object_get(severity, "code"));
Karthik Rajagopalan683e0552024-03-07 12:30:43 -080096 section_cper->Socket =
97 json_object_get_int(json_object_object_get(section, "socket"));
98 section_cper->NumberRegs = json_object_get_int(
Ed Tanous2d17ace2024-08-27 14:45:38 -070099 json_object_object_get(section, "registerCount"));
Karthik Rajagopalan683e0552024-03-07 12:30:43 -0800100 section_cper->InstanceBase = json_object_get_uint64(
101 json_object_object_get(section, "instanceBase"));
102
103 // Registers (Address Value pairs).
Ed Tanous2d17ace2024-08-27 14:45:38 -0700104 EFI_NVIDIA_REGISTER_DATA *regPtr = section_cper->Register;
105 for (int i = 0; i < numRegs; i++, regPtr++) {
Karthik Rajagopalan683e0552024-03-07 12:30:43 -0800106 json_object *reg = json_object_array_get_idx(regarr, i);
Ed Tanous2d17ace2024-08-27 14:45:38 -0700107 regPtr->Address = json_object_get_uint64(
Karthik Rajagopalan683e0552024-03-07 12:30:43 -0800108 json_object_object_get(reg, "address"));
Ed Tanous2d17ace2024-08-27 14:45:38 -0700109 regPtr->Value = json_object_get_uint64(
Karthik Rajagopalan683e0552024-03-07 12:30:43 -0800110 json_object_object_get(reg, "value"));
111 }
112
113 //Write to stream, free resources.
114 fwrite(section_cper, section_sz, 1, out);
115 fflush(out);
116 free(section_cper);
117}