1dfc7ec73SVishwanatha Subbanna #include <experimental/filesystem> 2dfc7ec73SVishwanatha Subbanna #include <phosphor-logging/log.hpp> 3dfc7ec73SVishwanatha Subbanna #include <phosphor-logging/elog-errors.hpp> 4dfc7ec73SVishwanatha Subbanna #include <xyz/openbmc_project/Common/error.hpp> 5dfc7ec73SVishwanatha Subbanna #include "occ_finder.hpp" 6dfc7ec73SVishwanatha Subbanna #include "occ_manager.hpp" 7dfc7ec73SVishwanatha Subbanna #include "i2c_occ.hpp" 8dfc7ec73SVishwanatha Subbanna #include "utils.hpp" 9dfc7ec73SVishwanatha Subbanna #include "config.h" 10dfc7ec73SVishwanatha Subbanna 11dfc7ec73SVishwanatha Subbanna namespace open_power 12dfc7ec73SVishwanatha Subbanna { 13dfc7ec73SVishwanatha Subbanna namespace occ 14dfc7ec73SVishwanatha Subbanna { 15dfc7ec73SVishwanatha Subbanna 16dfc7ec73SVishwanatha Subbanna void Manager::findAndCreateObjects() 17dfc7ec73SVishwanatha Subbanna { 18dfc7ec73SVishwanatha Subbanna // Need to watch for CPU inventory creation. 19dfc7ec73SVishwanatha Subbanna for (auto id = 0; id < MAX_CPUS; ++id) 20dfc7ec73SVishwanatha Subbanna { 21dfc7ec73SVishwanatha Subbanna auto path = std::string(CPU_PATH) + std::to_string(id); 22dfc7ec73SVishwanatha Subbanna cpuMatches.emplace_back( 23dfc7ec73SVishwanatha Subbanna bus, 24dfc7ec73SVishwanatha Subbanna sdbusRule::interfacesAdded() + 25dfc7ec73SVishwanatha Subbanna sdbusRule::argNpath(0, path), 26dfc7ec73SVishwanatha Subbanna std::bind(std::mem_fn(&Manager::cpuCreated), 27dfc7ec73SVishwanatha Subbanna this, std::placeholders::_1)); 28dfc7ec73SVishwanatha Subbanna } 29370f06b4SDeepak Kodihalli 30370f06b4SDeepak Kodihalli // Check if CPU inventory exists already. 31370f06b4SDeepak Kodihalli auto occs = open_power::occ::finder::get(bus); 32370f06b4SDeepak Kodihalli if (!occs.empty()) 33dfc7ec73SVishwanatha Subbanna { 34dfc7ec73SVishwanatha Subbanna for (const auto& occ : occs) 35dfc7ec73SVishwanatha Subbanna { 36dfc7ec73SVishwanatha Subbanna // CPU inventory exists already, OCC objects can be created. 37dfc7ec73SVishwanatha Subbanna createObjects(occ); 38dfc7ec73SVishwanatha Subbanna } 39dfc7ec73SVishwanatha Subbanna } 40dfc7ec73SVishwanatha Subbanna } 41dfc7ec73SVishwanatha Subbanna 42dfc7ec73SVishwanatha Subbanna int Manager::cpuCreated(sdbusplus::message::message& msg) 43dfc7ec73SVishwanatha Subbanna { 44dfc7ec73SVishwanatha Subbanna namespace fs = std::experimental::filesystem; 45dfc7ec73SVishwanatha Subbanna 46dfc7ec73SVishwanatha Subbanna sdbusplus::message::object_path o; 47dfc7ec73SVishwanatha Subbanna msg.read(o); 48dfc7ec73SVishwanatha Subbanna fs::path cpuPath(std::string(std::move(o))); 49dfc7ec73SVishwanatha Subbanna 50dfc7ec73SVishwanatha Subbanna auto name = cpuPath.filename().string(); 51dfc7ec73SVishwanatha Subbanna auto index = name.find(CPU_NAME); 52dfc7ec73SVishwanatha Subbanna name.replace(index, std::strlen(CPU_NAME), OCC_NAME); 53dfc7ec73SVishwanatha Subbanna 54dfc7ec73SVishwanatha Subbanna createObjects(name); 55dfc7ec73SVishwanatha Subbanna 56dfc7ec73SVishwanatha Subbanna return 0; 57dfc7ec73SVishwanatha Subbanna } 58dfc7ec73SVishwanatha Subbanna 59dfc7ec73SVishwanatha Subbanna void Manager::createObjects(const std::string& occ) 60dfc7ec73SVishwanatha Subbanna { 61dfc7ec73SVishwanatha Subbanna auto path = fs::path(OCC_CONTROL_ROOT) / occ; 62dfc7ec73SVishwanatha Subbanna 63dfc7ec73SVishwanatha Subbanna passThroughObjects.emplace_back( 64dfc7ec73SVishwanatha Subbanna std::make_unique<PassThrough>( 65dfc7ec73SVishwanatha Subbanna bus, 66dfc7ec73SVishwanatha Subbanna path.c_str())); 67dfc7ec73SVishwanatha Subbanna 68dfc7ec73SVishwanatha Subbanna statusObjects.emplace_back( 69dfc7ec73SVishwanatha Subbanna std::make_unique<Status>( 70dfc7ec73SVishwanatha Subbanna bus, 71dfc7ec73SVishwanatha Subbanna event, 72dfc7ec73SVishwanatha Subbanna path.c_str(), 73*636577f4SEdward A. James *this, 74dfc7ec73SVishwanatha Subbanna std::bind(std::mem_fn(&Manager::statusCallBack), 75dfc7ec73SVishwanatha Subbanna this, std::placeholders::_1))); 76dfc7ec73SVishwanatha Subbanna 77dfc7ec73SVishwanatha Subbanna // Create the power cap monitor object for master occ (0) 78dfc7ec73SVishwanatha Subbanna if (!pcap) 79dfc7ec73SVishwanatha Subbanna { 80dfc7ec73SVishwanatha Subbanna pcap = std::make_unique<open_power::occ::powercap::PowerCap>( 81dfc7ec73SVishwanatha Subbanna bus, 82dfc7ec73SVishwanatha Subbanna *statusObjects.front()); 83dfc7ec73SVishwanatha Subbanna } 84dfc7ec73SVishwanatha Subbanna } 85dfc7ec73SVishwanatha Subbanna 86dfc7ec73SVishwanatha Subbanna void Manager::statusCallBack(bool status) 87dfc7ec73SVishwanatha Subbanna { 88dfc7ec73SVishwanatha Subbanna using namespace phosphor::logging; 89dfc7ec73SVishwanatha Subbanna using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: 90dfc7ec73SVishwanatha Subbanna Error::InternalFailure; 91dfc7ec73SVishwanatha Subbanna 92dfc7ec73SVishwanatha Subbanna // At this time, it won't happen but keeping it 93dfc7ec73SVishwanatha Subbanna // here just in case something changes in the future 94dfc7ec73SVishwanatha Subbanna if ((activeCount == 0) && (!status)) 95dfc7ec73SVishwanatha Subbanna { 96dfc7ec73SVishwanatha Subbanna log<level::ERR>("Invalid update on OCCActive"); 97dfc7ec73SVishwanatha Subbanna elog<InternalFailure>(); 98dfc7ec73SVishwanatha Subbanna } 99dfc7ec73SVishwanatha Subbanna 100dfc7ec73SVishwanatha Subbanna activeCount += status ? 1 : -1; 101dfc7ec73SVishwanatha Subbanna 102dfc7ec73SVishwanatha Subbanna // If all the OCCs are bound, then start error detection 103dfc7ec73SVishwanatha Subbanna if (activeCount == statusObjects.size()) 104dfc7ec73SVishwanatha Subbanna { 105dfc7ec73SVishwanatha Subbanna for (const auto& occ: statusObjects) 106dfc7ec73SVishwanatha Subbanna { 107dfc7ec73SVishwanatha Subbanna occ->addErrorWatch(); 108dfc7ec73SVishwanatha Subbanna } 109dfc7ec73SVishwanatha Subbanna } 110dfc7ec73SVishwanatha Subbanna else if (!status) 111dfc7ec73SVishwanatha Subbanna { 112dfc7ec73SVishwanatha Subbanna // If some OCCs are not bound yet, those will be a NO-OP 113dfc7ec73SVishwanatha Subbanna for (const auto& occ: statusObjects) 114dfc7ec73SVishwanatha Subbanna { 115dfc7ec73SVishwanatha Subbanna occ->removeErrorWatch(); 116dfc7ec73SVishwanatha Subbanna } 117dfc7ec73SVishwanatha Subbanna } 118dfc7ec73SVishwanatha Subbanna } 119dfc7ec73SVishwanatha Subbanna 120dfc7ec73SVishwanatha Subbanna #ifdef I2C_OCC 121dfc7ec73SVishwanatha Subbanna void Manager::initStatusObjects() 122dfc7ec73SVishwanatha Subbanna { 123dfc7ec73SVishwanatha Subbanna // Make sure we have a valid path string 124dfc7ec73SVishwanatha Subbanna static_assert(sizeof(DEV_PATH) != 0); 125dfc7ec73SVishwanatha Subbanna 126dfc7ec73SVishwanatha Subbanna auto deviceNames = i2c_occ::getOccHwmonDevices(DEV_PATH); 127dfc7ec73SVishwanatha Subbanna for (auto& name : deviceNames) 128dfc7ec73SVishwanatha Subbanna { 129dfc7ec73SVishwanatha Subbanna i2c_occ::i2cToDbus(name); 130b5259a1eSLei YU name = std::string(OCC_NAME) + '_' + name; 131dfc7ec73SVishwanatha Subbanna auto path = fs::path(OCC_CONTROL_ROOT) / name; 132dfc7ec73SVishwanatha Subbanna statusObjects.emplace_back( 133dfc7ec73SVishwanatha Subbanna std::make_unique<Status>( 134dfc7ec73SVishwanatha Subbanna bus, 135dfc7ec73SVishwanatha Subbanna event, 136*636577f4SEdward A. James path.c_str(), 137*636577f4SEdward A. James *this)); 138dfc7ec73SVishwanatha Subbanna } 139dfc7ec73SVishwanatha Subbanna } 140dfc7ec73SVishwanatha Subbanna #endif 141dfc7ec73SVishwanatha Subbanna 142dfc7ec73SVishwanatha Subbanna } // namespace occ 143dfc7ec73SVishwanatha Subbanna } // namespace open_power 144