From 21929dbc4fae5aa78be51ee389523f6cdb638759 Mon Sep 17 00:00:00 2001 From: "hliangs90" Date: Thu, 15 Aug 2024 13:11:23 +0800 Subject: [PATCH] Add CPLD Update for SoftWare Manager. Signed-off-by: hliangs90 --- activation.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++++ activation.hpp | 8 +++++ item_updater.cpp | 37 +++++++++++++++++++ item_updater.hpp | 19 ++++++++++ meson.build | 5 +++ meson_options.txt | 8 +++++ 6 files changed, 169 insertions(+) diff --git a/activation.cpp b/activation.cpp index d9ee2d0..f866461 100644 --- a/activation.cpp +++ b/activation.cpp @@ -143,6 +143,23 @@ auto Activation::activation(Activations value) -> Activations } #endif +#ifdef CPLD_UPGRADE + auto purposeTemp = parent.versions.find(versionId)->second->purpose(); + if (purposeTemp == VersionPurpose::CPLD) + { + // Enable systemd signals + subscribeToSystemdSignals(); + + // Set initial progress + activationProgress->progress(20); + + // Initiate image writing to flash + flashWriteCPLD(); + + return softwareServer::Activation::activation(value); + } +#endif + activationProgress->progress(10); parent.freeSpace(*this); @@ -318,6 +335,15 @@ void Activation::unitStateChange(sdbusplus::message_t& msg) } #endif +#ifdef CPLD_UPGRADE + auto purposeTemp = parent.versions.find(versionId)->second->purpose(); + if (purposeTemp == VersionPurpose::CPLD) + { + onStateChangesCPLD(msg); + return; + } +#endif + onStateChanges(msg); return; @@ -456,6 +482,72 @@ void Activation::onStateChangesBios(sdbusplus::message_t& msg) #endif +#ifdef CPLD_UPGRADE +void Activation::flashWriteCPLD() +{ + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "StartUnit"); + auto cpldServiceFile = "obmc-flash-cpld@" + versionId + ".service"; + method.append(cpldServiceFile, "replace"); + try + { + auto reply = bus.call(method); + } + catch (const sdbusplus::exception_t& e) + { + error("Error in trying to upgrade CPLD: {ERROR}", "ERROR", e); + report(); + } +} + +void Activation::onStateChangesCPLD(sdbusplus::message_t& msg) +{ + uint32_t newStateID{}; + sdbusplus::message::object_path newStateObjPath; + std::string newStateUnit{}; + std::string newStateResult{}; + + // Read the msg and populate each variable + msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult); + + auto cpldServiceFile = "obmc-flash-cpld@" + versionId + ".service"; + + if (newStateUnit == cpldServiceFile) + { + // unsubscribe to systemd signals + unsubscribeFromSystemdSignals(); + + if (newStateResult == "done") + { + // Set activation progress to 100 + activationProgress->progress(100); + + // Set Activation value to active + activation(softwareServer::Activation::Activations::Active); + + info("CPLD upgrade completed successfully."); + parent.cpldVersion->version( + parent.versions.find(versionId)->second->version()); + + // Delete the uploaded activation + boost::asio::post(getIOContext(), [this]() { + this->parent.erase(this->versionId); + }); + } + else if (newStateResult == "failed") + { + // Set Activation value to Failed + activation(softwareServer::Activation::Activations::Failed); + + error("CPLD upgrade failed."); + } + } + + return; +} + +#endif + void Activation::rebootBmc() { auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, diff --git a/activation.hpp b/activation.hpp index 94cc1bb..7d10472 100644 --- a/activation.hpp +++ b/activation.hpp @@ -247,6 +247,14 @@ class Activation : public ActivationInherit, public Flash void onStateChangesBios(sdbusplus::message_t&); #endif +#ifdef CPLD_UPGRADE + /* @brief write to CPLD flash function */ + void flashWriteCPLD(); + + /** @brief Function that acts on CPLD upgrade service file state changes */ + void onStateChangesCPLD(sdbusplus::message_t&); +#endif + /** @brief Overloaded function that acts on service file state changes */ void onStateChanges(sdbusplus::message_t&) override; diff --git a/item_updater.cpp b/item_updater.cpp index 5613a49..76f72d4 100644 --- a/item_updater.cpp +++ b/item_updater.cpp @@ -71,6 +71,9 @@ void ItemUpdater::createActivation(sdbusplus::message_t& msg) if (value == VersionPurpose::BMC || #ifdef HOST_BIOS_UPGRADE value == VersionPurpose::Host || +#endif +#ifdef CPLD_UPGRADE + value == VersionPurpose::CPLD || #endif value == VersionPurpose::System) { @@ -879,6 +882,40 @@ void ItemUpdater::createBIOSObject() } #endif +#ifdef CPLD_UPGRADE +void ItemUpdater::createCPLDObject() +{ + std::string path = CPLD_OBJPATH; + // Get version id from last item in the path + auto pos = path.rfind("/"); + if (pos == std::string::npos) + { + error("No version id found in object path {PATH}", "PATH", path); + return; + } + + createActiveAssociation(path); + createFunctionalAssociation(path); + + auto versionId = path.substr(pos + 1); + auto version = "null"; + AssociationList assocs = {}; + cpldActivation = std::make_unique( + bus, path, *this, versionId, server::Activation::Activations::Active, + assocs); + auto dummyErase = [](std::string /*entryId*/) { + // Do nothing; + }; + cpldVersion = std::make_unique( + bus, path, version, VersionPurpose::CPLD, "", "", + std::vector(), + std::bind(dummyErase, std::placeholders::_1), ""); + cpldVersion->deleteObject = + std::make_unique(bus, path, + *cpldVersion); +} +#endif + void ItemUpdater::getRunningSlot() { // Check /run/media/slot to get the slot number diff --git a/item_updater.hpp b/item_updater.hpp index c50d9de..26b657d 100644 --- a/item_updater.hpp +++ b/item_updater.hpp @@ -67,6 +67,9 @@ class ItemUpdater : public ItemUpdaterInherit restoreFieldModeStatus(); #ifdef HOST_BIOS_UPGRADE createBIOSObject(); +#endif +#ifdef CPLD_UPGRADE + createCPLDObject(); #endif emit_object_added(); }; @@ -280,6 +283,22 @@ class ItemUpdater : public ItemUpdaterInherit std::unique_ptr biosVersion; #endif +#ifdef CPLD_UPGRADE + /** @brief Create the CPLD object without knowing the version. + * + * The object is created only to provide the DBus access so that an + * external service could set the correct CPLD version. + * On CPLD code update, the version is updated accordingly. + */ + void createCPLDObject(); + + /** @brief Persistent Activation D-Bus object for CPLD */ + std::unique_ptr cpldActivation; + + public: + /** @brief Persistent Version D-Bus object for CPLD */ + std::unique_ptr cpldVersion; +#endif /** @brief Get the slot number of running image */ void getRunningSlot(); }; diff --git a/meson.build b/meson.build index 41adfde..509d9f7 100644 --- a/meson.build +++ b/meson.build @@ -67,6 +67,7 @@ conf.set('MMC_LAYOUT', get_option('bmc-layout').contains('mmc')) # Configurable features conf.set('HOST_BIOS_UPGRADE', get_option('host-bios-upgrade').enabled()) +conf.set('CPLD_UPGRADE', get_option('cpld-upgrade').enabled()) conf.set('WANT_SIGNATURE_VERIFY', \ get_option('verify-signature').enabled() or \ get_option('verify-full-signature').enabled()) @@ -96,6 +97,10 @@ if get_option('host-bios-upgrade').enabled() conf.set_quoted('BIOS_OBJPATH', get_option('bios-object-path')) endif +if get_option('cpld-upgrade').enabled() + conf.set_quoted('CPLD_OBJPATH', get_option('cpld-object-path')) +endif + if get_option('bmc-static-dual-image').enabled() conf.set('BMC_STATIC_DUAL_IMAGE', get_option('bmc-static-dual-image').enabled()) conf.set_quoted('ALT_ROFS_DIR', get_option('alt-rofs-dir')) diff --git a/meson_options.txt b/meson_options.txt index d14ed3b..d638c93 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -11,6 +11,8 @@ option('bmc-layout', type: 'combo', # Features option('host-bios-upgrade', type: 'feature', value: 'enabled', description: 'Enable host bios upgrade support.') +option('cpld-upgrade', type: 'feature', value: 'enabled', + description: 'Enable cpld upgrade support.') option('sync-bmc-files', type: 'feature', value: 'enabled', description: 'Enable sync of filesystem files.') @@ -121,6 +123,12 @@ option( description: 'The BIOS DBus object path.', ) +option( + 'cpld-object-path', type: 'string', + value: '/xyz/openbmc_project/software/cpld_active', + description: 'The CPLD DBus object path.', +) + option('bmc-static-dual-image', type: 'feature', value: 'enabled', description: 'Enable the dual image support for static layout.') -- 2.25.1