xref: /openbmc/phosphor-logging/extensions/openpower-pels/callouts.cpp (revision 40fb54935ce7367636a7156039396ee91cc4d5e2)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright 2019 IBM Corporation
3 
4 #include "callouts.hpp"
5 
6 #include <phosphor-logging/lg2.hpp>
7 
8 #include <algorithm>
9 
10 namespace openpower
11 {
12 namespace pels
13 {
14 namespace src
15 {
16 
Callouts(Stream & pel)17 Callouts::Callouts(Stream& pel)
18 {
19     pel >> _subsectionID >> _subsectionFlags >> _subsectionWordLength;
20 
21     size_t currentLength = sizeof(_subsectionID) + sizeof(_subsectionFlags) +
22                            sizeof(_subsectionWordLength);
23 
24     while ((_subsectionWordLength * 4) > currentLength)
25     {
26         _callouts.emplace_back(new Callout(pel));
27         currentLength += _callouts.back()->flattenedSize();
28     }
29 }
30 
flatten(Stream & pel) const31 void Callouts::flatten(Stream& pel) const
32 {
33     pel << _subsectionID << _subsectionFlags << _subsectionWordLength;
34 
35     for (auto& callout : _callouts)
36     {
37         callout->flatten(pel);
38     }
39 }
40 
addCallout(std::unique_ptr<Callout> callout)41 void Callouts::addCallout(std::unique_ptr<Callout> callout)
42 {
43     bool shouldAdd = true;
44 
45     // Check if there is already a callout for this FRU
46     auto it = std::ranges::find_if(_callouts, [&callout](const auto& c) {
47         return *callout == *c;
48     });
49 
50     // If the callout already exists, but the new one has a higher
51     // priority, change the existing callout's priority to this
52     // new value and don't add the new one.
53     if (it != _callouts.end())
54     {
55         if (*callout > **it)
56         {
57             (*it)->setPriority(callout->priority());
58         }
59         shouldAdd = false;
60     }
61 
62     if (shouldAdd)
63     {
64         if (_callouts.size() < maxNumberOfCallouts)
65         {
66             _callouts.push_back(std::move(callout));
67 
68             _subsectionWordLength += _callouts.back()->flattenedSize() / 4;
69         }
70         else
71         {
72             lg2::info("Dropping PEL callout because at max");
73         }
74     }
75 
76     std::ranges::sort(_callouts,
77                       [](const auto& c1, const auto& c2) { return *c1 > *c2; });
78 }
79 
80 } // namespace src
81 } // namespace pels
82 } // namespace openpower
83