1dfc7ec73SVishwanatha Subbanna #include "config.h" 2dfc7ec73SVishwanatha Subbanna 394df8c90SGunnar Mills #include "occ_manager.hpp" 494df8c90SGunnar Mills 594df8c90SGunnar Mills #include "i2c_occ.hpp" 6bb895cb8SChicago Duan #include "occ_dbus.hpp" 794df8c90SGunnar Mills #include "utils.hpp" 894df8c90SGunnar Mills 9bb895cb8SChicago Duan #include <cmath> 1094df8c90SGunnar Mills #include <experimental/filesystem> 1194df8c90SGunnar Mills #include <phosphor-logging/elog-errors.hpp> 1294df8c90SGunnar Mills #include <phosphor-logging/log.hpp> 13bb895cb8SChicago Duan #include <regex> 1494df8c90SGunnar Mills #include <xyz/openbmc_project/Common/error.hpp> 1594df8c90SGunnar Mills 16dfc7ec73SVishwanatha Subbanna namespace open_power 17dfc7ec73SVishwanatha Subbanna { 18dfc7ec73SVishwanatha Subbanna namespace occ 19dfc7ec73SVishwanatha Subbanna { 20dfc7ec73SVishwanatha Subbanna 21*8b8abeedSMatt Spinler constexpr uint32_t fruTypeNotAvailable = 0xFF; 22*8b8abeedSMatt Spinler 23a8857c50SChris Cain using namespace phosphor::logging; 24a8857c50SChris Cain 25dfc7ec73SVishwanatha Subbanna void Manager::findAndCreateObjects() 26dfc7ec73SVishwanatha Subbanna { 27dfc7ec73SVishwanatha Subbanna for (auto id = 0; id < MAX_CPUS; ++id) 28dfc7ec73SVishwanatha Subbanna { 2930417a15SDeepak Kodihalli // Create one occ per cpu 3030417a15SDeepak Kodihalli auto occ = std::string(OCC_NAME) + std::to_string(id); 31dfc7ec73SVishwanatha Subbanna createObjects(occ); 32dfc7ec73SVishwanatha Subbanna } 33dfc7ec73SVishwanatha Subbanna } 34dfc7ec73SVishwanatha Subbanna 35dfc7ec73SVishwanatha Subbanna int Manager::cpuCreated(sdbusplus::message::message& msg) 36dfc7ec73SVishwanatha Subbanna { 37dfc7ec73SVishwanatha Subbanna namespace fs = std::experimental::filesystem; 38dfc7ec73SVishwanatha Subbanna 39dfc7ec73SVishwanatha Subbanna sdbusplus::message::object_path o; 40dfc7ec73SVishwanatha Subbanna msg.read(o); 41dfc7ec73SVishwanatha Subbanna fs::path cpuPath(std::string(std::move(o))); 42dfc7ec73SVishwanatha Subbanna 43dfc7ec73SVishwanatha Subbanna auto name = cpuPath.filename().string(); 44dfc7ec73SVishwanatha Subbanna auto index = name.find(CPU_NAME); 45dfc7ec73SVishwanatha Subbanna name.replace(index, std::strlen(CPU_NAME), OCC_NAME); 46dfc7ec73SVishwanatha Subbanna 47dfc7ec73SVishwanatha Subbanna createObjects(name); 48dfc7ec73SVishwanatha Subbanna 49dfc7ec73SVishwanatha Subbanna return 0; 50dfc7ec73SVishwanatha Subbanna } 51dfc7ec73SVishwanatha Subbanna 52dfc7ec73SVishwanatha Subbanna void Manager::createObjects(const std::string& occ) 53dfc7ec73SVishwanatha Subbanna { 54dfc7ec73SVishwanatha Subbanna auto path = fs::path(OCC_CONTROL_ROOT) / occ; 55dfc7ec73SVishwanatha Subbanna 56dfc7ec73SVishwanatha Subbanna passThroughObjects.emplace_back( 57f3b7514eSGeorge Liu std::make_unique<PassThrough>(path.c_str())); 58dfc7ec73SVishwanatha Subbanna 5994df8c90SGunnar Mills statusObjects.emplace_back(std::make_unique<Status>( 60f3b7514eSGeorge Liu event, path.c_str(), *this, 6194df8c90SGunnar Mills std::bind(std::mem_fn(&Manager::statusCallBack), this, 6200325238STom Joseph std::placeholders::_1) 6300325238STom Joseph #ifdef PLDM 6400325238STom Joseph , 6500325238STom Joseph std::bind(std::mem_fn(&pldm::Interface::resetOCC), pldmHandle.get(), 6600325238STom Joseph std::placeholders::_1) 6700325238STom Joseph #endif 6800325238STom Joseph )); 69dfc7ec73SVishwanatha Subbanna 70dfc7ec73SVishwanatha Subbanna // Create the power cap monitor object for master occ (0) 71dfc7ec73SVishwanatha Subbanna if (!pcap) 72dfc7ec73SVishwanatha Subbanna { 73dfc7ec73SVishwanatha Subbanna pcap = std::make_unique<open_power::occ::powercap::PowerCap>( 74f3b7514eSGeorge Liu *statusObjects.front()); 75dfc7ec73SVishwanatha Subbanna } 7678e86012SChris Cain 7778e86012SChris Cain #ifdef POWER10 7878e86012SChris Cain // Create the power mode monitor object for master occ (0) 7978e86012SChris Cain if (!pmode) 8078e86012SChris Cain { 8178e86012SChris Cain pmode = std::make_unique<open_power::occ::powermode::PowerMode>( 8278e86012SChris Cain *statusObjects.front()); 8378e86012SChris Cain } 8478e86012SChris Cain #endif 85dfc7ec73SVishwanatha Subbanna } 86dfc7ec73SVishwanatha Subbanna 87dfc7ec73SVishwanatha Subbanna void Manager::statusCallBack(bool status) 88dfc7ec73SVishwanatha Subbanna { 8994df8c90SGunnar Mills using InternalFailure = 9094df8c90SGunnar Mills sdbusplus::xyz::openbmc_project::Common::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; 101dae2d940SEddie James 102dae2d940SEddie James // Only start presence detection if all the OCCs are bound 103dae2d940SEddie James if (activeCount == statusObjects.size()) 104dae2d940SEddie James { 105dae2d940SEddie James for (auto& obj : statusObjects) 106dae2d940SEddie James { 107dae2d940SEddie James obj->addPresenceWatchMaster(); 108dae2d940SEddie James } 109dae2d940SEddie James } 110a8857c50SChris Cain 111a8857c50SChris Cain if ((!_pollTimer->isEnabled()) && (activeCount > 0)) 112a8857c50SChris Cain { 113a8857c50SChris Cain log<level::INFO>(fmt::format("Manager::statusCallBack(): {} OCCs will " 114a8857c50SChris Cain "be polled every {} seconds", 115a8857c50SChris Cain activeCount, pollInterval) 116a8857c50SChris Cain .c_str()); 117a8857c50SChris Cain 118a8857c50SChris Cain // Send poll and start OCC poll timer 119a8857c50SChris Cain pollerTimerExpired(); 120a8857c50SChris Cain } 121a8857c50SChris Cain else if ((_pollTimer->isEnabled()) && (activeCount == 0)) 122a8857c50SChris Cain { 123a8857c50SChris Cain // Stop OCC poll timer 124a8857c50SChris Cain log<level::INFO>("Manager::statusCallBack(): OCCs are not running, " 125a8857c50SChris Cain "stopping poll timer"); 126a8857c50SChris Cain _pollTimer->setEnabled(false); 127a8857c50SChris Cain } 128dfc7ec73SVishwanatha Subbanna } 129dfc7ec73SVishwanatha Subbanna 130dfc7ec73SVishwanatha Subbanna #ifdef I2C_OCC 131dfc7ec73SVishwanatha Subbanna void Manager::initStatusObjects() 132dfc7ec73SVishwanatha Subbanna { 133dfc7ec73SVishwanatha Subbanna // Make sure we have a valid path string 134dfc7ec73SVishwanatha Subbanna static_assert(sizeof(DEV_PATH) != 0); 135dfc7ec73SVishwanatha Subbanna 136dfc7ec73SVishwanatha Subbanna auto deviceNames = i2c_occ::getOccHwmonDevices(DEV_PATH); 13741470e56SLei YU auto occMasterName = deviceNames.front(); 138dfc7ec73SVishwanatha Subbanna for (auto& name : deviceNames) 139dfc7ec73SVishwanatha Subbanna { 140dfc7ec73SVishwanatha Subbanna i2c_occ::i2cToDbus(name); 141b5259a1eSLei YU name = std::string(OCC_NAME) + '_' + name; 142dfc7ec73SVishwanatha Subbanna auto path = fs::path(OCC_CONTROL_ROOT) / name; 143dfc7ec73SVishwanatha Subbanna statusObjects.emplace_back( 144f3b7514eSGeorge Liu std::make_unique<Status>(event, path.c_str(), *this)); 145dfc7ec73SVishwanatha Subbanna } 14641470e56SLei YU // The first device is master occ 14741470e56SLei YU pcap = std::make_unique<open_power::occ::powercap::PowerCap>( 148f3b7514eSGeorge Liu *statusObjects.front(), occMasterName); 14978e86012SChris Cain #ifdef POWER10 15078e86012SChris Cain pmode = std::make_unique<open_power::occ::powermode::PowerMode>( 15178e86012SChris Cain *statusObjects.front()); 15278e86012SChris Cain #endif 153dfc7ec73SVishwanatha Subbanna } 154dfc7ec73SVishwanatha Subbanna #endif 155dfc7ec73SVishwanatha Subbanna 156815f9f55STom Joseph #ifdef PLDM 157815f9f55STom Joseph bool Manager::updateOCCActive(instanceID instance, bool status) 158815f9f55STom Joseph { 159815f9f55STom Joseph return (statusObjects[instance])->occActive(status); 160815f9f55STom Joseph } 161815f9f55STom Joseph #endif 162815f9f55STom Joseph 163a8857c50SChris Cain void Manager::pollerTimerExpired() 164a8857c50SChris Cain { 165a8857c50SChris Cain if (activeCount == 0) 166a8857c50SChris Cain { 167a8857c50SChris Cain // No OCCs running, so poll timer will not be restarted 168a8857c50SChris Cain log<level::INFO>("Manager::pollerTimerExpire(): No OCCs running, poll " 169a8857c50SChris Cain "timer not restarted"); 170a8857c50SChris Cain } 171a8857c50SChris Cain 172a8857c50SChris Cain if (!_pollTimer) 173a8857c50SChris Cain { 174a8857c50SChris Cain log<level::ERR>( 175a8857c50SChris Cain "Manager::pollerTimerExpired() ERROR: Timer not defined"); 176a8857c50SChris Cain return; 177a8857c50SChris Cain } 178a8857c50SChris Cain 179a8857c50SChris Cain for (auto& obj : statusObjects) 180a8857c50SChris Cain { 181a8857c50SChris Cain // Read sysfs to force kernel to poll OCC 182a8857c50SChris Cain obj->readOccState(); 183bb895cb8SChicago Duan 184bb895cb8SChicago Duan #ifdef READ_OCC_SENSORS 185bb895cb8SChicago Duan // Read occ sensor values 186bb895cb8SChicago Duan auto id = obj->getOccInstanceID(); 187bb895cb8SChicago Duan if (!obj->occActive()) 188bb895cb8SChicago Duan { 189bb895cb8SChicago Duan // Occ not activated 190bb895cb8SChicago Duan setSensorValueToNaN(id); 191bb895cb8SChicago Duan continue; 192bb895cb8SChicago Duan } 193bb895cb8SChicago Duan getSensorValues(id, obj->isMasterOcc()); 194bb895cb8SChicago Duan #endif 195a8857c50SChris Cain } 196a8857c50SChris Cain 197a8857c50SChris Cain // Restart OCC poll timer 198a8857c50SChris Cain _pollTimer->restartOnce(std::chrono::seconds(pollInterval)); 199a8857c50SChris Cain } 200a8857c50SChris Cain 201bb895cb8SChicago Duan #ifdef READ_OCC_SENSORS 202bb895cb8SChicago Duan void Manager::readTempSensors(const fs::path& path, uint32_t id) 203bb895cb8SChicago Duan { 204bb895cb8SChicago Duan const int open_errno = errno; 205bb895cb8SChicago Duan std::regex expr{"temp\\d+_label$"}; // Example: temp5_label 206bb895cb8SChicago Duan for (auto& file : fs::directory_iterator(path)) 207bb895cb8SChicago Duan { 208bb895cb8SChicago Duan if (!std::regex_search(file.path().string(), expr)) 209bb895cb8SChicago Duan { 210bb895cb8SChicago Duan continue; 211bb895cb8SChicago Duan } 212bb895cb8SChicago Duan std::ifstream fileOpen(file.path(), std::ios::in); 213bb895cb8SChicago Duan if (!fileOpen) 214bb895cb8SChicago Duan { 215bb895cb8SChicago Duan // If not able to read, OCC may be offline 216bb895cb8SChicago Duan log<level::DEBUG>( 217bb895cb8SChicago Duan fmt::format("readTempSensors: open failed(errno = {}) ", 218bb895cb8SChicago Duan open_errno) 219bb895cb8SChicago Duan .c_str()); 220bb895cb8SChicago Duan 221bb895cb8SChicago Duan continue; 222bb895cb8SChicago Duan } 223bb895cb8SChicago Duan std::string labelValue; 224bb895cb8SChicago Duan fileOpen >> labelValue; 225bb895cb8SChicago Duan fileOpen.close(); 226bb895cb8SChicago Duan 227bb895cb8SChicago Duan const std::string& tempLabel = "label"; 228bb895cb8SChicago Duan const std::string filePathString = file.path().string().substr( 229bb895cb8SChicago Duan 0, file.path().string().length() - tempLabel.length()); 230bb895cb8SChicago Duan std::ifstream fruTypeFile(filePathString + "fru_type", std::ios::in); 231bb895cb8SChicago Duan if (!fruTypeFile) 232bb895cb8SChicago Duan { 233bb895cb8SChicago Duan // If not able to read, OCC may be offline 234bb895cb8SChicago Duan log<level::DEBUG>( 235bb895cb8SChicago Duan fmt::format("readTempSensors: open failed(errno = {}) ", 236bb895cb8SChicago Duan open_errno) 237bb895cb8SChicago Duan .c_str()); 238bb895cb8SChicago Duan continue; 239bb895cb8SChicago Duan } 240bb895cb8SChicago Duan uint32_t fruTypeValue{0}; 241bb895cb8SChicago Duan fruTypeFile >> fruTypeValue; 242bb895cb8SChicago Duan fruTypeFile.close(); 243bb895cb8SChicago Duan 244bb895cb8SChicago Duan std::string sensorPath = 245bb895cb8SChicago Duan OCC_SENSORS_ROOT + std::string("/temperature/"); 246bb895cb8SChicago Duan 247bb895cb8SChicago Duan if (fruTypeValue == VRMVdd) 248bb895cb8SChicago Duan { 249bb895cb8SChicago Duan sensorPath.append("vrm_vdd" + std::to_string(id) + "_temp"); 250bb895cb8SChicago Duan } 251bb895cb8SChicago Duan else 252bb895cb8SChicago Duan { 253bb895cb8SChicago Duan auto sensorTypeID = 254bb895cb8SChicago Duan open_power::occ::utils::checkLabelValue(labelValue); 255bb895cb8SChicago Duan if (sensorTypeID == std::nullopt) 256bb895cb8SChicago Duan { 257bb895cb8SChicago Duan continue; 258bb895cb8SChicago Duan } 259bb895cb8SChicago Duan auto& [type, instanceID] = *sensorTypeID; 260bb895cb8SChicago Duan 261bb895cb8SChicago Duan if (type == OCC_DIMM_TEMP_SENSOR_TYPE) 262bb895cb8SChicago Duan { 263*8b8abeedSMatt Spinler if (fruTypeValue == fruTypeNotAvailable) 264*8b8abeedSMatt Spinler { 265*8b8abeedSMatt Spinler // Not all DIMM related temps are available to read 266*8b8abeedSMatt Spinler // (no _input file in this case) 267*8b8abeedSMatt Spinler continue; 268*8b8abeedSMatt Spinler } 269bb895cb8SChicago Duan auto iter = dimmTempSensorName.find(fruTypeValue); 270bb895cb8SChicago Duan if (iter == dimmTempSensorName.end()) 271bb895cb8SChicago Duan { 272bb895cb8SChicago Duan log<level::ERR>(fmt::format("readTempSensors: Fru type " 273bb895cb8SChicago Duan "error! fruTypeValue = {}) ", 274bb895cb8SChicago Duan fruTypeValue) 275bb895cb8SChicago Duan .c_str()); 276bb895cb8SChicago Duan continue; 277bb895cb8SChicago Duan } 278bb895cb8SChicago Duan 279bb895cb8SChicago Duan sensorPath.append("dimm" + std::to_string(instanceID) + 280bb895cb8SChicago Duan iter->second); 281bb895cb8SChicago Duan } 282bb895cb8SChicago Duan else if (type == OCC_CPU_TEMP_SENSOR_TYPE) 283bb895cb8SChicago Duan { 284bb895cb8SChicago Duan if (fruTypeValue != processorCore) 285bb895cb8SChicago Duan { 286bb895cb8SChicago Duan log<level::ERR>(fmt::format("readTempSensors: Fru type " 287bb895cb8SChicago Duan "error! fruTypeValue = {}) ", 288bb895cb8SChicago Duan fruTypeValue) 289bb895cb8SChicago Duan .c_str()); 290bb895cb8SChicago Duan continue; 291bb895cb8SChicago Duan } 292bb895cb8SChicago Duan 293bb895cb8SChicago Duan sensorPath.append("proc" + std::to_string(id) + "_core" + 294bb895cb8SChicago Duan std::to_string(instanceID) + "_temp"); 295bb895cb8SChicago Duan } 296bb895cb8SChicago Duan else 297bb895cb8SChicago Duan { 298bb895cb8SChicago Duan continue; 299bb895cb8SChicago Duan } 300bb895cb8SChicago Duan } 301bb895cb8SChicago Duan 302bb895cb8SChicago Duan std::ifstream faultPathFile(filePathString + "fault", std::ios::in); 303bb895cb8SChicago Duan if (faultPathFile) 304bb895cb8SChicago Duan { 305bb895cb8SChicago Duan uint32_t faultValue; 306bb895cb8SChicago Duan faultPathFile >> faultValue; 307bb895cb8SChicago Duan faultPathFile.close(); 308bb895cb8SChicago Duan 309bb895cb8SChicago Duan if (faultValue != 0) 310bb895cb8SChicago Duan { 311bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus().setValue( 312bb895cb8SChicago Duan sensorPath, std::numeric_limits<double>::quiet_NaN()); 313bb895cb8SChicago Duan 314bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus() 315bb895cb8SChicago Duan .setOperationalStatus(sensorPath, false); 316bb895cb8SChicago Duan 317bb895cb8SChicago Duan continue; 318bb895cb8SChicago Duan } 319bb895cb8SChicago Duan } 320bb895cb8SChicago Duan 321bb895cb8SChicago Duan std::ifstream inputFile(filePathString + "input", std::ios::in); 322bb895cb8SChicago Duan if (inputFile) 323bb895cb8SChicago Duan { 324bb895cb8SChicago Duan double tempValue; 325bb895cb8SChicago Duan inputFile >> tempValue; 326bb895cb8SChicago Duan 327bb895cb8SChicago Duan inputFile.close(); 328bb895cb8SChicago Duan 329bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus().setValue( 330bb895cb8SChicago Duan sensorPath, tempValue * std::pow(10, -3)); 331bb895cb8SChicago Duan 332bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus() 333bb895cb8SChicago Duan .setOperationalStatus(sensorPath, true); 334bb895cb8SChicago Duan 335bb895cb8SChicago Duan existingSensors[sensorPath] = id; 336bb895cb8SChicago Duan } 337bb895cb8SChicago Duan else 338bb895cb8SChicago Duan { 339bb895cb8SChicago Duan // If not able to read, OCC may be offline 340bb895cb8SChicago Duan log<level::DEBUG>( 341bb895cb8SChicago Duan fmt::format("readTempSensors: open failed(errno = {}) ", 342bb895cb8SChicago Duan open_errno) 343bb895cb8SChicago Duan .c_str()); 344bb895cb8SChicago Duan } 345bb895cb8SChicago Duan } 346bb895cb8SChicago Duan return; 347bb895cb8SChicago Duan } 348bb895cb8SChicago Duan 349bb895cb8SChicago Duan std::optional<std::string> 350bb895cb8SChicago Duan Manager::getPowerLabelFunctionID(const std::string& value) 351bb895cb8SChicago Duan { 352bb895cb8SChicago Duan // If the value is "system", then the FunctionID is "system". 353bb895cb8SChicago Duan if (value == "system") 354bb895cb8SChicago Duan { 355bb895cb8SChicago Duan return value; 356bb895cb8SChicago Duan } 357bb895cb8SChicago Duan 358bb895cb8SChicago Duan // If the value is not "system", then the label value have 3 numbers, of 359bb895cb8SChicago Duan // which we only care about the middle one: 360bb895cb8SChicago Duan // <sensor id>_<function id>_<apss channel> 361bb895cb8SChicago Duan // eg: The value is "0_10_5" , then the FunctionID is "10". 362bb895cb8SChicago Duan if (value.find("_") == std::string::npos) 363bb895cb8SChicago Duan { 364bb895cb8SChicago Duan return std::nullopt; 365bb895cb8SChicago Duan } 366bb895cb8SChicago Duan 367bb895cb8SChicago Duan auto powerLabelValue = value.substr((value.find("_") + 1)); 368bb895cb8SChicago Duan 369bb895cb8SChicago Duan if (powerLabelValue.find("_") == std::string::npos) 370bb895cb8SChicago Duan { 371bb895cb8SChicago Duan return std::nullopt; 372bb895cb8SChicago Duan } 373bb895cb8SChicago Duan 374bb895cb8SChicago Duan return powerLabelValue.substr(0, powerLabelValue.find("_")); 375bb895cb8SChicago Duan } 376bb895cb8SChicago Duan 377bb895cb8SChicago Duan void Manager::readPowerSensors(const fs::path& path, uint32_t id) 378bb895cb8SChicago Duan { 379bb895cb8SChicago Duan const int open_errno = errno; 380bb895cb8SChicago Duan std::regex expr{"power\\d+_label$"}; // Example: power5_label 381bb895cb8SChicago Duan for (auto& file : fs::directory_iterator(path)) 382bb895cb8SChicago Duan { 383bb895cb8SChicago Duan if (!std::regex_search(file.path().string(), expr)) 384bb895cb8SChicago Duan { 385bb895cb8SChicago Duan continue; 386bb895cb8SChicago Duan } 387bb895cb8SChicago Duan std::ifstream fileOpen(file.path(), std::ios::in); 388bb895cb8SChicago Duan if (!fileOpen) 389bb895cb8SChicago Duan { 390bb895cb8SChicago Duan // If not able to read, OCC may be offline 391bb895cb8SChicago Duan log<level::DEBUG>( 392bb895cb8SChicago Duan fmt::format("readPowerSensors: open failed(errno = {}) ", 393bb895cb8SChicago Duan open_errno) 394bb895cb8SChicago Duan .c_str()); 395bb895cb8SChicago Duan 396bb895cb8SChicago Duan continue; 397bb895cb8SChicago Duan } 398bb895cb8SChicago Duan std::string labelValue; 399bb895cb8SChicago Duan fileOpen >> labelValue; 400bb895cb8SChicago Duan fileOpen.close(); 401bb895cb8SChicago Duan 402bb895cb8SChicago Duan auto functionID = getPowerLabelFunctionID(labelValue); 403bb895cb8SChicago Duan if (functionID == std::nullopt) 404bb895cb8SChicago Duan { 405bb895cb8SChicago Duan continue; 406bb895cb8SChicago Duan } 407bb895cb8SChicago Duan 408bb895cb8SChicago Duan const std::string& tempLabel = "label"; 409bb895cb8SChicago Duan const std::string filePathString = file.path().string().substr( 410bb895cb8SChicago Duan 0, file.path().string().length() - tempLabel.length()); 411bb895cb8SChicago Duan 412bb895cb8SChicago Duan std::string sensorPath = OCC_SENSORS_ROOT + std::string("/power/"); 413bb895cb8SChicago Duan 414bb895cb8SChicago Duan auto iter = powerSensorName.find(*functionID); 415bb895cb8SChicago Duan if (iter == powerSensorName.end()) 416bb895cb8SChicago Duan { 417bb895cb8SChicago Duan continue; 418bb895cb8SChicago Duan } 419bb895cb8SChicago Duan sensorPath.append(iter->second); 420bb895cb8SChicago Duan 421bb895cb8SChicago Duan std::ifstream faultPathFile(filePathString + "fault", std::ios::in); 422bb895cb8SChicago Duan if (faultPathFile) 423bb895cb8SChicago Duan { 424bb895cb8SChicago Duan uint32_t faultValue{0}; 425bb895cb8SChicago Duan faultPathFile >> faultValue; 426bb895cb8SChicago Duan faultPathFile.close(); 427bb895cb8SChicago Duan 428bb895cb8SChicago Duan if (faultValue != 0) 429bb895cb8SChicago Duan { 430bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus().setValue( 431bb895cb8SChicago Duan sensorPath, std::numeric_limits<double>::quiet_NaN()); 432bb895cb8SChicago Duan 433bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus() 434bb895cb8SChicago Duan .setOperationalStatus(sensorPath, false); 435bb895cb8SChicago Duan 436bb895cb8SChicago Duan continue; 437bb895cb8SChicago Duan } 438bb895cb8SChicago Duan } 439bb895cb8SChicago Duan 440bb895cb8SChicago Duan std::ifstream inputFile(filePathString + "input", std::ios::in); 441bb895cb8SChicago Duan if (inputFile) 442bb895cb8SChicago Duan { 443bb895cb8SChicago Duan double tempValue; 444bb895cb8SChicago Duan inputFile >> tempValue; 445bb895cb8SChicago Duan inputFile.close(); 446bb895cb8SChicago Duan 447bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus().setValue( 448bb895cb8SChicago Duan sensorPath, tempValue * std::pow(10, -3) * std::pow(10, -3)); 449bb895cb8SChicago Duan 450bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus() 451bb895cb8SChicago Duan .setOperationalStatus(sensorPath, true); 452bb895cb8SChicago Duan 453bb895cb8SChicago Duan existingSensors[sensorPath] = id; 454bb895cb8SChicago Duan } 455bb895cb8SChicago Duan else 456bb895cb8SChicago Duan { 457bb895cb8SChicago Duan // If not able to read, OCC may be offline 458bb895cb8SChicago Duan log<level::DEBUG>( 459bb895cb8SChicago Duan fmt::format("readPowerSensors: open failed(errno = {}) ", 460bb895cb8SChicago Duan open_errno) 461bb895cb8SChicago Duan .c_str()); 462bb895cb8SChicago Duan } 463bb895cb8SChicago Duan } 464bb895cb8SChicago Duan return; 465bb895cb8SChicago Duan } 466bb895cb8SChicago Duan 467bb895cb8SChicago Duan void Manager::setSensorValueToNaN(uint32_t id) 468bb895cb8SChicago Duan { 469bb895cb8SChicago Duan for (const auto& [sensorPath, occId] : existingSensors) 470bb895cb8SChicago Duan { 471bb895cb8SChicago Duan if (occId == id) 472bb895cb8SChicago Duan { 473bb895cb8SChicago Duan open_power::occ::dbus::OccDBusSensors::getOccDBus().setValue( 474bb895cb8SChicago Duan sensorPath, std::numeric_limits<double>::quiet_NaN()); 475bb895cb8SChicago Duan } 476bb895cb8SChicago Duan } 477bb895cb8SChicago Duan return; 478bb895cb8SChicago Duan } 479bb895cb8SChicago Duan 480bb895cb8SChicago Duan void Manager::getSensorValues(uint32_t id, bool masterOcc) 481bb895cb8SChicago Duan { 482bb895cb8SChicago Duan const auto occ = std::string("occ-hwmon.") + std::to_string(id + 1); 483bb895cb8SChicago Duan 484bb895cb8SChicago Duan fs::path fileName{OCC_HWMON_PATH + occ + "/hwmon/"}; 485bb895cb8SChicago Duan 486bb895cb8SChicago Duan // Need to get the hwmonXX directory name, there better only be 1 dir 487bb895cb8SChicago Duan assert(std::distance(fs::directory_iterator(fileName), 488bb895cb8SChicago Duan fs::directory_iterator{}) == 1); 489bb895cb8SChicago Duan // Now set our path to this full path, including this hwmonXX directory 490bb895cb8SChicago Duan fileName = fs::path(*fs::directory_iterator(fileName)); 491bb895cb8SChicago Duan 492bb895cb8SChicago Duan // Read temperature sensors 493bb895cb8SChicago Duan readTempSensors(fileName, id); 494bb895cb8SChicago Duan 495bb895cb8SChicago Duan if (masterOcc) 496bb895cb8SChicago Duan { 497bb895cb8SChicago Duan // Read power sensors 498bb895cb8SChicago Duan readPowerSensors(fileName, id); 499bb895cb8SChicago Duan } 500bb895cb8SChicago Duan 501bb895cb8SChicago Duan return; 502bb895cb8SChicago Duan } 503bb895cb8SChicago Duan #endif 504bb895cb8SChicago Duan 505dfc7ec73SVishwanatha Subbanna } // namespace occ 506dfc7ec73SVishwanatha Subbanna } // namespace open_power 507