blob: 0c4814fd722e3d188708957904fb4eb5fb7649b6 [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
Alexander Hansenf2c95a02024-11-26 11:16:44 +010022sdbusplus::async::task<bool> BIOSSoftwareManager::initDevice(
23 const std::string& service, const std::string& path, SoftwareConfig& config)
Alexander Hansenf2c95a02024-11-26 11:16:44 +010024{
25 std::string configIface =
26 "xyz.openbmc_project.Configuration." + config.configType;
27
Alexander Hansenfc4a9742025-04-10 16:44:59 +020028 std::optional<uint64_t> spiControllerIndex =
Alexander Hansenf2c95a02024-11-26 11:16:44 +010029 co_await dbusGetRequiredProperty<uint64_t>(
30 ctx, service, path, configIface, "SPIControllerIndex");
31
Alexander Hansenfc4a9742025-04-10 16:44:59 +020032 if (!spiControllerIndex.has_value())
33 {
34 error("Missing property: SPIControllerIndex");
35 co_return false;
36 }
37
38 std::optional<uint64_t> spiDeviceIndex =
Alexander Hansenf2c95a02024-11-26 11:16:44 +010039 co_await dbusGetRequiredProperty<uint64_t>(
40 ctx, service, path, configIface, "SPIDeviceIndex");
41
Alexander Hansenfc4a9742025-04-10 16:44:59 +020042 if (!spiDeviceIndex.has_value())
43 {
44 error("Missing property: SPIDeviceIndex");
45 co_return false;
46 }
47
Alexander Hansen7fbe7d82025-05-28 17:04:23 +020048 enum FlashTool tool = flashToolNone;
49
50 if (config.configType == "IntelSPIFlash")
51 {
52 tool = flashToolFlashrom;
53 }
Alexander Hansen5db0c6b2025-05-30 11:21:30 +020054 else if (config.configType == "SPIFlash")
55 {
56 tool = flashToolFlashcp;
57 }
Alexander Hansen7fbe7d82025-05-28 17:04:23 +020058
Alexander Hansenf2c95a02024-11-26 11:16:44 +010059 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
Alexander Hansenf2c95a02024-11-26 11:16:44 +010085 enum FlashLayout layout = flashLayoutFlat;
Alexander Hansenf2c95a02024-11-26 11:16:44 +010086
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}