~aleteoryx/muditaos

101afc48c1d0ebf21a42bec95a3682b6ae67b05c — Lucjan Bryndza 4 years ago d0558e5
[EGD-6518] Add EEPROM block device driver for VFS

Add block device driver for the factory EEPROM memory
needed for factory settings (aka personalizations)

Signed-off-by: Lucjan Bryndza <lucjan.bryndza@mudita.com>
M module-bsp/board/rt1051/bsp/eeprom/M24256.hpp => module-bsp/board/rt1051/bsp/eeprom/M24256.hpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 15,6 15,6 @@ namespace bsp::eeprom
    constexpr inline auto M24256_PAGE_SIZE  = 64;
    constexpr inline auto M24256_TOTAL_SIZE = (32 * 1024); // bytes

    constexpr inline auto M24256_SLAVE_ADDR = 0x00;
    constexpr inline auto M24256_SLAVE_ADDR = (0xA0 >> 1);

} // namespace bsp::eeprom

M module-bsp/board/rt1051/bsp/eeprom/eeprom.cpp => module-bsp/board/rt1051/bsp/eeprom/eeprom.cpp +3 -4
@@ 27,8 27,7 @@ namespace bsp::eeprom
        drivers::DriverI2CParams i2cParams;
        i2cParams.baudrate = static_cast<std::uint32_t>(BoardDefinitions::EEPROM_I2C_BAUDRATE);
        i2c = drivers::DriverI2C::Create(static_cast<drivers::I2CInstances>(BoardDefinitions::EEPROM_I2C), i2cParams);

        return isPresent(0) ? kStatus_Success : kStatus_Fail;
        return 0;
    }

    bool isPresent(int busid)


@@ 45,7 44,7 @@ namespace bsp::eeprom
        char *ptr      = const_cast<char *>(buf);

        addr.deviceAddress |= static_cast<std::uint32_t>(busid) & M24256_DEV_ID_MASK;
        addr.subAddress = mem_addr;
        addr.subAddress = __builtin_bswap16(mem_addr);

        size_t bl_len   = static_cast<size_t>(eeprom_block_size(busid));
        size_t chunks   = len / bl_len;


@@ 78,7 77,7 @@ namespace bsp::eeprom
        char *ptr   = const_cast<char *>(buf);

        addr.deviceAddress |= static_cast<std::uint32_t>(busid) & M24256_DEV_ID_MASK;
        addr.subAddress = mem_addr;
        addr.subAddress = __builtin_bswap16(mem_addr);

        size_t bl_len   = static_cast<size_t>(eeprom_block_size(busid));
        size_t chunks   = len / bl_len;

A module-vfs/board/rt1051/purefs/include/purefs/blkdev/disk_eeprom.hpp => module-vfs/board/rt1051/purefs/include/purefs/blkdev/disk_eeprom.hpp +31 -0
@@ 0,0 1,31 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include <purefs/blkdev/disk.hpp>
#include <mutex.hpp>

#if !defined(TARGET_RT1051)
#error Unsupported target
#endif

namespace purefs::blkdev
{
    class disk_eeprom final : public disk
    {
      public:
        explicit disk_eeprom(int _bus_id) : bus_id(_bus_id)
        {}
        virtual ~disk_eeprom() = default;
        auto probe(unsigned flags) -> int override;
        auto write(const void *buf, sector_t lba, std::size_t count, hwpart_t hwpart) -> int override;
        auto read(void *buf, sector_t lba, std::size_t count, hwpart_t hwpart) -> int override;
        auto status() const -> media_status override;
        auto get_info(info_type what, hwpart_t hwpart) const -> scount_t override;

      private:
        mutable cpp_freertos::MutexRecursive mutex;
        const int bus_id;
    };
} // namespace purefs::blkdev

A module-vfs/board/rt1051/purefs/src/blkdev/disk_eeprom.cpp => module-vfs/board/rt1051/purefs/src/blkdev/disk_eeprom.cpp +79 -0
@@ 0,0 1,79 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <purefs/blkdev/disk_eeprom.hpp>
#include "bsp/eeprom/eeprom.hpp"
#include "board/rt1051/bsp/eeprom/M24256.hpp"
#include "bsp/BoardDefinitions.hpp"

namespace purefs::blkdev
{
    auto disk_eeprom::probe(unsigned flags) -> int
    {
        cpp_freertos::LockGuard lock(mutex);
        const auto error = bsp::eeprom::init();
        if (error) {
            return -EIO;
        }
        if (!bsp::eeprom::isPresent(bus_id)) {
            return -ENXIO;
        }
        return 0;
    }

    auto disk_eeprom::status() const -> media_status
    {
        return (bsp::eeprom::isPresent(bus_id)) ? (media_status::healthly) : (media_status::error);
    }

    auto disk_eeprom::get_info(info_type what, hwpart_t hwpart) const -> scount_t
    {
        cpp_freertos::LockGuard lock(mutex);
        if (hwpart > 0) {
            return -ERANGE;
        }
        switch (what) {
        case info_type::sector_size:
            return bsp::eeprom::eeprom_block_size(bus_id);
        case info_type::sector_count:
            return bsp::eeprom::eeprom_total_size(bus_id) / bsp::eeprom::eeprom_block_size(bus_id);
        case info_type::erase_block:
            return 0;
        default:
            return -ENOTSUP;
        }
    }

    auto disk_eeprom::write(const void *buf, sector_t lba, std::size_t count, hwpart_t hwpart) -> int
    {
        cpp_freertos::LockGuard lock(mutex);
        if (hwpart > 0) {
            return -ERANGE;
        }
        const size_t block_siz = bsp::eeprom::eeprom_block_size(bus_id);
        const size_t total_siz = bsp::eeprom::eeprom_total_size(bus_id);
        const auto addr        = lba * block_siz;
        const auto len         = count * block_siz;
        if (addr + len > total_siz) {
            return -ERANGE;
        }
        const auto nwr = bsp::eeprom::eeprom_write(bus_id, addr, reinterpret_cast<const char *>(buf), len);
        return (nwr != int(len)) ? (-ENXIO) : (0);
    }

    auto disk_eeprom::read(void *buf, sector_t lba, std::size_t count, hwpart_t hwpart) -> int
    {
        cpp_freertos::LockGuard lock(mutex);
        if (hwpart > 0) {
            return -ERANGE;
        }
        const size_t block_siz = bsp::eeprom::eeprom_block_size(bus_id);
        const size_t total_siz = bsp::eeprom::eeprom_total_size(bus_id);
        const auto addr        = lba * block_siz;
        const auto len         = count * block_siz;
        if (addr + len > total_siz) {
            return -ERANGE;
        }
        const auto nwr = bsp::eeprom::eeprom_read(bus_id, addr, reinterpret_cast<char *>(buf), len);
        return (nwr != int(len)) ? (-ENXIO) : (0);
    }
} // namespace purefs::blkdev

M module-vfs/board/rt1051/purefs/src/blkdev/disk_emmc.cpp => module-vfs/board/rt1051/purefs/src/blkdev/disk_emmc.cpp +0 -2
@@ 9,8 9,6 @@
#include <bsp/common.hpp>
#include "board/rt1051/bsp/eMMC/fsl_mmc.h"
#include "bsp/BoardDefinitions.hpp"
#include "bsp/eeprom/eeprom.hpp"
#include "board/rt1051/bsp/eeprom/M24256.hpp"

namespace purefs::blkdev
{

M module-vfs/board/rt1051/purefs/src/vfs_subsystem_internal.cpp => module-vfs/board/rt1051/purefs/src/vfs_subsystem_internal.cpp +6 -1
@@ 4,9 4,14 @@
#include <purefs/vfs_subsystem_internal.hpp>
#include <purefs/blkdev/disk_manager.hpp>
#include <purefs/blkdev/disk_emmc.hpp>
#include <purefs/blkdev/disk_eeprom.hpp>

namespace purefs::subsystem::internal
{
    namespace
    {
        constexpr auto eeprom_bus_address = 0xA0 >> 1;
    }
    auto create_default_block_device() -> std::shared_ptr<blkdev::disk>
    {
        return std::make_shared<purefs::blkdev::disk_emmc>();


@@ 14,6 19,6 @@ namespace purefs::subsystem::internal

    auto create_default_nvm_device() -> std::shared_ptr<blkdev::disk>
    {
        return {};
        return std::make_shared<purefs::blkdev::disk_eeprom>(eeprom_bus_address);
    }
} // namespace purefs::subsystem::internal

M module-vfs/targets/Target_RT1051.cmake => module-vfs/targets/Target_RT1051.cmake +1 -0
@@ 1,5 1,6 @@
set(BOARD_SOURCES ${BOARD_SOURCES}
        ${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/purefs/src/blkdev/disk_emmc.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/purefs/src/blkdev/disk_eeprom.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/purefs/src/fs/thread_local_cwd.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/board/rt1051/purefs/src/vfs_subsystem_internal.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/src/newlib/vfs_io_syscalls.cpp