mirror of https://github.com/ARMmbed/mbed-os.git
955 lines
32 KiB
C++
955 lines
32 KiB
C++
/*
|
|
* Copyright (c) 2018 ARM Limited. All rights reserved.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
|
* not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "kv_config.h"
|
|
#include "KVStore.h"
|
|
#include "KVMap.h"
|
|
#include "BlockDevice.h"
|
|
#include "FileSystem.h"
|
|
#include "FileSystemStore.h"
|
|
#include "SlicingBlockDevice.h"
|
|
#include "FATFileSystem.h"
|
|
#include "LittleFileSystem.h"
|
|
#include "TDBStore.h"
|
|
#include "mbed_error.h"
|
|
#include "FlashIAP.h"
|
|
#include "FlashSimBlockDevice.h"
|
|
#include "mbed_trace.h"
|
|
#include "SecureStore.h"
|
|
#define TRACE_GROUP "KVCFG"
|
|
|
|
#if COMPONENT_FLASHIAP
|
|
#include "FlashIAPBlockDevice.h"
|
|
#endif
|
|
|
|
#if COMPONENT_QSPIF
|
|
#include "QSPIFBlockDevice.h"
|
|
#endif
|
|
|
|
#if COMPONENT_SPIF
|
|
#include "SPIFBlockDevice.h"
|
|
#endif
|
|
|
|
#if COMPONENT_DATAFLASH
|
|
#include "DataFlashBlockDevice.h"
|
|
#endif
|
|
|
|
#if COMPONENT_SD
|
|
#include "SDBlockDevice.h"
|
|
#endif
|
|
|
|
/**
|
|
* @brief This function initializes internal memory secure storage
|
|
* This includes a TDBStore instance with a FlashIAPBlockdevice
|
|
* as the supported storage.
|
|
* The following is a list of configuration parameter
|
|
* MBED_CONF_STORAGE_TDB_INTERNAL_SIZE - The size of the underlying FlashIAPBlockdevice
|
|
* MBED_CONF_STORAGE_TDB_INTERNAL_BASE_ADDRESS - The start address of the underlying FlashIAPBlockdevice
|
|
* @returns 0 on success or negative value on failure.
|
|
*/
|
|
int _storage_config_TDB_INTERNAL();
|
|
|
|
/**
|
|
* @brief This function initialize external memory secure storage
|
|
* This includes a SecureStore class with TDBStore over FlashIAPBlockdevice
|
|
* and an external TDBStore over a default blockdevice unless configured differently.
|
|
* The following is a list of configuration parameter:
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE - Size of the internal FlashIAPBlockDevice and by
|
|
* default is set to 4K*#enteries/32. The start address will be set to end of flash - rbp_internal_size.
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_NUMBER_OF_ENTRIES - If not defined default is 64
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS - The satrt address of the internal FlashIAPBlockDevice.
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_SIZE - Size of the external blockdevice in bytes or NULL for
|
|
* max possible size.
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_BASE_ADDRESS - The block device start address.
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_BLOCK_DEVICE - Alowed vlaues are: default, SPIF, DATAFASH, QSPIF or SD
|
|
* @returns 0 on success or negative value on failure.
|
|
*/
|
|
int _storage_config_TDB_EXTERNAL();
|
|
|
|
/**
|
|
* @brief This function initialize a external memory secure storage
|
|
* This includes a SecureStore class with external TDBStore over a blockdevice or,
|
|
* if no blockdevice was set the default blockdevice will be used.
|
|
* The following is a list of configuration parameter:
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_SIZE - Size of the external blockdevice in bytes
|
|
* or NULL for max possible size.
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_BASE_ADDRESS - The block device start address
|
|
* MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_BLOCK_DEVICE - Alowed vlaues are: default, SPIF, DATAFASH, QSPIF or SD
|
|
* @returns 0 on success or negative value on failure.
|
|
*/
|
|
int _storage_config_TDB_EXTERNAL_NO_RBP();
|
|
|
|
/**
|
|
* @brief This function initialize a FILESYSTEM memory secure storage
|
|
* This includes a SecureStore class with TDBStore over FlashIAPBlockdevice
|
|
* in the internal memory and an external FileSysteStore. If blockdevice and filesystem not set,
|
|
* the system will use the default block device and default filesystem
|
|
* The following is a list of configuration parameter:
|
|
* MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE - Size of the internal FlashIAPBlockDevice and by default is
|
|
* set to 4K*#enteries/32. The start address will be set to
|
|
* end of flash - rbp_internal_size.
|
|
* MBED_CONF_STORAGE_FILESYSTEM_RBP_NUMBER_OF_ENTRIES - If not defined default is 64
|
|
* MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS - The satrt address of the internal FlashIAPBlockDevice.
|
|
* MBED_CONF_STORAGE_FILESYSTEM_FILESYSTEM - Allowed values are: default, FAT or LITTLE
|
|
* MBED_CONF_STORAGE_FILESYSTEM_BLOCKDEVICE - Allowed values are: default, SPIF, DATAFASH, QSPIF or SD
|
|
* MBED_CONF_STORAGE_FILESYSTEM_EXTERNAL_SIZE - External Blockdevice size in bytes or NULL for max possible size.
|
|
* MBED_CONF_STORAGE_FILESYSTEM_EXTERNAL_BASE_ADDRESS - The block device start address.
|
|
* MBED_CONF_STORAGE_FILESYSTEM_MOUNT_POINT - Where to mount the filesystem
|
|
* MBED_CONF_STORAGE_FILESYSTEM_FOLDER_PATH - The working folder paths
|
|
*
|
|
* @returns 0 on success or negative value on failure.
|
|
*/
|
|
int _storage_config_FILESYSTEM();
|
|
|
|
/**
|
|
* @brief This function initialize a FILESYSTEM_NO_RBP memory secure storage with no
|
|
* rollback protection. This includes a SecureStore class an external FileSysteStore over a default
|
|
* filesystem with default blockdevice unless differently configured.
|
|
* The following is a list of configuration parameter:
|
|
* MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FILESYSTEM - Allowed values are: default, FAT or LITTLE
|
|
* MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_BLOCKDEVICE - Allowed values are: default, SPIF, DATAFASH, QSPIF or SD
|
|
* MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_SIZE - Blockdevice size in bytes. or NULL for max possible size.
|
|
* MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_BASE_ADDRESS - The block device start address.
|
|
* MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_MOUNT_POINT - Where to mount the filesystem
|
|
* MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FOLDER_PATH - The working folder paths
|
|
*
|
|
* @returns 0 on success or negative value on failure.
|
|
*/
|
|
int _storage_config_FILESYSTEM_NO_RBP();
|
|
|
|
int _storage_config_tdb_external_common();
|
|
int _storage_config_filesystem_common();
|
|
|
|
using namespace mbed;
|
|
|
|
|
|
static SingletonPtr<PlatformMutex> mutex;
|
|
static bool is_kv_config_initialize = false;
|
|
static kvstore_config_t kvstore_config;
|
|
|
|
#define INTERNAL_BLOCKDEVICE_NAME FLASHIAP
|
|
|
|
#define STR_EXPAND(tok) #tok
|
|
#define STR(tok) STR_EXPAND(tok)
|
|
|
|
#define _GET_FILESYSTEM_concat(dev, ...) _get_filesystem_##dev(__VA_ARGS__)
|
|
#define GET_FILESYSTEM(dev, ...) _GET_FILESYSTEM_concat(dev, __VA_ARGS__)
|
|
|
|
#define _GET_BLOCKDEVICE_concat(dev, ...) _get_blockdevice_##dev(__VA_ARGS__)
|
|
#define GET_BLOCKDEVICE(dev, ...) _GET_BLOCKDEVICE_concat(dev, __VA_ARGS__)
|
|
|
|
static inline uint32_t align_up(uint64_t val, uint64_t size)
|
|
{
|
|
return (((val - 1) / size) + 1) * size;
|
|
}
|
|
|
|
static inline uint32_t align_down(uint64_t val, uint64_t size)
|
|
{
|
|
return (((val) / size)) * size;
|
|
}
|
|
int _calculate_blocksize_match_tdbstore(BlockDevice *bd)
|
|
{
|
|
bd_size_t size = bd->size();
|
|
bd_size_t erase_size = bd->get_erase_size();
|
|
bd_size_t number_of_sector = size / erase_size;
|
|
|
|
if (number_of_sector < 2) {
|
|
tr_warning("KV Config: there is less then 2 sector TDBStore will not work.");
|
|
return -1;
|
|
}
|
|
|
|
|
|
if (number_of_sector % 2 != 0) {
|
|
tr_warning("KV Config: Number of sector is not even number. Consider changing the BlockDevice size");
|
|
}
|
|
|
|
return MBED_SUCCESS;
|
|
}
|
|
|
|
int _get_addresses(BlockDevice *bd, bd_addr_t start_address, bd_size_t size, bd_addr_t *out_start_addr,
|
|
bd_addr_t *out_end_addr)
|
|
{
|
|
bd_addr_t aligned_end_address;
|
|
bd_addr_t end_address;
|
|
bd_addr_t aligned_start_address;
|
|
|
|
aligned_start_address = align_down(start_address, bd->get_erase_size(start_address));
|
|
if (aligned_start_address != start_address) {
|
|
tr_error("KV Config: Start address is not aligned. Better use %02llx", aligned_start_address);
|
|
return -1;
|
|
}
|
|
|
|
if (size == 0) {
|
|
(*out_start_addr) = aligned_start_address;
|
|
(*out_end_addr) = bd->size();
|
|
return 0;
|
|
}
|
|
|
|
end_address = start_address + size;
|
|
aligned_end_address = align_up(end_address, bd->get_erase_size(end_address));
|
|
if (aligned_end_address != end_address) {
|
|
tr_error("KV Config: End address is not aligned. Consider changing the size parameter.");
|
|
return -1;
|
|
}
|
|
|
|
if (aligned_end_address > bd->size()) {
|
|
tr_error("KV Config: End address is out of boundaries");
|
|
return -1;
|
|
}
|
|
|
|
(*out_start_addr) = aligned_start_address;
|
|
(*out_end_addr) = aligned_end_address;
|
|
return 0;
|
|
}
|
|
|
|
FileSystem *_get_filesystem_FAT(BlockDevice *bd, const char *mount)
|
|
{
|
|
static FATFileSystem sdcard(mount, bd);
|
|
return &sdcard;
|
|
|
|
}
|
|
|
|
FileSystem *_get_filesystem_LITTLE(BlockDevice *bd, const char *mount)
|
|
{
|
|
static LittleFileSystem flash(mount, bd);
|
|
return &flash;
|
|
}
|
|
|
|
FileSystemStore *_get_file_system_store(FileSystem *fs)
|
|
{
|
|
static FileSystemStore fss(fs);
|
|
return &fss;
|
|
}
|
|
|
|
FileSystem *_get_filesystem_default(BlockDevice *bd, const char *mount)
|
|
{
|
|
#if COMPONENT_QSPIF || COMPONENT_SPIF || COMPONENT_DATAFLASH
|
|
return _get_filesystem_LITTLE(bd, mount);
|
|
#elif COMPONENT_SD
|
|
return _get_filesystem_FAT(bd, mount);
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
BlockDevice *_get_blockdevice_FLASHIAP(bd_addr_t start_address, bd_size_t size)
|
|
{
|
|
#if COMPONENT_FLASHIAP
|
|
|
|
bd_size_t bd_final_size;
|
|
bd_addr_t flash_end_address;
|
|
bd_addr_t flash_start_address;
|
|
bd_addr_t flash_first_writable_sector_address;
|
|
bd_addr_t aligned_start_address;
|
|
bd_addr_t aligned_end_address;
|
|
bd_addr_t end_address;
|
|
FlashIAP flash;
|
|
|
|
int ret = flash.init();
|
|
if (ret != 0) {
|
|
return NULL;
|
|
}
|
|
|
|
//Get flash parameters before starting
|
|
flash_first_writable_sector_address = align_up(FLASHIAP_ROM_END, flash.get_sector_size(FLASHIAP_ROM_END));
|
|
flash_start_address = flash.get_flash_start();
|
|
flash_end_address = flash_start_address + flash.get_flash_size();;
|
|
|
|
if (start_address != 0) {
|
|
|
|
if (start_address < flash_first_writable_sector_address) {
|
|
tr_error("KV Config: Internal block device start address overlapped ROM address ");
|
|
flash.deinit();
|
|
return NULL;
|
|
}
|
|
aligned_start_address = align_down(start_address, flash.get_sector_size(start_address));
|
|
if (start_address != aligned_start_address) {
|
|
tr_error("KV Config: Internal block device start address is not aligned. Better use %02llx", aligned_start_address);
|
|
flash.deinit();
|
|
return NULL;
|
|
}
|
|
|
|
if (size == 0) {
|
|
//will use 2 sector only.
|
|
bd_final_size = (flash_end_address - start_address);
|
|
|
|
static FlashIAPBlockDevice bd(start_address, bd_final_size);
|
|
flash.deinit();
|
|
return &bd;
|
|
}
|
|
|
|
if (size != 0) {
|
|
|
|
end_address = start_address + size;
|
|
if (end_address > flash_end_address) {
|
|
tr_error("KV Config: Internal block device end address is out of boundaries");
|
|
flash.deinit();
|
|
return NULL;
|
|
}
|
|
|
|
aligned_end_address = align_up(end_address, flash.get_sector_size(end_address - 1));
|
|
if (end_address != aligned_end_address) {
|
|
tr_error("KV Config: Internal block device start address is not aligned. Consider changing the size parameter");
|
|
flash.deinit();
|
|
return NULL;
|
|
}
|
|
|
|
static FlashIAPBlockDevice bd(start_address, size);
|
|
flash.deinit();
|
|
return &bd;
|
|
}
|
|
}
|
|
|
|
bool request_default = false;
|
|
if (start_address == 0 && size == 0) {
|
|
request_default = true;
|
|
size = 1;
|
|
}
|
|
|
|
start_address = flash_end_address - size;
|
|
aligned_start_address = align_down(start_address, flash.get_sector_size(start_address));
|
|
//Skip this check if default parameters are set (0 for base address and 0 size).
|
|
//We will calculate the address and size by ourselves
|
|
if (start_address != aligned_start_address && !request_default) {
|
|
tr_error("KV Config: Internal block device start address is not aligned. Consider changing the size parameter");
|
|
flash.deinit();
|
|
return NULL;
|
|
}
|
|
|
|
if (request_default) {
|
|
//update start_address to double the size for TDBStore needs
|
|
bd_final_size = (flash_end_address - aligned_start_address) * 2;
|
|
start_address = (flash_end_address - bd_final_size);
|
|
aligned_start_address = align_down(start_address, flash.get_sector_size(start_address));
|
|
} else {
|
|
bd_final_size = (flash_end_address - aligned_start_address);
|
|
}
|
|
|
|
flash.deinit();
|
|
|
|
if (aligned_start_address < flash_first_writable_sector_address) {
|
|
tr_error("KV Config: Internal block device start address overlapped ROM address ");
|
|
return NULL;
|
|
}
|
|
static FlashIAPBlockDevice bd(aligned_start_address, bd_final_size);
|
|
return &bd;
|
|
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
BlockDevice *_get_blockdevice_SPIF(bd_addr_t start_address, bd_size_t size)
|
|
{
|
|
#if COMPONENT_SPIF
|
|
|
|
bd_addr_t aligned_end_address;
|
|
bd_addr_t aligned_start_address;
|
|
|
|
static SPIFBlockDevice bd(
|
|
MBED_CONF_SPIF_DRIVER_SPI_MOSI,
|
|
MBED_CONF_SPIF_DRIVER_SPI_MISO,
|
|
MBED_CONF_SPIF_DRIVER_SPI_CLK,
|
|
MBED_CONF_SPIF_DRIVER_SPI_CS,
|
|
MBED_CONF_SPIF_DRIVER_SPI_FREQ
|
|
);
|
|
|
|
if (bd.init() != MBED_SUCCESS) {
|
|
tr_error("KV Config: SPIFBlockDevice init fail");
|
|
return NULL;
|
|
}
|
|
|
|
if (start_address == 0 && size == 0) {
|
|
return &bd;
|
|
}
|
|
|
|
if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
|
|
tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
|
|
return NULL;
|
|
}
|
|
|
|
static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
|
|
return &sbd;
|
|
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
BlockDevice *_get_blockdevice_QSPIF(bd_addr_t start_address, bd_size_t size)
|
|
{
|
|
#if COMPONENT_QSPIF
|
|
|
|
bd_addr_t aligned_end_address;
|
|
bd_addr_t aligned_start_address;
|
|
|
|
static QSPIFBlockDevice bd(
|
|
QSPI_FLASH1_IO0,
|
|
QSPI_FLASH1_IO1,
|
|
QSPI_FLASH1_IO2,
|
|
QSPI_FLASH1_IO3,
|
|
QSPI_FLASH1_SCK,
|
|
QSPI_FLASH1_CSN,
|
|
QSPIF_POLARITY_MODE_0,
|
|
MBED_CONF_QSPIF_QSPI_FREQ
|
|
);
|
|
|
|
if (bd.init() != MBED_SUCCESS) {
|
|
tr_error("KV Config: QSPIFBlockDevice init fail");
|
|
return NULL;
|
|
}
|
|
|
|
if (start_address == 0 && size == 0) {
|
|
return &bd;
|
|
}
|
|
|
|
if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
|
|
tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
|
|
return NULL;
|
|
}
|
|
|
|
static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
|
|
return &sbd;
|
|
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
BlockDevice *_get_blockdevice_DATAFLASH(bd_addr_t start_address, bd_size_t size)
|
|
{
|
|
#if COMPONENT_DATAFLASH
|
|
|
|
bd_addr_t aligned_end_address;
|
|
bd_addr_t aligned_start_address;
|
|
|
|
static DataFlashBlockDevice bd(
|
|
MBED_CONF_DATAFLASH_SPI_MOSI,
|
|
MBED_CONF_DATAFLASH_SPI_MISO,
|
|
MBED_CONF_DATAFLASH_SPI_CLK,
|
|
MBED_CONF_DATAFLASH_SPI_CS
|
|
);
|
|
|
|
if (bd.init() != MBED_SUCCESS) {
|
|
tr_error("KV Config: DataFlashBlockDevice init fail");
|
|
return NULL;
|
|
}
|
|
|
|
if (start_address == 0 && size == 0) {
|
|
return &bd;
|
|
}
|
|
|
|
if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
|
|
tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
|
|
return NULL;
|
|
}
|
|
|
|
static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
|
|
return &sbd;
|
|
|
|
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
BlockDevice *_get_blockdevice_SD(bd_addr_t start_address, bd_size_t size)
|
|
{
|
|
#if COMPONENT_SD
|
|
|
|
bd_addr_t aligned_end_address;
|
|
bd_addr_t aligned_start_address;
|
|
|
|
static SDBlockDevice bd(
|
|
MBED_CONF_SD_SPI_MOSI,
|
|
MBED_CONF_SD_SPI_MISO,
|
|
MBED_CONF_SD_SPI_CLK,
|
|
MBED_CONF_SD_SPI_CS
|
|
);
|
|
|
|
if (bd.init() != MBED_SUCCESS) {
|
|
tr_error("KV Config: SDBlockDevice init fail");
|
|
return NULL;
|
|
}
|
|
|
|
#if MBED_CONF_STORAGE_STORAGE_TYPE == TDB_EXTERNAL_NO_RBP || MBED_CONF_STORAGE_STORAGE_TYPE == TDB_EXTERNAL
|
|
//In TDBStore we have a constraint of 4GByte
|
|
if (start_address == 0 && size == 0 && bd.size() < (uint32_t)(-1)) {
|
|
return &bd;
|
|
}
|
|
|
|
size = size != 0 ? size : align_down(bd.size(), bd.get_erase_size(bd.size() - 1));
|
|
|
|
if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
|
|
tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
|
|
return NULL;
|
|
}
|
|
|
|
if (aligned_end_address - aligned_start_address != (uint32_t)(aligned_end_address - aligned_start_address)) {
|
|
aligned_end_address = aligned_start_address + (uint32_t)(-1);//Support up to 4G only
|
|
}
|
|
|
|
#else
|
|
if (start_address == 0 && size == 0) {
|
|
return &bd;
|
|
}
|
|
|
|
if (_get_addresses(&bd, start_address, size, &aligned_start_address, &aligned_end_address) != 0) {
|
|
tr_error("KV Config: Fail to get addresses for SlicingBlockDevice.");
|
|
return NULL;
|
|
}
|
|
|
|
#endif
|
|
|
|
aligned_end_address = align_down(aligned_end_address, bd.get_erase_size(aligned_end_address));
|
|
static SlicingBlockDevice sbd(&bd, aligned_start_address, aligned_end_address);
|
|
return &sbd;
|
|
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
BlockDevice *_get_blockdevice_default(bd_addr_t start_address, bd_size_t size)
|
|
{
|
|
#if COMPONENT_QSPIF
|
|
return _get_blockdevice_QSPIF(start_address, size);
|
|
#elif COMPONENT_SPIF
|
|
return _get_blockdevice_SPIF(start_address, size);
|
|
#elif COMPONENT_DATAFLASH
|
|
return _get_blockdevice_DATAFLASH(start_address, size);
|
|
#elif COMPONENT_SD
|
|
return _get_blockdevice_SD(start_address, size);
|
|
#else
|
|
tr_error("KV Config: No default component define in target.json for this target.");
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
int _storage_config_TDB_INTERNAL()
|
|
{
|
|
#if COMPONENT_FLASHIAP
|
|
bd_size_t internal_size = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE;
|
|
bd_addr_t internal_start_address = MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS;
|
|
|
|
//If default values are set, we should get maximum available size of internal bd.
|
|
if (internal_size == 0 && internal_start_address == 0) {
|
|
FlashIAP flash;
|
|
if (flash.init() != 0) {
|
|
return MBED_ERROR_FAILED_OPERATION;
|
|
}
|
|
internal_start_address = align_up(FLASHIAP_ROM_END, flash.get_sector_size(FLASHIAP_ROM_END));
|
|
flash.deinit();
|
|
}
|
|
|
|
kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_size);
|
|
if (kvstore_config.internal_bd == NULL) {
|
|
tr_error("KV Config: Fail to get internal BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION;
|
|
}
|
|
|
|
int ret = kvstore_config.internal_bd->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init internal BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION;
|
|
}
|
|
|
|
if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
|
|
tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
|
|
return MBED_ERROR_INVALID_ARGUMENT;
|
|
}
|
|
|
|
static TDBStore tdb_internal(kvstore_config.internal_bd);
|
|
kvstore_config.internal_store = &tdb_internal;
|
|
|
|
ret = kvstore_config.internal_store->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init internal TDBStore.");
|
|
return ret;
|
|
}
|
|
kvstore_config.kvstore_main_instance =
|
|
kvstore_config.internal_store;
|
|
|
|
kvstore_config.flags_mask = ~(KVStore::REQUIRE_CONFIDENTIALITY_FLAG |
|
|
KVStore::REQUIRE_INTEGRITY_FLAG | KVStore::REQUIRE_REPLAY_PROTECTION_FLAG);
|
|
|
|
KVMap &kv_map = KVMap::get_instance();
|
|
ret = kv_map.init();
|
|
if (MBED_SUCCESS != ret) {
|
|
tr_error("KV Config: Fail to init KVStore global API.");
|
|
return ret;
|
|
}
|
|
|
|
ret = kv_map.attach(STR(MBED_CONF_STORAGE_DEFAULT_KV), &kvstore_config);
|
|
if (MBED_SUCCESS != ret) {
|
|
tr_error("KV Config: Fail to attach KVStore main instance to KVStore global API.");
|
|
return ret;
|
|
}
|
|
return MBED_SUCCESS;
|
|
#else
|
|
return MBED_ERROR_UNSUPPORTED;
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
int _storage_config_TDB_EXTERNAL()
|
|
{
|
|
#if !SECURESTORE_ENABLED
|
|
return MBED_ERROR_UNSUPPORTED;
|
|
#endif
|
|
|
|
bd_size_t internal_rbp_size = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_INTERNAL_SIZE;
|
|
size_t rbp_num_of_enteries = MBED_CONF_STORAGE_TDB_EXTERNAL_RBP_NUMBER_OF_ENTRIES;
|
|
bd_addr_t internal_start_address = MBED_CONF_STORAGE_TDB_EXTERNAL_INTERNAL_BASE_ADDRESS;
|
|
|
|
if (internal_rbp_size == 0) {
|
|
internal_rbp_size = 4 * 1024 * rbp_num_of_enteries / 32;
|
|
}
|
|
|
|
kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_rbp_size);
|
|
if (kvstore_config.internal_bd == NULL) {
|
|
tr_error("KV Config: Fail to get internal BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
int ret = kvstore_config.internal_bd->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init internal BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
|
|
tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
|
|
return MBED_ERROR_INVALID_ARGUMENT;
|
|
}
|
|
|
|
static TDBStore tdb_internal(kvstore_config.internal_bd);
|
|
kvstore_config.internal_store = &tdb_internal;
|
|
|
|
ret = kvstore_config.internal_store->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init internal TDBStore.");
|
|
return ret;
|
|
}
|
|
|
|
bd_size_t size = MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_SIZE;
|
|
bd_addr_t address = MBED_CONF_STORAGE_TDB_EXTERNAL_EXTERNAL_BASE_ADDRESS;
|
|
|
|
BlockDevice *bd = GET_BLOCKDEVICE(MBED_CONF_STORAGE_TDB_EXTERNAL_BLOCKDEVICE, address, size);
|
|
if (bd == NULL) {
|
|
tr_error("KV Config: Fail to get external BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
#if defined(COMPONENT_SD)
|
|
if (strcmp(STR(MBED_CONF_STORAGE_TDB_EXTERNAL_BLOCKDEVICE), "SD") == 0
|
|
#if defined(COMPONENT_SD) && !defined(COMPONENT_SPIF) && !defined(COMPONENT_QSPIF) && !defined(COMPONENT_DATAFLASH)
|
|
|| strcmp(STR(MBED_CONF_STORAGE_TDB_EXTERNAL_BLOCKDEVICE), "default") == 0) {
|
|
#else
|
|
) {
|
|
|
|
#endif
|
|
//TDBStore need FlashSimBlockDevice when working with SD block device
|
|
if (bd->init() != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init external BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
static FlashSimBlockDevice flash_bd(bd);
|
|
kvstore_config.external_bd = &flash_bd;
|
|
} else {
|
|
kvstore_config.external_bd = bd;
|
|
}
|
|
#else
|
|
kvstore_config.external_bd = bd;
|
|
#endif
|
|
|
|
kvstore_config.flags_mask = ~(0);
|
|
|
|
return _storage_config_tdb_external_common();
|
|
}
|
|
|
|
int _storage_config_TDB_EXTERNAL_NO_RBP()
|
|
{
|
|
#if !SECURESTORE_ENABLED
|
|
return MBED_ERROR_UNSUPPORTED;
|
|
#endif
|
|
bd_size_t size = MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_SIZE;
|
|
bd_addr_t address = MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_EXTERNAL_BASE_ADDRESS;
|
|
|
|
BlockDevice *bd = GET_BLOCKDEVICE(MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_BLOCKDEVICE, address, size);
|
|
if (bd == NULL) {
|
|
tr_error("KV Config: Fail to get external BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
#if defined(COMPONENT_SD)
|
|
if (strcmp(STR(MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_BLOCKDEVICE), "SD") == 0
|
|
#if defined(COMPONENT_SD) && !defined(COMPONENT_SPIF) && !defined(COMPONENT_QSPIF) && !defined(COMPONENT_DATAFLASH)
|
|
|| strcmp(STR(MBED_CONF_STORAGE_TDB_EXTERNAL_NO_RBP_BLOCKDEVICE), "default") == 0) {
|
|
#else
|
|
) {
|
|
|
|
#endif
|
|
//TDBStore need FlashSimBlockDevice when working with SD block device
|
|
if (bd->init() != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init external BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
static FlashSimBlockDevice flash_bd(bd);
|
|
kvstore_config.external_bd = &flash_bd;
|
|
} else {
|
|
kvstore_config.external_bd = bd;
|
|
}
|
|
#else
|
|
kvstore_config.external_bd = bd;
|
|
#endif
|
|
|
|
kvstore_config.flags_mask = ~(KVStore::REQUIRE_REPLAY_PROTECTION_FLAG);
|
|
|
|
return _storage_config_tdb_external_common();
|
|
}
|
|
|
|
|
|
int _storage_config_tdb_external_common()
|
|
{
|
|
#if SECURESTORE_ENABLED
|
|
int ret = kvstore_config.external_bd->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init external BlockDevice.");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
if (_calculate_blocksize_match_tdbstore(kvstore_config.external_bd) != MBED_SUCCESS) {
|
|
tr_error("KV Config: Can not create TDBStore with less then 2 sector.");
|
|
return MBED_ERROR_INVALID_ARGUMENT;
|
|
}
|
|
|
|
static TDBStore tdb_external(kvstore_config.external_bd);
|
|
kvstore_config.external_store = &tdb_external;
|
|
|
|
ret = kvstore_config.external_store->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init external TDBStore");
|
|
return ret;
|
|
}
|
|
|
|
static SecureStore secst(kvstore_config.external_store, kvstore_config.internal_store);
|
|
|
|
ret = secst.init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init SecureStore.");
|
|
return ret ;
|
|
}
|
|
|
|
kvstore_config.kvstore_main_instance = &secst;
|
|
|
|
KVMap &kv_map = KVMap::get_instance();
|
|
ret = kv_map.init();
|
|
if (MBED_SUCCESS != ret) {
|
|
tr_error("KV Config: Fail to init KVStore global API");
|
|
return ret;
|
|
}
|
|
|
|
ret = kv_map.attach(STR(MBED_CONF_STORAGE_DEFAULT_KV), &kvstore_config);
|
|
if (MBED_SUCCESS != ret) {
|
|
tr_error("KV Config: Fail to attach KvStore main instance to KVStore global API");
|
|
return ret;
|
|
}
|
|
|
|
return MBED_SUCCESS;
|
|
#else
|
|
return MBED_ERROR_UNSUPPORTED;
|
|
#endif
|
|
}
|
|
|
|
int _storage_config_FILESYSTEM()
|
|
{
|
|
#if !SECURESTORE_ENABLED
|
|
return MBED_ERROR_UNSUPPORTED;
|
|
#endif
|
|
bd_size_t internal_rbp_size = MBED_CONF_STORAGE_FILESYSTEM_RBP_INTERNAL_SIZE;
|
|
size_t rbp_num_of_enteries = MBED_CONF_STORAGE_FILESYSTEM_RBP_NUMBER_OF_ENTRIES;
|
|
bd_addr_t internal_start_address = MBED_CONF_STORAGE_FILESYSTEM_INTERNAL_BASE_ADDRESS;
|
|
|
|
if (internal_rbp_size == 0) {
|
|
internal_rbp_size = 4 * 1024 * rbp_num_of_enteries / 32;
|
|
}
|
|
|
|
kvstore_config.internal_bd = GET_BLOCKDEVICE(INTERNAL_BLOCKDEVICE_NAME, internal_start_address, internal_rbp_size);
|
|
if (kvstore_config.internal_bd == NULL) {
|
|
tr_error("KV Config: Fail to get internal BlockDevice ");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
int ret = kvstore_config.internal_bd->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init internal BlockDevice ");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
static TDBStore tdb_internal(kvstore_config.internal_bd);
|
|
kvstore_config.internal_store = &tdb_internal;
|
|
|
|
ret = kvstore_config.internal_store->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init internal TDBStore");
|
|
return ret;
|
|
}
|
|
|
|
bd_size_t size = MBED_CONF_STORAGE_FILESYSTEM_EXTERNAL_SIZE;
|
|
bd_addr_t address = MBED_CONF_STORAGE_FILESYSTEM_EXTERNAL_BASE_ADDRESS;
|
|
const char *mount_point = STR(MBED_CONF_STORAGE_FILESYSTEM_MOUNT_POINT);
|
|
|
|
kvstore_config.external_bd = GET_BLOCKDEVICE(MBED_CONF_STORAGE_FILESYSTEM_BLOCKDEVICE, address, size);
|
|
if (kvstore_config.external_bd == NULL) {
|
|
tr_error("KV Config: Fail to get external BlockDevice ");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
ret = kvstore_config.external_bd->init();
|
|
if (MBED_SUCCESS != ret) {
|
|
tr_error("KV Config: Fail to init external BlockDevice ");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
kvstore_config.external_fs = GET_FILESYSTEM(MBED_CONF_STORAGE_FILESYSTEM_FILESYSTEM, kvstore_config.external_bd,
|
|
mount_point);
|
|
if (kvstore_config.external_fs == NULL) {
|
|
tr_error("KV Config: Fail to get FileSystem");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
kvstore_config.flags_mask = ~(0);
|
|
|
|
return _storage_config_filesystem_common();
|
|
}
|
|
|
|
int _storage_config_FILESYSTEM_NO_RBP()
|
|
{
|
|
bd_size_t size = MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_SIZE;
|
|
bd_addr_t address = MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_EXTERNAL_BASE_ADDRESS;
|
|
const char *mount_point = STR(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_MOUNT_POINT);
|
|
|
|
kvstore_config.external_bd = GET_BLOCKDEVICE(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_BLOCKDEVICE, address, size);
|
|
if (kvstore_config.external_bd == NULL) {
|
|
tr_error("KV Config: Fail to get external BlockDevice ");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
int ret = kvstore_config.external_bd->init();
|
|
if (MBED_SUCCESS != ret) {
|
|
tr_error("KV Config: Fail to init external BlockDevice ");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
kvstore_config.external_fs = GET_FILESYSTEM(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_FILESYSTEM, kvstore_config.external_bd,
|
|
mount_point);
|
|
if (kvstore_config.external_fs == NULL) {
|
|
tr_error("KV Config: Fail to get FileSystem");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
kvstore_config.flags_mask = ~(KVStore::REQUIRE_REPLAY_PROTECTION_FLAG);
|
|
|
|
return _storage_config_filesystem_common();
|
|
}
|
|
|
|
int _storage_config_filesystem_common()
|
|
{
|
|
#if SECURESTORE_ENABLED
|
|
int ret = kvstore_config.external_fs->mount(kvstore_config.external_bd);
|
|
if (ret != MBED_SUCCESS) {
|
|
ret = kvstore_config.external_fs->reformat(kvstore_config.external_bd);
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to mount FileSystem to %s",
|
|
STR(MBED_CONF_STORAGE_FILESYSTEM_NO_RBP_MOUNT_POINT));
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
}
|
|
|
|
kvstore_config.external_store = _get_file_system_store(kvstore_config.external_fs);
|
|
if (kvstore_config.external_store == NULL) {
|
|
tr_error("KV Config: Fail to get FileSystemStore");
|
|
return MBED_ERROR_FAILED_OPERATION ;
|
|
}
|
|
|
|
ret = kvstore_config.external_store->init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init FileSystemStore");
|
|
return ret;
|
|
}
|
|
|
|
static SecureStore secst(kvstore_config.external_store, kvstore_config.internal_store);
|
|
|
|
ret = secst.init();
|
|
if (ret != MBED_SUCCESS) {
|
|
tr_error("KV Config: Fail to init SecureStore.");
|
|
return ret; ;
|
|
}
|
|
|
|
kvstore_config.kvstore_main_instance = &secst;
|
|
|
|
KVMap &kv_map = KVMap::get_instance();
|
|
ret = kv_map.init();
|
|
if (MBED_SUCCESS != ret) {
|
|
tr_error("KV Config: Fail to init KVStore global API");
|
|
return ret;
|
|
}
|
|
|
|
ret = kv_map.attach(STR(MBED_CONF_STORAGE_DEFAULT_KV), &kvstore_config);
|
|
if (MBED_SUCCESS != ret) {
|
|
tr_error("KV Config: Fail to attach KvStore main instance to KVStore global API");
|
|
return ret;
|
|
}
|
|
|
|
return MBED_SUCCESS;
|
|
#else
|
|
return MBED_ERROR_UNSUPPORTED;
|
|
#endif
|
|
}
|
|
|
|
MBED_WEAK int kv_init_storage_config()
|
|
{
|
|
|
|
int ret = MBED_SUCCESS;
|
|
|
|
// We currently have no supported configuration without internal storage
|
|
#ifndef COMPONENT_FLASHIAP
|
|
return MBED_ERROR_UNSUPPORTED;
|
|
#endif
|
|
|
|
mutex->lock();
|
|
|
|
if (is_kv_config_initialize) {
|
|
goto exit;
|
|
}
|
|
|
|
memset(&kvstore_config, 0, sizeof(kvstore_config_t));
|
|
|
|
ret = _STORAGE_CONFIG(MBED_CONF_STORAGE_STORAGE_TYPE);
|
|
|
|
if (ret == MBED_SUCCESS) {
|
|
is_kv_config_initialize = true;
|
|
}
|
|
|
|
exit:
|
|
mutex->unlock();
|
|
return ret;
|
|
}
|