summaryrefslogtreecommitdiffstats
path: root/extensions/openpower-pels/callout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/openpower-pels/callout.cpp')
-rw-r--r--extensions/openpower-pels/callout.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/extensions/openpower-pels/callout.cpp b/extensions/openpower-pels/callout.cpp
new file mode 100644
index 0000000..95c6408
--- /dev/null
+++ b/extensions/openpower-pels/callout.cpp
@@ -0,0 +1,117 @@
+/**
+ * Copyright © 2019 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "callout.hpp"
+
+#include <phosphor-logging/log.hpp>
+
+namespace openpower
+{
+namespace pels
+{
+namespace src
+{
+
+using namespace phosphor::logging;
+
+Callout::Callout(Stream& pel)
+{
+ pel >> _size >> _flags >> _priority >> _locationCodeSize;
+
+ if (_locationCodeSize)
+ {
+ _locationCode.resize(_locationCodeSize);
+ pel >> _locationCode;
+ }
+
+ size_t currentSize = 4 + _locationCodeSize;
+
+ // Read in the substructures until the end of this structure.
+ // Any stream overflows will throw an exception up to the SRC constructor
+ while (_size > currentSize)
+ {
+ // Peek the type
+ uint16_t type = 0;
+ pel >> type;
+ pel.offset(pel.offset() - 2);
+
+ switch (type)
+ {
+ case FRUIdentity::substructureType:
+ {
+ _fruIdentity = std::make_unique<FRUIdentity>(pel);
+ currentSize += _fruIdentity->flattenedSize();
+ break;
+ }
+ case PCEIdentity::substructureType:
+ {
+ _pceIdentity = std::make_unique<PCEIdentity>(pel);
+ currentSize += _pceIdentity->flattenedSize();
+ break;
+ }
+ case MRU::substructureType:
+ {
+ _mru = std::make_unique<MRU>(pel);
+ currentSize += _mru->flattenedSize();
+ break;
+ }
+ default:
+ log<level::ERR>("Invalid Callout subsection type",
+ entry("CALLOUT_TYPE=0x%X", type));
+ throw std::runtime_error("Invalid Callout subsection type");
+ break;
+ }
+ }
+}
+
+size_t Callout::flattenedSize()
+{
+ size_t size = sizeof(_size) + sizeof(_flags) + sizeof(_priority) +
+ sizeof(_locationCodeSize) + _locationCodeSize;
+
+ size += _fruIdentity ? _fruIdentity->flattenedSize() : 0;
+ size += _pceIdentity ? _pceIdentity->flattenedSize() : 0;
+ size += _mru ? _mru->flattenedSize() : 0;
+
+ return size;
+}
+
+void Callout::flatten(Stream& pel) const
+{
+ pel << _size << _flags << _priority << _locationCodeSize;
+
+ if (_locationCodeSize)
+ {
+ pel << _locationCode;
+ }
+
+ if (_fruIdentity)
+ {
+ _fruIdentity->flatten(pel);
+ }
+
+ if (_pceIdentity)
+ {
+ _pceIdentity->flatten(pel);
+ }
+ if (_mru)
+ {
+ _mru->flatten(pel);
+ }
+}
+
+} // namespace src
+} // namespace pels
+} // namespace openpower
OpenPOWER on IntegriCloud