115527a43SZane Shelley 
215527a43SZane Shelley #include <analyzer/plugins/plugin.hpp>
32c228cdcSZane Shelley #include <hei_util.hpp>
42c228cdcSZane Shelley #include <util/pdbg.hpp>
515527a43SZane Shelley #include <util/trace.hpp>
615527a43SZane Shelley 
715527a43SZane Shelley namespace analyzer
815527a43SZane Shelley {
915527a43SZane Shelley 
1015527a43SZane Shelley namespace P10
1115527a43SZane Shelley {
1215527a43SZane Shelley 
1315527a43SZane Shelley /**
1415527a43SZane Shelley  * @brief Adds all clocks/chips reporting PLL unlock attentions to the callout
1515527a43SZane Shelley  *        list.
1615527a43SZane Shelley  *
1715527a43SZane Shelley  *  Processors are always called out at medium priority and never guarded. If
1815527a43SZane Shelley  *  more than one processor is reporting a PLL unlock attention on the same
1915527a43SZane Shelley  *  clock, the clock is called out with high priority. Otherwise, the clock
2015527a43SZane Shelley  *  callout priority is medium.
2115527a43SZane Shelley  */
222c228cdcSZane Shelley void pll_unlock(unsigned int i_instance, const libhei::Chip&,
232c228cdcSZane Shelley                 ServiceData& io_servData)
2415527a43SZane Shelley {
252c228cdcSZane Shelley     auto nodeId = libhei::hash<libhei::NodeId_t>("PLL_UNLOCK");
262c228cdcSZane Shelley 
272c228cdcSZane Shelley     auto sigList = io_servData.getIsolationData().getSignatureList();
282c228cdcSZane Shelley 
292c228cdcSZane Shelley     // The PLL list is initially the same size of the signature list.
302c228cdcSZane Shelley     std::vector<libhei::Signature> pllList{sigList.size()};
312c228cdcSZane Shelley 
322c228cdcSZane Shelley     // Copy all signatures that match the node ID and bit position. Note that
332c228cdcSZane Shelley     // in this case the bit position is the same as the plugin instance.
342c228cdcSZane Shelley     auto itr = std::copy_if(sigList.begin(), sigList.end(), pllList.begin(),
352c228cdcSZane Shelley                             [&nodeId, &i_instance](const auto& s) {
362c228cdcSZane Shelley                                 return (nodeId == s.getId() &&
372c228cdcSZane Shelley                                         i_instance == s.getBit());
382c228cdcSZane Shelley                             });
392c228cdcSZane Shelley 
402c228cdcSZane Shelley     // Shrink the size of the PLL list if necessary.
412c228cdcSZane Shelley     pllList.resize(std::distance(pllList.begin(), itr));
422c228cdcSZane Shelley 
432c228cdcSZane Shelley     // The clock callout priority is dependent on the number of chips with PLL
442c228cdcSZane Shelley     // unlock attentions.
452c228cdcSZane Shelley     auto clockPriority =
462c228cdcSZane Shelley         (1 < pllList.size()) ? callout::Priority::HIGH : callout::Priority::MED;
472c228cdcSZane Shelley 
482c228cdcSZane Shelley     // Callout the clock.
492c228cdcSZane Shelley     auto clockCallout = (0 == i_instance) ? callout::ClockType::OSC_REF_CLOCK_0
502c228cdcSZane Shelley                                           : callout::ClockType::OSC_REF_CLOCK_1;
512c228cdcSZane Shelley     io_servData.calloutClock(clockCallout, clockPriority, true);
522c228cdcSZane Shelley 
532c228cdcSZane Shelley     // Callout the processors connected to this clock that are reporting PLL
542c228cdcSZane Shelley     // unlock attentions. Always a medium callout and no guarding.
552c228cdcSZane Shelley     for (const auto& sig : pllList)
562c228cdcSZane Shelley     {
572c228cdcSZane Shelley         io_servData.calloutTarget(util::pdbg::getTrgt(sig.getChip()),
582c228cdcSZane Shelley                                   callout::Priority::MED, false);
592c228cdcSZane Shelley     }
6015527a43SZane Shelley }
6115527a43SZane Shelley 
62*e90b85dcSZane Shelley /**
63*e90b85dcSZane Shelley  * @brief Queries for an LPC timeout. If present, will callout all appropriate
64*e90b85dcSZane Shelley  *        hardware.
65*e90b85dcSZane Shelley  */
66*e90b85dcSZane Shelley void lpc_timeout(unsigned int, const libhei::Chip& i_chip,
67*e90b85dcSZane Shelley                  ServiceData& io_servData)
68*e90b85dcSZane Shelley {
69*e90b85dcSZane Shelley     auto target = util::pdbg::getTrgt(i_chip);
70*e90b85dcSZane Shelley     auto path   = util::pdbg::getPath(target);
71*e90b85dcSZane Shelley 
72*e90b85dcSZane Shelley     if (util::pdbg::queryLpcTimeout(target))
73*e90b85dcSZane Shelley     {
74*e90b85dcSZane Shelley         trace::inf("LPC timeout detected on %s", path);
75*e90b85dcSZane Shelley 
76*e90b85dcSZane Shelley         // Callout the PNOR.
77*e90b85dcSZane Shelley         io_servData.calloutPart(callout::PartType::PNOR,
78*e90b85dcSZane Shelley                                 callout::Priority::MED);
79*e90b85dcSZane Shelley 
80*e90b85dcSZane Shelley         // Callout the associated clock, no guard.
81*e90b85dcSZane Shelley         auto chipPos = util::pdbg::getChipPos(target);
82*e90b85dcSZane Shelley         if (0 == chipPos)
83*e90b85dcSZane Shelley         {
84*e90b85dcSZane Shelley             // Clock 0 is hardwired to proc 0.
85*e90b85dcSZane Shelley             io_servData.calloutClock(callout::ClockType::OSC_REF_CLOCK_0,
86*e90b85dcSZane Shelley                                      callout::Priority::MED, false);
87*e90b85dcSZane Shelley         }
88*e90b85dcSZane Shelley         else if (1 == chipPos)
89*e90b85dcSZane Shelley         {
90*e90b85dcSZane Shelley             // Clock 1 is hardwired to proc 1.
91*e90b85dcSZane Shelley             io_servData.calloutClock(callout::ClockType::OSC_REF_CLOCK_1,
92*e90b85dcSZane Shelley                                      callout::Priority::MED, false);
93*e90b85dcSZane Shelley         }
94*e90b85dcSZane Shelley         else
95*e90b85dcSZane Shelley         {
96*e90b85dcSZane Shelley             trace::err("LPC timeout on unexpected processor: %s", path);
97*e90b85dcSZane Shelley         }
98*e90b85dcSZane Shelley 
99*e90b85dcSZane Shelley         // Callout the processor, no guard.
100*e90b85dcSZane Shelley         io_servData.calloutTarget(target, callout::Priority::MED, false);
101*e90b85dcSZane Shelley     }
102*e90b85dcSZane Shelley     else
103*e90b85dcSZane Shelley     {
104*e90b85dcSZane Shelley         trace::inf("No LPC timeout detected on %s", path);
105*e90b85dcSZane Shelley 
106*e90b85dcSZane Shelley         io_servData.calloutProcedure(callout::Procedure::NEXTLVL,
107*e90b85dcSZane Shelley                                      callout::Priority::HIGH);
108*e90b85dcSZane Shelley     }
109*e90b85dcSZane Shelley }
110*e90b85dcSZane Shelley 
11115527a43SZane Shelley } // namespace P10
11215527a43SZane Shelley 
11315527a43SZane Shelley PLUGIN_DEFINE_NS(P10_10, P10, pll_unlock);
11415527a43SZane Shelley PLUGIN_DEFINE_NS(P10_20, P10, pll_unlock);
11515527a43SZane Shelley 
116*e90b85dcSZane Shelley PLUGIN_DEFINE_NS(P10_10, P10, lpc_timeout);
117*e90b85dcSZane Shelley PLUGIN_DEFINE_NS(P10_20, P10, lpc_timeout);
118*e90b85dcSZane Shelley 
11915527a43SZane Shelley } // namespace analyzer
120