/*
 * debugfs ops for the L1 cache
 *
 *  Copyright (C) 2006  Paul Mundt
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/cache.h>
#include <asm/io.h>

enum cache_type {
	CACHE_TYPE_ICACHE,
	CACHE_TYPE_DCACHE,
	CACHE_TYPE_UNIFIED,
};

static int cache_seq_show(struct seq_file *file, void *iter)
{
	unsigned int cache_type = (unsigned int)file->private;
	struct cache_info *cache;
	unsigned int waysize, way, cache_size;
	unsigned long ccr, base;
	static unsigned long addrstart = 0;

	/*
	 * Go uncached immediately so we don't skew the results any
	 * more than we already are..
	 */
	jump_to_uncached();

	ccr = __raw_readl(CCR);
	if ((ccr & CCR_CACHE_ENABLE) == 0) {
		back_to_cached();

		seq_printf(file, "disabled\n");
		return 0;
	}

	if (cache_type == CACHE_TYPE_DCACHE) {
		base = CACHE_OC_ADDRESS_ARRAY;
		cache = &current_cpu_data.dcache;
	} else {
		base = CACHE_IC_ADDRESS_ARRAY;
		cache = &current_cpu_data.icache;
	}

	/*
	 * Due to the amount of data written out (depending on the cache size),
	 * we may be iterated over multiple times. In this case, keep track of
	 * the entry position in addrstart, and rewind it when we've hit the
	 * end of the cache.
	 *
	 * Likewise, the same code is used for multiple caches, so care must
	 * be taken for bouncing addrstart back and forth so the appropriate
	 * cache is hit.
	 */
	cache_size = cache->ways * cache->sets * cache->linesz;
	if (((addrstart & 0xff000000) != base) ||
	     (addrstart & 0x00ffffff) > cache_size)
		addrstart = base;

	waysize = cache->sets;

	/*
	 * If the OC is already in RAM mode, we only have
	 * half of the entries to consider..
	 */
	if ((ccr & CCR_CACHE_ORA) && cache_type == CACHE_TYPE_DCACHE)
		waysize >>= 1;

	waysize <<= cache->entry_shift;

	for (way = 0; way < cache->ways; way++) {
		unsigned long addr;
		unsigned int line;

		seq_printf(file, "-----------------------------------------\n");
		seq_printf(file, "Way %d\n", way);
		seq_printf(file, "-----------------------------------------\n");

		for (addr = addrstart, line = 0;
		     addr < addrstart + waysize;
		     addr += cache->linesz, line++) {
			unsigned long data = __raw_readl(addr);

			/* Check the V bit, ignore invalid cachelines */
			if ((data & 1) == 0)
				continue;

			/* U: Dirty, cache tag is 10 bits up */
			seq_printf(file, "%3d: %c 0x%lx\n",
				   line, data & 2 ? 'U' : ' ',
				   data & 0x1ffffc00);
		}

		addrstart += cache->way_incr;
	}

	back_to_cached();

	return 0;
}

static int cache_debugfs_open(struct inode *inode, struct file *file)
{
	return single_open(file, cache_seq_show, inode->i_private);
}

static const struct file_operations cache_debugfs_fops = {
	.owner		= THIS_MODULE,
	.open		= cache_debugfs_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int __init cache_debugfs_init(void)
{
	struct dentry *dcache_dentry, *icache_dentry;

	dcache_dentry = debugfs_create_file("dcache", S_IRUSR, arch_debugfs_dir,
					    (unsigned int *)CACHE_TYPE_DCACHE,
					    &cache_debugfs_fops);
	if (!dcache_dentry)
		return -ENOMEM;

	icache_dentry = debugfs_create_file("icache", S_IRUSR, arch_debugfs_dir,
					    (unsigned int *)CACHE_TYPE_ICACHE,
					    &cache_debugfs_fops);
	if (!icache_dentry) {
		debugfs_remove(dcache_dentry);
		return -ENOMEM;
	}

	return 0;
}
module_init(cache_debugfs_init);

MODULE_LICENSE("GPL v2");
