blob: 61a9fef84bc6b0227eff6044dc30344c3d368d05 [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
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}