fw update: spi device code updater
This code updater is for updating spi flash devices.
It can for example update the host firmware on different server boards
and has following features:
- power down the host before update
- set mux gpios to access spi flash
- (very limited) communication with ME (Management Engine)
- use flashrom to utilize fw with IFD (Intel Flash Descriptor)
- otherwise directly write to the flash chip.
The behavior of this code updater can be configured via EM.
Tested: on Tyan S5549 Board
Change-Id: I27803b7fded71af2364c2f55fad841a410603dec
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/bios-spi/spi_device.hpp b/bios-spi/spi_device.hpp
new file mode 100644
index 0000000..f28c4ac
--- /dev/null
+++ b/bios-spi/spi_device.hpp
@@ -0,0 +1,102 @@
+#pragma once
+
+#include "common/include/device.hpp"
+#include "common/include/software_manager.hpp"
+
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/async/context.hpp>
+
+#include <string>
+
+class Software;
+
+class SPIDevice : public Device
+{
+ public:
+ SPIDevice(sdbusplus::async::context& ctx, const std::string& spiDevName,
+ bool dryRun, bool hasME,
+ const std::vector<std::string>& gpioLines,
+ const std::vector<uint8_t>& gpioValues, DeviceConfig& config,
+ SoftwareManager* parent, bool layoutFlat, bool toolFlashrom,
+ bool debug);
+
+ sdbusplus::async::task<bool> updateDevice(
+ const uint8_t* image, size_t image_size,
+ std::unique_ptr<SoftwareActivationProgress>& activationProgress) final;
+
+ sdbusplus::async::task<std::string> getInventoryItemObjectPath() final;
+
+ private:
+ // Management Engine specific members and functions
+ bool hasManagementEngine;
+ sdbusplus::async::task<> setManagementEngineRecoveryMode();
+ sdbusplus::async::task<> resetManagementEngine();
+
+ std::vector<std::string> gpioLines;
+ std::vector<uint8_t> gpioValues;
+
+ // SPI specific members and functions
+ std::string spiDev;
+
+ // does the spi flash have a flat layout?
+ // Otherwise, we have to use Intel Flash Descriptor
+ // or another descriptor to figure out which regions should be written
+ bool layoutFlat;
+
+ // do we use flashrom?
+ // if not, write directly to the mtd device.
+ bool toolFlashrom;
+
+ // @param spi_dev e.g. "1e630000.spi"
+ // @returns true on success
+ sdbusplus::async::task<bool> bindSPIFlash();
+
+ // @param spi_dev e.g. "1e630000.spi"
+ // @returns true on success
+ sdbusplus::async::task<bool> unbindSPIFlash();
+
+ // @param spi_dev e.g. "1e630000.spi"
+ bool isSPIFlashBound();
+
+ bool debug;
+
+ sdbusplus::async::task<bool> writeSPIFlash(
+ const uint8_t* image, size_t image_size,
+ const std::unique_ptr<SoftwareActivationProgress>& activationProgress);
+
+ // this function assumes:
+ // - host is powered off
+ sdbusplus::async::task<bool>
+ writeSPIFlashHostOff(const uint8_t* image, size_t image_size);
+
+ // this function assumes:
+ // - host is powered off
+ // - gpio / mux is set
+ sdbusplus::async::task<bool>
+ writeSPIFlashHostOffGPIOSet(const uint8_t* image, size_t image_size);
+
+ // this function assumes:
+ // - host is powered off
+ // - gpio / mux is set
+ // - spi device is bound to the driver
+ // we write the flat image here
+ // @param image the component image
+ // @param image_size size of 'image'
+ // @returns true on success
+ sdbusplus::async::task<bool> writeSPIFlashHostOffGPIOSetDeviceBound(
+ const uint8_t* image, size_t image_size);
+
+ // this function assumes:
+ // - host is powered off
+ // - gpio / mux is set
+ // - spi device is bound to the driver
+ // we use 'flashrom' here to write the image since it can deal with
+ // Intel Flash Descriptor
+ // TODO: look into using libflashrom instead
+ // @param image the component image
+ // @param image_size size of 'image'
+ // @returns true on success
+ sdbusplus::async::task<bool> writeSPIFlashFlashromHostOffGPIOSetDeviceBound(
+ const uint8_t* image, size_t image_size);
+};