Squash minor ARM CPER issues, add ARM generation.
diff --git a/generator/cper-generate.c b/generator/cper-generate.c
index dd336fe..90ad460 100644
--- a/generator/cper-generate.c
+++ b/generator/cper-generate.c
@@ -9,10 +9,9 @@
#include <string.h>
#include "../edk/Cper.h"
#include "gen-utils.h"
-#include "sections/gen-section-generic.h"
-#include "sections/gen-section-ia32x64.h"
+#include "sections/gen-sections.h"
-EFI_ERROR_SECTION_DESCRIPTOR* generate_section_descriptor(char* type, size_t* lengths, int index);
+EFI_ERROR_SECTION_DESCRIPTOR* generate_section_descriptor(char* type, size_t* lengths, int index, int num_sections);
size_t generate_section(void** location, char* type);
void print_help();
@@ -54,17 +53,20 @@
(EFI_COMMON_ERROR_RECORD_HEADER*)calloc(1, sizeof(EFI_COMMON_ERROR_RECORD_HEADER));
header->SignatureStart = 0x52455043; //CPER
header->SectionCount = num_sections;
- printf("%d sections\n", num_sections);
header->SignatureEnd = 0xFFFFFFFF;
header->Flags = 4; //HW_ERROR_FLAGS_SIMULATED
+ header->RecordID = (UINT64)rand();
+ header->ErrorSeverity = rand() % 4;
+ *((UINT64*)&header->TimeStamp) = (UINT64)rand();
+ header->ValidationBits = rand() % 0b1000;
//Generate the section descriptors given the number of sections.
EFI_ERROR_SECTION_DESCRIPTOR* section_descriptors[num_sections];
for (int i=0; i<num_sections; i++)
- section_descriptors[i] = generate_section_descriptor(argv[4 + i], section_lengths, i);
+ section_descriptors[i] = generate_section_descriptor(argv[4 + i], section_lengths, i, num_sections);
//Calculate total length of structure, set in header.
- size_t total_len = sizeof(header);
+ size_t total_len = sizeof(EFI_COMMON_ERROR_RECORD_HEADER);
for (int i=0; i<num_sections; i++)
total_len += section_lengths[i];
total_len += num_sections * sizeof(EFI_ERROR_SECTION_DESCRIPTOR);
@@ -98,7 +100,7 @@
}
//Generates a single section descriptor for a section with the given properties.
-EFI_ERROR_SECTION_DESCRIPTOR* generate_section_descriptor(char* type, size_t* lengths, int index)
+EFI_ERROR_SECTION_DESCRIPTOR* generate_section_descriptor(char* type, size_t* lengths, int index, int num_sections)
{
EFI_ERROR_SECTION_DESCRIPTOR* descriptor =
(EFI_ERROR_SECTION_DESCRIPTOR*)generate_random_bytes(sizeof(EFI_ERROR_SECTION_DESCRIPTOR));
@@ -110,7 +112,8 @@
//Set length, offset from base record.
descriptor->SectionLength = (UINT32)lengths[index];
- descriptor->SectionOffset = sizeof(EFI_COMMON_ERROR_RECORD_HEADER);
+ descriptor->SectionOffset = sizeof(EFI_COMMON_ERROR_RECORD_HEADER)
+ + (num_sections * sizeof(EFI_ERROR_SECTION_DESCRIPTOR));
for (int i=0; i<index; i++)
descriptor->SectionOffset += lengths[i];
@@ -191,8 +194,8 @@
length = generate_section_ia32x64(location);
// else if (strcmp(type, "ipf") == 0)
// length = generate_section_ipf(location);
- // else if (strcmp(type, "arm") == 0)
- // length = generate_section_arm(location);
+ else if (strcmp(type, "arm") == 0)
+ length = generate_section_arm(location);
// else if (strcmp(type, "memory") == 0)
// length = generate_section_memory(location);
// else if (strcmp(type, "memory2") == 0)
diff --git a/generator/sections/gen-section-arm.c b/generator/sections/gen-section-arm.c
new file mode 100644
index 0000000..53fb24c
--- /dev/null
+++ b/generator/sections/gen-section-arm.c
@@ -0,0 +1,176 @@
+/**
+ * Functions for generating psuedo-random CPER ARM processor sections.
+ *
+ * Author: Lawrence.Tang@arm.com
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include "../../edk/BaseTypes.h"
+#include "../gen-utils.h"
+#include "gen-sections.h"
+#define ARM_ERROR_INFO_SIZE 32
+
+void* generate_arm_error_info();
+size_t generate_arm_context_info(void** location);
+
+//Generates a single psuedo-random ARM processor section, saving the resulting address to the given
+//location. Returns the size of the newly created section.
+size_t generate_section_arm(void** location)
+{
+ //Set up for generation of error/context structures.
+ UINT16 error_structure_num = rand() % 4 + 1; //Must be at least 1.
+ UINT16 context_structure_num = rand() % 3;
+ void* error_structures[error_structure_num];
+ void* context_structures[context_structure_num];
+ size_t context_structure_lengths[context_structure_num];
+
+ //Generate the structures.
+ for (int i=0; i<error_structure_num; i++)
+ error_structures[i] = generate_arm_error_info();
+ for (int i=0; i<context_structure_num; i++)
+ context_structure_lengths[i] = generate_arm_context_info(context_structures + i);
+
+ //Determine a random amount of vendor specific info.
+ int vendor_info_len = rand() % 16;
+
+ //Create the section as a whole.
+ size_t total_len = 40 + (error_structure_num * ARM_ERROR_INFO_SIZE);
+ for (int i=0; i<context_structure_num; i++)
+ total_len += context_structure_lengths[i];
+ total_len += vendor_info_len;
+ UINT8* section = generate_random_bytes(total_len);
+
+ //Set header information.
+ UINT16* info_nums = (UINT16*)(section + 4);
+ *info_nums = error_structure_num;
+ *(info_nums + 1) = context_structure_num;
+ UINT32* section_length = (UINT32*)(section + 8);
+ *section_length = total_len;
+
+ //Error affinity.
+ *(section + 12) = rand() % 4;
+
+ //Reserved zero bytes.
+ memset(section + 13, 0, 3);
+
+ //Copy in the sections/context structures, free resources.
+ UINT8* cur_pos = section + 40;
+ for (int i=0; i<error_structure_num; i++)
+ {
+ memcpy(cur_pos, error_structures[i], ARM_ERROR_INFO_SIZE);
+ free(error_structures[i]);
+ cur_pos += ARM_ERROR_INFO_SIZE;
+ }
+ for (int i=0; i<context_structure_num; i++)
+ {
+ memcpy(cur_pos, context_structures[i], context_structure_lengths[i]);
+ free(context_structures[i]);
+ cur_pos += context_structure_lengths[i];
+ }
+
+ //Set return values and exit.
+ *location = section;
+ return total_len;
+}
+
+//Generates a single pseudo-random ARM error info structure. Must be later freed.
+void* generate_arm_error_info()
+{
+ UINT8* error_info = generate_random_bytes(ARM_ERROR_INFO_SIZE);
+
+ //Version (zero for revision of table referenced), length.
+ *error_info = 0;
+ *(error_info + 1) = ARM_ERROR_INFO_SIZE;
+
+ //Type of error.
+ UINT8 error_type = rand() % 4;
+ *(error_info + 4) = error_type;
+
+ //Make sure reserved bits are zero according with the type.
+ UINT64* error_subinfo = (UINT64*)(error_info + 8);
+ switch (error_type)
+ {
+ //Cache/TLB
+ case 0:
+ case 1:
+ *error_subinfo &= 0xFFFFFFF;
+ break;
+
+ //Bus
+ case 2:
+ *error_subinfo &= 0xFFFFFFFFFFF;
+ break;
+
+ //Microarch/other.
+ default:
+ break;
+ }
+
+ return error_info;
+}
+
+//Generates a single pseudo-random ARM context info structure. Must be later freed.
+size_t generate_arm_context_info(void** location)
+{
+ //Initial length is 8 bytes. Add extra based on type.
+ UINT16 reg_type = rand() % 9;
+ UINT32 reg_size = 0;
+
+ //Set register size.
+ switch (reg_type)
+ {
+ //AARCH32 GPR, AARCH32 EL2
+ case 0:
+ case 2:
+ reg_size = 64;
+ break;
+
+ //AARCH32 EL1
+ case 1:
+ reg_size = 96;
+ break;
+
+ //AARCH32 EL3
+ case 3:
+ reg_size = 8;
+ break;
+
+ //AARCH64 GPR
+ case 4:
+ reg_size = 256;
+ break;
+
+ //AARCH64 EL1
+ case 5:
+ reg_size = 136;
+ break;
+
+ //AARCH64 EL2
+ case 6:
+ reg_size = 120;
+ break;
+
+ //AARCH64 EL3
+ case 7:
+ reg_size = 80;
+ break;
+
+ //Misc. single register.
+ case 8:
+ reg_size = 10;
+ break;
+ }
+
+ //Create context structure randomly.
+ int total_size = 8 + reg_size;
+ UINT16* context_info = (UINT16*)generate_random_bytes(total_size);
+
+ //Set header information.
+ *(context_info + 1) = reg_type;
+ *((UINT32*)(context_info + 2)) = reg_size;
+
+ //Set return values and exit.
+ *location = context_info;
+ return total_size;
+}
\ No newline at end of file
diff --git a/generator/sections/gen-section-generic.c b/generator/sections/gen-section-generic.c
index 205fea1..b2bda16 100644
--- a/generator/sections/gen-section-generic.c
+++ b/generator/sections/gen-section-generic.c
@@ -7,7 +7,7 @@
#include <stdlib.h>
#include "../../edk/BaseTypes.h"
#include "../gen-utils.h"
-#include "gen-section-generic.h"
+#include "gen-sections.h"
//Generates a single psuedo-random generic processor section, saving the resulting address to the given
//location. Returns the size of the newly created section.
diff --git a/generator/sections/gen-section-generic.h b/generator/sections/gen-section-generic.h
deleted file mode 100644
index 49ff655..0000000
--- a/generator/sections/gen-section-generic.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef GEN_SECTION_GENERIC_H
-#define GEN_SECTION_GENERIC_H
-
-#include <stdlib.h>
-
-size_t generate_section_generic(void** location);
-
-#endif
\ No newline at end of file
diff --git a/generator/sections/gen-section-ia32x64.c b/generator/sections/gen-section-ia32x64.c
index b06a237..7412ca3 100644
--- a/generator/sections/gen-section-ia32x64.c
+++ b/generator/sections/gen-section-ia32x64.c
@@ -8,7 +8,8 @@
#include <string.h>
#include "../../edk/Cper.h"
#include "../gen-utils.h"
-#include "gen-section-ia32x64.h"
+#include "gen-sections.h"
+#define IA32X64_ERROR_STRUCTURE_SIZE 64
void* generate_ia32x64_error_structure();
size_t generate_ia32x64_context_structure(void** location);
diff --git a/generator/sections/gen-section-ia32x64.h b/generator/sections/gen-section-ia32x64.h
deleted file mode 100644
index 78f5052..0000000
--- a/generator/sections/gen-section-ia32x64.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef GEN_SECTION_IA32X64_H
-#define GEN_SECTION_IA32X64_H
-
-#include <stdlib.h>
-
-#define IA32X64_ERROR_STRUCTURE_SIZE 64
-
-size_t generate_section_ia32x64(void** location);
-
-#endif
\ No newline at end of file
diff --git a/generator/sections/gen-sections.h b/generator/sections/gen-sections.h
new file mode 100644
index 0000000..33ecd39
--- /dev/null
+++ b/generator/sections/gen-sections.h
@@ -0,0 +1,10 @@
+#ifndef GEN_SECTIONS_H
+#define GEN_SECTIONS_H
+
+#include <stdlib.h>
+
+size_t generate_section_generic(void** location);
+size_t generate_section_ia32x64(void** location);
+size_t generate_section_arm(void** location);
+
+#endif
\ No newline at end of file