linux/arch/sh/mm/cache-debugfs.c
<<
>>
Prefs
   1/*
   2 * debugfs ops for the L1 cache
   3 *
   4 *  Copyright (C) 2006  Paul Mundt
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file "COPYING" in the main directory of this archive
   8 * for more details.
   9 */
  10#include <linux/init.h>
  11#include <linux/module.h>
  12#include <linux/debugfs.h>
  13#include <linux/seq_file.h>
  14#include <asm/processor.h>
  15#include <linux/uaccess.h>
  16#include <asm/cache.h>
  17#include <asm/io.h>
  18
  19enum cache_type {
  20        CACHE_TYPE_ICACHE,
  21        CACHE_TYPE_DCACHE,
  22        CACHE_TYPE_UNIFIED,
  23};
  24
  25static int cache_seq_show(struct seq_file *file, void *iter)
  26{
  27        unsigned int cache_type = (unsigned int)file->private;
  28        struct cache_info *cache;
  29        unsigned int waysize, way;
  30        unsigned long ccr;
  31        unsigned long addrstart = 0;
  32
  33        /*
  34         * Go uncached immediately so we don't skew the results any
  35         * more than we already are..
  36         */
  37        jump_to_uncached();
  38
  39        ccr = __raw_readl(SH_CCR);
  40        if ((ccr & CCR_CACHE_ENABLE) == 0) {
  41                back_to_cached();
  42
  43                seq_printf(file, "disabled\n");
  44                return 0;
  45        }
  46
  47        if (cache_type == CACHE_TYPE_DCACHE) {
  48                addrstart = CACHE_OC_ADDRESS_ARRAY;
  49                cache = &current_cpu_data.dcache;
  50        } else {
  51                addrstart = CACHE_IC_ADDRESS_ARRAY;
  52                cache = &current_cpu_data.icache;
  53        }
  54
  55        waysize = cache->sets;
  56
  57        /*
  58         * If the OC is already in RAM mode, we only have
  59         * half of the entries to consider..
  60         */
  61        if ((ccr & CCR_CACHE_ORA) && cache_type == CACHE_TYPE_DCACHE)
  62                waysize >>= 1;
  63
  64        waysize <<= cache->entry_shift;
  65
  66        for (way = 0; way < cache->ways; way++) {
  67                unsigned long addr;
  68                unsigned int line;
  69
  70                seq_printf(file, "-----------------------------------------\n");
  71                seq_printf(file, "Way %d\n", way);
  72                seq_printf(file, "-----------------------------------------\n");
  73
  74                for (addr = addrstart, line = 0;
  75                     addr < addrstart + waysize;
  76                     addr += cache->linesz, line++) {
  77                        unsigned long data = __raw_readl(addr);
  78
  79                        /* Check the V bit, ignore invalid cachelines */
  80                        if ((data & 1) == 0)
  81                                continue;
  82
  83                        /* U: Dirty, cache tag is 10 bits up */
  84                        seq_printf(file, "%3d: %c 0x%lx\n",
  85                                   line, data & 2 ? 'U' : ' ',
  86                                   data & 0x1ffffc00);
  87                }
  88
  89                addrstart += cache->way_incr;
  90        }
  91
  92        back_to_cached();
  93
  94        return 0;
  95}
  96
  97static int cache_debugfs_open(struct inode *inode, struct file *file)
  98{
  99        return single_open(file, cache_seq_show, inode->i_private);
 100}
 101
 102static const struct file_operations cache_debugfs_fops = {
 103        .owner          = THIS_MODULE,
 104        .open           = cache_debugfs_open,
 105        .read           = seq_read,
 106        .llseek         = seq_lseek,
 107        .release        = single_release,
 108};
 109
 110static int __init cache_debugfs_init(void)
 111{
 112        struct dentry *dcache_dentry, *icache_dentry;
 113
 114        dcache_dentry = debugfs_create_file("dcache", S_IRUSR, arch_debugfs_dir,
 115                                            (unsigned int *)CACHE_TYPE_DCACHE,
 116                                            &cache_debugfs_fops);
 117        if (!dcache_dentry)
 118                return -ENOMEM;
 119
 120        icache_dentry = debugfs_create_file("icache", S_IRUSR, arch_debugfs_dir,
 121                                            (unsigned int *)CACHE_TYPE_ICACHE,
 122                                            &cache_debugfs_fops);
 123        if (!icache_dentry) {
 124                debugfs_remove(dcache_dentry);
 125                return -ENOMEM;
 126        }
 127
 128        return 0;
 129}
 130module_init(cache_debugfs_init);
 131
 132MODULE_LICENSE("GPL v2");
 133