Nvidia add cmet-info
Add decoding of more specific Error codes.
Unit tests pass.
Change-Id: Ia0ca0dfdf550381da435b0fb9041b664784f7476
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/sections/cper-section-nvidia.c b/sections/cper-section-nvidia.c
index 7cb2e87..b633396 100644
--- a/sections/cper-section-nvidia.c
+++ b/sections/cper-section-nvidia.c
@@ -12,6 +12,103 @@
#include <libcper/sections/cper-section-nvidia.h>
#include <libcper/log.h>
+void parse_cmet_info(EFI_NVIDIA_REGISTER_DATA *regPtr, UINT8 NumberRegs,
+ size_t size, json_object *section_ir)
+{
+ json_object *regarr = json_object_new_array();
+ for (int i = 0; i < NumberRegs; i++, regPtr++) {
+ json_object *reg = NULL;
+ if (sizeof(EFI_NVIDIA_ERROR_DATA) +
+ i * sizeof(EFI_NVIDIA_REGISTER_DATA) <
+ size) {
+ reg = json_object_new_object();
+ add_int_hex_64(reg, "ChannelAddress", regPtr->Address);
+ add_int(reg, "ErrorCount", regPtr->CmetInfo.ErrorCount);
+ add_bool(reg, "ChannelEnabled",
+ regPtr->CmetInfo.ChannelEnabled);
+ add_bool(reg, "ChannelIsSpare",
+ regPtr->CmetInfo.ChannelIsSpare);
+ add_dict(reg, "DisabledReason",
+ regPtr->CmetInfo.DisabledReason,
+ channel_disable_reason_dict,
+ channel_disable_reason_dict_size);
+ } else {
+ reg = json_object_new_null();
+ }
+
+ json_object_array_add(regarr, reg);
+ }
+
+ json_object_object_add(section_ir, "CMETInfo", regarr);
+}
+
+void parse_fwerror(EFI_NVIDIA_REGISTER_DATA *regPtr, UINT8 NumberRegs,
+ size_t size, json_object *section_ir)
+{
+ (void)NumberRegs;
+ json_object *fwinfo;
+ if (sizeof(EFI_NVIDIA_ERROR_DATA) + sizeof(EFI_NVIDIA_FWERROR) > size) {
+ fwinfo = json_object_new_null();
+ } else {
+ fwinfo = json_object_new_object();
+ EFI_NVIDIA_FWERROR *fwerror = (EFI_NVIDIA_FWERROR *)regPtr;
+ add_untrusted_string(fwinfo, "initiating_firmware",
+ fwerror->initiating_firmware,
+ sizeof(fwerror->initiating_firmware));
+ add_int_hex_64(fwinfo, "task_checkpoint",
+ fwerror->task_checkpoint);
+ add_int_hex_64(fwinfo, "mb1_error_code",
+ fwerror->mb1_error_code);
+ add_untrusted_string(fwinfo, "mb1_version_string",
+ fwerror->mb1_version_string,
+ sizeof(fwerror->mb1_version_string));
+ add_int_hex_64(fwinfo, "bad_pages_retired_mask",
+ fwerror->bad_pages_retired_mask);
+ add_int_hex_64(fwinfo, "training_or_alias_check_retired_mask",
+ fwerror->training_or_alias_check_retired_mask);
+ }
+
+ json_object_object_add(section_ir, "FWErrorInfo", fwinfo);
+}
+
+void parse_registers(EFI_NVIDIA_REGISTER_DATA *regPtr, UINT8 NumberRegs,
+ size_t size, json_object *section_ir)
+{
+ // Registers (Address Value pairs).
+ json_object *regarr = json_object_new_array();
+ for (int i = 0; i < NumberRegs; i++, regPtr++) {
+ json_object *reg = NULL;
+ if (sizeof(EFI_NVIDIA_ERROR_DATA) +
+ i * sizeof(EFI_NVIDIA_REGISTER_DATA) <
+ size) {
+ reg = json_object_new_object();
+ json_object_object_add(
+ reg, "address",
+ json_object_new_uint64(regPtr->Address));
+ json_object_object_add(
+ reg, "value",
+ json_object_new_uint64(regPtr->Value));
+ } else {
+ reg = json_object_new_null();
+ }
+
+ json_object_array_add(regarr, reg);
+ }
+ json_object_object_add(section_ir, "registers", regarr);
+}
+
+typedef struct {
+ const char *ip_signature;
+ void (*callback)(EFI_NVIDIA_REGISTER_DATA *, UINT8, size_t,
+ json_object *);
+} NV_SECTION_CALLBACKS;
+
+NV_SECTION_CALLBACKS section_handlers[] = {
+ { "CMET-INFO\0", &parse_cmet_info },
+ { "FWERROR\0", &parse_fwerror },
+ { "", &parse_registers },
+};
+
//Converts a single NVIDIA CPER section into JSON IR.
json_object *cper_section_nvidia_to_ir(const UINT8 *section, UINT32 size)
{
@@ -47,29 +144,17 @@
section_ir, "instanceBase",
json_object_new_uint64(nvidia_error->InstanceBase));
- // Registers (Address Value pairs).
- json_object *regarr = json_object_new_array();
- EFI_NVIDIA_REGISTER_DATA *regPtr = nvidia_error->Register;
- for (int i = 0; i < nvidia_error->NumberRegs; i++, regPtr++) {
- json_object *reg = NULL;
- if (sizeof(EFI_NVIDIA_ERROR_DATA) +
- i * sizeof(EFI_NVIDIA_REGISTER_DATA) <
- size) {
- reg = json_object_new_object();
- json_object_object_add(
- reg, "address",
- json_object_new_uint64(regPtr->Address));
- json_object_object_add(
- reg, "value",
- json_object_new_uint64(regPtr->Value));
- } else {
- reg = json_object_new_null();
+ for (long unsigned int i = 0;
+ i < sizeof(section_handlers) / sizeof(section_handlers[0]); i++) {
+ const char *ip_signature = section_handlers[i].ip_signature;
+ if (strncmp(nvidia_error->Signature, ip_signature,
+ strlen(ip_signature)) == 0) {
+ section_handlers[i].callback(&nvidia_error->Register[0],
+ nvidia_error->NumberRegs,
+ size, section_ir);
+ break;
}
-
- json_object_array_add(regarr, reg);
}
- json_object_object_add(section_ir, "registers", regarr);
-
return section_ir;
}