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