blob: 941c1eea776ada26747c5ab6e431f9c6079de310 [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,
Zane Shelley9980d482022-01-28 15:21:47 -06009 callout::Priority i_priority, bool i_guard)
Zane Shelley37acb282022-01-10 16:05:22 -060010{
11 // Add the target to the callout list.
12 addTargetCallout(i_target, i_priority, i_guard);
13
14 // Add the callout FFDC.
15 nlohmann::json ffdc;
16 ffdc["Callout Type"] = "Hardware Callout";
Patrick Williams27dd6362023-05-10 07:51:20 -050017 ffdc["Target"] = util::pdbg::getPhysDevPath(i_target);
18 ffdc["Priority"] = callout::getStringFFDC(i_priority);
19 ffdc["Guard"] = i_guard;
Zane Shelley37acb282022-01-10 16:05:22 -060020 addCalloutFFDC(ffdc);
Zane Shelley55e7fec2022-01-28 15:29:44 -060021 setSrcSubsystem(getTargetSubsystem(i_target), i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -060022}
23
24//------------------------------------------------------------------------------
25
26void ServiceData::calloutConnected(pdbg_target* i_rxTarget,
27 const callout::BusType& i_busType,
Zane Shelley9980d482022-01-28 15:21:47 -060028 callout::Priority i_priority, bool i_guard)
Zane Shelley37acb282022-01-10 16:05:22 -060029{
30 // Get the endpoint target for the transfer side of the bus.
31 auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
32
33 // Callout the TX endpoint.
34 addTargetCallout(txTarget, i_priority, i_guard);
35
36 // Add the callout FFDC.
37 nlohmann::json ffdc;
38 ffdc["Callout Type"] = "Connected Callout";
Patrick Williams27dd6362023-05-10 07:51:20 -050039 ffdc["Bus Type"] = i_busType.getString();
40 ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget);
41 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
42 ffdc["Priority"] = callout::getStringFFDC(i_priority);
43 ffdc["Guard"] = i_guard;
Zane Shelley37acb282022-01-10 16:05:22 -060044 addCalloutFFDC(ffdc);
Zane Shelley55e7fec2022-01-28 15:29:44 -060045 setSrcSubsystem(getTargetSubsystem(txTarget), i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -060046}
47
48//------------------------------------------------------------------------------
49
50void ServiceData::calloutBus(pdbg_target* i_rxTarget,
51 const callout::BusType& i_busType,
Zane Shelley9980d482022-01-28 15:21:47 -060052 callout::Priority i_priority, bool i_guard)
Zane Shelley37acb282022-01-10 16:05:22 -060053{
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";
Patrick Williams27dd6362023-05-10 07:51:20 -050070 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"] = callout::getStringFFDC(i_priority);
74 ffdc["Guard"] = i_guard;
Zane Shelley37acb282022-01-10 16:05:22 -060075 addCalloutFFDC(ffdc);
Zane Shelley55e7fec2022-01-28 15:29:44 -060076 setSrcSubsystem(i_busType.getSrcSubsystem(), i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -060077}
78
79//------------------------------------------------------------------------------
80
81void ServiceData::calloutClock(const callout::ClockType& i_clockType,
Zane Shelley9980d482022-01-28 15:21:47 -060082 callout::Priority i_priority, bool)
Zane Shelley37acb282022-01-10 16:05:22 -060083{
84 // Callout the clock target.
85 // TODO: For P10, the callout is simply the backplane. Also, there are no
86 // clock targets in the device tree. So at the moment there is no
87 // guard support for clock targets.
88 addBackplaneCallout(i_priority);
89
90 // Add the callout FFDC.
91 // TODO: Add the target and guard type if guard is ever supported.
92 nlohmann::json ffdc;
93 ffdc["Callout Type"] = "Clock Callout";
Patrick Williams27dd6362023-05-10 07:51:20 -050094 ffdc["Clock Type"] = i_clockType.getString();
95 ffdc["Priority"] = callout::getStringFFDC(i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -060096 addCalloutFFDC(ffdc);
Zane Shelley55e7fec2022-01-28 15:29:44 -060097 setSrcSubsystem(i_clockType.getSrcSubsystem(), i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -060098}
99
100//------------------------------------------------------------------------------
101
102void ServiceData::calloutProcedure(const callout::Procedure& i_procedure,
Zane Shelley9980d482022-01-28 15:21:47 -0600103 callout::Priority i_priority)
Zane Shelley37acb282022-01-10 16:05:22 -0600104{
105 // Add the actual callout to the service data.
106 nlohmann::json callout;
107 callout["Procedure"] = i_procedure.getString();
Patrick Williams27dd6362023-05-10 07:51:20 -0500108 callout["Priority"] = callout::getString(i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -0600109 addCallout(callout);
110
111 // Add the callout FFDC.
112 nlohmann::json ffdc;
113 ffdc["Callout Type"] = "Procedure Callout";
Patrick Williams27dd6362023-05-10 07:51:20 -0500114 ffdc["Procedure"] = i_procedure.getString();
115 ffdc["Priority"] = callout::getStringFFDC(i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -0600116 addCalloutFFDC(ffdc);
Zane Shelley55e7fec2022-01-28 15:29:44 -0600117 setSrcSubsystem(i_procedure.getSrcSubsystem(), i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -0600118}
119
120//------------------------------------------------------------------------------
121
Zane Shelleya4134772022-01-10 17:22:44 -0600122void ServiceData::calloutPart(const callout::PartType& i_part,
Zane Shelley9980d482022-01-28 15:21:47 -0600123 callout::Priority i_priority)
Zane Shelleya4134772022-01-10 17:22:44 -0600124{
125 if (callout::PartType::PNOR == i_part)
126 {
127 // The PNOR is on the BMC card.
128 // TODO: Will need to be modified if we ever support systems with more
129 // than one BMC.
130 addTargetCallout(util::pdbg::getTrgt("/bmc0"), i_priority, false);
131 }
132 else
133 {
134 throw std::logic_error("Unsupported part type: " + i_part.getString());
135 }
136
137 // Add the callout FFDC.
138 nlohmann::json ffdc;
139 ffdc["Callout Type"] = "Part Callout";
Patrick Williams27dd6362023-05-10 07:51:20 -0500140 ffdc["Part Type"] = i_part.getString();
141 ffdc["Priority"] = callout::getStringFFDC(i_priority);
Zane Shelleya4134772022-01-10 17:22:44 -0600142 addCalloutFFDC(ffdc);
Zane Shelley55e7fec2022-01-28 15:29:44 -0600143 setSrcSubsystem(i_part.getSrcSubsystem(), i_priority);
Zane Shelleya4134772022-01-10 17:22:44 -0600144}
145
146//------------------------------------------------------------------------------
147
Zane Shelley979e2872021-09-20 22:46:06 -0500148void ServiceData::addCallout(const nlohmann::json& i_callout)
149{
150 // The new callout is either a hardware callout with a location code or a
151 // procedure callout.
152
153 std::string type{};
154 if (i_callout.contains("LocationCode"))
155 {
156 type = "LocationCode";
157 }
158 else if (i_callout.contains("Procedure"))
159 {
160 type = "Procedure";
161 }
162 else
163 {
164 throw std::logic_error("Unsupported callout: " + i_callout.dump());
165 }
166
167 // A map to determine the priority order. All of the medium priorities,
168 // including the medium group priorities, are all the same level.
Zane Shelley2fbd2672022-02-03 13:56:35 -0600169 // clang-format off
Zane Shelley979e2872021-09-20 22:46:06 -0500170 static const std::map<std::string, unsigned int> m = {
Zane Shelley2fbd2672022-02-03 13:56:35 -0600171 {callout::getString(callout::Priority::HIGH), 3},
172 {callout::getString(callout::Priority::MED), 2},
173 {callout::getString(callout::Priority::MED_A), 2},
174 {callout::getString(callout::Priority::MED_B), 2},
175 {callout::getString(callout::Priority::MED_C), 2},
176 {callout::getString(callout::Priority::LOW), 1},
Zane Shelley979e2872021-09-20 22:46:06 -0500177 };
Zane Shelley2fbd2672022-02-03 13:56:35 -0600178 // clang-format on
179
180 // The new callout must contain a valid priority.
181 assert(i_callout.contains("Priority") &&
182 m.contains(i_callout.at("Priority")));
Zane Shelley979e2872021-09-20 22:46:06 -0500183
Zane Shelleyc08f5ff2025-06-26 16:58:39 -0500184 // Look if this callout already exists in the list.
185 auto itr = std::find_if(
186 iv_calloutList.begin(), iv_calloutList.end(), [&](const auto& c) {
187 return c.contains(type) && c.at(type) == i_callout.at(type);
188 });
Zane Shelley979e2872021-09-20 22:46:06 -0500189
Zane Shelleyc08f5ff2025-06-26 16:58:39 -0500190 if (iv_calloutList.end() != itr)
Zane Shelley979e2872021-09-20 22:46:06 -0500191 {
Zane Shelleyc08f5ff2025-06-26 16:58:39 -0500192 // The callout already exists in the list. If the priority of the
193 // callout in the list is lower than the new callout, replace it with
194 // the new callout. Otherwise, use the current callout in the list and
195 // ignore the new callout. This is done to maintain any guard
196 // information that may be associated with the highest priority callout.
197 if (m.at(itr->at("Priority")) < m.at(i_callout.at("Priority")))
Zane Shelley979e2872021-09-20 22:46:06 -0500198 {
Zane Shelleyc08f5ff2025-06-26 16:58:39 -0500199 *itr = i_callout;
Zane Shelley979e2872021-09-20 22:46:06 -0500200 }
201 }
Zane Shelleyc08f5ff2025-06-26 16:58:39 -0500202 else
Zane Shelley979e2872021-09-20 22:46:06 -0500203 {
Zane Shelleyc08f5ff2025-06-26 16:58:39 -0500204 // New callout. So push it to the list.
Zane Shelley979e2872021-09-20 22:46:06 -0500205 iv_calloutList.push_back(i_callout);
206 }
207}
208
Zane Shelley37acb282022-01-10 16:05:22 -0600209//------------------------------------------------------------------------------
210
211void ServiceData::addTargetCallout(pdbg_target* i_target,
Zane Shelley9980d482022-01-28 15:21:47 -0600212 callout::Priority i_priority, bool i_guard)
Zane Shelley37acb282022-01-10 16:05:22 -0600213{
214 nlohmann::json callout;
215
216 callout["LocationCode"] = util::pdbg::getLocationCode(i_target);
Patrick Williams27dd6362023-05-10 07:51:20 -0500217 callout["Priority"] = callout::getString(i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -0600218 callout["Deconfigured"] = false;
Patrick Williams27dd6362023-05-10 07:51:20 -0500219 callout["Guarded"] = false; // default
Zane Shelley37acb282022-01-10 16:05:22 -0600220
221 // Check if guard info should be added.
222 if (i_guard)
223 {
224 auto guardType = queryGuardPolicy();
225
226 if (!(callout::GuardType::NONE == guardType))
227 {
Patrick Williams27dd6362023-05-10 07:51:20 -0500228 callout["Guarded"] = true;
Zane Shelley37acb282022-01-10 16:05:22 -0600229 callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target);
Patrick Williams27dd6362023-05-10 07:51:20 -0500230 callout["GuardType"] = guardType.getString();
Zane Shelley37acb282022-01-10 16:05:22 -0600231 }
232 }
233
234 addCallout(callout);
235}
236
237//------------------------------------------------------------------------------
238
Zane Shelley9980d482022-01-28 15:21:47 -0600239void ServiceData::addBackplaneCallout(callout::Priority i_priority)
Zane Shelley37acb282022-01-10 16:05:22 -0600240{
241 // TODO: There isn't a device tree object for this. So will need to hardcode
242 // the location code for now. In the future, we will need a mechanism
243 // to make this data driven.
244
245 nlohmann::json callout;
246
247 callout["LocationCode"] = "P0";
Patrick Williams27dd6362023-05-10 07:51:20 -0500248 callout["Priority"] = callout::getString(i_priority);
Zane Shelley37acb282022-01-10 16:05:22 -0600249 callout["Deconfigured"] = false;
Patrick Williams27dd6362023-05-10 07:51:20 -0500250 callout["Guarded"] = false;
Zane Shelley37acb282022-01-10 16:05:22 -0600251
252 addCallout(callout);
253}
254
255//------------------------------------------------------------------------------
256
Zane Shelley55e7fec2022-01-28 15:29:44 -0600257void ServiceData::setSrcSubsystem(callout::SrcSubsystem i_subsystem,
258 callout::Priority i_priority)
259{
260 // clang-format off
261 static const std::map<callout::Priority, unsigned int> m =
262 {
263 // Note that all medium priorities, including groups A, B, and C, are
264 // the same priority.
265 {callout::Priority::HIGH, 3},
266 {callout::Priority::MED, 2},
267 {callout::Priority::MED_A, 2},
268 {callout::Priority::MED_B, 2},
269 {callout::Priority::MED_C, 2},
270 {callout::Priority::LOW, 1},
271 };
272 // clang-format on
273
274 // The default subsystem is CEC_HARDWARE with LOW priority. Change the
275 // subsystem if the given subsystem has a higher priority or if the stored
276 // subsystem is still the default.
277 if (m.at(iv_srcSubsystem.second) < m.at(i_priority) ||
278 (callout::SrcSubsystem::CEC_HARDWARE == iv_srcSubsystem.first &&
279 callout::Priority::LOW == iv_srcSubsystem.second))
280 {
Patrick Williams27dd6362023-05-10 07:51:20 -0500281 iv_srcSubsystem.first = i_subsystem;
Zane Shelley55e7fec2022-01-28 15:29:44 -0600282 iv_srcSubsystem.second = i_priority;
283 }
284}
285
286//------------------------------------------------------------------------------
287
288callout::SrcSubsystem ServiceData::getTargetSubsystem(pdbg_target* i_target)
289{
290 using TargetType_t = util::pdbg::TargetType_t;
291
292 // Default the subsystem to CEC_HARDWARE
293 callout::SrcSubsystem o_subSys = callout::SrcSubsystem::CEC_HARDWARE;
294
295 // clang-format off
296 static const std::map<uint8_t, callout::SrcSubsystem> subSysMap =
297 {
298 {TargetType_t::TYPE_DIMM, callout::SrcSubsystem::MEMORY_DIMM },
Caleb Palmerbc94bde2022-02-18 09:03:37 -0600299 {TargetType_t::TYPE_PROC, callout::SrcSubsystem::PROCESSOR_FRU },
Zane Shelley55e7fec2022-01-28 15:29:44 -0600300 {TargetType_t::TYPE_CORE, callout::SrcSubsystem::PROCESSOR_UNIT},
Caleb Palmerbc94bde2022-02-18 09:03:37 -0600301 {TargetType_t::TYPE_NX, callout::SrcSubsystem::PROCESSOR },
302 {TargetType_t::TYPE_EQ, callout::SrcSubsystem::PROCESSOR_UNIT},
303 {TargetType_t::TYPE_PEC, callout::SrcSubsystem::PROCESSOR_UNIT},
Zane Shelley55e7fec2022-01-28 15:29:44 -0600304 {TargetType_t::TYPE_PHB, callout::SrcSubsystem::PHB },
Caleb Palmerbc94bde2022-02-18 09:03:37 -0600305 {TargetType_t::TYPE_MC, callout::SrcSubsystem::MEMORY_CTLR },
306 {TargetType_t::TYPE_IOLINK, callout::SrcSubsystem::PROCESSOR_BUS },
307 {TargetType_t::TYPE_OMI, callout::SrcSubsystem::MEMORY_CTLR },
308 {TargetType_t::TYPE_MCC, callout::SrcSubsystem::MEMORY_CTLR },
309 {TargetType_t::TYPE_OMIC, callout::SrcSubsystem::MEMORY_CTLR },
310 {TargetType_t::TYPE_OCMB, callout::SrcSubsystem::MEMORY_FRU },
311 {TargetType_t::TYPE_MEM_PORT, callout::SrcSubsystem::MEMORY_CTLR },
312 {TargetType_t::TYPE_NMMU, callout::SrcSubsystem::PROCESSOR_UNIT},
313 {TargetType_t::TYPE_PAU, callout::SrcSubsystem::PROCESSOR_UNIT},
314 {TargetType_t::TYPE_IOHS, callout::SrcSubsystem::PROCESSOR_UNIT},
315 {TargetType_t::TYPE_PAUC, callout::SrcSubsystem::PROCESSOR_UNIT},
Zane Shelley55e7fec2022-01-28 15:29:44 -0600316 };
317 // clang-format on
318
319 auto targetType = util::pdbg::getTrgtType(i_target);
320
321 // If the type of the input target exists in the map, update the output
322 if (subSysMap.count(targetType) > 0)
323 {
324 o_subSys = subSysMap.at(targetType);
325 }
326
327 return o_subSys;
328}
329
330//------------------------------------------------------------------------------
331
Zane Shelley979e2872021-09-20 22:46:06 -0500332} // namespace analyzer