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