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/lg2.hpp> 19 20 namespace openpower 21 { 22 namespace pels 23 { 24 namespace src 25 { 26 27 // The MRU substructure supports up to 15 MRUs. 28 static constexpr size_t maxMRUs = 15; 29 30 MRU::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 { 49 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); 55 } 56 } 57 58 MRU::MRU(const std::vector<MRUCallout>& mrus) 59 { 60 if (mrus.empty()) 61 { 62 lg2::error("Trying to create a MRU section with no MRUs"); 63 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 79 void MRU::flatten(Stream& pel) const 80 { 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 92