1 #include <analyzer/service_data.hpp> 2 3 namespace analyzer 4 { 5 6 //------------------------------------------------------------------------------ 7 8 void ServiceData::calloutTarget(pdbg_target* i_target, 9 const callout::Priority& i_priority, 10 bool i_guard) 11 { 12 // Add the target to the callout list. 13 addTargetCallout(i_target, i_priority, i_guard); 14 15 // Add the callout FFDC. 16 nlohmann::json ffdc; 17 ffdc["Callout Type"] = "Hardware Callout"; 18 ffdc["Target"] = util::pdbg::getPhysDevPath(i_target); 19 ffdc["Priority"] = i_priority.getRegistryString(); 20 ffdc["Guard"] = i_guard; 21 addCalloutFFDC(ffdc); 22 } 23 24 //------------------------------------------------------------------------------ 25 26 void ServiceData::calloutConnected(pdbg_target* i_rxTarget, 27 const callout::BusType& i_busType, 28 const callout::Priority& i_priority, 29 bool i_guard) 30 { 31 // Get the endpoint target for the transfer side of the bus. 32 auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType); 33 34 // Callout the TX endpoint. 35 addTargetCallout(txTarget, i_priority, i_guard); 36 37 // Add the callout FFDC. 38 nlohmann::json ffdc; 39 ffdc["Callout Type"] = "Connected Callout"; 40 ffdc["Bus Type"] = i_busType.getString(); 41 ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget); 42 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget); 43 ffdc["Priority"] = i_priority.getRegistryString(); 44 ffdc["Guard"] = i_guard; 45 addCalloutFFDC(ffdc); 46 } 47 48 //------------------------------------------------------------------------------ 49 50 void ServiceData::calloutBus(pdbg_target* i_rxTarget, 51 const callout::BusType& i_busType, 52 const callout::Priority& i_priority, bool i_guard) 53 { 54 // Get the endpoint target for the transfer side of the bus. 55 auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType); 56 57 // Callout the RX endpoint. 58 addTargetCallout(i_rxTarget, i_priority, i_guard); 59 60 // Callout the TX endpoint. 61 addTargetCallout(txTarget, i_priority, i_guard); 62 63 // Callout everything else in between. 64 // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane. 65 addBackplaneCallout(i_priority); 66 67 // Add the callout FFDC. 68 nlohmann::json ffdc; 69 ffdc["Callout Type"] = "Bus Callout"; 70 ffdc["Bus Type"] = i_busType.getString(); 71 ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget); 72 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget); 73 ffdc["Priority"] = i_priority.getRegistryString(); 74 ffdc["Guard"] = i_guard; 75 addCalloutFFDC(ffdc); 76 } 77 78 //------------------------------------------------------------------------------ 79 80 void ServiceData::calloutClock(const callout::ClockType& i_clockType, 81 const callout::Priority& i_priority, bool) 82 { 83 // Callout the clock target. 84 // TODO: For P10, the callout is simply the backplane. Also, there are no 85 // clock targets in the device tree. So at the moment there is no 86 // guard support for clock targets. 87 addBackplaneCallout(i_priority); 88 89 // Add the callout FFDC. 90 // TODO: Add the target and guard type if guard is ever supported. 91 nlohmann::json ffdc; 92 ffdc["Callout Type"] = "Clock Callout"; 93 ffdc["Clock Type"] = i_clockType.getString(); 94 ffdc["Priority"] = i_priority.getRegistryString(); 95 addCalloutFFDC(ffdc); 96 } 97 98 //------------------------------------------------------------------------------ 99 100 void ServiceData::calloutProcedure(const callout::Procedure& i_procedure, 101 const callout::Priority& i_priority) 102 { 103 // Add the actual callout to the service data. 104 nlohmann::json callout; 105 callout["Procedure"] = i_procedure.getString(); 106 callout["Priority"] = i_priority.getUserDataString(); 107 addCallout(callout); 108 109 // Add the callout FFDC. 110 nlohmann::json ffdc; 111 ffdc["Callout Type"] = "Procedure Callout"; 112 ffdc["Procedure"] = i_procedure.getString(); 113 ffdc["Priority"] = i_priority.getRegistryString(); 114 addCalloutFFDC(ffdc); 115 } 116 117 //------------------------------------------------------------------------------ 118 119 void ServiceData::addCallout(const nlohmann::json& i_callout) 120 { 121 // The new callout is either a hardware callout with a location code or a 122 // procedure callout. 123 124 std::string type{}; 125 if (i_callout.contains("LocationCode")) 126 { 127 type = "LocationCode"; 128 } 129 else if (i_callout.contains("Procedure")) 130 { 131 type = "Procedure"; 132 } 133 else 134 { 135 throw std::logic_error("Unsupported callout: " + i_callout.dump()); 136 } 137 138 // A map to determine the priority order. All of the medium priorities, 139 // including the medium group priorities, are all the same level. 140 static const std::map<std::string, unsigned int> m = { 141 {"H", 3}, {"M", 2}, {"A", 2}, {"B", 2}, {"C", 2}, {"L", 1}, 142 }; 143 144 bool addCallout = true; 145 146 for (auto& c : iv_calloutList) 147 { 148 if (c.contains(type) && (c.at(type) == i_callout.at(type))) 149 { 150 // The new callout already exists. Don't add a new callout. 151 addCallout = false; 152 153 if (m.at(c.at("Priority")) < m.at(i_callout.at("Priority"))) 154 { 155 // The new callout has a higher priority, update it. 156 c["Priority"] = i_callout.at("Priority"); 157 } 158 } 159 } 160 161 if (addCallout) 162 { 163 iv_calloutList.push_back(i_callout); 164 } 165 } 166 167 //------------------------------------------------------------------------------ 168 169 void ServiceData::addTargetCallout(pdbg_target* i_target, 170 const callout::Priority& i_priority, 171 bool i_guard) 172 { 173 nlohmann::json callout; 174 175 callout["LocationCode"] = util::pdbg::getLocationCode(i_target); 176 callout["Priority"] = i_priority.getUserDataString(); 177 callout["Deconfigured"] = false; 178 callout["Guarded"] = false; // default 179 180 // Check if guard info should be added. 181 if (i_guard) 182 { 183 auto guardType = queryGuardPolicy(); 184 185 if (!(callout::GuardType::NONE == guardType)) 186 { 187 callout["Guarded"] = true; 188 callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target); 189 callout["GuardType"] = guardType.getString(); 190 } 191 } 192 193 addCallout(callout); 194 } 195 196 //------------------------------------------------------------------------------ 197 198 void ServiceData::addBackplaneCallout(const callout::Priority& i_priority) 199 { 200 // TODO: There isn't a device tree object for this. So will need to hardcode 201 // the location code for now. In the future, we will need a mechanism 202 // to make this data driven. 203 204 nlohmann::json callout; 205 206 callout["LocationCode"] = "P0"; 207 callout["Priority"] = i_priority.getUserDataString(); 208 callout["Deconfigured"] = false; 209 callout["Guarded"] = false; 210 211 addCallout(callout); 212 } 213 214 //------------------------------------------------------------------------------ 215 216 } // namespace analyzer 217