1 /** 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 */ 16 #include "mru.hpp" 17 18 #include <phosphor-logging/log.hpp> 19 20 namespace openpower 21 { 22 namespace pels 23 { 24 namespace src 25 { 26 27 using namespace phosphor::logging; 28 29 // The MRU substructure supports up to 15 MRUs. 30 static constexpr size_t maxMRUs = 15; 31 32 MRU::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 59 MRU::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 80 void MRU::flatten(Stream& pel) const 81 { 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 93