6#include "module_debug.h"
8#define SECTORS_PER_BLOCK 8
10#define BLOCK_WEIGHT_FACTOR 256
15 int weight[BLOCK_COUNT];
16 u64 sector[BLOCK_COUNT];
17 u8 cache[BLOCK_COUNT][SECTORS_PER_BLOCK*512];
26static int _overlaps(u64 csector, u64 sector, u16
count)
28 if ((sector < (csector + SECTORS_PER_BLOCK)) && ((sector +
count) > csector))
35static int _contains(u64 csector, u64 sector, u16
count)
37 if ((sector >= csector) && ((sector +
count) <= (csector + SECTORS_PER_BLOCK)))
43static void _invalidate(
struct bd_cache *c, u64 sector, u16
count)
47 for (blkidx = 0; blkidx < BLOCK_COUNT; blkidx++) {
48 if (_overlaps(c->sector[blkidx], sector,
count)) {
50 c->sector[blkidx] = 0xffffffffffffffff;
59 DEBUG_U64_2XU32(sector);
60 M_DEBUG(
"%s(0x%08x%08x, %d)\n", __FUNCTION__, sector_u32[1], sector_u32[0],
count);
62 if (
count >= SECTORS_PER_BLOCK) {
64 return c->bd->read(c->bd, sector, buffer,
count);
68 c->sectors_read +=
count;
73 for (blkidx = 0; blkidx < BLOCK_COUNT; blkidx++) {
74 if (_contains(c->sector[blkidx], sector,
count)) {
76 c->sectors_cache +=
count;
80 if (c->weight[blkidx] < 0)
81 c->weight[blkidx] = 0;
83 c->weight[blkidx] +=
count * BLOCK_WEIGHT_FACTOR;
86 u64 offset = (sector - c->sector[blkidx]) * 512;
87 memcpy(buffer, &c->cache[blkidx][offset],
count * 512);
93 int blkidx_best_weight = 0x7fffffff;
96 for (blkidx = 0; blkidx < BLOCK_COUNT; blkidx++) {
98 printf(
"%*d ", 3, c->weight[blkidx] / BLOCK_WEIGHT_FACTOR);
102 c->weight[blkidx] -= (SECTORS_PER_BLOCK * BLOCK_WEIGHT_FACTOR / BLOCK_COUNT) + (c->weight[blkidx] / 32);
104 if (c->weight[blkidx] < blkidx_best_weight) {
106 blkidx_best_weight = c->weight[blkidx];
107 blkidx_best = blkidx;
111 printf(
" devread: %*d, evict %*d [%*d], add [%*d]\n", 4, c->sectors_dev, 2, blkidx_best, 8, c->sector[blkidx_best], 8, sector);
112 c->sectors_dev += SECTORS_PER_BLOCK;
117 c->bd->read(c->bd, sector, c->cache[blkidx_best], SECTORS_PER_BLOCK);
118 c->sector[blkidx_best] = sector;
121 u64 offset = (sector - c->sector[blkidx_best]) * 512;
122 c->weight[blkidx_best] =
count * BLOCK_WEIGHT_FACTOR;
123 memcpy(buffer, &c->cache[blkidx_best][offset],
count * 512);
127static int _write(
struct block_device *bd, u64 sector,
const void *buffer, u16
count)
131 DEBUG_U64_2XU32(sector);
132 M_DEBUG(
"%s(0x%08x%08x, %d)\n", __FUNCTION__, sector_u32[1], sector_u32[0],
count);
134 _invalidate(c, sector,
count);
136 return c->bd->write(c->bd, sector, buffer,
count);
143 M_DEBUG(
"%s\n", __FUNCTION__);
145 return c->bd->flush(c->bd);
152 M_DEBUG(
"%s\n", __FUNCTION__);
154 return c->bd->stop(c->bd);
164 struct bd_cache *c = AllocSysMemory(ALLOC_FIRST,
sizeof(
struct bd_cache), NULL);
166 M_DEBUG(
"%s\n", __FUNCTION__);
169 for (blkidx = 0; blkidx < BLOCK_COUNT; blkidx++) {
170 c->weight[blkidx] = 0;
171 c->sector[blkidx] = 0xffffffffffffffff;
175 c->sectors_cache = 0;
182 cbd->name = bd->name;
183 cbd->devNr = bd->devNr;
184 cbd->parNr = bd->parNr;
185 cbd->parId = bd->parId;
186 cbd->sectorSize = bd->sectorSize;
187 cbd->sectorOffset = bd->sectorOffset;
188 cbd->sectorCount = bd->sectorCount;
200 M_DEBUG(
"%s\n", __FUNCTION__);
202 FreeSysMemory(cbd->priv);
u32 count
start sector of fragmented bd/file