fw update: common code
new daemons to implement the flow as described in
https://github.com/openbmc/docs/blob/master/designs/code-update.md
- common/
common code folder
- common update flow
- base class for the device specific update daemons
The new daemons are all following the generic template of Code Updater
daemon as outlined in the design.
The idea is that they are separate daemons (per device, as outlined in
the design) but share all the code that's not device specific.
Tested: next patch in series
Change-Id: If2438b8506aceb8c5313ec13a0bf7cb68f3cc279
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/common/include/device.hpp b/common/include/device.hpp
new file mode 100644
index 0000000..56fc920
--- /dev/null
+++ b/common/include/device.hpp
@@ -0,0 +1,123 @@
+#pragma once
+
+#include "common/pldm/package_parser.hpp"
+#include "software.hpp"
+#include "software_config.hpp"
+
+#include <sdbusplus/async/context.hpp>
+#include <xyz/openbmc_project/Association/Definitions/aserver.hpp>
+#include <xyz/openbmc_project/Software/Activation/aserver.hpp>
+#include <xyz/openbmc_project/Software/Update/aserver.hpp>
+#include <xyz/openbmc_project/Software/Version/aserver.hpp>
+
+#include <string>
+
+using ActivationInterface =
+ sdbusplus::common::xyz::openbmc_project::software::Activation;
+
+namespace phosphor::software::manager
+{
+class SoftwareManager;
+};
+
+namespace phosphor::software::device
+{
+
+class Device
+{
+ public:
+ Device(sdbusplus::async::context& ctx,
+ const phosphor::software::config::SoftwareConfig& deviceConfig,
+ phosphor::software::manager::SoftwareManager* parent,
+ std::set<RequestedApplyTimes> allowedApplyTimes);
+
+ virtual ~Device() = default;
+ Device(const Device&) = delete;
+ Device& operator=(const Device&) = delete;
+ Device(Device&&) = delete;
+ Device& operator=(Device&&) = delete;
+
+ // @brief Applies the image to the device
+ // @param image raw fw image without pldm header
+ // @param image_size size of 'image'
+ // @returns true if update was applied successfully.
+ // Should also return true if update was applied
+ // successfully, but the host failed to power
+ // on.
+ virtual sdbusplus::async::task<bool> updateDevice(const uint8_t* image,
+ size_t image_size) = 0;
+
+ // @brief Set the ActivationProgress properties on dbus
+ // @param progress progress value
+ // @returns true on successful property update
+ bool setUpdateProgress(uint8_t progress) const;
+
+ // @brief This coroutine is spawned to perform the
+ // async update of the device.
+ // @param image The memory fd with the pldm package
+ // @param applyTime When the update should be applied
+ // @param swid The software id to use
+ // @returns true if update was successfull
+ sdbusplus::async::task<bool> startUpdateAsync(
+ sdbusplus::message::unix_fd image, RequestedApplyTimes applyTime,
+ std::unique_ptr<Software> softwareUpdateExternal);
+
+ // Value of 'Type' field for the configuration in EM exposes record
+ std::string getEMConfigType() const;
+
+ protected:
+ // The apply times for updates which are supported by the device
+ // Override this if your device deviates from the default set of apply
+ // times.
+ std::set<RequestedApplyTimes> allowedApplyTimes;
+
+ // software instance, identified by its swid
+ // The specific derived class also owns its dbus interfaces,
+ // which are destroyed when the instance is deleted.
+ std::unique_ptr<Software> softwareCurrent;
+
+ // In case of apply time == OnReset, this contains the software version
+ // which has been written to the device, or should be written to it,
+ // but is not active yet.
+ std::unique_ptr<Software> softwarePending;
+
+ // Resets the device, in whichever way is appropriate for the device.
+ // The reset must be capable to apply the firmware update which was done
+ // by 'deviceSpecificUpdateFunction', in case that function did not already
+ // apply it. This method is optional to implement for that reason.
+ virtual sdbusplus::async::task<bool> resetDevice();
+
+ // The common configuration that all devices share.
+ // We get this from EM configuration.
+ config::SoftwareConfig config;
+
+ manager::SoftwareManager* parent;
+
+ sdbusplus::async::context& ctx;
+
+ private:
+ bool updateInProgress = false;
+
+ // @param componentImage component image as extracted from update pkg
+ // @param componentImageSize size of 'componentImage'
+ // @param applyTime when the update should be applied
+ // @param softwarePendingIn the pending software instance
+ // @returns the return value of the device specific
+ // update function
+ sdbusplus::async::task<bool> continueUpdateWithMappedPackage(
+ const uint8_t* componentImage, size_t componentImageSize,
+ const std::string& componentVersion, RequestedApplyTimes applyTime,
+ const std::unique_ptr<Software>& softwarePendingIn);
+
+ // @brief extracts the information we need from the pldm package
+ // @returns true on success
+ sdbusplus::async::task<bool> getImageInfo(
+ std::unique_ptr<void, std::function<void(void*)>>& pldmPackage,
+ size_t pldmPackageSize, uint8_t** matchingComponentImage,
+ size_t* componentImageSize, std::string& componentVersion);
+
+ friend update::SoftwareUpdate;
+ friend Software;
+};
+
+}; // namespace phosphor::software::device