blob: 8ead2a4c0252e5ca493d111c010f974885bf79bd [file] [log] [blame]
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +05301#include "config.h"
2
Gunnar Mills94df8c92018-09-14 14:50:03 -05003#include "occ_manager.hpp"
4
5#include "i2c_occ.hpp"
6#include "occ_finder.hpp"
7#include "utils.hpp"
8
9#include <experimental/filesystem>
10#include <phosphor-logging/elog-errors.hpp>
11#include <phosphor-logging/log.hpp>
12#include <xyz/openbmc_project/Common/error.hpp>
13
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053014namespace open_power
15{
16namespace occ
17{
18
19void Manager::findAndCreateObjects()
20{
Deepak Kodihalli370f06b2017-10-25 04:26:07 -050021 for (auto id = 0; id < MAX_CPUS; ++id)
22 {
Deepak Kodihalli30417a12017-12-04 00:54:01 -060023 // Create one occ per cpu
24 auto occ = std::string(OCC_NAME) + std::to_string(id);
25 createObjects(occ);
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053026 }
27}
28
29int Manager::cpuCreated(sdbusplus::message::message& msg)
30{
31 namespace fs = std::experimental::filesystem;
32
33 sdbusplus::message::object_path o;
34 msg.read(o);
35 fs::path cpuPath(std::string(std::move(o)));
36
37 auto name = cpuPath.filename().string();
38 auto index = name.find(CPU_NAME);
39 name.replace(index, std::strlen(CPU_NAME), OCC_NAME);
40
41 createObjects(name);
42
43 return 0;
44}
45
46void Manager::createObjects(const std::string& occ)
47{
48 auto path = fs::path(OCC_CONTROL_ROOT) / occ;
49
50 passThroughObjects.emplace_back(
Gunnar Mills94df8c92018-09-14 14:50:03 -050051 std::make_unique<PassThrough>(bus, path.c_str()));
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053052
Gunnar Mills94df8c92018-09-14 14:50:03 -050053 statusObjects.emplace_back(std::make_unique<Status>(
54 bus, event, path.c_str(), *this,
55 std::bind(std::mem_fn(&Manager::statusCallBack), this,
Tom Joseph00325232020-07-29 17:51:48 +053056 std::placeholders::_1)
57#ifdef PLDM
58 ,
59 std::bind(std::mem_fn(&pldm::Interface::resetOCC), pldmHandle.get(),
60 std::placeholders::_1)
61#endif
62 ));
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053063
64 // Create the power cap monitor object for master occ (0)
65 if (!pcap)
66 {
67 pcap = std::make_unique<open_power::occ::powercap::PowerCap>(
Gunnar Mills94df8c92018-09-14 14:50:03 -050068 bus, *statusObjects.front());
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053069 }
70}
71
72void Manager::statusCallBack(bool status)
73{
74 using namespace phosphor::logging;
Gunnar Mills94df8c92018-09-14 14:50:03 -050075 using InternalFailure =
76 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053077
78 // At this time, it won't happen but keeping it
79 // here just in case something changes in the future
80 if ((activeCount == 0) && (!status))
81 {
82 log<level::ERR>("Invalid update on OCCActive");
83 elog<InternalFailure>();
84 }
85
86 activeCount += status ? 1 : -1;
Eddie Jamesdae2d942017-12-20 10:50:03 -060087
88 // Only start presence detection if all the OCCs are bound
89 if (activeCount == statusObjects.size())
90 {
Gunnar Mills94df8c92018-09-14 14:50:03 -050091 for (auto& obj : statusObjects)
Eddie Jamesdae2d942017-12-20 10:50:03 -060092 {
93 obj->addPresenceWatchMaster();
94 }
95 }
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +053096}
97
98#ifdef I2C_OCC
99void Manager::initStatusObjects()
100{
101 // Make sure we have a valid path string
102 static_assert(sizeof(DEV_PATH) != 0);
103
104 auto deviceNames = i2c_occ::getOccHwmonDevices(DEV_PATH);
Lei YU41470e52017-11-30 16:03:50 +0800105 auto occMasterName = deviceNames.front();
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530106 for (auto& name : deviceNames)
107 {
108 i2c_occ::i2cToDbus(name);
Lei YUb5259a12017-09-01 16:22:40 +0800109 name = std::string(OCC_NAME) + '_' + name;
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530110 auto path = fs::path(OCC_CONTROL_ROOT) / name;
111 statusObjects.emplace_back(
Gunnar Mills94df8c92018-09-14 14:50:03 -0500112 std::make_unique<Status>(bus, event, path.c_str(), *this));
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530113 }
Lei YU41470e52017-11-30 16:03:50 +0800114 // The first device is master occ
115 pcap = std::make_unique<open_power::occ::powercap::PowerCap>(
Gunnar Mills94df8c92018-09-14 14:50:03 -0500116 bus, *statusObjects.front(), occMasterName);
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530117}
118#endif
119
Tom Joseph815f9f52020-07-27 12:12:13 +0530120#ifdef PLDM
121bool Manager::updateOCCActive(instanceID instance, bool status)
122{
123 return (statusObjects[instance])->occActive(status);
124}
125#endif
126
Vishwanatha Subbannadfc7ec72017-09-07 18:18:01 +0530127} // namespace occ
128} // namespace open_power