#include "eeprom_device_software_manager.hpp" #include "common/include/dbus_helper.hpp" #include "eeprom_device.hpp" #include #include #include #include #include #include PHOSPHOR_LOG2_USING; namespace SoftwareInf = phosphor::software; const std::vector emConfigTypes = {"PT5161LFirmware"}; void EEPROMDeviceSoftwareManager::start() { std::vector configIntfs; configIntfs.reserve(emConfigTypes.size()); std::transform(emConfigTypes.begin(), emConfigTypes.end(), std::back_inserter(configIntfs), [](const std::string& type) { return "xyz.openbmc_project.Configuration." + type; }); ctx.spawn(initDevices(configIntfs)); ctx.run(); } sdbusplus::async::task EEPROMDeviceSoftwareManager::initDevice( const std::string& service, const std::string& path, SoftwareConfig& config) { const std::string configIface = "xyz.openbmc_project.Configuration." + config.configType; std::optional bus = co_await dbusGetRequiredProperty( ctx, service, path, configIface, "Bus"); std::optional address = co_await dbusGetRequiredProperty(ctx, service, path, configIface, "Address"); std::optional type = co_await dbusGetRequiredProperty(ctx, service, path, configIface, "Type"); std::optional fwDevice = co_await dbusGetRequiredProperty( ctx, service, path, configIface, "FirmwareDevice"); if (!bus.has_value() || !address.has_value() || !type.has_value() || !fwDevice.has_value()) { error("Missing EEPROM device config property"); co_return false; } debug("EEPROM Device: Bus={BUS}, Address={ADDR}, Type={TYPE}, " "Firmware Device={DEVICE}", "BUS", bus.value(), "ADDR", address.value(), "TYPE", type.value(), "DEVICE", fwDevice.value()); std::unique_ptr deviceVersion = getVersionProvider(type.value(), bus.value(), address.value()); if (!deviceVersion) { error("Failed to get version provider for chip type: {CHIP}", "CHIP", type.value()); co_return false; } std::string version = deviceVersion->getVersion(); using ObjectMapper = sdbusplus::client::xyz::openbmc_project::ObjectMapper<>; auto mapper = ObjectMapper(ctx) .service(ObjectMapper::default_service) .path(ObjectMapper::instance_path); auto res = co_await mapper.get_sub_tree("/xyz/openbmc_project/inventory", 0, {}); bus.reset(); address.reset(); type.reset(); for (auto& [p, v] : res) { if (!p.ends_with(fwDevice.value())) { continue; } for (auto& [s, ifaces] : v) { for (std::string& iface : ifaces) { if (iface.starts_with("xyz.openbmc_project.Configuration.")) { bus = co_await dbusGetRequiredProperty( ctx, s, p, iface, "Bus"); address = co_await dbusGetRequiredProperty( ctx, s, p, iface, "Address"); type = co_await dbusGetRequiredProperty( ctx, s, p, iface, "Type"); break; } } if (bus.has_value() && address.has_value() && type.has_value()) { break; } } break; } if (!bus.has_value() || !address.has_value() || !type.has_value()) { error("Missing EEPROM config property"); co_return false; } debug("EEPROM: Bus={BUS}, Address={ADDR}, Type={TYPE}", "BUS", bus.value(), "ADDR", address.value(), "TYPE", type.value()); const std::string configIfaceMux = configIface + ".MuxOutputs"; std::vector gpioLines; std::vector gpioPolarities; for (size_t i = 0; true; i++) { const std::string iface = configIfaceMux + std::to_string(i); std::optional name = co_await dbusGetRequiredProperty(ctx, service, path, iface, "Name"); std::optional polarity = co_await dbusGetRequiredProperty(ctx, service, path, iface, "Polarity"); if (!name.has_value() || !polarity.has_value()) { break; } gpioLines.push_back(name.value()); gpioPolarities.push_back(polarity.value() == "High"); } for (size_t i = 0; i < gpioLines.size(); i++) { debug("Mux gpio {NAME} polarity = {VALUE}", "NAME", gpioLines[i], "VALUE", gpioPolarities[i]); } auto eepromDevice = std::make_unique( ctx, static_cast(bus.value()), static_cast(address.value()), type.value(), gpioLines, gpioPolarities, std::move(deviceVersion), config, this); std::unique_ptr software = std::make_unique(ctx, *eepromDevice); software->setVersion(version.empty() ? "Unknown" : version, SoftwareInf::SoftwareVersion::VersionPurpose::Other); std::set allowedApplyTimes = { RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset}; software->enableUpdate(allowedApplyTimes); eepromDevice->softwareCurrent = std::move(software); devices.insert({config.objectPath, std::move(eepromDevice)}); co_return true; } int main() { sdbusplus::async::context ctx; EEPROMDeviceSoftwareManager eepromDeviceSoftwareManager(ctx); eepromDeviceSoftwareManager.start(); return 0; }