#include "bios_software_manager.hpp" #include "common/include/dbus_helper.hpp" #include "common/include/software_manager.hpp" #include "spi_device.hpp" #include #include #include #include #include using namespace phosphor::software; PHOSPHOR_LOG2_USING; BIOSSoftwareManager::BIOSSoftwareManager(sdbusplus::async::context& ctx, bool isDryRun) : SoftwareManager(ctx, configTypeBIOS), dryRun(isDryRun) {} sdbusplus::async::task BIOSSoftwareManager::initDevice( const std::string& service, const std::string& path, SoftwareConfig& config) { std::string configIface = "xyz.openbmc_project.Configuration." + config.configType; std::optional spiControllerIndex = co_await dbusGetRequiredProperty( ctx, service, path, configIface, "SPIControllerIndex"); if (!spiControllerIndex.has_value()) { error("Missing property: SPIControllerIndex"); co_return false; } std::optional spiDeviceIndex = co_await dbusGetRequiredProperty( ctx, service, path, configIface, "SPIDeviceIndex"); if (!spiDeviceIndex.has_value()) { error("Missing property: SPIDeviceIndex"); co_return false; } enum FlashTool tool = flashToolNone; if (config.configType == "IntelSPIFlash") { tool = flashToolFlashrom; } else if (config.configType == "SPIFlash") { tool = flashToolFlashcp; } const std::string configIfaceMux = configIface + ".MuxOutputs"; std::vector names; std::vector values; 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; } names.push_back(name.value()); values.push_back((polarity == "High") ? 1 : 0); } enum FlashLayout layout = flashLayoutFlat; debug("SPI device: {INDEX1}:{INDEX2}", "INDEX1", spiControllerIndex.value(), "INDEX2", spiDeviceIndex.value()); std::unique_ptr spiDevice; try { spiDevice = std::make_unique( ctx, spiControllerIndex.value(), spiDeviceIndex.value(), dryRun, names, values, config, this, layout, tool); } catch (std::exception& e) { co_return false; } std::unique_ptr software = std::make_unique(ctx, *spiDevice); // enable this software to be updated std::set allowedApplyTimes = { RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset}; software->enableUpdate(allowedApplyTimes); spiDevice->softwareCurrent = std::move(software); spiDevice->softwareCurrent->setVersion( SPIDevice::getVersion(), SoftwareVersion::VersionPurpose::Host); devices.insert({config.objectPath, std::move(spiDevice)}); co_return true; }