xref: /openbmc/phosphor-bmc-code-mgmt/bios/bios_software_manager.cpp (revision bd5081f0b99a27dde8101576524b2c02a4a580b6)
1f2c95a08SAlexander Hansen #include "bios_software_manager.hpp"
2f2c95a08SAlexander Hansen 
3f2c95a08SAlexander Hansen #include "common/include/dbus_helper.hpp"
4f2c95a08SAlexander Hansen #include "common/include/software_manager.hpp"
5f2c95a08SAlexander Hansen #include "spi_device.hpp"
6f2c95a08SAlexander Hansen 
7f2c95a08SAlexander Hansen #include <gpiod.hpp>
8f2c95a08SAlexander Hansen #include <phosphor-logging/lg2.hpp>
9f2c95a08SAlexander Hansen #include <sdbusplus/async.hpp>
10f2c95a08SAlexander Hansen #include <sdbusplus/bus.hpp>
11f2c95a08SAlexander Hansen #include <xyz/openbmc_project/ObjectMapper/client.hpp>
12f2c95a08SAlexander Hansen 
13f2c95a08SAlexander Hansen using namespace phosphor::software;
14f2c95a08SAlexander Hansen 
15f2c95a08SAlexander Hansen PHOSPHOR_LOG2_USING;
16f2c95a08SAlexander Hansen 
BIOSSoftwareManager(sdbusplus::async::context & ctx,bool isDryRun)17f2c95a08SAlexander Hansen BIOSSoftwareManager::BIOSSoftwareManager(sdbusplus::async::context& ctx,
18f2c95a08SAlexander Hansen                                          bool isDryRun) :
19f2c95a08SAlexander Hansen     SoftwareManager(ctx, configTypeBIOS), dryRun(isDryRun)
20f2c95a08SAlexander Hansen {}
21f2c95a08SAlexander Hansen 
initDevice(const std::string & service,const std::string & path,SoftwareConfig & config)22f2c95a08SAlexander Hansen sdbusplus::async::task<bool> BIOSSoftwareManager::initDevice(
23f2c95a08SAlexander Hansen     const std::string& service, const std::string& path, SoftwareConfig& config)
24f2c95a08SAlexander Hansen {
25f2c95a08SAlexander Hansen     std::string configIface =
26f2c95a08SAlexander Hansen         "xyz.openbmc_project.Configuration." + config.configType;
27f2c95a08SAlexander Hansen 
28fc4a9741SAlexander Hansen     std::optional<uint64_t> spiControllerIndex =
29f2c95a08SAlexander Hansen         co_await dbusGetRequiredProperty<uint64_t>(
30f2c95a08SAlexander Hansen             ctx, service, path, configIface, "SPIControllerIndex");
31f2c95a08SAlexander Hansen 
32fc4a9741SAlexander Hansen     if (!spiControllerIndex.has_value())
33fc4a9741SAlexander Hansen     {
34fc4a9741SAlexander Hansen         error("Missing property: SPIControllerIndex");
35fc4a9741SAlexander Hansen         co_return false;
36fc4a9741SAlexander Hansen     }
37fc4a9741SAlexander Hansen 
38fc4a9741SAlexander Hansen     std::optional<uint64_t> spiDeviceIndex =
39f2c95a08SAlexander Hansen         co_await dbusGetRequiredProperty<uint64_t>(
40f2c95a08SAlexander Hansen             ctx, service, path, configIface, "SPIDeviceIndex");
41f2c95a08SAlexander Hansen 
42fc4a9741SAlexander Hansen     if (!spiDeviceIndex.has_value())
43fc4a9741SAlexander Hansen     {
44fc4a9741SAlexander Hansen         error("Missing property: SPIDeviceIndex");
45fc4a9741SAlexander Hansen         co_return false;
46fc4a9741SAlexander Hansen     }
47fc4a9741SAlexander Hansen 
487fbe7d82SAlexander Hansen     enum FlashTool tool = flashToolNone;
497fbe7d82SAlexander Hansen 
507fbe7d82SAlexander Hansen     if (config.configType == "IntelSPIFlash")
517fbe7d82SAlexander Hansen     {
527fbe7d82SAlexander Hansen         tool = flashToolFlashrom;
537fbe7d82SAlexander Hansen     }
54*5db0c6beSAlexander Hansen     else if (config.configType == "SPIFlash")
55*5db0c6beSAlexander Hansen     {
56*5db0c6beSAlexander Hansen         tool = flashToolFlashcp;
57*5db0c6beSAlexander Hansen     }
587fbe7d82SAlexander Hansen 
59f2c95a08SAlexander Hansen     const std::string configIfaceMux = configIface + ".MuxOutputs";
60f2c95a08SAlexander Hansen 
61f2c95a08SAlexander Hansen     std::vector<std::string> names;
62f2c95a08SAlexander Hansen     std::vector<uint64_t> values;
63f2c95a08SAlexander Hansen 
64f2c95a08SAlexander Hansen     for (size_t i = 0; true; i++)
65f2c95a08SAlexander Hansen     {
66f2c95a08SAlexander Hansen         const std::string iface = configIfaceMux + std::to_string(i);
67f2c95a08SAlexander Hansen 
68f2c95a08SAlexander Hansen         std::optional<std::string> name =
69f2c95a08SAlexander Hansen             co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
70f2c95a08SAlexander Hansen                                                           iface, "Name");
71f2c95a08SAlexander Hansen 
72f2c95a08SAlexander Hansen         std::optional<std::string> polarity =
73f2c95a08SAlexander Hansen             co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
74f2c95a08SAlexander Hansen                                                           iface, "Polarity");
75f2c95a08SAlexander Hansen 
76f2c95a08SAlexander Hansen         if (!name.has_value() || !polarity.has_value())
77f2c95a08SAlexander Hansen         {
78f2c95a08SAlexander Hansen             break;
79f2c95a08SAlexander Hansen         }
80f2c95a08SAlexander Hansen 
81f2c95a08SAlexander Hansen         names.push_back(name.value());
82f2c95a08SAlexander Hansen         values.push_back((polarity == "High") ? 1 : 0);
83f2c95a08SAlexander Hansen     }
84f2c95a08SAlexander Hansen 
85f2c95a08SAlexander Hansen     enum FlashLayout layout = flashLayoutFlat;
86f2c95a08SAlexander Hansen 
87f2c95a08SAlexander Hansen     debug("SPI device: {INDEX1}:{INDEX2}", "INDEX1", spiControllerIndex.value(),
88f2c95a08SAlexander Hansen           "INDEX2", spiDeviceIndex.value());
89f2c95a08SAlexander Hansen 
90f2c95a08SAlexander Hansen     std::unique_ptr<SPIDevice> spiDevice;
91f2c95a08SAlexander Hansen     try
92f2c95a08SAlexander Hansen     {
93f2c95a08SAlexander Hansen         spiDevice = std::make_unique<SPIDevice>(
94f2c95a08SAlexander Hansen             ctx, spiControllerIndex.value(), spiDeviceIndex.value(), dryRun,
95f2c95a08SAlexander Hansen             names, values, config, this, layout, tool);
96f2c95a08SAlexander Hansen     }
97f2c95a08SAlexander Hansen     catch (std::exception& e)
98f2c95a08SAlexander Hansen     {
99f2c95a08SAlexander Hansen         co_return false;
100f2c95a08SAlexander Hansen     }
101f2c95a08SAlexander Hansen 
102f2c95a08SAlexander Hansen     std::unique_ptr<Software> software =
103f2c95a08SAlexander Hansen         std::make_unique<Software>(ctx, *spiDevice);
104f2c95a08SAlexander Hansen 
105f2c95a08SAlexander Hansen     // enable this software to be updated
106f2c95a08SAlexander Hansen     std::set<RequestedApplyTimes> allowedApplyTimes = {
107f2c95a08SAlexander Hansen         RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset};
108f2c95a08SAlexander Hansen 
109f2c95a08SAlexander Hansen     software->enableUpdate(allowedApplyTimes);
110f2c95a08SAlexander Hansen 
111f2c95a08SAlexander Hansen     spiDevice->softwareCurrent = std::move(software);
112f2c95a08SAlexander Hansen 
113f2c95a08SAlexander Hansen     spiDevice->softwareCurrent->setVersion(SPIDevice::getVersion());
114f2c95a08SAlexander Hansen 
115f2c95a08SAlexander Hansen     devices.insert({config.objectPath, std::move(spiDevice)});
116f2c95a08SAlexander Hansen 
117f2c95a08SAlexander Hansen     co_return true;
118f2c95a08SAlexander Hansen }
119