Add support for AMPERE CPERs
Support Ampere CPER entries
Change-Id: I607a89209138fa53914c55c07aba8b7d6f382e5e
Signed-off-by: Dung Cao <dung@os.amperecomputing.com>
diff --git a/edk/Cper.c b/edk/Cper.c
index 218589b..a4d5713 100644
--- a/edk/Cper.c
+++ b/edk/Cper.c
@@ -215,3 +215,9 @@
0x11ec,
{ 0xbe, 0xa7, 0xcb, 0x3f, 0xdb, 0x95,
0xc7, 0x86 } };
+
+EFI_GUID gEfiAmpereErrorSectionGuid = { 0x2826cc9f,
+ 0x448c,
+ 0x4c2b,
+ { 0x86, 0xb6, 0xa9, 0x53, 0x94, 0xb7,
+ 0xef, 0x33 } };
diff --git a/edk/Cper.h b/edk/Cper.h
index 57e2657..a982d18 100644
--- a/edk/Cper.h
+++ b/edk/Cper.h
@@ -299,6 +299,13 @@
0xa7, 0x9e, 0x57, 0x5f, 0xdf, 0xaa, 0x84, 0xec \
} \
}
+#define EFI_ERROR_SECTION_AMPERE_SPECIFIC_GUID \
+ { \
+ 0x2826cc9f, 0x448c, 0x4c2b, \
+ { \
+ 0x86, 0xb6, 0xa9, 0x53, 0x94, 0xb7, 0xef, 0x33 \
+ } \
+ }
///@}
///
@@ -1414,6 +1421,18 @@
} EFI_NVIDIA_ERROR_DATA;
extern EFI_GUID gEfiNvidiaErrorSectionGuid;
+
+///
+/// Ampere Error Record Section
+///
+typedef struct {
+ UINT16 TypeId;
+ UINT16 SubtypeId;
+ UINT32 InstanceId;
+} __attribute__((packed)) EFI_AMPERE_ERROR_DATA;
+
+extern EFI_GUID gEfiAmpereErrorSectionGuid;
+
#pragma pack(pop)
#ifdef __cplusplus
diff --git a/generator/sections/gen-section-ampere.c b/generator/sections/gen-section-ampere.c
new file mode 100644
index 0000000..85fa765
--- /dev/null
+++ b/generator/sections/gen-section-ampere.c
@@ -0,0 +1,30 @@
+/**
+ * Functions for generating pseudo-random CPER AMPERE 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 Ampere error section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_ampere(void **location)
+{
+ //Create random bytes.
+ size_t size = sizeof(EFI_AMPERE_ERROR_DATA);
+ UINT8 *section = generate_random_bytes(size);
+
+ //Reserved byte.
+ EFI_AMPERE_ERROR_DATA *ampere_error = (EFI_AMPERE_ERROR_DATA *)section;
+ ampere_error->TypeId = 10;
+ ampere_error->SubtypeId = 1;
+ ampere_error->InstanceId = 0;
+
+ //Set return values, exit.
+ *location = section;
+ return size;
+}
diff --git a/generator/sections/gen-section.c b/generator/sections/gen-section.c
index 819ebdb..56b6d84 100644
--- a/generator/sections/gen-section.c
+++ b/generator/sections/gen-section.c
@@ -43,6 +43,7 @@
{ &gEfiCxlMldPortErrorSectionGuid, "cxlcomponent-mld",
generate_section_cxl_component },
{ &gEfiNvidiaErrorSectionGuid, "nvidia", generate_section_nvidia },
+ { &gEfiAmpereErrorSectionGuid, "ampere", generate_section_ampere },
};
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 d1987b9..1c6e227 100644
--- a/generator/sections/gen-section.h
+++ b/generator/sections/gen-section.h
@@ -25,6 +25,7 @@
size_t generate_section_cxl_protocol(void **location);
size_t generate_section_cxl_component(void **location);
size_t generate_section_nvidia(void **location);
+size_t generate_section_ampere(void **location);
//Definition structure for a single CPER section generator.
typedef struct {
diff --git a/meson.build b/meson.build
index 10c05fe..1eee4ec 100644
--- a/meson.build
+++ b/meson.build
@@ -42,6 +42,7 @@
'sections/cper-section-pci-dev.c',
'sections/cper-section-pcie.c',
'sections/cper-section.c',
+ 'sections/cper-section-ampere.c',
)
edk_sources = files('edk/Cper.c')
@@ -61,6 +62,7 @@
'generator/sections/gen-section-pci-dev.c',
'generator/sections/gen-section-pcie.c',
'generator/sections/gen-section.c',
+ 'generator/sections/gen-section-ampere.c',
)
cc = meson.get_compiler('c')
diff --git a/sections/cper-section-ampere.c b/sections/cper-section-ampere.c
new file mode 100644
index 0000000..264c2f6
--- /dev/null
+++ b/sections/cper-section-ampere.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <json.h>
+#include "../edk/Cper.h"
+#include "../cper-utils.h"
+#include "cper-section-ampere.h"
+
+//Converts the given processor-generic CPER section into JSON IR.
+json_object *cper_section_ampere_to_ir(void *section)
+{
+ EFI_AMPERE_ERROR_DATA *record = (EFI_AMPERE_ERROR_DATA *)section;
+ json_object *section_ir = json_object_new_object();
+
+ json_object_object_add(section_ir, "typeId",
+ json_object_new_int(record->TypeId));
+ json_object_object_add(section_ir, "subTypeId",
+ json_object_new_int(record->SubtypeId));
+ json_object_object_add(section_ir, "instanceId",
+ json_object_new_int(record->InstanceId));
+
+ return section_ir;
+}
+
+//Converts a single CPER-JSON ARM error section into CPER binary, outputting to the given stream.
+void ir_section_ampere_to_cper(json_object *section, FILE *out)
+{
+ EFI_AMPERE_ERROR_DATA *section_cper = (EFI_AMPERE_ERROR_DATA *)calloc(
+ 1, sizeof(EFI_AMPERE_ERROR_DATA));
+
+ //Count of error/context info structures.
+ section_cper->TypeId =
+ json_object_get_int(json_object_object_get(section, "typeId"));
+ section_cper->SubtypeId = json_object_get_int(
+ json_object_object_get(section, "subTypeId"));
+ section_cper->InstanceId = json_object_get_int(
+ json_object_object_get(section, "instanceId"));
+
+ //Flush header to stream.
+ fwrite(section_cper, sizeof(EFI_AMPERE_ERROR_DATA), 1, out);
+ fflush(out);
+ free(section_cper);
+}
diff --git a/sections/cper-section-ampere.h b/sections/cper-section-ampere.h
new file mode 100644
index 0000000..9264098
--- /dev/null
+++ b/sections/cper-section-ampere.h
@@ -0,0 +1,10 @@
+#ifndef CPER_SECTION_AMPERE_H
+#define CPER_SECTION_AMPERE_H
+
+#include <json.h>
+#include "../edk/Cper.h"
+
+json_object *cper_section_ampere_to_ir(void *section);
+void ir_section_ampere_to_cper(json_object *section, FILE *out);
+
+#endif
diff --git a/sections/cper-section.c b/sections/cper-section.c
index 1845118..defecf6 100644
--- a/sections/cper-section.c
+++ b/sections/cper-section.c
@@ -21,6 +21,7 @@
#include "cper-section-cxl-protocol.h"
#include "cper-section-cxl-component.h"
#include "cper-section-nvidia.h"
+#include "cper-section-ampere.h"
//Definitions of all sections available to the CPER parser.
CPER_SECTION_DEFINITION section_definitions[] = {
@@ -72,6 +73,8 @@
cper_section_cxl_component_to_ir, ir_section_cxl_component_to_cper },
{ &gEfiNvidiaErrorSectionGuid, "NVIDIA", cper_section_nvidia_to_ir,
ir_section_nvidia_to_cper },
+ { &gEfiAmpereErrorSectionGuid, "Ampere", cper_section_ampere_to_ir,
+ ir_section_ampere_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 029ce2f..b4dd875 100644
--- a/specification/json/cper-json-full-log.json
+++ b/specification/json/cper-json-full-log.json
@@ -34,6 +34,7 @@
{ "$ref": "./sections/cper-cxl-protocol.json" },
{ "$ref": "./sections/cper-cxl-component.json" },
{ "$ref": "./sections/cper-nvidia.json" },
+ { "$ref": "./sections/cper-ampere.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 4287316..0909197 100644
--- a/specification/json/cper-json-section-log.json
+++ b/specification/json/cper-json-section-log.json
@@ -28,6 +28,7 @@
{ "$ref": "./sections/cper-cxl-protocol.json" },
{ "$ref": "./sections/cper-cxl-component.json" },
{ "$ref": "./sections/cper-nvidia.json" },
+ { "$ref": "./sections/cper-ampere.json" },
{ "$ref": "./sections/cper-unknown.json" }
]
}
diff --git a/specification/json/sections/cper-ampere.json b/specification/json/sections/cper-ampere.json
new file mode 100644
index 0000000..64d1d3f
--- /dev/null
+++ b/specification/json/sections/cper-ampere.json
@@ -0,0 +1,18 @@
+{
+ "$id": "cper-json-ampere-section",
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "type": "object",
+ "required": ["typeId", "subTypeId", "instanceId"],
+ "additionalProperties": false,
+ "properties": {
+ "typeId": {
+ "type": "integer"
+ },
+ "subTypeId": {
+ "type": "integer"
+ },
+ "instanceId": {
+ "type": "integer"
+ }
+ }
+}