1979e2871SZane Shelley #include <analyzer/service_data.hpp> 2979e2871SZane Shelley 3979e2871SZane Shelley namespace analyzer 4979e2871SZane Shelley { 5979e2871SZane Shelley 637acb289SZane Shelley //------------------------------------------------------------------------------ 737acb289SZane Shelley 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 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 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 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 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 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 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. 169*2fbd267eSZane Shelley // clang-format off 170979e2871SZane Shelley static const std::map<std::string, unsigned int> m = { 171*2fbd267eSZane Shelley {callout::getString(callout::Priority::HIGH), 3}, 172*2fbd267eSZane Shelley {callout::getString(callout::Priority::MED), 2}, 173*2fbd267eSZane Shelley {callout::getString(callout::Priority::MED_A), 2}, 174*2fbd267eSZane Shelley {callout::getString(callout::Priority::MED_B), 2}, 175*2fbd267eSZane Shelley {callout::getString(callout::Priority::MED_C), 2}, 176*2fbd267eSZane Shelley {callout::getString(callout::Priority::LOW), 1}, 177979e2871SZane Shelley }; 178*2fbd267eSZane Shelley // clang-format on 179*2fbd267eSZane Shelley 180*2fbd267eSZane Shelley // The new callout must contain a valid priority. 181*2fbd267eSZane Shelley assert(i_callout.contains("Priority") && 182*2fbd267eSZane 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 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 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 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 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 }, 29755e7fec3SZane Shelley {TargetType_t::TYPE_PROC, callout::SrcSubsystem::PROCESSOR }, 29855e7fec3SZane Shelley {TargetType_t::TYPE_CORE, callout::SrcSubsystem::PROCESSOR_UNIT}, 29955e7fec3SZane Shelley {TargetType_t::TYPE_EQ, callout::SrcSubsystem::PROCESSOR }, 30055e7fec3SZane Shelley {TargetType_t::TYPE_PEC, callout::SrcSubsystem::PHB }, 30155e7fec3SZane Shelley {TargetType_t::TYPE_PHB, callout::SrcSubsystem::PHB }, 30255e7fec3SZane Shelley {TargetType_t::TYPE_MC, callout::SrcSubsystem::MEMORY }, 30355e7fec3SZane Shelley {TargetType_t::TYPE_IOLINK, callout::SrcSubsystem::CEC_HARDWARE }, 30455e7fec3SZane Shelley {TargetType_t::TYPE_OMI, callout::SrcSubsystem::MEMORY }, 30555e7fec3SZane Shelley {TargetType_t::TYPE_MCC, callout::SrcSubsystem::MEMORY }, 30655e7fec3SZane Shelley {TargetType_t::TYPE_OMIC, callout::SrcSubsystem::MEMORY }, 30755e7fec3SZane Shelley {TargetType_t::TYPE_OCMB, callout::SrcSubsystem::MEMORY }, 30855e7fec3SZane Shelley {TargetType_t::TYPE_MEM_PORT, callout::SrcSubsystem::MEMORY }, 30955e7fec3SZane Shelley {TargetType_t::TYPE_NMMU, callout::SrcSubsystem::PROCESSOR }, 31055e7fec3SZane Shelley {TargetType_t::TYPE_PAU, callout::SrcSubsystem::PROCESSOR_BUS }, 31155e7fec3SZane Shelley {TargetType_t::TYPE_IOHS, callout::SrcSubsystem::PROCESSOR_BUS }, 31255e7fec3SZane Shelley {TargetType_t::TYPE_PAUC, callout::SrcSubsystem::PROCESSOR }, 31355e7fec3SZane Shelley }; 31455e7fec3SZane Shelley // clang-format on 31555e7fec3SZane Shelley 31655e7fec3SZane Shelley auto targetType = util::pdbg::getTrgtType(i_target); 31755e7fec3SZane Shelley 31855e7fec3SZane Shelley // If the type of the input target exists in the map, update the output 31955e7fec3SZane Shelley if (subSysMap.count(targetType) > 0) 32055e7fec3SZane Shelley { 32155e7fec3SZane Shelley o_subSys = subSysMap.at(targetType); 32255e7fec3SZane Shelley } 32355e7fec3SZane Shelley 32455e7fec3SZane Shelley return o_subSys; 32555e7fec3SZane Shelley } 32655e7fec3SZane Shelley 32755e7fec3SZane Shelley //------------------------------------------------------------------------------ 32855e7fec3SZane Shelley 329979e2871SZane Shelley } // namespace analyzer 330