xref: /openbmc/phosphor-bmc-code-mgmt/i2c-vr/i2cvr_software_manager.cpp (revision 7e446a407a579ec72f48009008ad2f83c01c2262)
1*7e446a40SChristopher Meis #include "i2cvr_software_manager.hpp"
2*7e446a40SChristopher Meis 
3*7e446a40SChristopher Meis #include "common/include/dbus_helper.hpp"
4*7e446a40SChristopher Meis #include "common/include/software_manager.hpp"
5*7e446a40SChristopher Meis #include "i2cvr_device.hpp"
6*7e446a40SChristopher Meis #include "vr.hpp"
7*7e446a40SChristopher Meis 
8*7e446a40SChristopher Meis #include <phosphor-logging/lg2.hpp>
9*7e446a40SChristopher Meis #include <sdbusplus/async.hpp>
10*7e446a40SChristopher Meis #include <sdbusplus/bus.hpp>
11*7e446a40SChristopher Meis #include <xyz/openbmc_project/ObjectMapper/client.hpp>
12*7e446a40SChristopher Meis 
13*7e446a40SChristopher Meis #include <cstdint>
14*7e446a40SChristopher Meis 
15*7e446a40SChristopher Meis PHOSPHOR_LOG2_USING;
16*7e446a40SChristopher Meis 
17*7e446a40SChristopher Meis namespace VR = phosphor::software::VR;
18*7e446a40SChristopher Meis namespace I2CDevice = phosphor::software::i2c_vr::device;
19*7e446a40SChristopher Meis namespace SoftwareInf = phosphor::software;
20*7e446a40SChristopher Meis namespace ManagerInf = phosphor::software::manager;
21*7e446a40SChristopher Meis 
22*7e446a40SChristopher Meis const std::string configDBusName = "I2CVR";
23*7e446a40SChristopher Meis const std::vector<std::string> emConfigTypes = {"XDPE1X2XXFirmware",
24*7e446a40SChristopher Meis                                                 "DummyDeviceFirmware"};
25*7e446a40SChristopher Meis 
26*7e446a40SChristopher Meis I2CVRSoftwareManager::I2CVRSoftwareManager(sdbusplus::async::context& ctx) :
27*7e446a40SChristopher Meis     ManagerInf::SoftwareManager(ctx, configDBusName)
28*7e446a40SChristopher Meis {}
29*7e446a40SChristopher Meis 
30*7e446a40SChristopher Meis void I2CVRSoftwareManager::start()
31*7e446a40SChristopher Meis {
32*7e446a40SChristopher Meis     std::vector<std::string> configIntfs;
33*7e446a40SChristopher Meis     configIntfs.reserve(emConfigTypes.size());
34*7e446a40SChristopher Meis     for (auto& name : emConfigTypes)
35*7e446a40SChristopher Meis     {
36*7e446a40SChristopher Meis         configIntfs.push_back("xyz.openbmc_project.Configuration." + name);
37*7e446a40SChristopher Meis     }
38*7e446a40SChristopher Meis 
39*7e446a40SChristopher Meis     ctx.spawn(initDevices(configIntfs));
40*7e446a40SChristopher Meis     ctx.run();
41*7e446a40SChristopher Meis }
42*7e446a40SChristopher Meis 
43*7e446a40SChristopher Meis // NOLINTBEGIN(readability-static-accessed-through-instance)
44*7e446a40SChristopher Meis sdbusplus::async::task<bool> I2CVRSoftwareManager::initDevice(
45*7e446a40SChristopher Meis     const std::string& service, const std::string& path, SoftwareConfig& config)
46*7e446a40SChristopher Meis // NOLINTEND(readability-static-accessed-through-instance)
47*7e446a40SChristopher Meis {
48*7e446a40SChristopher Meis     std::string configIface =
49*7e446a40SChristopher Meis         "xyz.openbmc_project.Configuration." + config.configType;
50*7e446a40SChristopher Meis 
51*7e446a40SChristopher Meis     std::optional<uint64_t> busNum = co_await dbusGetRequiredProperty<uint64_t>(
52*7e446a40SChristopher Meis         ctx, service, path, configIface, "Bus");
53*7e446a40SChristopher Meis     std::optional<uint64_t> address =
54*7e446a40SChristopher Meis         co_await dbusGetRequiredProperty<uint64_t>(ctx, service, path,
55*7e446a40SChristopher Meis                                                    configIface, "Address");
56*7e446a40SChristopher Meis     std::optional<std::string> vrChipType =
57*7e446a40SChristopher Meis         co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
58*7e446a40SChristopher Meis                                                       configIface, "Type");
59*7e446a40SChristopher Meis 
60*7e446a40SChristopher Meis     if (!busNum.has_value() || !address.has_value() || !vrChipType.has_value())
61*7e446a40SChristopher Meis     {
62*7e446a40SChristopher Meis         error("missing config property");
63*7e446a40SChristopher Meis         co_return false;
64*7e446a40SChristopher Meis     }
65*7e446a40SChristopher Meis 
66*7e446a40SChristopher Meis     VR::VRType vrType;
67*7e446a40SChristopher Meis     if (!VR::stringToEnum(vrChipType.value(), vrType))
68*7e446a40SChristopher Meis     {
69*7e446a40SChristopher Meis         error("unknown voltage regulator type: {TYPE}", "TYPE",
70*7e446a40SChristopher Meis               vrChipType.value());
71*7e446a40SChristopher Meis         co_return false;
72*7e446a40SChristopher Meis     }
73*7e446a40SChristopher Meis 
74*7e446a40SChristopher Meis     lg2::debug(
75*7e446a40SChristopher Meis         "[config] Voltage regulator device type: {TYPE} on Bus: {BUS} at Address: {ADDR}",
76*7e446a40SChristopher Meis         "TYPE", vrChipType.value(), "BUS", busNum.value(), "ADDR",
77*7e446a40SChristopher Meis         address.value());
78*7e446a40SChristopher Meis 
79*7e446a40SChristopher Meis     auto i2cDevice = std::make_unique<I2CDevice::I2CVRDevice>(
80*7e446a40SChristopher Meis         ctx, vrType, static_cast<uint16_t>(busNum.value()),
81*7e446a40SChristopher Meis         static_cast<uint16_t>(address.value()), config, this);
82*7e446a40SChristopher Meis 
83*7e446a40SChristopher Meis     std::unique_ptr<SoftwareInf::Software> software =
84*7e446a40SChristopher Meis         std::make_unique<SoftwareInf::Software>(ctx, *i2cDevice);
85*7e446a40SChristopher Meis 
86*7e446a40SChristopher Meis     uint32_t sum;
87*7e446a40SChristopher Meis     if (!(co_await i2cDevice->getVersion(&sum)))
88*7e446a40SChristopher Meis     {
89*7e446a40SChristopher Meis         error("unable to obtain Version/CRC from voltage regulator");
90*7e446a40SChristopher Meis         co_return false;
91*7e446a40SChristopher Meis     }
92*7e446a40SChristopher Meis 
93*7e446a40SChristopher Meis     software->setVersion(std::to_string(sum));
94*7e446a40SChristopher Meis 
95*7e446a40SChristopher Meis     std::set<RequestedApplyTimes> allowedApplyTime = {
96*7e446a40SChristopher Meis         RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset};
97*7e446a40SChristopher Meis 
98*7e446a40SChristopher Meis     software->enableUpdate(allowedApplyTime);
99*7e446a40SChristopher Meis 
100*7e446a40SChristopher Meis     i2cDevice->softwareCurrent = std::move(software);
101*7e446a40SChristopher Meis 
102*7e446a40SChristopher Meis     devices.insert({config.objectPath, std::move(i2cDevice)});
103*7e446a40SChristopher Meis 
104*7e446a40SChristopher Meis     co_return true;
105*7e446a40SChristopher Meis }
106*7e446a40SChristopher Meis 
107*7e446a40SChristopher Meis int main()
108*7e446a40SChristopher Meis {
109*7e446a40SChristopher Meis     sdbusplus::async::context ctx;
110*7e446a40SChristopher Meis 
111*7e446a40SChristopher Meis     I2CVRSoftwareManager i2cVRSoftwareManager(ctx);
112*7e446a40SChristopher Meis 
113*7e446a40SChristopher Meis     i2cVRSoftwareManager.start();
114*7e446a40SChristopher Meis     return 0;
115*7e446a40SChristopher Meis }
116