1 2 #include <analyzer/plugins/plugin.hpp> 3 #include <hei_util.hpp> 4 #include <util/pdbg.hpp> 5 #include <util/trace.hpp> 6 7 namespace analyzer 8 { 9 10 namespace P10 11 { 12 13 /** 14 * @brief Adds all clocks/chips reporting PLL unlock attentions to the callout 15 * list. 16 * 17 * Processors are always called out at medium priority and never guarded. If 18 * more than one processor is reporting a PLL unlock attention on the same 19 * clock, the clock is called out with high priority. Otherwise, the clock 20 * callout priority is medium. 21 */ 22 void pll_unlock(unsigned int i_instance, const libhei::Chip&, 23 ServiceData& io_servData) 24 { 25 auto nodeId = libhei::hash<libhei::NodeId_t>("PLL_UNLOCK"); 26 27 auto sigList = io_servData.getIsolationData().getSignatureList(); 28 29 // The PLL list is initially the same size of the signature list. 30 std::vector<libhei::Signature> pllList{sigList.size()}; 31 32 // Copy all signatures that match the node ID and bit position. Note that 33 // in this case the bit position is the same as the plugin instance. 34 auto itr = std::copy_if(sigList.begin(), sigList.end(), pllList.begin(), 35 [&nodeId, &i_instance](const auto& s) { 36 return (nodeId == s.getId() && 37 i_instance == s.getBit()); 38 }); 39 40 // Shrink the size of the PLL list if necessary. 41 pllList.resize(std::distance(pllList.begin(), itr)); 42 43 // The clock callout priority is dependent on the number of chips with PLL 44 // unlock attentions. 45 auto clockPriority = 46 (1 < pllList.size()) ? callout::Priority::HIGH : callout::Priority::MED; 47 48 // Callout the clock. 49 auto clockCallout = (0 == i_instance) ? callout::ClockType::OSC_REF_CLOCK_0 50 : callout::ClockType::OSC_REF_CLOCK_1; 51 io_servData.calloutClock(clockCallout, clockPriority, true); 52 53 // Callout the processors connected to this clock that are reporting PLL 54 // unlock attentions. Always a medium callout and no guarding. 55 for (const auto& sig : pllList) 56 { 57 io_servData.calloutTarget(util::pdbg::getTrgt(sig.getChip()), 58 callout::Priority::MED, false); 59 } 60 } 61 62 /** 63 * @brief Queries for an LPC timeout. If present, will callout all appropriate 64 * hardware. 65 */ 66 void lpc_timeout(unsigned int, const libhei::Chip& i_chip, 67 ServiceData& io_servData) 68 { 69 auto target = util::pdbg::getTrgt(i_chip); 70 auto path = util::pdbg::getPath(target); 71 72 if (util::pdbg::queryLpcTimeout(target)) 73 { 74 trace::inf("LPC timeout detected on %s", path); 75 76 // Callout the PNOR. 77 io_servData.calloutPart(callout::PartType::PNOR, 78 callout::Priority::MED); 79 80 // Callout the associated clock, no guard. 81 auto chipPos = util::pdbg::getChipPos(target); 82 if (0 == chipPos) 83 { 84 // Clock 0 is hardwired to proc 0. 85 io_servData.calloutClock(callout::ClockType::OSC_REF_CLOCK_0, 86 callout::Priority::MED, false); 87 } 88 else if (1 == chipPos) 89 { 90 // Clock 1 is hardwired to proc 1. 91 io_servData.calloutClock(callout::ClockType::OSC_REF_CLOCK_1, 92 callout::Priority::MED, false); 93 } 94 else 95 { 96 trace::err("LPC timeout on unexpected processor: %s", path); 97 } 98 99 // Callout the processor, no guard. 100 io_servData.calloutTarget(target, callout::Priority::MED, false); 101 } 102 else 103 { 104 trace::inf("No LPC timeout detected on %s", path); 105 106 io_servData.calloutProcedure(callout::Procedure::NEXTLVL, 107 callout::Priority::HIGH); 108 } 109 } 110 111 } // namespace P10 112 113 PLUGIN_DEFINE_NS(P10_10, P10, pll_unlock); 114 PLUGIN_DEFINE_NS(P10_20, P10, pll_unlock); 115 116 PLUGIN_DEFINE_NS(P10_10, P10, lpc_timeout); 117 PLUGIN_DEFINE_NS(P10_20, P10, lpc_timeout); 118 119 } // namespace analyzer 120