*
* \author Francesco Sacchi <batt@develer.com>
*
- * \brief KBlock interface
+ * \brief KBlock interface on RAM memory
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ *
+ * $WIZ$ module_name = "kfile_ram"
+ * $WIZ$ module_depends = "kblock"
*/
static int kblockram_load(KBlock *b, block_idx_t index)
{
KBlockRam *r = KBLOCKRAM_CAST(b);
- memcpy(r->b.priv.pagebuf, r->membuf + index * r->b.blk_size, r->b.blk_size);
+ 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.pagebuf, r->b.blk_size);
+ 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.pagebuf + offset, size);
+ memcpy(buf, (uint8_t *)r->b.priv.buf + offset, size);
return size;
}
-static size_t kblockram_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t 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((uint8_t *)r->b.priv.pagebuf + offset, buf, size);
+ memcpy(buf, r->membuf + index * r->b.blk_size + offset, size);
return size;
}
-static void * kblockram_map(struct KBlock *b, size_t offset, UNUSED_ARG(size_t, size))
+static size_t kblockram_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size)
{
- return (uint8_t *)b->priv.pagebuf + offset;
+ KBlockRam *r = KBLOCKRAM_CAST(b);
+ memcpy((uint8_t *)r->b.priv.buf + offset, buf, size);
+ return size;
}
-
-static int kblockram_unmap(UNUSED_ARG(struct KBlock *, b), UNUSED_ARG(size_t, offset), UNUSED_ARG(size_t, size))
+static size_t kblockram_writeDirect(struct KBlock *b, block_idx_t index, const void *buf, size_t offset, size_t size)
{
- return 0;
-}
+ KBlockRam *r = KBLOCKRAM_CAST(b);
+ ASSERT(buf);
+ ASSERT(index < b->blk_cnt);
-static int kblockram_error(struct KBlock *b)
-{
- return b->priv.flags;
+ 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 KBlockVTable kblockram_vt =
+static const KBlockVTable kblockram_hwbuffered_vt =
{
+ .readDirect = kblockram_readDirect,
+
.readBuf = kblockram_readBuf,
.writeBuf = kblockram_writeBuf,
.load = kblockram_load,
.store = kblockram_store,
- .map = kblockram_map,
- .unmap = kblockram_unmap,
- .error = kblockram_error,
- .clearerr = kblockram_dummy,
+
+ .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)
+
+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);
-
- // First page used as page buffer
- ram->b.blk_cnt = (size / block_size) - 1;
- ram->b.priv.pagebuf = buf;
- ram->b.priv.pagebuf_size = block_size;
-
- ram->membuf = (uint8_t *)buf + block_size;
- ram->b.blk_size = block_size;
- ram->b.vt = &kblockram_vt;
+ 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;
+ }
}