blob: 9d444fd3a32aa48a90253573cee7a78d717c564d [file] [log] [blame]
Alexander Hansen40fb5492025-10-28 17:56:12 +01001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2019 IBM Corporation
3
Matt Spinler90b4a0a2019-10-09 10:08:43 -05004#include "mru.hpp"
5
Arya K Padman5bc26532024-04-10 06:19:25 -05006#include <phosphor-logging/lg2.hpp>
Matt Spinler90b4a0a2019-10-09 10:08:43 -05007
8namespace openpower
9{
10namespace pels
11{
12namespace src
13{
14
Matt Spinler5ab39972020-08-13 13:02:28 -050015// The MRU substructure supports up to 15 MRUs.
16static constexpr size_t maxMRUs = 15;
17
Matt Spinler90b4a0a2019-10-09 10:08:43 -050018MRU::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
Patrick Williams075c7922024-08-16 15:19:49 -040032 size_t actualSize =
33 sizeof(_type) + sizeof(_size) + sizeof(_flags) + sizeof(_reserved4B) +
34 (sizeof(MRUCallout) * _mrus.size());
Matt Spinler90b4a0a2019-10-09 10:08:43 -050035 if (_size != actualSize)
36 {
Arya K Padman5bc26532024-04-10 06:19:25 -050037 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);
Matt Spinler90b4a0a2019-10-09 10:08:43 -050043 }
44}
45
Matt Spinler5ab39972020-08-13 13:02:28 -050046MRU::MRU(const std::vector<MRUCallout>& mrus)
47{
48 if (mrus.empty())
49 {
Arya K Padman5bc26532024-04-10 06:19:25 -050050 lg2::error("Trying to create a MRU section with no MRUs");
Matt Spinler5ab39972020-08-13 13:02:28 -050051 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
Matt Spinler724d0d82019-11-06 10:05:36 -060067void MRU::flatten(Stream& pel) const
Matt Spinler90b4a0a2019-10-09 10:08:43 -050068{
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