blob: e53966abda9aa35e9a2fe68cf9873dc48a59ce17 [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
Arya K Padman5bc26532024-04-10 06:19:25 -050018#include <phosphor-logging/lg2.hpp>
Matt Spinler90b4a0a2019-10-09 10:08:43 -050019
20namespace openpower
21{
22namespace pels
23{
24namespace src
25{
26
Matt Spinler5ab39972020-08-13 13:02:28 -050027// The MRU substructure supports up to 15 MRUs.
28static constexpr size_t maxMRUs = 15;
29
Matt Spinler90b4a0a2019-10-09 10:08:43 -050030MRU::MRU(Stream& pel)
31{
32 pel >> _type >> _size >> _flags >> _reserved4B;
33
34 size_t numMRUs = _flags & 0xF;
35
36 for (size_t i = 0; i < numMRUs; i++)
37 {
38 MRUCallout mru;
39 pel >> mru.priority;
40 pel >> mru.id;
41 _mrus.push_back(std::move(mru));
42 }
43
44 size_t actualSize = sizeof(_type) + sizeof(_size) + sizeof(_flags) +
45 sizeof(_reserved4B) +
46 (sizeof(MRUCallout) * _mrus.size());
47 if (_size != actualSize)
48 {
Arya K Padman5bc26532024-04-10 06:19:25 -050049 lg2::warning(
50 "MRU callout section in PEL with {NUM_MRUS} MRUs has listed size "
51 "{SUBSTRUCTURE_SIZE} that doesn't match the actual size "
52 "{ACTUAL_SIZE}",
53 "SUBSTRUCTURE_SIZE", _size, "NUM_MRUS", _mrus.size(), "ACTUAL_SIZE",
54 actualSize);
Matt Spinler90b4a0a2019-10-09 10:08:43 -050055 }
56}
57
Matt Spinler5ab39972020-08-13 13:02:28 -050058MRU::MRU(const std::vector<MRUCallout>& mrus)
59{
60 if (mrus.empty())
61 {
Arya K Padman5bc26532024-04-10 06:19:25 -050062 lg2::error("Trying to create a MRU section with no MRUs");
Matt Spinler5ab39972020-08-13 13:02:28 -050063 throw std::runtime_error{"Trying to create a MRU section with no MRUs"};
64 }
65
66 _mrus = mrus;
67 if (_mrus.size() > maxMRUs)
68 {
69 _mrus.resize(maxMRUs);
70 }
71
72 _type = substructureType;
73 _size = sizeof(_type) + sizeof(_size) + sizeof(_flags) +
74 sizeof(_reserved4B) + (sizeof(MRUCallout) * _mrus.size());
75 _flags = _mrus.size();
76 _reserved4B = 0;
77}
78
Matt Spinler724d0d82019-11-06 10:05:36 -060079void MRU::flatten(Stream& pel) const
Matt Spinler90b4a0a2019-10-09 10:08:43 -050080{
81 pel << _type << _size << _flags << _reserved4B;
82
83 for (auto& mru : _mrus)
84 {
85 pel << mru.priority;
86 pel << mru.id;
87 }
88}
89} // namespace src
90} // namespace pels
91} // namespace openpower