PEL: Add symbolic FRU support to FRUIdentity

A symbolic FRU is a FRU where the part is known, but the part number is
not available for it.  A trusted symbolic FRU adds the requirement that
the location code is known to be correct so it can be used for lighting
LEDs and FRU replacement.

The symbolic FRU name shares the same field as the part number.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I2fa936d9d7235c5cff245effcdb9d445aefffe23
diff --git a/extensions/openpower-pels/fru_identity.cpp b/extensions/openpower-pels/fru_identity.cpp
index 8cf6382..b8dc94f 100644
--- a/extensions/openpower-pels/fru_identity.cpp
+++ b/extensions/openpower-pels/fru_identity.cpp
@@ -93,6 +93,17 @@
     _size = flattenedSize();
 }
 
+FRUIdentity::FRUIdentity(const std::string& symbolicFRUFromRegistry,
+                         bool trustedLocationCode)
+{
+    _type = substructureType;
+    _flags = (trustedLocationCode) ? symbolicFRUTrustedLocCode : symbolicFRU;
+
+    setSymbolicFRU(symbolicFRUFromRegistry);
+
+    _size = flattenedSize();
+}
+
 std::optional<std::string> FRUIdentity::getPN() const
 {
     if (hasPN())
@@ -231,6 +242,30 @@
     _pnOrProcedureID.back() = 0;
 }
 
+void FRUIdentity::setSymbolicFRU(const std::string& symbolicFRUFromRegistry)
+{
+
+    // Treat this has a HW callout.
+    _flags |= pnSupplied;
+    _flags &= ~maintProcSupplied;
+
+    if (pel_values::symbolicFRUs.count(symbolicFRUFromRegistry))
+    {
+        strncpy(_pnOrProcedureID.data(),
+                pel_values::symbolicFRUs.at(symbolicFRUFromRegistry).c_str(),
+                _pnOrProcedureID.size());
+    }
+    else
+    {
+        log<level::ERR>("Invalid symbolic FRU",
+                        entry("FRU=%s", symbolicFRUFromRegistry.c_str()));
+        strncpy(_pnOrProcedureID.data(), "INVALID", _pnOrProcedureID.size());
+    }
+
+    // ensure null terminated
+    _pnOrProcedureID.back() = 0;
+}
+
 } // namespace src
 } // namespace pels
 } // namespace openpower