1711d51d8SMatt Spinler /**
2711d51d8SMatt Spinler * Copyright © 2019 IBM Corporation
3711d51d8SMatt Spinler *
4711d51d8SMatt Spinler * Licensed under the Apache License, Version 2.0 (the "License");
5711d51d8SMatt Spinler * you may not use this file except in compliance with the License.
6711d51d8SMatt Spinler * You may obtain a copy of the License at
7711d51d8SMatt Spinler *
8711d51d8SMatt Spinler * http://www.apache.org/licenses/LICENSE-2.0
9711d51d8SMatt Spinler *
10711d51d8SMatt Spinler * Unless required by applicable law or agreed to in writing, software
11711d51d8SMatt Spinler * distributed under the License is distributed on an "AS IS" BASIS,
12711d51d8SMatt Spinler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13711d51d8SMatt Spinler * See the License for the specific language governing permissions and
14711d51d8SMatt Spinler * limitations under the License.
15711d51d8SMatt Spinler */
1690b4a0a0SMatt Spinler #include "mru.hpp"
1790b4a0a0SMatt Spinler
185bc26533SArya K Padman #include <phosphor-logging/lg2.hpp>
1990b4a0a0SMatt Spinler
2090b4a0a0SMatt Spinler namespace openpower
2190b4a0a0SMatt Spinler {
2290b4a0a0SMatt Spinler namespace pels
2390b4a0a0SMatt Spinler {
2490b4a0a0SMatt Spinler namespace src
2590b4a0a0SMatt Spinler {
2690b4a0a0SMatt Spinler
275ab39978SMatt Spinler // The MRU substructure supports up to 15 MRUs.
285ab39978SMatt Spinler static constexpr size_t maxMRUs = 15;
295ab39978SMatt Spinler
MRU(Stream & pel)3090b4a0a0SMatt Spinler MRU::MRU(Stream& pel)
3190b4a0a0SMatt Spinler {
3290b4a0a0SMatt Spinler pel >> _type >> _size >> _flags >> _reserved4B;
3390b4a0a0SMatt Spinler
3490b4a0a0SMatt Spinler size_t numMRUs = _flags & 0xF;
3590b4a0a0SMatt Spinler
3690b4a0a0SMatt Spinler for (size_t i = 0; i < numMRUs; i++)
3790b4a0a0SMatt Spinler {
3890b4a0a0SMatt Spinler MRUCallout mru;
3990b4a0a0SMatt Spinler pel >> mru.priority;
4090b4a0a0SMatt Spinler pel >> mru.id;
4190b4a0a0SMatt Spinler _mrus.push_back(std::move(mru));
4290b4a0a0SMatt Spinler }
4390b4a0a0SMatt Spinler
44*075c7923SPatrick Williams size_t actualSize =
45*075c7923SPatrick Williams sizeof(_type) + sizeof(_size) + sizeof(_flags) + sizeof(_reserved4B) +
4690b4a0a0SMatt Spinler (sizeof(MRUCallout) * _mrus.size());
4790b4a0a0SMatt Spinler if (_size != actualSize)
4890b4a0a0SMatt Spinler {
495bc26533SArya K Padman lg2::warning(
505bc26533SArya K Padman "MRU callout section in PEL with {NUM_MRUS} MRUs has listed size "
515bc26533SArya K Padman "{SUBSTRUCTURE_SIZE} that doesn't match the actual size "
525bc26533SArya K Padman "{ACTUAL_SIZE}",
535bc26533SArya K Padman "SUBSTRUCTURE_SIZE", _size, "NUM_MRUS", _mrus.size(), "ACTUAL_SIZE",
545bc26533SArya K Padman actualSize);
5590b4a0a0SMatt Spinler }
5690b4a0a0SMatt Spinler }
5790b4a0a0SMatt Spinler
MRU(const std::vector<MRUCallout> & mrus)585ab39978SMatt Spinler MRU::MRU(const std::vector<MRUCallout>& mrus)
595ab39978SMatt Spinler {
605ab39978SMatt Spinler if (mrus.empty())
615ab39978SMatt Spinler {
625bc26533SArya K Padman lg2::error("Trying to create a MRU section with no MRUs");
635ab39978SMatt Spinler throw std::runtime_error{"Trying to create a MRU section with no MRUs"};
645ab39978SMatt Spinler }
655ab39978SMatt Spinler
665ab39978SMatt Spinler _mrus = mrus;
675ab39978SMatt Spinler if (_mrus.size() > maxMRUs)
685ab39978SMatt Spinler {
695ab39978SMatt Spinler _mrus.resize(maxMRUs);
705ab39978SMatt Spinler }
715ab39978SMatt Spinler
725ab39978SMatt Spinler _type = substructureType;
735ab39978SMatt Spinler _size = sizeof(_type) + sizeof(_size) + sizeof(_flags) +
745ab39978SMatt Spinler sizeof(_reserved4B) + (sizeof(MRUCallout) * _mrus.size());
755ab39978SMatt Spinler _flags = _mrus.size();
765ab39978SMatt Spinler _reserved4B = 0;
775ab39978SMatt Spinler }
785ab39978SMatt Spinler
flatten(Stream & pel) const79724d0d8cSMatt Spinler void MRU::flatten(Stream& pel) const
8090b4a0a0SMatt Spinler {
8190b4a0a0SMatt Spinler pel << _type << _size << _flags << _reserved4B;
8290b4a0a0SMatt Spinler
8390b4a0a0SMatt Spinler for (auto& mru : _mrus)
8490b4a0a0SMatt Spinler {
8590b4a0a0SMatt Spinler pel << mru.priority;
8690b4a0a0SMatt Spinler pel << mru.id;
8790b4a0a0SMatt Spinler }
8890b4a0a0SMatt Spinler }
8990b4a0a0SMatt Spinler } // namespace src
9090b4a0a0SMatt Spinler } // namespace pels
9190b4a0a0SMatt Spinler } // namespace openpower
92