blob: 1a9ce00ad3ad27bec6c124e789a5295b838d3832 [file] [log] [blame]
Matt Spinler711d51d2019-11-06 09:36:51 -06001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Matt Spinler90b4a0a2019-10-09 10:08:43 -050016#include "mru.hpp"
17
18#include <phosphor-logging/log.hpp>
19
20namespace openpower
21{
22namespace pels
23{
24namespace src
25{
26
27using namespace phosphor::logging;
28
Matt Spinler5ab39972020-08-13 13:02:28 -050029// The MRU substructure supports up to 15 MRUs.
30static constexpr size_t maxMRUs = 15;
31
Matt Spinler90b4a0a2019-10-09 10:08:43 -050032MRU::MRU(Stream& pel)
33{
34 pel >> _type >> _size >> _flags >> _reserved4B;
35
36 size_t numMRUs = _flags & 0xF;
37
38 for (size_t i = 0; i < numMRUs; i++)
39 {
40 MRUCallout mru;
41 pel >> mru.priority;
42 pel >> mru.id;
43 _mrus.push_back(std::move(mru));
44 }
45
46 size_t actualSize = sizeof(_type) + sizeof(_size) + sizeof(_flags) +
47 sizeof(_reserved4B) +
48 (sizeof(MRUCallout) * _mrus.size());
49 if (_size != actualSize)
50 {
51 log<level::WARNING>("MRU callout section in PEL has listed size that "
52 "doesn't match actual size",
53 entry("SUBSTRUCTURE_SIZE=%lu", _size),
54 entry("NUM_MRUS=%lu", _mrus.size()),
55 entry("ACTUAL_SIZE=%lu", actualSize));
56 }
57}
58
Matt Spinler5ab39972020-08-13 13:02:28 -050059MRU::MRU(const std::vector<MRUCallout>& mrus)
60{
61 if (mrus.empty())
62 {
63 log<level::ERR>("Trying to create a MRU section with no MRUs");
64 throw std::runtime_error{"Trying to create a MRU section with no MRUs"};
65 }
66
67 _mrus = mrus;
68 if (_mrus.size() > maxMRUs)
69 {
70 _mrus.resize(maxMRUs);
71 }
72
73 _type = substructureType;
74 _size = sizeof(_type) + sizeof(_size) + sizeof(_flags) +
75 sizeof(_reserved4B) + (sizeof(MRUCallout) * _mrus.size());
76 _flags = _mrus.size();
77 _reserved4B = 0;
78}
79
Matt Spinler724d0d82019-11-06 10:05:36 -060080void MRU::flatten(Stream& pel) const
Matt Spinler90b4a0a2019-10-09 10:08:43 -050081{
82 pel << _type << _size << _flags << _reserved4B;
83
84 for (auto& mru : _mrus)
85 {
86 pel << mru.priority;
87 pel << mru.id;
88 }
89}
90} // namespace src
91} // namespace pels
92} // namespace openpower