blob: 163c8274427be3c27865ed59b81ccdd4745becc4 [file] [log] [blame]
Alexander Hansenf2c95a02024-11-26 11:16:44 +01001#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
13using namespace phosphor::software;
14
15PHOSPHOR_LOG2_USING;
16
17BIOSSoftwareManager::BIOSSoftwareManager(sdbusplus::async::context& ctx,
18 bool isDryRun) :
19 SoftwareManager(ctx, configTypeBIOS), dryRun(isDryRun)
20{}
21
22// NOLINTBEGIN(readability-static-accessed-through-instance)
23sdbusplus::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
Alexander Hansenfc4a9742025-04-10 16:44:59 +020030 std::optional<uint64_t> spiControllerIndex =
Alexander Hansenf2c95a02024-11-26 11:16:44 +010031 co_await dbusGetRequiredProperty<uint64_t>(
32 ctx, service, path, configIface, "SPIControllerIndex");
33
Alexander Hansenfc4a9742025-04-10 16:44:59 +020034 if (!spiControllerIndex.has_value())
35 {
36 error("Missing property: SPIControllerIndex");
37 co_return false;
38 }
39
40 std::optional<uint64_t> spiDeviceIndex =
Alexander Hansenf2c95a02024-11-26 11:16:44 +010041 co_await dbusGetRequiredProperty<uint64_t>(
42 ctx, service, path, configIface, "SPIDeviceIndex");
43
Alexander Hansenfc4a9742025-04-10 16:44:59 +020044 if (!spiDeviceIndex.has_value())
45 {
46 error("Missing property: SPIDeviceIndex");
47 co_return false;
48 }
49
Alexander Hansenf2c95a02024-11-26 11:16:44 +010050 const std::string configIfaceMux = configIface + ".MuxOutputs";
51
52 std::vector<std::string> names;
53 std::vector<uint64_t> values;
54
55 for (size_t i = 0; true; i++)
56 {
57 const std::string iface = configIfaceMux + std::to_string(i);
58
59 std::optional<std::string> name =
60 co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
61 iface, "Name");
62
63 std::optional<std::string> polarity =
64 co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
65 iface, "Polarity");
66
67 if (!name.has_value() || !polarity.has_value())
68 {
69 break;
70 }
71
72 names.push_back(name.value());
73 values.push_back((polarity == "High") ? 1 : 0);
74 }
75
Alexander Hansenf2c95a02024-11-26 11:16:44 +010076 enum FlashLayout layout = flashLayoutFlat;
77 enum FlashTool tool = flashToolNone;
78
79 debug("SPI device: {INDEX1}:{INDEX2}", "INDEX1", spiControllerIndex.value(),
80 "INDEX2", spiDeviceIndex.value());
81
82 std::unique_ptr<SPIDevice> spiDevice;
83 try
84 {
85 spiDevice = std::make_unique<SPIDevice>(
86 ctx, spiControllerIndex.value(), spiDeviceIndex.value(), dryRun,
87 names, values, config, this, layout, tool);
88 }
89 catch (std::exception& e)
90 {
91 co_return false;
92 }
93
94 std::unique_ptr<Software> software =
95 std::make_unique<Software>(ctx, *spiDevice);
96
97 // enable this software to be updated
98 std::set<RequestedApplyTimes> allowedApplyTimes = {
99 RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset};
100
101 software->enableUpdate(allowedApplyTimes);
102
103 spiDevice->softwareCurrent = std::move(software);
104
105 spiDevice->softwareCurrent->setVersion(SPIDevice::getVersion());
106
107 devices.insert({config.objectPath, std::move(spiDevice)});
108
109 co_return true;
110}