Remove validation bits
Discard invalid properties from json decode. JSON output should only
contain valid properties. This saves time in preventing post
processing of output for valid fields.
Ensure round trip validity with validation bits removed and required
properties populated.
Fix bugs in json decode.
Overhaul unit tests to use valijson. Add tests with static examples
to validate against schema. Use and nlohmann for better schema
validation over intrinsic libcper validation.
Example json output before:
{
"ValidationBits": {
"LevelValid": false,
"CorrectedValid": true
},
"Level": 1,
"Corrected": true
}
After:
{
"Corrected": true
}
Change-Id: I188bdc2827a57d938c22a431238fadfcdc939ab8
Signed-off-by: Aushim Nagarkatti <anagarkatti@nvidia.com>
diff --git a/generator/sections/gen-section-arm.c b/generator/sections/gen-section-arm.c
index 5043741..c181663 100644
--- a/generator/sections/gen-section-arm.c
+++ b/generator/sections/gen-section-arm.c
@@ -5,18 +5,20 @@
**/
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <libcper/BaseTypes.h>
#include <libcper/generator/gen-utils.h>
#include <libcper/generator/sections/gen-section.h>
#define ARM_ERROR_INFO_SIZE 32
-void *generate_arm_error_info();
+void *generate_arm_error_info(GEN_VALID_BITS_TEST_TYPE validBitsType);
size_t generate_arm_context_info(void **location);
//Generates a single pseudo-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)
+size_t generate_section_arm(void **location,
+ GEN_VALID_BITS_TEST_TYPE validBitsType)
{
//Set up for generation of error/context structures.
UINT16 error_structure_num = rand() % 4 + 1; //Must be at least 1.
@@ -27,7 +29,7 @@
//Generate the structures.
for (int i = 0; i < error_structure_num; i++) {
- error_structures[i] = generate_arm_error_info();
+ error_structures[i] = generate_arm_error_info(validBitsType);
}
for (int i = 0; i < context_structure_num; i++) {
context_structure_lengths[i] =
@@ -35,7 +37,7 @@
}
//Determine a random amount of vendor specific info.
- int vendor_info_len = rand() % 16;
+ size_t vendor_info_len = rand() % 16 + 4;
//Create the section as a whole.
size_t total_len = 40 + (error_structure_num * ARM_ERROR_INFO_SIZE);
@@ -56,8 +58,13 @@
*(section + 12) = rand() % 4;
//Reserved zero bytes.
- UINT64 *validation = (UINT64 *)section;
- *validation &= 0x7;
+ UINT32 *validation = (UINT32 *)section;
+ *validation &= 0xF;
+ if (validBitsType == ALL_VALID) {
+ *validation = 0xF;
+ } else if (validBitsType == SOME_VALID) {
+ *validation = 0xA;
+ }
UINT32 *running_state = (UINT32 *)(section + 32);
*running_state &= 0x1;
memset(section + 13, 0, 3);
@@ -76,13 +83,21 @@
cur_pos += context_structure_lengths[i];
}
+ //vendor specific
+ for (size_t i = 0; i < vendor_info_len; i++) {
+ //Ensure only ascii is used so we don't
+ // fail base64E
+ *cur_pos = rand() % 127 + 1;
+ cur_pos += 1;
+ }
+
//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()
+void *generate_arm_error_info(GEN_VALID_BITS_TEST_TYPE validBitsType)
{
UINT8 *error_info = generate_random_bytes(ARM_ERROR_INFO_SIZE);
@@ -91,12 +106,17 @@
*(error_info + 1) = ARM_ERROR_INFO_SIZE;
//Type of error.
- UINT8 error_type = rand() % 4;
+ UINT8 error_type = rand() % 3;
*(error_info + 4) = error_type;
//Reserved bits for error information.
UINT16 *validation = (UINT16 *)(error_info + 2);
*validation &= 0x1F;
+ if (validBitsType == ALL_VALID) {
+ *validation = 0x1F;
+ } else if (validBitsType == SOME_VALID) {
+ *validation = 0x15;
+ }
//Make sure reserved bits are zero according with the type.
UINT64 *error_subinfo = (UINT64 *)(error_info + 8);
@@ -105,11 +125,25 @@
case 0:
case 1:
*error_subinfo &= 0xFFFFFFF;
+ //Reserved bits for cache/tlb.
+ UINT16 *val_cache = (UINT16 *)(error_info + 8);
+ if (validBitsType == ALL_VALID) {
+ *val_cache = 0x7F;
+ } else if (validBitsType == SOME_VALID) {
+ *val_cache = 0x55;
+ }
break;
//Bus
case 2:
*error_subinfo &= 0xFFFFFFFFFFF;
+ UINT16 *val_bus = (UINT16 *)(error_info + 8);
+ if (validBitsType == ALL_VALID) {
+ *val_bus = 0xFFF;
+ } else if (validBitsType == SOME_VALID) {
+ *val_bus = 0x555;
+ }
+
break;
//Microarch/other.
@@ -117,6 +151,10 @@
break;
}
+ //flags
+ UINT8 *flags = (UINT8 *)(error_info + 7);
+ *flags &= 0xF;
+
return error_info;
}
@@ -175,6 +213,14 @@
int total_size = 8 + reg_size;
UINT16 *context_info = (UINT16 *)generate_random_bytes(total_size);
+ //UEFI spec is not clear about bit 15 in the
+ // reg type 8 section. This sets it to 0 to
+ // avoid confusion for now.
+ if (reg_type == 8) {
+ UINT8 *reg_decode = (UINT8 *)context_info;
+ *(reg_decode + 9) &= 0x7F;
+ }
+
//Set header information.
*(context_info + 1) = reg_type;
*((UINT32 *)(context_info + 2)) = reg_size;