mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
2b6f65a08a
This changes the API of xfa from XFA(array_name, prio) type element_name = INITIALIZER; to XFA(type, array_name, prio) element_name = INITIALIZER; this allows forcing natural alignment of the type, fixing failing tests on `native64`.
235 lines
6.0 KiB
C
235 lines
6.0 KiB
C
/*
|
|
* Copyright (C) 2020 Koen Zandberg
|
|
* 2020 Inria
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup sys_suit_storage
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief SUIT ram storage module implementation
|
|
*
|
|
* @author Koen Zandberg <koen@bergzand.net>
|
|
*
|
|
* @}
|
|
*/
|
|
#include <string.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "fmt.h"
|
|
#include "kernel_defines.h"
|
|
#include "log.h"
|
|
#include "xfa.h"
|
|
|
|
#include "suit.h"
|
|
#include "suit/storage.h"
|
|
#include "suit/storage/ram.h"
|
|
|
|
XFA_USE(suit_storage_t, suit_storage_reg);
|
|
|
|
static inline suit_storage_ram_t *_get_ram(suit_storage_t *storage)
|
|
{
|
|
return container_of(storage, suit_storage_ram_t, storage);
|
|
}
|
|
|
|
static inline const suit_storage_ram_t *_get_ram_const(
|
|
const suit_storage_t *storage)
|
|
{
|
|
return container_of(storage, suit_storage_ram_t, storage);
|
|
}
|
|
|
|
static inline suit_storage_ram_region_t *_get_active_region(
|
|
suit_storage_ram_t *ram)
|
|
{
|
|
return &ram->regions[ram->active_region];
|
|
}
|
|
|
|
static bool _get_region_by_string(const char *location, uint32_t *val)
|
|
{
|
|
/* Matching on .ram.### */
|
|
static const char prefix[] = CONFIG_SUIT_STORAGE_RAM_LOCATION_PREFIX;
|
|
static const size_t prefix_len = sizeof(prefix) - 1;
|
|
|
|
/* Check for prefix */
|
|
if (strncmp(prefix, location, prefix_len) == 0 &&
|
|
location[prefix_len] != '\n') {
|
|
/* Advance to the number */
|
|
location += prefix_len;
|
|
/* Check if the rest of the string is a number */
|
|
if (fmt_is_number(location)) {
|
|
/* grab the number */
|
|
*val = scn_u32_dec(location, 5);
|
|
/* Number must be smaller than the number of regions */
|
|
if (*val < CONFIG_SUIT_STORAGE_RAM_REGIONS) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static int _ram_init(suit_storage_t *storage)
|
|
{
|
|
|
|
suit_storage_ram_t *ram = _get_ram(storage);
|
|
|
|
/* Clear the ram regions */
|
|
memset(ram->regions, 0,
|
|
sizeof(suit_storage_ram_region_t) * CONFIG_SUIT_STORAGE_RAM_REGIONS);
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_start(suit_storage_t *storage, const suit_manifest_t *manifest,
|
|
size_t len)
|
|
{
|
|
(void)manifest;
|
|
suit_storage_ram_t *ram = _get_ram(storage);
|
|
suit_storage_ram_region_t *region = _get_active_region(ram);
|
|
|
|
if (len > CONFIG_SUIT_STORAGE_RAM_SIZE) {
|
|
return SUIT_ERR_STORAGE_EXCEEDED;
|
|
}
|
|
|
|
region->occupied = 0;
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_write(suit_storage_t *storage, const suit_manifest_t *manifest,
|
|
const uint8_t *buf, size_t offset, size_t len)
|
|
{
|
|
(void)manifest;
|
|
suit_storage_ram_t *ram = _get_ram(storage);
|
|
suit_storage_ram_region_t *region = _get_active_region(ram);
|
|
|
|
if (offset + len > CONFIG_SUIT_STORAGE_RAM_SIZE) {
|
|
return SUIT_ERR_STORAGE_EXCEEDED;
|
|
}
|
|
|
|
memcpy(®ion->mem[offset], buf, len);
|
|
region->occupied += len;
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_finish(suit_storage_t *storage, const suit_manifest_t *manifest)
|
|
{
|
|
(void)storage;
|
|
(void)manifest;
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_install(suit_storage_t *storage, const suit_manifest_t *manifest)
|
|
{
|
|
suit_storage_set_seq_no(storage, manifest->seq_number);
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_erase(suit_storage_t *storage)
|
|
{
|
|
suit_storage_ram_t *ram = _get_ram(storage);
|
|
suit_storage_ram_region_t *region = _get_active_region(ram);
|
|
|
|
memset(region->mem, 0, CONFIG_SUIT_STORAGE_RAM_SIZE);
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_read(suit_storage_t *storage, uint8_t *buf, size_t offset,
|
|
size_t len)
|
|
{
|
|
suit_storage_ram_t *ram = _get_ram(storage);
|
|
suit_storage_ram_region_t *region = _get_active_region(ram);
|
|
|
|
if (offset + len > CONFIG_SUIT_STORAGE_RAM_SIZE) {
|
|
return SUIT_ERR_STORAGE_EXCEEDED;
|
|
}
|
|
|
|
memcpy(buf, ®ion->mem[offset], len);
|
|
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_read_ptr(suit_storage_t *storage,
|
|
const uint8_t **buf, size_t *len)
|
|
{
|
|
suit_storage_ram_t *ram = _get_ram(storage);
|
|
suit_storage_ram_region_t *region = _get_active_region(ram);
|
|
|
|
*buf = region->mem;
|
|
*len = region->occupied;
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static bool _ram_has_location(const suit_storage_t *storage,
|
|
const char *location)
|
|
{
|
|
(void)storage;
|
|
uint32_t val;
|
|
|
|
return _get_region_by_string(location, &val);
|
|
}
|
|
|
|
static int _ram_set_active_location(suit_storage_t *storage,
|
|
const char *location)
|
|
{
|
|
suit_storage_ram_t *ram = _get_ram(storage);
|
|
uint32_t region = 0;
|
|
|
|
if (!_get_region_by_string(location, ®ion)) {
|
|
return -1;
|
|
}
|
|
|
|
ram->active_region = region;
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_get_seq_no(const suit_storage_t *storage, uint32_t *seq_no)
|
|
{
|
|
const suit_storage_ram_t *ram = _get_ram_const(storage);
|
|
|
|
*seq_no = ram->sequence_no;
|
|
LOG_INFO("Retrieved sequence number: %" PRIu32 "\n", *seq_no);
|
|
return SUIT_OK;
|
|
}
|
|
|
|
static int _ram_set_seq_no(suit_storage_t *storage, uint32_t seq_no)
|
|
{
|
|
suit_storage_ram_t *ram = _get_ram(storage);
|
|
|
|
if (ram->sequence_no < seq_no) {
|
|
LOG_INFO("Stored sequence number: %" PRIu32 "\n", seq_no);
|
|
ram->sequence_no = seq_no;
|
|
return SUIT_OK;
|
|
}
|
|
|
|
return SUIT_ERR_SEQUENCE_NUMBER;
|
|
}
|
|
|
|
static const suit_storage_driver_t suit_storage_ram_driver = {
|
|
.init = _ram_init,
|
|
.start = _ram_start,
|
|
.write = _ram_write,
|
|
.finish = _ram_finish,
|
|
.read = _ram_read,
|
|
.read_ptr = _ram_read_ptr,
|
|
.install = _ram_install,
|
|
.erase = _ram_erase,
|
|
.has_location = _ram_has_location,
|
|
.set_active_location = _ram_set_active_location,
|
|
.get_seq_no = _ram_get_seq_no,
|
|
.set_seq_no = _ram_set_seq_no,
|
|
.separator = CONFIG_SUIT_STORAGE_RAM_LOCATION_SEPARATOR,
|
|
};
|
|
|
|
suit_storage_ram_t suit_storage_ram = {
|
|
.storage = {
|
|
.driver = &suit_storage_ram_driver,
|
|
},
|
|
};
|
|
|
|
XFA(suit_storage_t *, suit_storage_reg, 0) suit_storage_ram_ptr = &suit_storage_ram.storage;
|