/** * \file * * * \author Francesco Sacchi * * \brief KBlock interface on RAM memory * * \author Francesco Sacchi * * $WIZ$ module_name = "kfile_ram" * $WIZ$ module_depends = "kblock" */ #include "kblock_ram.h" #include static int kblockram_load(KBlock *b, block_idx_t index) { KBlockRam *r = KBLOCKRAM_CAST(b); memcpy(r->b.priv.buf, r->membuf + index * r->b.blk_size, r->b.blk_size); return 0; } static int kblockram_store(struct KBlock *b, block_idx_t index) { KBlockRam *r = KBLOCKRAM_CAST(b); memcpy(r->membuf + index * r->b.blk_size, r->b.priv.buf, r->b.blk_size); return 0; } static size_t kblockram_readBuf(struct KBlock *b, void *buf, size_t offset, size_t size) { KBlockRam *r = KBLOCKRAM_CAST(b); memcpy(buf, (uint8_t *)r->b.priv.buf + offset, size); return size; } static size_t kblockram_readDirect(struct KBlock *b, block_idx_t index, void *buf, size_t offset, size_t size) { KBlockRam *r = KBLOCKRAM_CAST(b); memcpy(buf, r->membuf + index * r->b.blk_size + offset, size); return size; } static size_t kblockram_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size) { KBlockRam *r = KBLOCKRAM_CAST(b); memcpy((uint8_t *)r->b.priv.buf + offset, buf, size); return size; } static size_t kblockram_writeDirect(struct KBlock *b, block_idx_t index, const void *buf, size_t offset, size_t size) { KBlockRam *r = KBLOCKRAM_CAST(b); ASSERT(buf); ASSERT(index < b->blk_cnt); memcpy(r->membuf + index * r->b.blk_size + offset, buf, size); return size; } static int kblockram_dummy(UNUSED_ARG(struct KBlock *,b)) { return 0; } static const KBlockVTable kblockram_hwbuffered_vt = { .readDirect = kblockram_readDirect, .readBuf = kblockram_readBuf, .writeBuf = kblockram_writeBuf, .load = kblockram_load, .store = kblockram_store, .error = kblockram_dummy, .clearerr = (kblock_clearerr_t)kblockram_dummy, .close = kblockram_dummy, }; static const KBlockVTable kblockram_swbuffered_vt = { .readDirect = kblockram_readDirect, .writeDirect = kblockram_writeDirect, .readBuf = kblock_swReadBuf, .writeBuf = kblock_swWriteBuf, .load = kblock_swLoad, .store = kblock_swStore, .error = kblockram_dummy, .clearerr = (kblock_clearerr_t)kblockram_dummy, .close = kblockram_dummy, }; static const KBlockVTable kblockram_unbuffered_vt = { .readDirect = kblockram_readDirect, .writeDirect = kblockram_writeDirect, .error = kblockram_dummy, .clearerr = (kblock_clearerr_t)kblockram_dummy, .close = kblockram_dummy, }; void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size, bool buffered, bool hwbuffered) { ASSERT(buf); ASSERT(size); ASSERT(block_size); memset(ram, 0, sizeof(*ram)); DB(ram->b.priv.type = KBT_KBLOCKRAM); ram->b.blk_size = block_size; ram->b.priv.flags |= KB_PARTIAL_WRITE; if (buffered) { ram->b.priv.flags |= KB_BUFFERED; ram->b.blk_cnt = (size / block_size) - 1; ram->b.priv.buf = buf; // First page used as page buffer ram->membuf = (uint8_t *)buf + block_size; if (hwbuffered) ram->b.priv.vt = &kblockram_hwbuffered_vt; else ram->b.priv.vt = &kblockram_swbuffered_vt; kblockram_load(&ram->b, 0); } else { ram->b.blk_cnt = (size / block_size); ram->membuf = (uint8_t *)buf; ram->b.priv.vt = &kblockram_unbuffered_vt; } }