PEL: Support 'PossibleSubsystems' in msg registry

Add a 'PossibleSubsystems' field to the message registry schema where
someone can list which subsystems they might pass into the PEL_SUBSYSTEM
AdditionalData property field when creating a PEL.

The PossibleSubsystems value will be used by a off-BMC script that
generates field documentation for SRCs, so it knows what all SRC ASCII
string values are possible for that entry since the subsystem is part of
them. For example, if that field was ['processor', 'memory'], then that
means the possible SRCs are BD10AAAA and BD20AAAA for reason code
'AAAA'.

The Subsystem and PossibleSubsystems fields are mutually exclusive in
the message registry, so code changes had to be made to support the
subsystem field now being optional.

There is now a chance that even though the subsystem is supposed to be
passed in using PEL_SUBSYSTEM, it isn't.  In that case, the 'Other'
subsystem will be used, since it seems fairly generic.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Ic8087fc46b2a192459b7287186f8972610e84730
diff --git a/extensions/openpower-pels/user_header.cpp b/extensions/openpower-pels/user_header.cpp
index 7aed654..b2365a9 100644
--- a/extensions/openpower-pels/user_header.cpp
+++ b/extensions/openpower-pels/user_header.cpp
@@ -58,26 +58,44 @@
     _header.subType = 0;
     _header.componentID = static_cast<uint16_t>(ComponentID::phosphorLogging);
 
-    _eventSubsystem = entry.subsystem;
+    std::optional<uint8_t> subsys;
 
     // Check for additional data - PEL_SUBSYSTEM
     auto ss = additionalData.getValue("PEL_SUBSYSTEM");
     if (ss)
     {
         auto eventSubsystem = std::stoul(*ss, NULL, 16);
-        std::string subsystem =
+        std::string subsystemString =
             pv::getValue(eventSubsystem, pel_values::subsystemValues);
-        if (subsystem == "invalid")
+        if (subsystemString == "invalid")
         {
             log<level::WARNING>(
-                fmt::format("UH: Invalid SubSystem value:{:#X}", eventSubsystem)
+                fmt::format(
+                    "UH: Invalid SubSystem value in PEL_SUBSYSTEM: {:#X}",
+                    eventSubsystem)
                     .c_str());
         }
         else
         {
-            _eventSubsystem = eventSubsystem;
+            subsys = eventSubsystem;
         }
     }
+    else
+    {
+        subsys = entry.subsystem;
+    }
+
+    if (subsys)
+    {
+        _eventSubsystem = *subsys;
+    }
+    else
+    {
+        // Gotta use something, how about 'others'.
+        log<level::WARNING>(
+            "No PEL subystem value supplied for error, using 'others'");
+        _eventSubsystem = 0x70;
+    }
 
     _eventScope = entry.eventScope.value_or(
         static_cast<uint8_t>(EventScope::entirePlatform));