Signed-off-by: Eric Nelson <e...@nelint.com> --- drivers/block/Makefile | 1 + drivers/block/cache_block.c | 76 +++++++++++++++++++++++++++++++++++++++++++++ include/part.h | 65 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 drivers/block/cache_block.c
diff --git a/drivers/block/Makefile b/drivers/block/Makefile index b5c7ae1..056a48b 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_IDE_SIL680) += sil680.o obj-$(CONFIG_SANDBOX) += sandbox.o obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o obj-$(CONFIG_SYSTEMACE) += systemace.o +obj-$(CONFIG_BLOCK_CACHE) += cache_block.o diff --git a/drivers/block/cache_block.c b/drivers/block/cache_block.c new file mode 100644 index 0000000..12e60ac --- /dev/null +++ b/drivers/block/cache_block.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) Nelson Integration, LLC 2016 + * Author: Eric Nelson<e...@nelint.com> + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ +#include <config.h> +#include <common.h> +#include <malloc.h> +#include <part.h> + +#define MAX_CACHEBLOCKS 8 + +static int cache_iftype = -1; +static int cache_devnum = -1; +static lbaint_t cache_start = -1; +static lbaint_t cache_blkcnt = -1; +static unsigned long cache_blksz; +static void *cache; + +int cache_block_read(int iftype, int dev, + lbaint_t start, lbaint_t blkcnt, + unsigned long blksz, void *buffer) +{ + if ((iftype == cache_iftype) && + (dev == cache_devnum) && + (start == cache_start) && + (blkcnt <= cache_blkcnt) && + (blksz == cache_blksz) && + (cache != 0)) { + memcpy(buffer, cache, blksz*blkcnt); + return 1; + } + return 0; +} + +void cache_block_fill(int iftype, int dev, + lbaint_t start, lbaint_t blkcnt, + unsigned long blksz, void const *buffer) +{ + lbaint_t bytes; + + /* don't cache big stuff */ + if (blkcnt > MAX_CACHEBLOCKS) + return; + + bytes = blksz*blkcnt; + if (cache != 0) { + if (bytes != (cache_blksz*cache_blkcnt)) { + free(cache); + cache = malloc(blksz*blkcnt); + if (!cache) + return; + } /* change in size */ + } else { + cache = malloc(blksz*blkcnt); + if (!cache) + return; + } + memcpy(cache, buffer, bytes); + cache_iftype = iftype; + cache_devnum = dev; + cache_start = start; + cache_blkcnt = blkcnt; + cache_blksz = blksz; +} + +void cache_block_invalidate(int iftype, int dev) +{ + cache_iftype = -1; + if (cache) { + free(cache); + cache = 0; + } +} diff --git a/include/part.h b/include/part.h index 6d8f520..21f820f 100644 --- a/include/part.h +++ b/include/part.h @@ -369,4 +369,69 @@ int gpt_verify_partitions(struct blk_desc *dev_desc, gpt_header *gpt_head, gpt_entry **gpt_pte); #endif +#ifdef CONFIG_BLOCK_CACHE +/** + * cache_block_read() - attempt to read a set of blocks from cache + * + * @param iftype - IF_TYPE_x for type of device + * @param dev - device index of particular type + * @param start - starting block number + * @param blkcnt - number of blocks to read + * @param blksz - size in bytes of each block + * @param buf - buffer to contain cached data + * + * @return - '1' if block returned from cache, '0' otherwise. + */ +int cache_block_read + (int iftype, int dev, + lbaint_t start, lbaint_t blkcnt, + unsigned long blksz, void *buffer); + +/** + * cache_block_fill() - make data read from a block device available + * to the block cache + * + * @param iftype - IF_TYPE_x for type of device + * @param dev - device index of particular type + * @param start - starting block number + * @param blkcnt - number of blocks available + * @param blksz - size in bytes of each block + * @param buf - buffer containing data to cache + * + */ +void cache_block_fill + (int iftype, int dev, + lbaint_t start, lbaint_t blkcnt, + unsigned long blksz, void const *buffer); + +/** + * cache_block_invalidate() - discard the cache for a set of blocks + * because of a write or device (re)initialization. + * + * @param iftype - IF_TYPE_x for type of device + * @param dev - device index of particular type + */ +void cache_block_invalidate + (int iftype, int dev); + +#else + +static inline int cache_block_read + (int iftype, int dev, + lbaint_t start, lbaint_t blkcnt, + unsigned long blksz, void *buffer) +{ + return 0; +} + +static inline void cache_block_fill + (int iftype, int dev, + lbaint_t start, lbaint_t blkcnt, + unsigned long blksz, void const *buffer) {} + +static inline void cache_block_invalidate + (int iftype, int dev) {} + +#endif + #endif /* _PART_H */ -- 2.6.2 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot