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