PEL: Support new DeconfigFlag msg reg field

Add a new field to the PEL message registry to indicate that some
hardware associated with a callout was deconfigured.

"DeconfigFlag": true

This results in bit 6 in the SRC's hex word 5 being set.  It is looked
at by the code that creates the periodic PELs when there is a system
running with deconfigured hardware.

Note: For something to be considered deconfigured, it doesn't
necessarily mean that firmware chose to not configure it.  It could also
mean that it is broken or missing, at least in the case of power
supplies or fans.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I3e657cb52416fc50000e299bf2d583db7b67caf8
diff --git a/extensions/openpower-pels/registry.cpp b/extensions/openpower-pels/registry.cpp
index 9cccb0b..c9c4169 100644
--- a/extensions/openpower-pels/registry.cpp
+++ b/extensions/openpower-pels/registry.cpp
@@ -190,6 +190,11 @@
     return type;
 }
 
+bool getSRCDeconfigFlag(const nlohmann::json& src)
+{
+    return src["DeconfigFlag"].get<bool>();
+}
+
 std::optional<std::map<SRC::WordNum, SRC::AdditionalDataField>>
     getSRCHexwordFields(const nlohmann::json& src, const std::string& name)
 {
@@ -735,6 +740,11 @@
                 entry.src.symptomID = helper::getSRCSymptomIDFields(src, name);
             }
 
+            if (src.contains("DeconfigFlag"))
+            {
+                entry.src.deconfigFlag = helper::getSRCDeconfigFlag(src);
+            }
+
             auto& doc = (*e)["Documentation"];
             entry.doc.message = doc["Message"];
             entry.doc.description = doc["Description"];
diff --git a/extensions/openpower-pels/registry.hpp b/extensions/openpower-pels/registry.hpp
index 7ee5979..e72fafb 100644
--- a/extensions/openpower-pels/registry.hpp
+++ b/extensions/openpower-pels/registry.hpp
@@ -105,7 +105,12 @@
     using AdditionalDataField = std::tuple<std::string, std::string>;
     std::optional<std::map<WordNum, AdditionalDataField>> hexwordADFields;
 
-    SRC() : type(0), reasonCode(0) {}
+    /**
+     * @brief If the Deconfigured flag should be set in hex word 5
+     */
+    bool deconfigFlag;
+
+    SRC() : type(0), reasonCode(0), deconfigFlag(false) {}
 };
 
 struct AppCapture
@@ -448,6 +453,15 @@
     getSRCSymptomIDFields(const nlohmann::json& src, const std::string& name);
 
 /**
+ * @brief Returns the value of the 'DeconfigFlag' field.
+ *
+ * @param[in] src - The message registry SRC dictionary to read from
+ *
+ * @return bool - The field value
+ */
+bool getSRCDeconfigFlag(const nlohmann::json& src);
+
+/**
  * @brief Reads the "ComponentID" field out of JSON and converts it to a
  *        uint16_t like 0xFF00.
  *
diff --git a/extensions/openpower-pels/registry/README.md b/extensions/openpower-pels/registry/README.md
index 154622e..f914bfc 100644
--- a/extensions/openpower-pels/registry/README.md
+++ b/extensions/openpower-pels/registry/README.md
@@ -239,6 +239,20 @@
 }
 ```
 
+### SRC Deconfig Flag
+
+Bit 6 in hex word 5 of the SRC means that one or more called out resources have
+been deconfigured, and this flag can be used to set that bit. The only other way
+to set it is by indicating it when
+[passing in the callouts via JSON](../README.md#callouts).
+
+This is looked at by the software that creates the periodic PELs that indicate a
+system is running with deconfigured hardware.
+
+```json
+"DeconfigFlag": true
+```
+
 ### Documentation Fields
 
 The documentation fields are used by PEL parsers to display a human readable
diff --git a/extensions/openpower-pels/registry/schema/schema.json b/extensions/openpower-pels/registry/schema/schema.json
index 0d23cd8..3a2ac42 100644
--- a/extensions/openpower-pels/registry/schema/schema.json
+++ b/extensions/openpower-pels/registry/schema/schema.json
@@ -100,7 +100,9 @@
 
                 "SymptomIDFields": { "$ref": "#/definitions/symptomID" },
 
-                "Words6To9": { "$ref": "#/definitions/srcWords6To9" }
+                "Words6To9": { "$ref": "#/definitions/srcWords6To9" },
+
+                "DeconfigFlag": { "$ref": "#/definitions/deconfigFlag" }
             },
 
             "required": ["ReasonCode", "Words6To9"],
@@ -132,6 +134,11 @@
             "enum": ["BD", "11"]
         },
 
+        "deconfigFlag": {
+            "description": "If true, will set bit 6 in hex data word 5, which means 'one or more resources are deconfigured'.",
+            "type": "boolean"
+        },
+
         "docNotes": {
             "description": "Any notes/comments about the error. An array of strings for manual line wrapping. Optional.",
             "type": "array",
diff --git a/extensions/openpower-pels/src.cpp b/extensions/openpower-pels/src.cpp
index 063c2ad..dc75e07 100644
--- a/extensions/openpower-pels/src.cpp
+++ b/extensions/openpower-pels/src.cpp
@@ -350,6 +350,11 @@
     setBMCPosition();
     setMotherboardCCIN(dataIface);
 
+    if (regEntry.src.deconfigFlag)
+    {
+        setErrorStatusFlag(ErrorStatusFlags::deconfigured);
+    }
+
     // Fill in the last 4 words from the AdditionalData property contents.
     setUserDefinedHexWords(regEntry, additionalData);
 
diff --git a/test/openpower-pels/registry_test.cpp b/test/openpower-pels/registry_test.cpp
index 12a205f..b33c07e 100644
--- a/test/openpower-pels/registry_test.cpp
+++ b/test/openpower-pels/registry_test.cpp
@@ -85,7 +85,8 @@
                         "Description": "bad voltage",
                         "AdditionalDataPropSource": "VOLTAGE"
                     }
-                }
+                },
+                "DeconfigFlag": true
             },
 
             "Documentation":
@@ -222,6 +223,7 @@
 
     EXPECT_EQ(entry->src.type, 0xBD);
     EXPECT_EQ(entry->src.reasonCode, 0x2333);
+    EXPECT_TRUE(entry->src.deconfigFlag);
 
     auto& hexwords = entry->src.hexwordADFields;
     EXPECT_TRUE(hexwords);
@@ -282,6 +284,7 @@
     EXPECT_EQ(entry->src.type, 0xBD);
     EXPECT_FALSE(entry->src.hexwordADFields);
     EXPECT_FALSE(entry->src.symptomID);
+    EXPECT_FALSE(entry->src.deconfigFlag);
 }
 
 TEST_F(RegistryTest, TestBadJSON)
diff --git a/test/openpower-pels/src_test.cpp b/test/openpower-pels/src_test.cpp
index f2ade68..ed8af4b 100644
--- a/test/openpower-pels/src_test.cpp
+++ b/test/openpower-pels/src_test.cpp
@@ -230,6 +230,7 @@
     // Validate more fields here as the code starts filling them in.
 
     // Ensure hex word 5 wasn't allowed to be set to TEST1's contents
+    // And that none of the error status flags are set
     EXPECT_EQ(hexwords[5 - 2], 0);
 
     // The user defined hex word fields specifed in the additional data.
@@ -491,6 +492,7 @@
     message::Entry entry;
     entry.src.type = 0xBD;
     entry.src.reasonCode = 0xABCD;
+    entry.src.deconfigFlag = true;
     entry.subsystem = 0x42;
 
     entry.callouts = R"(
@@ -555,6 +557,10 @@
 
         SRC src{entry, ad, dataIface};
 
+        const auto& hexwords = src.hexwordData();
+        auto mask = static_cast<uint32_t>(SRC::ErrorStatusFlags::deconfigured);
+        EXPECT_EQ(hexwords[5 - 2] & mask, mask);
+
         auto& callouts = src.callouts()->callouts();
         ASSERT_EQ(callouts.size(), 2);