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 sdbusplus::async::task<bool> BIOSSoftwareManager::initDevice( 23 const std::string& service, const std::string& path, SoftwareConfig& config) 24 { 25 std::string configIface = 26 "xyz.openbmc_project.Configuration." + config.configType; 27 28 std::optional<uint64_t> spiControllerIndex = 29 co_await dbusGetRequiredProperty<uint64_t>( 30 ctx, service, path, configIface, "SPIControllerIndex"); 31 32 if (!spiControllerIndex.has_value()) 33 { 34 error("Missing property: SPIControllerIndex"); 35 co_return false; 36 } 37 38 std::optional<uint64_t> spiDeviceIndex = 39 co_await dbusGetRequiredProperty<uint64_t>( 40 ctx, service, path, configIface, "SPIDeviceIndex"); 41 42 if (!spiDeviceIndex.has_value()) 43 { 44 error("Missing property: SPIDeviceIndex"); 45 co_return false; 46 } 47 48 enum FlashTool tool = flashToolNone; 49 50 if (config.configType == "IntelSPIFlash") 51 { 52 tool = flashToolFlashrom; 53 } 54 else if (config.configType == "SPIFlash") 55 { 56 tool = flashToolFlashcp; 57 } 58 59 const std::string configIfaceMux = configIface + ".MuxOutputs"; 60 61 std::vector<std::string> names; 62 std::vector<uint64_t> values; 63 64 for (size_t i = 0; true; i++) 65 { 66 const std::string iface = configIfaceMux + std::to_string(i); 67 68 std::optional<std::string> name = 69 co_await dbusGetRequiredProperty<std::string>(ctx, service, path, 70 iface, "Name"); 71 72 std::optional<std::string> polarity = 73 co_await dbusGetRequiredProperty<std::string>(ctx, service, path, 74 iface, "Polarity"); 75 76 if (!name.has_value() || !polarity.has_value()) 77 { 78 break; 79 } 80 81 names.push_back(name.value()); 82 values.push_back((polarity == "High") ? 1 : 0); 83 } 84 85 enum FlashLayout layout = flashLayoutFlat; 86 87 debug("SPI device: {INDEX1}:{INDEX2}", "INDEX1", spiControllerIndex.value(), 88 "INDEX2", spiDeviceIndex.value()); 89 90 std::unique_ptr<SPIDevice> spiDevice; 91 try 92 { 93 spiDevice = std::make_unique<SPIDevice>( 94 ctx, spiControllerIndex.value(), spiDeviceIndex.value(), dryRun, 95 names, values, config, this, layout, tool); 96 } 97 catch (std::exception& e) 98 { 99 co_return false; 100 } 101 102 std::unique_ptr<Software> software = 103 std::make_unique<Software>(ctx, *spiDevice); 104 105 // enable this software to be updated 106 std::set<RequestedApplyTimes> allowedApplyTimes = { 107 RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset}; 108 109 software->enableUpdate(allowedApplyTimes); 110 111 spiDevice->softwareCurrent = std::move(software); 112 113 spiDevice->softwareCurrent->setVersion(SPIDevice::getVersion()); 114 115 devices.insert({config.objectPath, std::move(spiDevice)}); 116 117 co_return true; 118 } 119