1979e2871SZane Shelley #include <analyzer/service_data.hpp>
2979e2871SZane Shelley
3979e2871SZane Shelley namespace analyzer
4979e2871SZane Shelley {
5979e2871SZane Shelley
637acb289SZane Shelley //------------------------------------------------------------------------------
737acb289SZane Shelley
calloutTarget(pdbg_target * i_target,callout::Priority i_priority,bool i_guard)837acb289SZane Shelley void ServiceData::calloutTarget(pdbg_target* i_target,
99980d489SZane Shelley callout::Priority i_priority, bool i_guard)
1037acb289SZane Shelley {
1137acb289SZane Shelley // Add the target to the callout list.
1237acb289SZane Shelley addTargetCallout(i_target, i_priority, i_guard);
1337acb289SZane Shelley
1437acb289SZane Shelley // Add the callout FFDC.
1537acb289SZane Shelley nlohmann::json ffdc;
1637acb289SZane Shelley ffdc["Callout Type"] = "Hardware Callout";
1737acb289SZane Shelley ffdc["Target"] = util::pdbg::getPhysDevPath(i_target);
189980d489SZane Shelley ffdc["Priority"] = callout::getStringFFDC(i_priority);
1937acb289SZane Shelley ffdc["Guard"] = i_guard;
2037acb289SZane Shelley addCalloutFFDC(ffdc);
2155e7fec3SZane Shelley setSrcSubsystem(getTargetSubsystem(i_target), i_priority);
2237acb289SZane Shelley }
2337acb289SZane Shelley
2437acb289SZane Shelley //------------------------------------------------------------------------------
2537acb289SZane Shelley
calloutConnected(pdbg_target * i_rxTarget,const callout::BusType & i_busType,callout::Priority i_priority,bool i_guard)2637acb289SZane Shelley void ServiceData::calloutConnected(pdbg_target* i_rxTarget,
2737acb289SZane Shelley const callout::BusType& i_busType,
289980d489SZane Shelley callout::Priority i_priority, bool i_guard)
2937acb289SZane Shelley {
3037acb289SZane Shelley // Get the endpoint target for the transfer side of the bus.
3137acb289SZane Shelley auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
3237acb289SZane Shelley
3337acb289SZane Shelley // Callout the TX endpoint.
3437acb289SZane Shelley addTargetCallout(txTarget, i_priority, i_guard);
3537acb289SZane Shelley
3637acb289SZane Shelley // Add the callout FFDC.
3737acb289SZane Shelley nlohmann::json ffdc;
3837acb289SZane Shelley ffdc["Callout Type"] = "Connected Callout";
3937acb289SZane Shelley ffdc["Bus Type"] = i_busType.getString();
4037acb289SZane Shelley ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget);
4137acb289SZane Shelley ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
429980d489SZane Shelley ffdc["Priority"] = callout::getStringFFDC(i_priority);
4337acb289SZane Shelley ffdc["Guard"] = i_guard;
4437acb289SZane Shelley addCalloutFFDC(ffdc);
4555e7fec3SZane Shelley setSrcSubsystem(getTargetSubsystem(txTarget), i_priority);
4637acb289SZane Shelley }
4737acb289SZane Shelley
4837acb289SZane Shelley //------------------------------------------------------------------------------
4937acb289SZane Shelley
calloutBus(pdbg_target * i_rxTarget,const callout::BusType & i_busType,callout::Priority i_priority,bool i_guard)5037acb289SZane Shelley void ServiceData::calloutBus(pdbg_target* i_rxTarget,
5137acb289SZane Shelley const callout::BusType& i_busType,
529980d489SZane Shelley callout::Priority i_priority, bool i_guard)
5337acb289SZane Shelley {
5437acb289SZane Shelley // Get the endpoint target for the transfer side of the bus.
5537acb289SZane Shelley auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
5637acb289SZane Shelley
5737acb289SZane Shelley // Callout the RX endpoint.
5837acb289SZane Shelley addTargetCallout(i_rxTarget, i_priority, i_guard);
5937acb289SZane Shelley
6037acb289SZane Shelley // Callout the TX endpoint.
6137acb289SZane Shelley addTargetCallout(txTarget, i_priority, i_guard);
6237acb289SZane Shelley
6337acb289SZane Shelley // Callout everything else in between.
6437acb289SZane Shelley // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane.
6537acb289SZane Shelley addBackplaneCallout(i_priority);
6637acb289SZane Shelley
6737acb289SZane Shelley // Add the callout FFDC.
6837acb289SZane Shelley nlohmann::json ffdc;
6937acb289SZane Shelley ffdc["Callout Type"] = "Bus Callout";
7037acb289SZane Shelley ffdc["Bus Type"] = i_busType.getString();
7137acb289SZane Shelley ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget);
7237acb289SZane Shelley ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
739980d489SZane Shelley ffdc["Priority"] = callout::getStringFFDC(i_priority);
7437acb289SZane Shelley ffdc["Guard"] = i_guard;
7537acb289SZane Shelley addCalloutFFDC(ffdc);
7655e7fec3SZane Shelley setSrcSubsystem(i_busType.getSrcSubsystem(), i_priority);
7737acb289SZane Shelley }
7837acb289SZane Shelley
7937acb289SZane Shelley //------------------------------------------------------------------------------
8037acb289SZane Shelley
calloutClock(const callout::ClockType & i_clockType,callout::Priority i_priority,bool)8137acb289SZane Shelley void ServiceData::calloutClock(const callout::ClockType& i_clockType,
829980d489SZane Shelley callout::Priority i_priority, bool)
8337acb289SZane Shelley {
8437acb289SZane Shelley // Callout the clock target.
8537acb289SZane Shelley // TODO: For P10, the callout is simply the backplane. Also, there are no
8637acb289SZane Shelley // clock targets in the device tree. So at the moment there is no
8737acb289SZane Shelley // guard support for clock targets.
8837acb289SZane Shelley addBackplaneCallout(i_priority);
8937acb289SZane Shelley
9037acb289SZane Shelley // Add the callout FFDC.
9137acb289SZane Shelley // TODO: Add the target and guard type if guard is ever supported.
9237acb289SZane Shelley nlohmann::json ffdc;
9337acb289SZane Shelley ffdc["Callout Type"] = "Clock Callout";
9437acb289SZane Shelley ffdc["Clock Type"] = i_clockType.getString();
959980d489SZane Shelley ffdc["Priority"] = callout::getStringFFDC(i_priority);
9637acb289SZane Shelley addCalloutFFDC(ffdc);
9755e7fec3SZane Shelley setSrcSubsystem(i_clockType.getSrcSubsystem(), i_priority);
9837acb289SZane Shelley }
9937acb289SZane Shelley
10037acb289SZane Shelley //------------------------------------------------------------------------------
10137acb289SZane Shelley
calloutProcedure(const callout::Procedure & i_procedure,callout::Priority i_priority)10237acb289SZane Shelley void ServiceData::calloutProcedure(const callout::Procedure& i_procedure,
1039980d489SZane Shelley callout::Priority i_priority)
10437acb289SZane Shelley {
10537acb289SZane Shelley // Add the actual callout to the service data.
10637acb289SZane Shelley nlohmann::json callout;
10737acb289SZane Shelley callout["Procedure"] = i_procedure.getString();
1089980d489SZane Shelley callout["Priority"] = callout::getString(i_priority);
10937acb289SZane Shelley addCallout(callout);
11037acb289SZane Shelley
11137acb289SZane Shelley // Add the callout FFDC.
11237acb289SZane Shelley nlohmann::json ffdc;
11337acb289SZane Shelley ffdc["Callout Type"] = "Procedure Callout";
11437acb289SZane Shelley ffdc["Procedure"] = i_procedure.getString();
1159980d489SZane Shelley ffdc["Priority"] = callout::getStringFFDC(i_priority);
11637acb289SZane Shelley addCalloutFFDC(ffdc);
11755e7fec3SZane Shelley setSrcSubsystem(i_procedure.getSrcSubsystem(), i_priority);
11837acb289SZane Shelley }
11937acb289SZane Shelley
12037acb289SZane Shelley //------------------------------------------------------------------------------
12137acb289SZane Shelley
calloutPart(const callout::PartType & i_part,callout::Priority i_priority)122a4134770SZane Shelley void ServiceData::calloutPart(const callout::PartType& i_part,
1239980d489SZane Shelley callout::Priority i_priority)
124a4134770SZane Shelley {
125a4134770SZane Shelley if (callout::PartType::PNOR == i_part)
126a4134770SZane Shelley {
127a4134770SZane Shelley // The PNOR is on the BMC card.
128a4134770SZane Shelley // TODO: Will need to be modified if we ever support systems with more
129a4134770SZane Shelley // than one BMC.
130a4134770SZane Shelley addTargetCallout(util::pdbg::getTrgt("/bmc0"), i_priority, false);
131a4134770SZane Shelley }
132a4134770SZane Shelley else
133a4134770SZane Shelley {
134a4134770SZane Shelley throw std::logic_error("Unsupported part type: " + i_part.getString());
135a4134770SZane Shelley }
136a4134770SZane Shelley
137a4134770SZane Shelley // Add the callout FFDC.
138a4134770SZane Shelley nlohmann::json ffdc;
139a4134770SZane Shelley ffdc["Callout Type"] = "Part Callout";
140a4134770SZane Shelley ffdc["Part Type"] = i_part.getString();
1419980d489SZane Shelley ffdc["Priority"] = callout::getStringFFDC(i_priority);
142a4134770SZane Shelley addCalloutFFDC(ffdc);
14355e7fec3SZane Shelley setSrcSubsystem(i_part.getSrcSubsystem(), i_priority);
144a4134770SZane Shelley }
145a4134770SZane Shelley
146a4134770SZane Shelley //------------------------------------------------------------------------------
147a4134770SZane Shelley
addCallout(const nlohmann::json & i_callout)148979e2871SZane Shelley void ServiceData::addCallout(const nlohmann::json& i_callout)
149979e2871SZane Shelley {
150979e2871SZane Shelley // The new callout is either a hardware callout with a location code or a
151979e2871SZane Shelley // procedure callout.
152979e2871SZane Shelley
153979e2871SZane Shelley std::string type{};
154979e2871SZane Shelley if (i_callout.contains("LocationCode"))
155979e2871SZane Shelley {
156979e2871SZane Shelley type = "LocationCode";
157979e2871SZane Shelley }
158979e2871SZane Shelley else if (i_callout.contains("Procedure"))
159979e2871SZane Shelley {
160979e2871SZane Shelley type = "Procedure";
161979e2871SZane Shelley }
162979e2871SZane Shelley else
163979e2871SZane Shelley {
164979e2871SZane Shelley throw std::logic_error("Unsupported callout: " + i_callout.dump());
165979e2871SZane Shelley }
166979e2871SZane Shelley
167979e2871SZane Shelley // A map to determine the priority order. All of the medium priorities,
168979e2871SZane Shelley // including the medium group priorities, are all the same level.
1692fbd267eSZane Shelley // clang-format off
170979e2871SZane Shelley static const std::map<std::string, unsigned int> m = {
1712fbd267eSZane Shelley {callout::getString(callout::Priority::HIGH), 3},
1722fbd267eSZane Shelley {callout::getString(callout::Priority::MED), 2},
1732fbd267eSZane Shelley {callout::getString(callout::Priority::MED_A), 2},
1742fbd267eSZane Shelley {callout::getString(callout::Priority::MED_B), 2},
1752fbd267eSZane Shelley {callout::getString(callout::Priority::MED_C), 2},
1762fbd267eSZane Shelley {callout::getString(callout::Priority::LOW), 1},
177979e2871SZane Shelley };
1782fbd267eSZane Shelley // clang-format on
1792fbd267eSZane Shelley
1802fbd267eSZane Shelley // The new callout must contain a valid priority.
1812fbd267eSZane Shelley assert(i_callout.contains("Priority") &&
1822fbd267eSZane Shelley m.contains(i_callout.at("Priority")));
183979e2871SZane Shelley
184979e2871SZane Shelley bool addCallout = true;
185979e2871SZane Shelley
186979e2871SZane Shelley for (auto& c : iv_calloutList)
187979e2871SZane Shelley {
188979e2871SZane Shelley if (c.contains(type) && (c.at(type) == i_callout.at(type)))
189979e2871SZane Shelley {
190979e2871SZane Shelley // The new callout already exists. Don't add a new callout.
191979e2871SZane Shelley addCallout = false;
192979e2871SZane Shelley
193979e2871SZane Shelley if (m.at(c.at("Priority")) < m.at(i_callout.at("Priority")))
194979e2871SZane Shelley {
195979e2871SZane Shelley // The new callout has a higher priority, update it.
196979e2871SZane Shelley c["Priority"] = i_callout.at("Priority");
197979e2871SZane Shelley }
198979e2871SZane Shelley }
199979e2871SZane Shelley }
200979e2871SZane Shelley
201979e2871SZane Shelley if (addCallout)
202979e2871SZane Shelley {
203979e2871SZane Shelley iv_calloutList.push_back(i_callout);
204979e2871SZane Shelley }
205979e2871SZane Shelley }
206979e2871SZane Shelley
20737acb289SZane Shelley //------------------------------------------------------------------------------
20837acb289SZane Shelley
addTargetCallout(pdbg_target * i_target,callout::Priority i_priority,bool i_guard)20937acb289SZane Shelley void ServiceData::addTargetCallout(pdbg_target* i_target,
2109980d489SZane Shelley callout::Priority i_priority, bool i_guard)
21137acb289SZane Shelley {
21237acb289SZane Shelley nlohmann::json callout;
21337acb289SZane Shelley
21437acb289SZane Shelley callout["LocationCode"] = util::pdbg::getLocationCode(i_target);
2159980d489SZane Shelley callout["Priority"] = callout::getString(i_priority);
21637acb289SZane Shelley callout["Deconfigured"] = false;
21737acb289SZane Shelley callout["Guarded"] = false; // default
21837acb289SZane Shelley
21937acb289SZane Shelley // Check if guard info should be added.
22037acb289SZane Shelley if (i_guard)
22137acb289SZane Shelley {
22237acb289SZane Shelley auto guardType = queryGuardPolicy();
22337acb289SZane Shelley
22437acb289SZane Shelley if (!(callout::GuardType::NONE == guardType))
22537acb289SZane Shelley {
22637acb289SZane Shelley callout["Guarded"] = true;
22737acb289SZane Shelley callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target);
22837acb289SZane Shelley callout["GuardType"] = guardType.getString();
22937acb289SZane Shelley }
23037acb289SZane Shelley }
23137acb289SZane Shelley
23237acb289SZane Shelley addCallout(callout);
23337acb289SZane Shelley }
23437acb289SZane Shelley
23537acb289SZane Shelley //------------------------------------------------------------------------------
23637acb289SZane Shelley
addBackplaneCallout(callout::Priority i_priority)2379980d489SZane Shelley void ServiceData::addBackplaneCallout(callout::Priority i_priority)
23837acb289SZane Shelley {
23937acb289SZane Shelley // TODO: There isn't a device tree object for this. So will need to hardcode
24037acb289SZane Shelley // the location code for now. In the future, we will need a mechanism
24137acb289SZane Shelley // to make this data driven.
24237acb289SZane Shelley
24337acb289SZane Shelley nlohmann::json callout;
24437acb289SZane Shelley
24537acb289SZane Shelley callout["LocationCode"] = "P0";
2469980d489SZane Shelley callout["Priority"] = callout::getString(i_priority);
24737acb289SZane Shelley callout["Deconfigured"] = false;
24837acb289SZane Shelley callout["Guarded"] = false;
24937acb289SZane Shelley
25037acb289SZane Shelley addCallout(callout);
25137acb289SZane Shelley }
25237acb289SZane Shelley
25337acb289SZane Shelley //------------------------------------------------------------------------------
25437acb289SZane Shelley
setSrcSubsystem(callout::SrcSubsystem i_subsystem,callout::Priority i_priority)25555e7fec3SZane Shelley void ServiceData::setSrcSubsystem(callout::SrcSubsystem i_subsystem,
25655e7fec3SZane Shelley callout::Priority i_priority)
25755e7fec3SZane Shelley {
25855e7fec3SZane Shelley // clang-format off
25955e7fec3SZane Shelley static const std::map<callout::Priority, unsigned int> m =
26055e7fec3SZane Shelley {
26155e7fec3SZane Shelley // Note that all medium priorities, including groups A, B, and C, are
26255e7fec3SZane Shelley // the same priority.
26355e7fec3SZane Shelley {callout::Priority::HIGH, 3},
26455e7fec3SZane Shelley {callout::Priority::MED, 2},
26555e7fec3SZane Shelley {callout::Priority::MED_A, 2},
26655e7fec3SZane Shelley {callout::Priority::MED_B, 2},
26755e7fec3SZane Shelley {callout::Priority::MED_C, 2},
26855e7fec3SZane Shelley {callout::Priority::LOW, 1},
26955e7fec3SZane Shelley };
27055e7fec3SZane Shelley // clang-format on
27155e7fec3SZane Shelley
27255e7fec3SZane Shelley // The default subsystem is CEC_HARDWARE with LOW priority. Change the
27355e7fec3SZane Shelley // subsystem if the given subsystem has a higher priority or if the stored
27455e7fec3SZane Shelley // subsystem is still the default.
27555e7fec3SZane Shelley if (m.at(iv_srcSubsystem.second) < m.at(i_priority) ||
27655e7fec3SZane Shelley (callout::SrcSubsystem::CEC_HARDWARE == iv_srcSubsystem.first &&
27755e7fec3SZane Shelley callout::Priority::LOW == iv_srcSubsystem.second))
27855e7fec3SZane Shelley {
27955e7fec3SZane Shelley iv_srcSubsystem.first = i_subsystem;
28055e7fec3SZane Shelley iv_srcSubsystem.second = i_priority;
28155e7fec3SZane Shelley }
28255e7fec3SZane Shelley }
28355e7fec3SZane Shelley
28455e7fec3SZane Shelley //------------------------------------------------------------------------------
28555e7fec3SZane Shelley
getTargetSubsystem(pdbg_target * i_target)28655e7fec3SZane Shelley callout::SrcSubsystem ServiceData::getTargetSubsystem(pdbg_target* i_target)
28755e7fec3SZane Shelley {
28855e7fec3SZane Shelley using TargetType_t = util::pdbg::TargetType_t;
28955e7fec3SZane Shelley
29055e7fec3SZane Shelley // Default the subsystem to CEC_HARDWARE
29155e7fec3SZane Shelley callout::SrcSubsystem o_subSys = callout::SrcSubsystem::CEC_HARDWARE;
29255e7fec3SZane Shelley
29355e7fec3SZane Shelley // clang-format off
29455e7fec3SZane Shelley static const std::map<uint8_t, callout::SrcSubsystem> subSysMap =
29555e7fec3SZane Shelley {
29655e7fec3SZane Shelley {TargetType_t::TYPE_DIMM, callout::SrcSubsystem::MEMORY_DIMM },
297*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_PROC, callout::SrcSubsystem::PROCESSOR_FRU },
29855e7fec3SZane Shelley {TargetType_t::TYPE_CORE, callout::SrcSubsystem::PROCESSOR_UNIT},
299*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_NX, callout::SrcSubsystem::PROCESSOR },
300*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_EQ, callout::SrcSubsystem::PROCESSOR_UNIT},
301*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_PEC, callout::SrcSubsystem::PROCESSOR_UNIT},
30255e7fec3SZane Shelley {TargetType_t::TYPE_PHB, callout::SrcSubsystem::PHB },
303*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_MC, callout::SrcSubsystem::MEMORY_CTLR },
304*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_IOLINK, callout::SrcSubsystem::PROCESSOR_BUS },
305*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_OMI, callout::SrcSubsystem::MEMORY_CTLR },
306*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_MCC, callout::SrcSubsystem::MEMORY_CTLR },
307*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_OMIC, callout::SrcSubsystem::MEMORY_CTLR },
308*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_OCMB, callout::SrcSubsystem::MEMORY_FRU },
309*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_MEM_PORT, callout::SrcSubsystem::MEMORY_CTLR },
310*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_NMMU, callout::SrcSubsystem::PROCESSOR_UNIT},
311*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_PAU, callout::SrcSubsystem::PROCESSOR_UNIT},
312*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_IOHS, callout::SrcSubsystem::PROCESSOR_UNIT},
313*bc94bdeaSCaleb Palmer {TargetType_t::TYPE_PAUC, callout::SrcSubsystem::PROCESSOR_UNIT},
31455e7fec3SZane Shelley };
31555e7fec3SZane Shelley // clang-format on
31655e7fec3SZane Shelley
31755e7fec3SZane Shelley auto targetType = util::pdbg::getTrgtType(i_target);
31855e7fec3SZane Shelley
31955e7fec3SZane Shelley // If the type of the input target exists in the map, update the output
32055e7fec3SZane Shelley if (subSysMap.count(targetType) > 0)
32155e7fec3SZane Shelley {
32255e7fec3SZane Shelley o_subSys = subSysMap.at(targetType);
32355e7fec3SZane Shelley }
32455e7fec3SZane Shelley
32555e7fec3SZane Shelley return o_subSys;
32655e7fec3SZane Shelley }
32755e7fec3SZane Shelley
32855e7fec3SZane Shelley //------------------------------------------------------------------------------
32955e7fec3SZane Shelley
330979e2871SZane Shelley } // namespace analyzer
331