PEL: Let Callout object ctor take a MRU list

A list of MRUs (Manufacturing Replaceable Units) can now be passed into
the Callout object constructor.  There is also a new MRU object
constructor that will build that object with a MRU list as well.

This will be used in the future when someone wants to add MRUs to a
callout.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Ic0e93e081a91ffc47dfd6642a34f02fd9a6edb8e
diff --git a/extensions/openpower-pels/mru.cpp b/extensions/openpower-pels/mru.cpp
index a79c026..1a9ce00 100644
--- a/extensions/openpower-pels/mru.cpp
+++ b/extensions/openpower-pels/mru.cpp
@@ -26,6 +26,9 @@
 
 using namespace phosphor::logging;
 
+// The MRU substructure supports up to 15 MRUs.
+static constexpr size_t maxMRUs = 15;
+
 MRU::MRU(Stream& pel)
 {
     pel >> _type >> _size >> _flags >> _reserved4B;
@@ -53,6 +56,27 @@
     }
 }
 
+MRU::MRU(const std::vector<MRUCallout>& mrus)
+{
+    if (mrus.empty())
+    {
+        log<level::ERR>("Trying to create a MRU section with no MRUs");
+        throw std::runtime_error{"Trying to create a MRU section with no MRUs"};
+    }
+
+    _mrus = mrus;
+    if (_mrus.size() > maxMRUs)
+    {
+        _mrus.resize(maxMRUs);
+    }
+
+    _type = substructureType;
+    _size = sizeof(_type) + sizeof(_size) + sizeof(_flags) +
+            sizeof(_reserved4B) + (sizeof(MRUCallout) * _mrus.size());
+    _flags = _mrus.size();
+    _reserved4B = 0;
+}
+
 void MRU::flatten(Stream& pel) const
 {
     pel << _type << _size << _flags << _reserved4B;