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