Add support for NVIDIA CPERs
Support Nvidia CPER entries.
Change-Id: Iea9bde181ead55ad99cdb2a341501bf48e1d82a8
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/edk/Cper.c b/edk/Cper.c
index 4f80023..218589b 100644
--- a/edk/Cper.c
+++ b/edk/Cper.c
@@ -210,3 +210,8 @@
0x4f6c,
{ 0xA7, 0xD3, 0xB0, 0xB5, 0xB0,
0xA7, 0x43, 0x14 } };
+EFI_GUID gEfiNvidiaErrorSectionGuid = { 0x6d5244f2,
+ 0x2712,
+ 0x11ec,
+ { 0xbe, 0xa7, 0xcb, 0x3f, 0xdb, 0x95,
+ 0xc7, 0x86 } };
diff --git a/edk/Cper.h b/edk/Cper.h
index 8f9e529..5fd5b48 100644
--- a/edk/Cper.h
+++ b/edk/Cper.h
@@ -1383,6 +1383,21 @@
#endif
+///
+/// NVIDIA Error Record Section
+///
+typedef struct {
+ CHAR8 Signature[16];
+ UINT16 ErrorType;
+ UINT16 ErrorInstance;
+ UINT8 Severity;
+ UINT8 Socket;
+ UINT8 NumberRegs;
+ UINT8 Reserved;
+ UINT64 InstanceBase;
+} EFI_NVIDIA_ERROR_DATA;
+
+extern EFI_GUID gEfiNvidiaErrorSectionGuid;
#pragma pack(pop)
#endif
diff --git a/generator/sections/gen-section-nvidia.c b/generator/sections/gen-section-nvidia.c
new file mode 100644
index 0000000..83ed84e
--- /dev/null
+++ b/generator/sections/gen-section-nvidia.c
@@ -0,0 +1,44 @@
+/**
+ * Functions for generating pseudo-random CPER NVIDIA error sections.
+ *
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-section.h"
+
+//Generates a single pseudo-random NVIDIA error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_nvidia(void **location)
+{
+ const char *signatures[] = {
+ "DCC-ECC", "DCC-COH", "HSS-BUSY", "HSS-IDLE",
+ "CLink", "C2C", "C2C-IP-FAIL", "L0 RESET",
+ "L1 RESET", "L2 RESET", "PCIe", "PCIe-DPC",
+ "SOCHUB", "CCPLEXSCF", "CMET-NULL", "CMET-SHA256",
+ "CMET-FULL", "DRAM-CHANNELS", "PAGES-RETIRED", "CCPLEXGIC",
+ "MCF", "GPU-STATUS", "GPU-CONTNMT", "SMMU",
+ };
+
+ init_random();
+
+ //Create random bytes.
+ size_t size = sizeof(EFI_NVIDIA_ERROR_DATA);
+ UINT8 *section = generate_random_bytes(size);
+
+ //Reserved byte.
+ EFI_NVIDIA_ERROR_DATA *nvidia_error = (EFI_NVIDIA_ERROR_DATA *)section;
+ nvidia_error->Reserved = 0;
+
+ //Signature.
+ int idx_random = rand() % (sizeof(signatures) / sizeof(signatures[0]));
+ strncpy(nvidia_error->Signature, signatures[idx_random],
+ sizeof(nvidia_error->Signature));
+
+ //Set return values, exit.
+ *location = section;
+ return size;
+}
diff --git a/generator/sections/gen-section.c b/generator/sections/gen-section.c
index 7240145..819ebdb 100644
--- a/generator/sections/gen-section.c
+++ b/generator/sections/gen-section.c
@@ -42,6 +42,7 @@
generate_section_cxl_component },
{ &gEfiCxlMldPortErrorSectionGuid, "cxlcomponent-mld",
generate_section_cxl_component },
+ { &gEfiNvidiaErrorSectionGuid, "nvidia", generate_section_nvidia },
};
const size_t generator_definitions_len =
sizeof(generator_definitions) / sizeof(CPER_GENERATOR_DEFINITION);
diff --git a/generator/sections/gen-section.h b/generator/sections/gen-section.h
index df1e227..be00b5f 100644
--- a/generator/sections/gen-section.h
+++ b/generator/sections/gen-section.h
@@ -20,6 +20,7 @@
size_t generate_section_ccix_per(void **location);
size_t generate_section_cxl_protocol(void **location);
size_t generate_section_cxl_component(void **location);
+size_t generate_section_nvidia(void **location);
//Definition structure for a single CPER section generator.
typedef struct {
diff --git a/meson.build b/meson.build
index 624d85b..865f50a 100644
--- a/meson.build
+++ b/meson.build
@@ -37,6 +37,7 @@
'sections/cper-section-ia32x64.c',
'sections/cper-section-ipf.c',
'sections/cper-section-memory.c',
+ 'sections/cper-section-nvidia.c',
'sections/cper-section-pci-bus.c',
'sections/cper-section-pci-dev.c',
'sections/cper-section-pcie.c',
@@ -55,6 +56,7 @@
'generator/sections/gen-section-generic.c',
'generator/sections/gen-section-ia32x64.c',
'generator/sections/gen-section-memory.c',
+ 'generator/sections/gen-section-nvidia.c',
'generator/sections/gen-section-pci-bus.c',
'generator/sections/gen-section-pci-dev.c',
'generator/sections/gen-section-pcie.c',
diff --git a/sections/cper-section-nvidia.c b/sections/cper-section-nvidia.c
new file mode 100644
index 0000000..f0ccec6
--- /dev/null
+++ b/sections/cper-section-nvidia.c
@@ -0,0 +1,100 @@
+/**
+ * Describes functions for converting NVIDIA CPER sections from binary and JSON format
+ * into an intermediate format.
+ **/
+
+#include <stdio.h>
+#include <string.h>
+#include <json.h>
+#include "../edk/Cper.h"
+#include "../cper-utils.h"
+#include "cper-section-nvidia.h"
+
+//Converts a single NVIDIA CPER section into JSON IR.
+json_object *cper_section_nvidia_to_ir(void *section)
+{
+ EFI_NVIDIA_ERROR_DATA *nvidia_error = (EFI_NVIDIA_ERROR_DATA *)section;
+ json_object *section_ir = json_object_new_object();
+
+ //Signature.
+ json_object_object_add(section_ir, "signature",
+ json_object_new_string(nvidia_error->Signature));
+
+ //Fields.
+ json_object_object_add(section_ir, "errorType",
+ json_object_new_int(nvidia_error->ErrorType));
+ json_object_object_add(
+ section_ir, "errorInstance",
+ json_object_new_int(nvidia_error->ErrorInstance));
+ json_object_object_add(section_ir, "severity",
+ json_object_new_int(nvidia_error->Severity));
+ json_object_object_add(section_ir, "socket",
+ json_object_new_int(nvidia_error->Socket));
+ json_object_object_add(section_ir, "numberRegs",
+ json_object_new_int(nvidia_error->NumberRegs));
+ json_object_object_add(
+ section_ir, "instanceBase",
+ json_object_new_uint64(nvidia_error->InstanceBase));
+
+ // Registers (Address Value pairs).
+ json_object *regarr = json_object_new_array();
+ UINT64 *regPtr = &nvidia_error->InstanceBase;
+ for (int i = 0; i < nvidia_error->NumberRegs; i++) {
+ json_object *reg = json_object_new_object();
+ json_object_object_add(reg, "address",
+ json_object_new_uint64(*++regPtr));
+ json_object_object_add(reg, "value",
+ json_object_new_uint64(*++regPtr));
+ json_object_array_add(regarr, reg);
+ }
+ json_object_object_add(section_ir, "registers", regarr);
+
+ return section_ir;
+}
+
+//Converts a single NVIDIA CPER-JSON section into CPER binary, outputting to the given stream.
+void ir_section_nvidia_to_cper(json_object *section, FILE *out)
+{
+ json_object *regarr = json_object_object_get(section, "registers");
+ int numRegs = json_object_array_length(regarr);
+
+ size_t section_sz =
+ sizeof(EFI_NVIDIA_ERROR_DATA) + (numRegs * 2 * sizeof(UINT64));
+ EFI_NVIDIA_ERROR_DATA *section_cper =
+ (EFI_NVIDIA_ERROR_DATA *)calloc(1, section_sz);
+
+ //Signature.
+ strncpy(section_cper->Signature,
+ json_object_get_string(
+ json_object_object_get(section, "signature")),
+ sizeof(section_cper->Signature));
+
+ //Fields.
+ section_cper->ErrorType = json_object_get_int(
+ json_object_object_get(section, "errorType"));
+ section_cper->ErrorInstance = json_object_get_int(
+ json_object_object_get(section, "errorInstance"));
+ section_cper->Severity = json_object_get_int(
+ json_object_object_get(section, "severity"));
+ section_cper->Socket =
+ json_object_get_int(json_object_object_get(section, "socket"));
+ section_cper->NumberRegs = json_object_get_int(
+ json_object_object_get(section, "numberRegs"));
+ section_cper->InstanceBase = json_object_get_uint64(
+ json_object_object_get(section, "instanceBase"));
+
+ // Registers (Address Value pairs).
+ UINT64 *regPtr = §ion_cper->InstanceBase;
+ for (int i = 0; i < numRegs; i++) {
+ json_object *reg = json_object_array_get_idx(regarr, i);
+ *++regPtr = json_object_get_uint64(
+ json_object_object_get(reg, "address"));
+ *++regPtr = json_object_get_uint64(
+ json_object_object_get(reg, "value"));
+ }
+
+ //Write to stream, free resources.
+ fwrite(section_cper, section_sz, 1, out);
+ fflush(out);
+ free(section_cper);
+}
diff --git a/sections/cper-section-nvidia.h b/sections/cper-section-nvidia.h
new file mode 100644
index 0000000..973c3af
--- /dev/null
+++ b/sections/cper-section-nvidia.h
@@ -0,0 +1,10 @@
+#ifndef CPER_SECTION_NVIDIA_H
+#define CPER_SECTION_NVIDIA_H
+
+#include <json.h>
+#include "../edk/Cper.h"
+
+json_object *cper_section_nvidia_to_ir(void *section);
+void ir_section_nvidia_to_cper(json_object *section, FILE *out);
+
+#endif
diff --git a/sections/cper-section.c b/sections/cper-section.c
index 9352800..1845118 100644
--- a/sections/cper-section.c
+++ b/sections/cper-section.c
@@ -20,6 +20,7 @@
#include "cper-section-ccix-per.h"
#include "cper-section-cxl-protocol.h"
#include "cper-section-cxl-component.h"
+#include "cper-section-nvidia.h"
//Definitions of all sections available to the CPER parser.
CPER_SECTION_DEFINITION section_definitions[] = {
@@ -69,6 +70,8 @@
cper_section_cxl_component_to_ir, ir_section_cxl_component_to_cper },
{ &gEfiCxlMldPortErrorSectionGuid, "CXL MLD Port Component Error",
cper_section_cxl_component_to_ir, ir_section_cxl_component_to_cper },
+ { &gEfiNvidiaErrorSectionGuid, "NVIDIA", cper_section_nvidia_to_ir,
+ ir_section_nvidia_to_cper },
};
const size_t section_definitions_len =
sizeof(section_definitions) / sizeof(CPER_SECTION_DEFINITION);
diff --git a/specification/json/cper-json-full-log.json b/specification/json/cper-json-full-log.json
index bb7b83e..029ce2f 100644
--- a/specification/json/cper-json-full-log.json
+++ b/specification/json/cper-json-full-log.json
@@ -33,6 +33,7 @@
{ "$ref": "./sections/cper-ccix-per.json" },
{ "$ref": "./sections/cper-cxl-protocol.json" },
{ "$ref": "./sections/cper-cxl-component.json" },
+ { "$ref": "./sections/cper-nvidia.json" },
{ "$ref": "./sections/cper-unknown.json" }
]
}
diff --git a/specification/json/cper-json-section-log.json b/specification/json/cper-json-section-log.json
index 6d41cd0..4287316 100644
--- a/specification/json/cper-json-section-log.json
+++ b/specification/json/cper-json-section-log.json
@@ -27,6 +27,7 @@
{ "$ref": "./sections/cper-ccix-per.json" },
{ "$ref": "./sections/cper-cxl-protocol.json" },
{ "$ref": "./sections/cper-cxl-component.json" },
+ { "$ref": "./sections/cper-nvidia.json" },
{ "$ref": "./sections/cper-unknown.json" }
]
}
diff --git a/specification/json/sections/cper-nvidia.json b/specification/json/sections/cper-nvidia.json
new file mode 100644
index 0000000..fb6dac5
--- /dev/null
+++ b/specification/json/sections/cper-nvidia.json
@@ -0,0 +1,38 @@
+{
+ "$id": "cper-json-nvidia-section",
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "type": "object",
+ "required": [
+ "signature",
+ "errorType",
+ "errorInstance",
+ "severity",
+ "socket",
+ "numRegs",
+ "instanceBase"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "signature": {
+ "type": "string"
+ },
+ "errorType": {
+ "type": "integer"
+ },
+ "errorInstance": {
+ "type": "integer"
+ },
+ "severity": {
+ "type": "integer"
+ },
+ "socket": {
+ "type": "integer"
+ },
+ "numberRegs": {
+ "type": "integer"
+ },
+ "instanceBase": {
+ "type": "uint64"
+ }
+ }
+}