1 /*
2 * Block device emulated in RAM
3 *
4 * Copyright (c) 2022, The littlefs authors.
5 * Copyright (c) 2017, Arm Limited. All rights reserved.
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #include "bd/lfs_rambd.h"
9
lfs_rambd_create(const struct lfs_config * cfg,const struct lfs_rambd_config * bdcfg)10 int lfs_rambd_create(const struct lfs_config *cfg,
11 const struct lfs_rambd_config *bdcfg) {
12 LFS_RAMBD_TRACE("lfs_rambd_create(%p {.context=%p, "
13 ".read=%p, .prog=%p, .erase=%p, .sync=%p}, "
14 "%p {.read_size=%"PRIu32", .prog_size=%"PRIu32", "
15 ".erase_size=%"PRIu32", .erase_count=%"PRIu32", "
16 ".buffer=%p})",
17 (void*)cfg, cfg->context,
18 (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
19 (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
20 (void*)bdcfg,
21 bdcfg->read_size, bdcfg->prog_size, bdcfg->erase_size,
22 bdcfg->erase_count, bdcfg->buffer);
23 lfs_rambd_t *bd = cfg->context;
24 bd->cfg = bdcfg;
25
26 // allocate buffer?
27 if (bd->cfg->buffer) {
28 bd->buffer = bd->cfg->buffer;
29 } else {
30 bd->buffer = lfs_malloc(bd->cfg->erase_size * bd->cfg->erase_count);
31 if (!bd->buffer) {
32 LFS_RAMBD_TRACE("lfs_rambd_create -> %d", LFS_ERR_NOMEM);
33 return LFS_ERR_NOMEM;
34 }
35 }
36
37 // zero for reproducibility
38 memset(bd->buffer, 0, bd->cfg->erase_size * bd->cfg->erase_count);
39
40 LFS_RAMBD_TRACE("lfs_rambd_create -> %d", 0);
41 return 0;
42 }
43
lfs_rambd_destroy(const struct lfs_config * cfg)44 int lfs_rambd_destroy(const struct lfs_config *cfg) {
45 LFS_RAMBD_TRACE("lfs_rambd_destroy(%p)", (void*)cfg);
46 // clean up memory
47 lfs_rambd_t *bd = cfg->context;
48 if (!bd->cfg->buffer) {
49 lfs_free(bd->buffer);
50 }
51 LFS_RAMBD_TRACE("lfs_rambd_destroy -> %d", 0);
52 return 0;
53 }
54
lfs_rambd_read(const struct lfs_config * cfg,lfs_block_t block,lfs_off_t off,void * buffer,lfs_size_t size)55 int lfs_rambd_read(const struct lfs_config *cfg, lfs_block_t block,
56 lfs_off_t off, void *buffer, lfs_size_t size) {
57 LFS_RAMBD_TRACE("lfs_rambd_read(%p, "
58 "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
59 (void*)cfg, block, off, buffer, size);
60 lfs_rambd_t *bd = cfg->context;
61
62 // check if read is valid
63 LFS_ASSERT(block < bd->cfg->erase_count);
64 LFS_ASSERT(off % bd->cfg->read_size == 0);
65 LFS_ASSERT(size % bd->cfg->read_size == 0);
66 LFS_ASSERT(off+size <= bd->cfg->erase_size);
67
68 // read data
69 memcpy(buffer, &bd->buffer[block*bd->cfg->erase_size + off], size);
70
71 LFS_RAMBD_TRACE("lfs_rambd_read -> %d", 0);
72 return 0;
73 }
74
lfs_rambd_prog(const struct lfs_config * cfg,lfs_block_t block,lfs_off_t off,const void * buffer,lfs_size_t size)75 int lfs_rambd_prog(const struct lfs_config *cfg, lfs_block_t block,
76 lfs_off_t off, const void *buffer, lfs_size_t size) {
77 LFS_RAMBD_TRACE("lfs_rambd_prog(%p, "
78 "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
79 (void*)cfg, block, off, buffer, size);
80 lfs_rambd_t *bd = cfg->context;
81
82 // check if write is valid
83 LFS_ASSERT(block < bd->cfg->erase_count);
84 LFS_ASSERT(off % bd->cfg->prog_size == 0);
85 LFS_ASSERT(size % bd->cfg->prog_size == 0);
86 LFS_ASSERT(off+size <= bd->cfg->erase_size);
87
88 // program data
89 memcpy(&bd->buffer[block*bd->cfg->erase_size + off], buffer, size);
90
91 LFS_RAMBD_TRACE("lfs_rambd_prog -> %d", 0);
92 return 0;
93 }
94
lfs_rambd_erase(const struct lfs_config * cfg,lfs_block_t block)95 int lfs_rambd_erase(const struct lfs_config *cfg, lfs_block_t block) {
96 LFS_RAMBD_TRACE("lfs_rambd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
97 (void*)cfg, block, ((lfs_rambd_t*)cfg->context)->cfg->erase_size);
98 lfs_rambd_t *bd = cfg->context;
99
100 // check if erase is valid
101 LFS_ASSERT(block < bd->cfg->erase_count);
102
103 // erase is a noop
104 (void)block;
105
106 LFS_RAMBD_TRACE("lfs_rambd_erase -> %d", 0);
107 return 0;
108 }
109
lfs_rambd_sync(const struct lfs_config * cfg)110 int lfs_rambd_sync(const struct lfs_config *cfg) {
111 LFS_RAMBD_TRACE("lfs_rambd_sync(%p)", (void*)cfg);
112
113 // sync is a noop
114 (void)cfg;
115
116 LFS_RAMBD_TRACE("lfs_rambd_sync -> %d", 0);
117 return 0;
118 }
119