1 #include "bios_software_manager.hpp" 2 3 #include "common/include/dbus_helper.hpp" 4 #include "common/include/software_manager.hpp" 5 #include "spi_device.hpp" 6 7 #include <gpiod.hpp> 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 using namespace phosphor::software; 14 15 PHOSPHOR_LOG2_USING; 16 17 BIOSSoftwareManager::BIOSSoftwareManager(sdbusplus::async::context& ctx, 18 bool isDryRun) : 19 SoftwareManager(ctx, configTypeBIOS), dryRun(isDryRun) 20 {} 21 22 // NOLINTBEGIN(readability-static-accessed-through-instance) 23 sdbusplus::async::task<bool> BIOSSoftwareManager::initDevice( 24 const std::string& service, const std::string& path, SoftwareConfig& config) 25 // NOLINTEND(readability-static-accessed-through-instance) 26 { 27 std::string configIface = 28 "xyz.openbmc_project.Configuration." + config.configType; 29 30 std::optional<int64_t> spiControllerIndex = 31 co_await dbusGetRequiredProperty<uint64_t>( 32 ctx, service, path, configIface, "SPIControllerIndex"); 33 34 std::optional<int64_t> spiDeviceIndex = 35 co_await dbusGetRequiredProperty<uint64_t>( 36 ctx, service, path, configIface, "SPIDeviceIndex"); 37 38 const std::string configIfaceMux = configIface + ".MuxOutputs"; 39 40 std::vector<std::string> names; 41 std::vector<uint64_t> values; 42 43 for (size_t i = 0; true; i++) 44 { 45 const std::string iface = configIfaceMux + std::to_string(i); 46 47 std::optional<std::string> name = 48 co_await dbusGetRequiredProperty<std::string>(ctx, service, path, 49 iface, "Name"); 50 51 std::optional<std::string> polarity = 52 co_await dbusGetRequiredProperty<std::string>(ctx, service, path, 53 iface, "Polarity"); 54 55 if (!name.has_value() || !polarity.has_value()) 56 { 57 break; 58 } 59 60 names.push_back(name.value()); 61 values.push_back((polarity == "High") ? 1 : 0); 62 } 63 64 if (!spiControllerIndex.has_value() || !spiDeviceIndex.has_value()) 65 { 66 error("Error: Missing property"); 67 co_return false; 68 } 69 70 enum FlashLayout layout = flashLayoutFlat; 71 enum FlashTool tool = flashToolNone; 72 73 debug("SPI device: {INDEX1}:{INDEX2}", "INDEX1", spiControllerIndex.value(), 74 "INDEX2", spiDeviceIndex.value()); 75 76 std::unique_ptr<SPIDevice> spiDevice; 77 try 78 { 79 spiDevice = std::make_unique<SPIDevice>( 80 ctx, spiControllerIndex.value(), spiDeviceIndex.value(), dryRun, 81 names, values, config, this, layout, tool); 82 } 83 catch (std::exception& e) 84 { 85 co_return false; 86 } 87 88 std::unique_ptr<Software> software = 89 std::make_unique<Software>(ctx, *spiDevice); 90 91 // enable this software to be updated 92 std::set<RequestedApplyTimes> allowedApplyTimes = { 93 RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset}; 94 95 software->enableUpdate(allowedApplyTimes); 96 97 spiDevice->softwareCurrent = std::move(software); 98 99 spiDevice->softwareCurrent->setVersion(SPIDevice::getVersion()); 100 101 devices.insert({config.objectPath, std::move(spiDevice)}); 102 103 co_return true; 104 } 105