[U-Boot] [RFC PATCH 1/2] add block device cache

Eric Nelson
2016-03-16T21:40:23Z

Signed-off-by: Eric Nelson <eric@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<eric@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