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 "callout.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 Callout::Callout(Stream& pel) 30 { 31 pel >> _size >> _flags >> _priority >> _locationCodeSize; 32 33 if (_locationCodeSize) 34 { 35 _locationCode.resize(_locationCodeSize); 36 pel >> _locationCode; 37 } 38 39 size_t currentSize = 4 + _locationCodeSize; 40 41 // Read in the substructures until the end of this structure. 42 // Any stream overflows will throw an exception up to the SRC constructor 43 while (_size > currentSize) 44 { 45 // Peek the type 46 uint16_t type = 0; 47 pel >> type; 48 pel.offset(pel.offset() - 2); 49 50 switch (type) 51 { 52 case FRUIdentity::substructureType: 53 { 54 _fruIdentity = std::make_unique<FRUIdentity>(pel); 55 currentSize += _fruIdentity->flattenedSize(); 56 break; 57 } 58 case PCEIdentity::substructureType: 59 { 60 _pceIdentity = std::make_unique<PCEIdentity>(pel); 61 currentSize += _pceIdentity->flattenedSize(); 62 break; 63 } 64 case MRU::substructureType: 65 { 66 _mru = std::make_unique<MRU>(pel); 67 currentSize += _mru->flattenedSize(); 68 break; 69 } 70 default: 71 log<level::ERR>("Invalid Callout subsection type", 72 entry("CALLOUT_TYPE=0x%X", type)); 73 throw std::runtime_error("Invalid Callout subsection type"); 74 break; 75 } 76 } 77 } 78 79 size_t Callout::flattenedSize() 80 { 81 size_t size = sizeof(_size) + sizeof(_flags) + sizeof(_priority) + 82 sizeof(_locationCodeSize) + _locationCodeSize; 83 84 size += _fruIdentity ? _fruIdentity->flattenedSize() : 0; 85 size += _pceIdentity ? _pceIdentity->flattenedSize() : 0; 86 size += _mru ? _mru->flattenedSize() : 0; 87 88 return size; 89 } 90 91 void Callout::flatten(Stream& pel) const 92 { 93 pel << _size << _flags << _priority << _locationCodeSize; 94 95 if (_locationCodeSize) 96 { 97 pel << _locationCode; 98 } 99 100 if (_fruIdentity) 101 { 102 _fruIdentity->flatten(pel); 103 } 104 105 if (_pceIdentity) 106 { 107 _pceIdentity->flatten(pel); 108 } 109 if (_mru) 110 { 111 _mru->flatten(pel); 112 } 113 } 114 115 } // namespace src 116 } // namespace pels 117 } // namespace openpower 118