blob: 938686244fa5e99f7dbc5e48d93e23781061297c [file] [log] [blame]
Matt Spinler711d51d2019-11-06 09:36:51 -06001/**
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 */
Matt Spinler6c9662c2019-10-09 11:27:20 -050016#include "callout.hpp"
17
18#include <phosphor-logging/log.hpp>
19
20namespace openpower
21{
22namespace pels
23{
24namespace src
25{
26
27using namespace phosphor::logging;
28
29Callout::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
79size_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
91void Callout::flatten(Stream& pel)
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