blob: de2c0a7cdd1e7f8b07e7868e097328f45a7c2d2e [file] [log] [blame]
Zane Shelley979e2872021-09-20 22:46:06 -05001#include <analyzer/service_data.hpp>
2
3namespace analyzer
4{
5
Zane Shelley37acb282022-01-10 16:05:22 -06006//------------------------------------------------------------------------------
7
8void ServiceData::calloutTarget(pdbg_target* i_target,
9 const callout::Priority& i_priority,
10 bool i_guard)
11{
12 // Add the target to the callout list.
13 addTargetCallout(i_target, i_priority, i_guard);
14
15 // Add the callout FFDC.
16 nlohmann::json ffdc;
17 ffdc["Callout Type"] = "Hardware Callout";
18 ffdc["Target"] = util::pdbg::getPhysDevPath(i_target);
19 ffdc["Priority"] = i_priority.getRegistryString();
20 ffdc["Guard"] = i_guard;
21 addCalloutFFDC(ffdc);
22}
23
24//------------------------------------------------------------------------------
25
26void ServiceData::calloutConnected(pdbg_target* i_rxTarget,
27 const callout::BusType& i_busType,
28 const callout::Priority& i_priority,
29 bool i_guard)
30{
31 // Get the endpoint target for the transfer side of the bus.
32 auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
33
34 // Callout the TX endpoint.
35 addTargetCallout(txTarget, i_priority, i_guard);
36
37 // Add the callout FFDC.
38 nlohmann::json ffdc;
39 ffdc["Callout Type"] = "Connected Callout";
40 ffdc["Bus Type"] = i_busType.getString();
41 ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget);
42 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
43 ffdc["Priority"] = i_priority.getRegistryString();
44 ffdc["Guard"] = i_guard;
45 addCalloutFFDC(ffdc);
46}
47
48//------------------------------------------------------------------------------
49
50void ServiceData::calloutBus(pdbg_target* i_rxTarget,
51 const callout::BusType& i_busType,
52 const callout::Priority& i_priority, bool i_guard)
53{
54 // Get the endpoint target for the transfer side of the bus.
55 auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
56
57 // Callout the RX endpoint.
58 addTargetCallout(i_rxTarget, i_priority, i_guard);
59
60 // Callout the TX endpoint.
61 addTargetCallout(txTarget, i_priority, i_guard);
62
63 // Callout everything else in between.
64 // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane.
65 addBackplaneCallout(i_priority);
66
67 // Add the callout FFDC.
68 nlohmann::json ffdc;
69 ffdc["Callout Type"] = "Bus Callout";
70 ffdc["Bus Type"] = i_busType.getString();
71 ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget);
72 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
73 ffdc["Priority"] = i_priority.getRegistryString();
74 ffdc["Guard"] = i_guard;
75 addCalloutFFDC(ffdc);
76}
77
78//------------------------------------------------------------------------------
79
80void ServiceData::calloutClock(const callout::ClockType& i_clockType,
81 const callout::Priority& i_priority, bool)
82{
83 // Callout the clock target.
84 // TODO: For P10, the callout is simply the backplane. Also, there are no
85 // clock targets in the device tree. So at the moment there is no
86 // guard support for clock targets.
87 addBackplaneCallout(i_priority);
88
89 // Add the callout FFDC.
90 // TODO: Add the target and guard type if guard is ever supported.
91 nlohmann::json ffdc;
92 ffdc["Callout Type"] = "Clock Callout";
93 ffdc["Clock Type"] = i_clockType.getString();
94 ffdc["Priority"] = i_priority.getRegistryString();
95 addCalloutFFDC(ffdc);
96}
97
98//------------------------------------------------------------------------------
99
100void ServiceData::calloutProcedure(const callout::Procedure& i_procedure,
101 const callout::Priority& i_priority)
102{
103 // Add the actual callout to the service data.
104 nlohmann::json callout;
105 callout["Procedure"] = i_procedure.getString();
106 callout["Priority"] = i_priority.getUserDataString();
107 addCallout(callout);
108
109 // Add the callout FFDC.
110 nlohmann::json ffdc;
111 ffdc["Callout Type"] = "Procedure Callout";
112 ffdc["Procedure"] = i_procedure.getString();
113 ffdc["Priority"] = i_priority.getRegistryString();
114 addCalloutFFDC(ffdc);
115}
116
117//------------------------------------------------------------------------------
118
Zane Shelleya4134772022-01-10 17:22:44 -0600119void ServiceData::calloutPart(const callout::PartType& i_part,
120 const callout::Priority& i_priority)
121{
122 if (callout::PartType::PNOR == i_part)
123 {
124 // The PNOR is on the BMC card.
125 // TODO: Will need to be modified if we ever support systems with more
126 // than one BMC.
127 addTargetCallout(util::pdbg::getTrgt("/bmc0"), i_priority, false);
128 }
129 else
130 {
131 throw std::logic_error("Unsupported part type: " + i_part.getString());
132 }
133
134 // Add the callout FFDC.
135 nlohmann::json ffdc;
136 ffdc["Callout Type"] = "Part Callout";
137 ffdc["Part Type"] = i_part.getString();
138 ffdc["Priority"] = i_priority.getRegistryString();
139 addCalloutFFDC(ffdc);
140}
141
142//------------------------------------------------------------------------------
143
Zane Shelley979e2872021-09-20 22:46:06 -0500144void ServiceData::addCallout(const nlohmann::json& i_callout)
145{
146 // The new callout is either a hardware callout with a location code or a
147 // procedure callout.
148
149 std::string type{};
150 if (i_callout.contains("LocationCode"))
151 {
152 type = "LocationCode";
153 }
154 else if (i_callout.contains("Procedure"))
155 {
156 type = "Procedure";
157 }
158 else
159 {
160 throw std::logic_error("Unsupported callout: " + i_callout.dump());
161 }
162
163 // A map to determine the priority order. All of the medium priorities,
164 // including the medium group priorities, are all the same level.
165 static const std::map<std::string, unsigned int> m = {
166 {"H", 3}, {"M", 2}, {"A", 2}, {"B", 2}, {"C", 2}, {"L", 1},
167 };
168
169 bool addCallout = true;
170
171 for (auto& c : iv_calloutList)
172 {
173 if (c.contains(type) && (c.at(type) == i_callout.at(type)))
174 {
175 // The new callout already exists. Don't add a new callout.
176 addCallout = false;
177
178 if (m.at(c.at("Priority")) < m.at(i_callout.at("Priority")))
179 {
180 // The new callout has a higher priority, update it.
181 c["Priority"] = i_callout.at("Priority");
182 }
183 }
184 }
185
186 if (addCallout)
187 {
188 iv_calloutList.push_back(i_callout);
189 }
190}
191
Zane Shelley37acb282022-01-10 16:05:22 -0600192//------------------------------------------------------------------------------
193
194void ServiceData::addTargetCallout(pdbg_target* i_target,
195 const callout::Priority& i_priority,
196 bool i_guard)
197{
198 nlohmann::json callout;
199
200 callout["LocationCode"] = util::pdbg::getLocationCode(i_target);
201 callout["Priority"] = i_priority.getUserDataString();
202 callout["Deconfigured"] = false;
203 callout["Guarded"] = false; // default
204
205 // Check if guard info should be added.
206 if (i_guard)
207 {
208 auto guardType = queryGuardPolicy();
209
210 if (!(callout::GuardType::NONE == guardType))
211 {
212 callout["Guarded"] = true;
213 callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target);
214 callout["GuardType"] = guardType.getString();
215 }
216 }
217
218 addCallout(callout);
219}
220
221//------------------------------------------------------------------------------
222
223void ServiceData::addBackplaneCallout(const callout::Priority& i_priority)
224{
225 // TODO: There isn't a device tree object for this. So will need to hardcode
226 // the location code for now. In the future, we will need a mechanism
227 // to make this data driven.
228
229 nlohmann::json callout;
230
231 callout["LocationCode"] = "P0";
232 callout["Priority"] = i_priority.getUserDataString();
233 callout["Deconfigured"] = false;
234 callout["Guarded"] = false;
235
236 addCallout(callout);
237}
238
239//------------------------------------------------------------------------------
240
Zane Shelley979e2872021-09-20 22:46:06 -0500241} // namespace analyzer