1 #include <analyzer/plugins/plugin.hpp> 2 #include <analyzer/resolution.hpp> 3 #include <util/pdbg.hpp> 4 #include <util/trace.hpp> 5 6 namespace analyzer 7 { 8 9 //------------------------------------------------------------------------------ 10 11 // Helper function to get the root cause chip target from the service data. 12 pdbg_target* __getRootCauseChipTarget(const ServiceData& i_sd) 13 { 14 auto target = util::pdbg::getTrgt(i_sd.getRootCause().getChip()); 15 assert(nullptr != target); // This would be a really bad bug. 16 return target; 17 } 18 19 //------------------------------------------------------------------------------ 20 21 // Helper function to get a unit target from the given unit path, which is a 22 // devtree path relative the the containing chip. An empty string indicates the 23 // chip target should be returned. 24 pdbg_target* __getUnitTarget(pdbg_target* i_chipTarget, 25 const std::string& i_unitPath) 26 { 27 assert(nullptr != i_chipTarget); 28 29 auto target = i_chipTarget; // default, if i_unitPath is empty 30 31 if (!i_unitPath.empty()) 32 { 33 auto path = std::string{util::pdbg::getPath(target)} + "/" + i_unitPath; 34 35 target = util::pdbg::getTrgt(path); 36 if (nullptr == target) 37 { 38 // Likely a bug the RAS data files. 39 throw std::logic_error("Unable to find target for " + path); 40 } 41 } 42 43 return target; 44 } 45 46 //------------------------------------------------------------------------------ 47 48 void __calloutTarget(ServiceData& io_sd, pdbg_target* i_target, 49 const callout::Priority& i_priority, bool i_guard) 50 { 51 nlohmann::json callout; 52 callout["LocationCode"] = util::pdbg::getLocationCode(i_target); 53 callout["Priority"] = i_priority.getUserDataString(); 54 callout["Deconfigured"] = false; 55 callout["Guarded"] = false; // default 56 57 // Check if guard info should be added. 58 if (i_guard) 59 { 60 auto guardType = io_sd.queryGuardPolicy(); 61 62 if (!(callout::GuardType::NONE == guardType)) 63 { 64 callout["Guarded"] = true; 65 callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target); 66 callout["GuardType"] = guardType.getString(); 67 } 68 } 69 70 io_sd.addCallout(callout); 71 } 72 73 //------------------------------------------------------------------------------ 74 75 void __calloutBackplane(ServiceData& io_sd, const callout::Priority& i_priority) 76 { 77 // TODO: There isn't a device tree object for this. So will need to hardcode 78 // the location code for now. In the future, we will need a mechanism 79 // to make this data driven. 80 81 nlohmann::json callout; 82 callout["LocationCode"] = "P0"; 83 callout["Priority"] = i_priority.getUserDataString(); 84 callout["Deconfigured"] = false; 85 callout["Guarded"] = false; 86 io_sd.addCallout(callout); 87 } 88 89 //------------------------------------------------------------------------------ 90 91 void HardwareCalloutResolution::resolve(ServiceData& io_sd) const 92 { 93 // Get the target for the hardware callout. 94 auto target = __getUnitTarget(__getRootCauseChipTarget(io_sd), iv_unitPath); 95 96 // Add the actual callout to the service data. 97 __calloutTarget(io_sd, target, iv_priority, iv_guard); 98 99 // Add the callout FFDC to the service data. 100 nlohmann::json ffdc; 101 ffdc["Callout Type"] = "Hardware Callout"; 102 ffdc["Target"] = util::pdbg::getPhysDevPath(target); 103 ffdc["Priority"] = iv_priority.getRegistryString(); 104 ffdc["Guard"] = iv_guard; 105 io_sd.addCalloutFFDC(ffdc); 106 } 107 108 //------------------------------------------------------------------------------ 109 110 void ConnectedCalloutResolution::resolve(ServiceData& io_sd) const 111 { 112 // Get the chip target from the root cause signature. 113 auto chipTarget = __getRootCauseChipTarget(io_sd); 114 115 // Get the endpoint target for the receiving side of the bus. 116 auto rxTarget = __getUnitTarget(chipTarget, iv_unitPath); 117 118 // Get the endpoint target for the transfer side of the bus. 119 auto txTarget = util::pdbg::getConnectedTarget(rxTarget, iv_busType); 120 121 // Callout the TX endpoint. 122 __calloutTarget(io_sd, txTarget, iv_priority, iv_guard); 123 124 // Add the callout FFDC to the service data. 125 nlohmann::json ffdc; 126 ffdc["Callout Type"] = "Connected Callout"; 127 ffdc["Bus Type"] = iv_busType.getString(); 128 ffdc["Target"] = util::pdbg::getPhysDevPath(txTarget); 129 ffdc["Priority"] = iv_priority.getRegistryString(); 130 ffdc["Guard"] = iv_guard; 131 io_sd.addCalloutFFDC(ffdc); 132 } 133 134 //------------------------------------------------------------------------------ 135 136 void BusCalloutResolution::resolve(ServiceData& io_sd) const 137 { 138 // Get the chip target from the root cause signature. 139 auto chipTarget = __getRootCauseChipTarget(io_sd); 140 141 // Get the endpoint target for the receiving side of the bus. 142 auto rxTarget = __getUnitTarget(chipTarget, iv_unitPath); 143 144 // Get the endpoint target for the transfer side of the bus. 145 auto txTarget = util::pdbg::getConnectedTarget(rxTarget, iv_busType); 146 147 // Callout the RX endpoint. 148 __calloutTarget(io_sd, rxTarget, iv_priority, iv_guard); 149 150 // Callout the TX endpoint. 151 __calloutTarget(io_sd, txTarget, iv_priority, iv_guard); 152 153 // Callout everything else in between. 154 // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane. 155 __calloutBackplane(io_sd, iv_priority); 156 157 // Add the callout FFDC to the service data. 158 nlohmann::json ffdc; 159 ffdc["Callout Type"] = "Bus Callout"; 160 ffdc["Bus Type"] = iv_busType.getString(); 161 ffdc["RX Target"] = util::pdbg::getPhysDevPath(rxTarget); 162 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget); 163 ffdc["Priority"] = iv_priority.getRegistryString(); 164 ffdc["Guard"] = iv_guard; 165 io_sd.addCalloutFFDC(ffdc); 166 } 167 168 //------------------------------------------------------------------------------ 169 170 void ClockCalloutResolution::resolve(ServiceData& io_sd) const 171 { 172 // Callout the clock target. 173 // TODO: For P10, the callout is simply the backplane. Also, there are no 174 // clock targets in the device tree. So at the moment there is no 175 // guard support for clock targets. 176 __calloutBackplane(io_sd, iv_priority); 177 178 // Add the callout FFDC to the service data. 179 // TODO: Add the target and guard type if guard is ever supported. 180 nlohmann::json ffdc; 181 ffdc["Callout Type"] = "Clock Callout"; 182 ffdc["Clock Type"] = iv_clockType.getString(); 183 ffdc["Priority"] = iv_priority.getRegistryString(); 184 io_sd.addCalloutFFDC(ffdc); 185 } 186 187 //------------------------------------------------------------------------------ 188 189 void ProcedureCalloutResolution::resolve(ServiceData& io_sd) const 190 { 191 // Add the actual callout to the service data. 192 nlohmann::json callout; 193 callout["Procedure"] = iv_procedure.getString(); 194 callout["Priority"] = iv_priority.getUserDataString(); 195 io_sd.addCallout(callout); 196 197 // Add the callout FFDC to the service data. 198 nlohmann::json ffdc; 199 ffdc["Callout Type"] = "Procedure Callout"; 200 ffdc["Procedure"] = iv_procedure.getString(); 201 ffdc["Priority"] = iv_priority.getRegistryString(); 202 io_sd.addCalloutFFDC(ffdc); 203 } 204 205 //------------------------------------------------------------------------------ 206 207 void PluginResolution::resolve(ServiceData& io_sd) const 208 { 209 // Get the plugin function and call it. 210 211 auto chip = io_sd.getRootCause().getChip(); 212 213 auto func = PluginMap::getSingleton().get(chip.getType(), iv_name); 214 215 func(iv_instance, chip, io_sd); 216 } 217 218 //------------------------------------------------------------------------------ 219 220 } // namespace analyzer 221