blob: 1183ea1f79784224c9f4223d3949f3507d8aec08 [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 Hansen7fbe7d82025-05-28 17:04:23 +020050 enum FlashTool tool = flashToolNone;
51
52 if (config.configType == "IntelSPIFlash")
53 {
54 tool = flashToolFlashrom;
55 }
Alexander Hansen5db0c6b2025-05-30 11:21:30 +020056 else if (config.configType == "SPIFlash")
57 {
58 tool = flashToolFlashcp;
59 }
Alexander Hansen7fbe7d82025-05-28 17:04:23 +020060
Alexander Hansenf2c95a02024-11-26 11:16:44 +010061 const std::string configIfaceMux = configIface + ".MuxOutputs";
62
63 std::vector<std::string> names;
64 std::vector<uint64_t> values;
65
66 for (size_t i = 0; true; i++)
67 {
68 const std::string iface = configIfaceMux + std::to_string(i);
69
70 std::optional<std::string> name =
71 co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
72 iface, "Name");
73
74 std::optional<std::string> polarity =
75 co_await dbusGetRequiredProperty<std::string>(ctx, service, path,
76 iface, "Polarity");
77
78 if (!name.has_value() || !polarity.has_value())
79 {
80 break;
81 }
82
83 names.push_back(name.value());
84 values.push_back((polarity == "High") ? 1 : 0);
85 }
86
Alexander Hansenf2c95a02024-11-26 11:16:44 +010087 enum FlashLayout layout = flashLayoutFlat;
Alexander Hansenf2c95a02024-11-26 11:16:44 +010088
89 debug("SPI device: {INDEX1}:{INDEX2}", "INDEX1", spiControllerIndex.value(),
90 "INDEX2", spiDeviceIndex.value());
91
92 std::unique_ptr<SPIDevice> spiDevice;
93 try
94 {
95 spiDevice = std::make_unique<SPIDevice>(
96 ctx, spiControllerIndex.value(), spiDeviceIndex.value(), dryRun,
97 names, values, config, this, layout, tool);
98 }
99 catch (std::exception& e)
100 {
101 co_return false;
102 }
103
104 std::unique_ptr<Software> software =
105 std::make_unique<Software>(ctx, *spiDevice);
106
107 // enable this software to be updated
108 std::set<RequestedApplyTimes> allowedApplyTimes = {
109 RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset};
110
111 software->enableUpdate(allowedApplyTimes);
112
113 spiDevice->softwareCurrent = std::move(software);
114
115 spiDevice->softwareCurrent->setVersion(SPIDevice::getVersion());
116
117 devices.insert({config.objectPath, std::move(spiDevice)});
118
119 co_return true;
120}