diff --git a/bios/spi_device.cpp b/bios/spi_device.cpp
new file mode 100644
index 0000000..93cb9a3
--- /dev/null
+++ b/bios/spi_device.cpp
@@ -0,0 +1,519 @@
+#include "spi_device.hpp"
+
+#include "common/include/NotifyWatch.hpp"
+#include "common/include/device.hpp"
+#include "common/include/host_power.hpp"
+#include "common/include/software_manager.hpp"
+
+#include <gpiod.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/async.hpp>
+#include <sdbusplus/async/context.hpp>
+#include <xyz/openbmc_project/Association/Definitions/server.hpp>
+#include <xyz/openbmc_project/ObjectMapper/client.hpp>
+#include <xyz/openbmc_project/State/Host/client.hpp>
+
+#include <cstddef>
+#include <fstream>
+#include <random>
+
+PHOSPHOR_LOG2_USING;
+
+using namespace std::literals;
+using namespace phosphor::software;
+using namespace phosphor::software::manager;
+using namespace phosphor::software::host_power;
+
+SPIDevice::SPIDevice(sdbusplus::async::context& ctx,
+                     uint64_t spiControllerIndex, uint64_t spiDeviceIndex,
+                     bool dryRun, const std::vector<std::string>& gpioLinesIn,
+                     const std::vector<uint64_t>& gpioValuesIn,
+                     SoftwareConfig& config, SoftwareManager* parent,
+                     enum FlashLayout layout, enum FlashTool tool,
+                     const std::string& versionDirPath) :
+    Device(ctx, config, parent,
+           {RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset}),
+    NotifyWatchIntf(ctx, versionDirPath), dryRun(dryRun),
+    gpioLines(gpioLinesIn),
+    gpioValues(gpioValuesIn.begin(), gpioValuesIn.end()),
+    spiControllerIndex(spiControllerIndex), spiDeviceIndex(spiDeviceIndex),
+    layout(layout), tool(tool)
+{
+    // To probe the driver for our spi flash, we need the memory-mapped address
+    // of the spi peripheral. These values are specific to aspeed BMC.
+    // https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
+    std::map<uint32_t, std::string> spiDevAddr = {
+        {0, "1e620000.spi"},
+        {1, "1e630000.spi"},
+        {2, "1e631000.spi"},
+    };
+
+    if (spiControllerIndex >= spiDevAddr.size())
+    {
+        throw std::invalid_argument("SPI controller index out of bounds");
+    }
+
+    spiDev = spiDevAddr[spiControllerIndex];
+
+    ctx.spawn(readNotifyAsync());
+
+    debug(
+        "SPI Device {NAME} at {CONTROLLERINDEX}:{DEVICEINDEX} initialized successfully",
+        "NAME", config.configName, "CONTROLLERINDEX", spiControllerIndex,
+        "DEVICEINDEX", spiDeviceIndex);
+}
+
+// NOLINTBEGIN(readability-static-accessed-through-instance)
+sdbusplus::async::task<bool> SPIDevice::updateDevice(const uint8_t* image,
+                                                     size_t image_size)
+// NOLINTEND(readability-static-accessed-through-instance)
+{
+    // NOLINTBEGIN(readability-static-accessed-through-instance)
+    // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Branch)
+    auto prevPowerstate = co_await HostPower::getState(ctx);
+
+    if (prevPowerstate != stateOn && prevPowerstate != stateOff)
+    {
+        co_return false;
+    }
+
+    // NOLINTBEGIN(readability-static-accessed-through-instance)
+    bool success = co_await HostPower::setState(ctx, stateOff);
+    // NOLINTEND(readability-static-accessed-through-instance)
+    if (!success)
+    {
+        error("error changing host power state");
+        co_return false;
+    }
+    setUpdateProgress(10);
+
+    success = co_await writeSPIFlash(image, image_size);
+
+    if (success)
+    {
+        setUpdateProgress(100);
+    }
+
+    // restore the previous powerstate
+    const bool powerstate_restore =
+        co_await HostPower::setState(ctx, prevPowerstate);
+    if (!powerstate_restore)
+    {
+        error("error changing host power state");
+        co_return false;
+    }
+
+    // return value here is only describing if we successfully wrote to the
+    // SPI flash. Restoring powerstate can still fail.
+    co_return success;
+    // NOLINTEND(readability-static-accessed-through-instance)
+}
+
+const std::string spiAspeedSMCPath = "/sys/bus/platform/drivers/spi-aspeed-smc";
+
+// NOLINTBEGIN(readability-static-accessed-through-instance)
+sdbusplus::async::task<bool> SPIDevice::bindSPIFlash()
+// NOLINTEND(readability-static-accessed-through-instance)
+{
+    debug("binding flash to SMC");
+
+    if (SPIDevice::isSPIFlashBound())
+    {
+        debug("flash was already bound, unbinding it now");
+        bool success = co_await SPIDevice::unbindSPIFlash();
+
+        if (!success)
+        {
+            error("error unbinding spi flash");
+            co_return false;
+        }
+    }
+
+    std::ofstream ofbind(spiAspeedSMCPath + "/bind", std::ofstream::out);
+    ofbind << spiDev;
+    ofbind.close();
+
+    const int driverBindSleepDuration = 2;
+
+    co_await sdbusplus::async::sleep_for(
+        ctx, std::chrono::seconds(driverBindSleepDuration));
+
+    const bool isBound = isSPIFlashBound();
+
+    if (!isBound)
+    {
+        error("failed to bind spi device");
+    }
+
+    co_return isBound;
+}
+
+// NOLINTBEGIN(readability-static-accessed-through-instance)
+sdbusplus::async::task<bool> SPIDevice::unbindSPIFlash()
+// NOLINTEND(readability-static-accessed-through-instance)
+{
+    debug("unbinding flash from SMC");
+    std::ofstream ofunbind(spiAspeedSMCPath + "/unbind", std::ofstream::out);
+    ofunbind << spiDev;
+    ofunbind.close();
+
+    // wait for kernel
+    co_await sdbusplus::async::sleep_for(ctx, std::chrono::seconds(2));
+
+    co_return !isSPIFlashBound();
+}
+
+bool SPIDevice::isSPIFlashBound()
+{
+    std::string path = spiAspeedSMCPath + "/" + spiDev;
+
+    return std::filesystem::exists(path);
+}
+
+static std::unique_ptr<::gpiod::line_bulk> requestMuxGPIOs(
+    const std::vector<std::string>& gpioLines,
+    const std::vector<int>& gpioValues, bool inverted)
+{
+    std::vector<::gpiod::line> lines;
+
+    for (const std::string& lineName : gpioLines)
+    {
+        const ::gpiod::line line = ::gpiod::find_line(lineName);
+
+        if (line.is_used())
+        {
+            error("gpio line {LINE} was still used", "LINE", lineName);
+            return nullptr;
+        }
+
+        lines.push_back(line);
+    }
+
+    ::gpiod::line_request config{"", ::gpiod::line_request::DIRECTION_OUTPUT,
+                                 0};
+
+    debug("[gpio] requesting gpios to mux SPI to BMC");
+
+    auto lineBulk = std::make_unique<::gpiod::line_bulk>(lines);
+
+    if (inverted)
+    {
+        std::vector<int> valuesInverted;
+        valuesInverted.reserve(gpioValues.size());
+
+        for (int value : gpioValues)
+        {
+            valuesInverted.push_back(value ? 0 : 1);
+        }
+
+        lineBulk->request(config, valuesInverted);
+    }
+    else
+    {
+        lineBulk->request(config, gpioValues);
+    }
+
+    return lineBulk;
+}
+
+// NOLINTBEGIN(readability-static-accessed-through-instance)
+sdbusplus::async::task<bool> SPIDevice::writeSPIFlash(const uint8_t* image,
+                                                      size_t image_size)
+// NOLINTEND(readability-static-accessed-through-instance)
+{
+    debug("[gpio] requesting gpios to mux SPI to BMC");
+
+    std::unique_ptr<::gpiod::line_bulk> lineBulk =
+        requestMuxGPIOs(gpioLines, gpioValues, false);
+
+    if (!lineBulk)
+    {
+        co_return false;
+    }
+
+    bool success = co_await SPIDevice::bindSPIFlash();
+    if (success)
+    {
+        if (dryRun)
+        {
+            info("dry run, NOT writing to the chip");
+        }
+        else
+        {
+            if (tool == flashToolFlashrom)
+            {
+                const int status =
+                    co_await SPIDevice::writeSPIFlashWithFlashrom(image,
+                                                                  image_size);
+                if (status != 0)
+                {
+                    error(
+                        "Error writing to SPI flash {CONTROLLERINDEX}:{DEVICEINDEX}, exit code {EXITCODE}",
+                        "CONTROLLERINDEX", spiControllerIndex, "DEVICEINDEX",
+                        spiDeviceIndex, "EXITCODE", status);
+                }
+                success = (status == 0);
+            }
+            else
+            {
+                success =
+                    co_await SPIDevice::writeSPIFlashDefault(image, image_size);
+            }
+        }
+
+        success = success && co_await SPIDevice::unbindSPIFlash();
+    }
+
+    lineBulk->release();
+
+    // switch bios flash back to host via mux / GPIO
+    // (not assume there is a pull to the default value)
+    debug("[gpio] requesting gpios to mux SPI to Host");
+
+    lineBulk = requestMuxGPIOs(gpioLines, gpioValues, true);
+
+    if (!lineBulk)
+    {
+        co_return success;
+    }
+
+    lineBulk->release();
+
+    co_return success;
+}
+
+// NOLINTBEGIN(readability-static-accessed-through-instance)
+sdbusplus::async::task<int> asyncSystem(sdbusplus::async::context& ctx,
+                                        const std::string& cmd)
+// NOLINTEND(readability-static-accessed-through-instance)
+{
+    int pipefd[2];
+    if (pipe(pipefd) == -1)
+    {
+        perror("pipe");
+        co_return -1;
+    }
+
+    pid_t pid = fork();
+    if (pid == -1)
+    {
+        perror("fork");
+        close(pipefd[0]);
+        close(pipefd[1]);
+        co_return -1;
+    }
+    else if (pid == 0)
+    {
+        close(pipefd[0]);
+        int exitCode = std::system(cmd.c_str());
+
+        ssize_t status = write(pipefd[1], &exitCode, sizeof(exitCode));
+        close(pipefd[1]);
+        exit((status == sizeof(exitCode)) ? 0 : 1);
+    }
+    else
+    {
+        close(pipefd[1]);
+
+        sdbusplus::async::fdio pipe_fdio(ctx, pipefd[0]);
+
+        co_await pipe_fdio.next();
+
+        int status;
+        waitpid(pid, &status, 0);
+        close(pipefd[0]);
+
+        co_return WEXITSTATUS(status);
+    }
+}
+
+// NOLINTBEGIN(readability-static-accessed-through-instance)
+sdbusplus::async::task<int> SPIDevice::writeSPIFlashWithFlashrom(
+    const uint8_t* image, size_t image_size) const
+// NOLINTEND(readability-static-accessed-through-instance)
+{
+    // randomize the name to enable parallel updates
+    const std::string path = "/tmp/spi-device-image-" +
+                             std::to_string(Software::getRandomId()) + ".bin";
+
+    int fd = open(path.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644);
+    if (fd < 0)
+    {
+        error("Failed to open file: {PATH}", "PATH", path);
+        co_return 1;
+    }
+
+    const ssize_t bytesWritten = write(fd, image, image_size);
+
+    close(fd);
+
+    setUpdateProgress(30);
+
+    if (bytesWritten < 0 || static_cast<size_t>(bytesWritten) != image_size)
+    {
+        error("Failed to write image to file");
+        co_return 1;
+    }
+
+    debug("wrote {SIZE} bytes to {PATH}", "SIZE", bytesWritten, "PATH", path);
+
+    auto devPath = getMTDDevicePath();
+
+    if (!devPath.has_value())
+    {
+        co_return 1;
+    }
+
+    std::string cmd = "flashrom -p linux_mtd:dev=" + devPath.value();
+
+    if (layout == flashLayoutFlat)
+    {
+        cmd += " -w " + path;
+    }
+    else
+    {
+        error("unsupported flash layout");
+
+        co_return 1;
+    }
+
+    debug("[flashrom] running {CMD}", "CMD", cmd);
+
+    const int exitCode = co_await asyncSystem(ctx, cmd);
+
+    std::filesystem::remove(path);
+
+    co_return exitCode;
+}
+
+// NOLINTBEGIN(readability-static-accessed-through-instance)
+sdbusplus::async::task<bool> SPIDevice::writeSPIFlashDefault(
+    const uint8_t* image, size_t image_size)
+// NOLINTEND(readability-static-accessed-through-instance)
+{
+    auto devPath = getMTDDevicePath();
+
+    if (!devPath.has_value())
+    {
+        co_return false;
+    }
+
+    int fd = open(devPath.value().c_str(), O_WRONLY);
+    if (fd < 0)
+    {
+        error("Failed to open device: {PATH}", "PATH", devPath.value());
+        co_return false;
+    }
+
+    // Write the image in chunks to avoid blocking for too long.
+    // Also, to provide meaningful progress updates.
+
+    const size_t chunk = static_cast<size_t>(1024 * 1024);
+    ssize_t bytesWritten = 0;
+
+    const int progressStart = 30;
+    const int progressEnd = 90;
+
+    for (size_t offset = 0; offset < image_size; offset += chunk)
+    {
+        const ssize_t written =
+            write(fd, image + offset, std::min(chunk, image_size - offset));
+
+        if (written < 0)
+        {
+            error("Failed to write to device");
+            co_return false;
+        }
+
+        bytesWritten += written;
+
+        setUpdateProgress(
+            progressStart + int((progressEnd - progressStart) *
+                                (double(offset) / double(image_size))));
+    }
+
+    close(fd);
+
+    if (static_cast<size_t>(bytesWritten) != image_size)
+    {
+        error("Incomplete write to device");
+        co_return false;
+    }
+
+    debug("Successfully wrote {NBYTES} bytes to {PATH}", "NBYTES", bytesWritten,
+          "PATH", devPath.value());
+
+    co_return true;
+}
+
+std::string SPIDevice::getVersion()
+{
+    std::string version{};
+    try
+    {
+        std::ifstream config(biosVersionPath);
+
+        config >> version;
+    }
+    catch (std::exception& e)
+    {
+        error("Failed to get version with {ERROR}", "ERROR", e.what());
+        version = versionUnknown;
+    }
+
+    if (version.empty())
+    {
+        version = versionUnknown;
+    }
+
+    return version;
+}
+
+// NOLINTNEXTLINE(readability-static-accessed-through-instance)
+auto SPIDevice::processUpdate(std::string versionFileName)
+    -> sdbusplus::async::task<>
+{
+    if (biosVersionFilename != versionFileName)
+    {
+        error(
+            "Update config file name '{NAME}' (!= '{EXPECTED}') is not expected",
+            "NAME", versionFileName, "EXPECTED", biosVersionFilename);
+        co_return;
+    }
+
+    if (softwareCurrent)
+    {
+        softwareCurrent->setVersion(getVersion());
+    }
+
+    co_return;
+}
+
+std::optional<std::string> SPIDevice::getMTDDevicePath() const
+{
+    const std::string spiPath =
+        "/sys/class/spi_master/spi" + std::to_string(spiControllerIndex) +
+        "/spi" + std::to_string(spiControllerIndex) + "." +
+        std::to_string(spiDeviceIndex) + "/mtd/";
+
+    if (!std::filesystem::exists(spiPath))
+    {
+        error("Error: SPI path not found: {PATH}", "PATH", spiPath);
+        return "";
+    }
+
+    for (const auto& entry : std::filesystem::directory_iterator(spiPath))
+    {
+        const std::string mtdName = entry.path().filename().string();
+
+        if (mtdName.starts_with("mtd") && !mtdName.ends_with("ro"))
+        {
+            return "/dev/" + mtdName;
+        }
+    }
+
+    error("Error: No MTD device found for spi {CONTROLLERINDEX}.{DEVICEINDEX}",
+          "CONTROLLERINDEX", spiControllerIndex, "DEVICEINDEX", spiDeviceIndex);
+
+    return std::nullopt;
+}
