00001
00044 #include "kblock_ram.h"
00045 #include <string.h>
00046
00047
00048 static int kblockram_load(KBlock *b, block_idx_t index)
00049 {
00050 KBlockRam *r = KBLOCKRAM_CAST(b);
00051 memcpy(r->b.priv.buf, r->membuf + index * r->b.blk_size, r->b.blk_size);
00052 return 0;
00053 }
00054
00055 static int kblockram_store(struct KBlock *b, block_idx_t index)
00056 {
00057 KBlockRam *r = KBLOCKRAM_CAST(b);
00058 memcpy(r->membuf + index * r->b.blk_size, r->b.priv.buf, r->b.blk_size);
00059 return 0;
00060 }
00061
00062 static size_t kblockram_readBuf(struct KBlock *b, void *buf, size_t offset, size_t size)
00063 {
00064 KBlockRam *r = KBLOCKRAM_CAST(b);
00065 memcpy(buf, (uint8_t *)r->b.priv.buf + offset, size);
00066 return size;
00067 }
00068
00069 static size_t kblockram_readDirect(struct KBlock *b, block_idx_t index, void *buf, size_t offset, size_t size)
00070 {
00071 KBlockRam *r = KBLOCKRAM_CAST(b);
00072 memcpy(buf, r->membuf + index * r->b.blk_size + offset, size);
00073 return size;
00074 }
00075
00076 static size_t kblockram_writeBuf(struct KBlock *b, const void *buf, size_t offset, size_t size)
00077 {
00078 KBlockRam *r = KBLOCKRAM_CAST(b);
00079 memcpy((uint8_t *)r->b.priv.buf + offset, buf, size);
00080 return size;
00081 }
00082
00083 static size_t kblockram_writeDirect(struct KBlock *b, block_idx_t index, const void *buf, size_t offset, size_t size)
00084 {
00085 KBlockRam *r = KBLOCKRAM_CAST(b);
00086 ASSERT(buf);
00087 ASSERT(index < b->blk_cnt);
00088
00089 memcpy(r->membuf + index * r->b.blk_size + offset, buf, size);
00090 return size;
00091 }
00092
00093 static int kblockram_dummy(UNUSED_ARG(struct KBlock *,b))
00094 {
00095 return 0;
00096 }
00097
00098 static const KBlockVTable kblockram_hwbuffered_vt =
00099 {
00100 .readDirect = kblockram_readDirect,
00101
00102 .readBuf = kblockram_readBuf,
00103 .writeBuf = kblockram_writeBuf,
00104 .load = kblockram_load,
00105 .store = kblockram_store,
00106
00107 .error = kblockram_dummy,
00108 .clearerr = (kblock_clearerr_t)kblockram_dummy,
00109 .close = kblockram_dummy,
00110 };
00111
00112
00113 static const KBlockVTable kblockram_swbuffered_vt =
00114 {
00115 .readDirect = kblockram_readDirect,
00116 .writeDirect = kblockram_writeDirect,
00117
00118 .readBuf = kblock_swReadBuf,
00119 .writeBuf = kblock_swWriteBuf,
00120 .load = kblock_swLoad,
00121 .store = kblock_swStore,
00122
00123 .error = kblockram_dummy,
00124 .clearerr = (kblock_clearerr_t)kblockram_dummy,
00125 .close = kblockram_dummy,
00126 };
00127
00128 static const KBlockVTable kblockram_unbuffered_vt =
00129 {
00130 .readDirect = kblockram_readDirect,
00131 .writeDirect = kblockram_writeDirect,
00132
00133 .error = kblockram_dummy,
00134 .clearerr = (kblock_clearerr_t)kblockram_dummy,
00135 .close = kblockram_dummy,
00136 };
00137
00138 void kblockram_init(KBlockRam *ram, void *buf, size_t size, size_t block_size, bool buffered, bool hwbuffered)
00139 {
00140 ASSERT(buf);
00141 ASSERT(size);
00142 ASSERT(block_size);
00143
00144 memset(ram, 0, sizeof(*ram));
00145
00146 DB(ram->b.priv.type = KBT_KBLOCKRAM);
00147 ram->b.blk_size = block_size;
00148 ram->b.priv.flags |= KB_PARTIAL_WRITE;
00149
00150 if (buffered)
00151 {
00152 ram->b.priv.flags |= KB_BUFFERED;
00153 ram->b.blk_cnt = (size / block_size) - 1;
00154 ram->b.priv.buf = buf;
00155
00156 ram->membuf = (uint8_t *)buf + block_size;
00157
00158 if (hwbuffered)
00159 ram->b.priv.vt = &kblockram_hwbuffered_vt;
00160 else
00161 ram->b.priv.vt = &kblockram_swbuffered_vt;
00162
00163 kblockram_load(&ram->b, 0);
00164 }
00165 else
00166 {
00167 ram->b.blk_cnt = (size / block_size);
00168 ram->membuf = (uint8_t *)buf;
00169 ram->b.priv.vt = &kblockram_unbuffered_vt;
00170 }
00171 }