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