xref: /openbmc/phosphor-logging/extensions/openpower-pels/mru.cpp (revision 40fb54935ce7367636a7156039396ee91cc4d5e2)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright 2019 IBM Corporation
3 
4 #include "mru.hpp"
5 
6 #include <phosphor-logging/lg2.hpp>
7 
8 namespace openpower
9 {
10 namespace pels
11 {
12 namespace src
13 {
14 
15 // The MRU substructure supports up to 15 MRUs.
16 static constexpr size_t maxMRUs = 15;
17 
MRU(Stream & pel)18 MRU::MRU(Stream& pel)
19 {
20     pel >> _type >> _size >> _flags >> _reserved4B;
21 
22     size_t numMRUs = _flags & 0xF;
23 
24     for (size_t i = 0; i < numMRUs; i++)
25     {
26         MRUCallout mru;
27         pel >> mru.priority;
28         pel >> mru.id;
29         _mrus.push_back(std::move(mru));
30     }
31 
32     size_t actualSize =
33         sizeof(_type) + sizeof(_size) + sizeof(_flags) + sizeof(_reserved4B) +
34         (sizeof(MRUCallout) * _mrus.size());
35     if (_size != actualSize)
36     {
37         lg2::warning(
38             "MRU callout section in PEL with {NUM_MRUS} MRUs has listed size "
39             "{SUBSTRUCTURE_SIZE} that doesn't match the actual size "
40             "{ACTUAL_SIZE}",
41             "SUBSTRUCTURE_SIZE", _size, "NUM_MRUS", _mrus.size(), "ACTUAL_SIZE",
42             actualSize);
43     }
44 }
45 
MRU(const std::vector<MRUCallout> & mrus)46 MRU::MRU(const std::vector<MRUCallout>& mrus)
47 {
48     if (mrus.empty())
49     {
50         lg2::error("Trying to create a MRU section with no MRUs");
51         throw std::runtime_error{"Trying to create a MRU section with no MRUs"};
52     }
53 
54     _mrus = mrus;
55     if (_mrus.size() > maxMRUs)
56     {
57         _mrus.resize(maxMRUs);
58     }
59 
60     _type = substructureType;
61     _size = sizeof(_type) + sizeof(_size) + sizeof(_flags) +
62             sizeof(_reserved4B) + (sizeof(MRUCallout) * _mrus.size());
63     _flags = _mrus.size();
64     _reserved4B = 0;
65 }
66 
flatten(Stream & pel) const67 void MRU::flatten(Stream& pel) const
68 {
69     pel << _type << _size << _flags << _reserved4B;
70 
71     for (auto& mru : _mrus)
72     {
73         pel << mru.priority;
74         pel << mru.id;
75     }
76 }
77 } // namespace src
78 } // namespace pels
79 } // namespace openpower
80