// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) Nelson Integration, LLC 2016
 * Author: Eric Nelson<eric@nelint.com>
 *
 */
#include <common.h>
#include <blk.h>
#include <log.h>
#include <malloc.h>
#include <part.h>
#include <asm/global_data.h>
#include <linux/ctype.h>
#include <linux/list.h>

struct block_cache_node {
	struct list_head lh;
	int iftype;
	int devnum;
	lbaint_t start;
	lbaint_t blkcnt;
	unsigned long blksz;
	char *cache;
};

static LIST_HEAD(block_cache);

static struct block_cache_stats _stats = {
	.max_blocks_per_entry = 8,
	.max_entries = 32
};

static struct block_cache_node *cache_find(int iftype, int devnum,
					   lbaint_t start, lbaint_t blkcnt,
					   unsigned long blksz)
{
	struct block_cache_node *node;

	list_for_each_entry(node, &block_cache, lh)
		if ((node->iftype == iftype) &&
		    (node->devnum == devnum) &&
		    (node->blksz == blksz) &&
		    (node->start <= start) &&
		    (node->start + node->blkcnt >= start + blkcnt)) {
			if (block_cache.next != &node->lh) {
				/* maintain MRU ordering */
				list_del(&node->lh);
				list_add(&node->lh, &block_cache);
			}
			return node;
		}
	return 0;
}

int blkcache_read(int iftype, int devnum,
		  lbaint_t start, lbaint_t blkcnt,
		  unsigned long blksz, void *buffer)
{
	struct block_cache_node *node = cache_find(iftype, devnum, start,
						   blkcnt, blksz);
	if (node) {
		const char *src = node->cache + (start - node->start) * blksz;
		memcpy(buffer, src, blksz * blkcnt);
		debug("hit: start " LBAF ", count " LBAFU "\n",
		      start, blkcnt);
		++_stats.hits;
		return 1;
	}

	debug("miss: start " LBAF ", count " LBAFU "\n",
	      start, blkcnt);
	++_stats.misses;
	return 0;
}

void blkcache_fill(int iftype, int devnum,
		   lbaint_t start, lbaint_t blkcnt,
		   unsigned long blksz, void const *buffer)
{
	lbaint_t bytes;
	struct block_cache_node *node;

	/* don't cache big stuff */
	if (blkcnt > _stats.max_blocks_per_entry)
		return;

	if (_stats.max_entries == 0)
		return;

	bytes = blksz * blkcnt;
	if (_stats.max_entries <= _stats.entries) {
		/* pop LRU */
		node = (struct block_cache_node *)block_cache.prev;
		list_del(&node->lh);
		_stats.entries--;
		debug("drop: start " LBAF ", count " LBAFU "\n",
		      node->start, node->blkcnt);
		if (node->blkcnt * node->blksz < bytes) {
			free(node->cache);
			node->cache = 0;
		}
	} else {
		node = malloc(sizeof(*node));
		if (!node)
			return;
		node->cache = 0;
	}

	if (!node->cache) {
		node->cache = malloc(bytes);
		if (!node->cache) {
			free(node);
			return;
		}
	}

	debug("fill: start " LBAF ", count " LBAFU "\n",
	      start, blkcnt);

	node->iftype = iftype;
	node->devnum = devnum;
	node->start = start;
	node->blkcnt = blkcnt;
	node->blksz = blksz;
	memcpy(node->cache, buffer, bytes);
	list_add(&node->lh, &block_cache);
	_stats.entries++;
}

void blkcache_invalidate(int iftype, int devnum)
{
	struct list_head *entry, *n;
	struct block_cache_node *node;

	list_for_each_safe(entry, n, &block_cache) {
		node = (struct block_cache_node *)entry;
		if (iftype == -1 ||
		    (node->iftype == iftype && node->devnum == devnum)) {
			list_del(entry);
			free(node->cache);
			free(node);
			--_stats.entries;
		}
	}
}

void blkcache_configure(unsigned blocks, unsigned entries)
{
	/* invalidate cache if there is a change */
	if ((blocks != _stats.max_blocks_per_entry) ||
	    (entries != _stats.max_entries))
		blkcache_invalidate(-1, 0);

	_stats.max_blocks_per_entry = blocks;
	_stats.max_entries = entries;

	_stats.hits = 0;
	_stats.misses = 0;
}

void blkcache_stats(struct block_cache_stats *stats)
{
	memcpy(stats, &_stats, sizeof(*stats));
	_stats.hits = 0;
	_stats.misses = 0;
}

void blkcache_free(void)
{
	blkcache_invalidate(-1, 0);
}
