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)18MRU::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)46MRU::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) const67void 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