~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sh/mm/tlb-debugfs.c

Version: ~ [ linux-5.10-rc1 ] ~ [ linux-5.9.1 ] ~ [ linux-5.8.16 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.72 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.152 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.202 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.240 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.240 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * arch/sh/mm/tlb-debugfs.c
  3  *
  4  * debugfs ops for SH-4 ITLB/UTLBs.
  5  *
  6  * Copyright (C) 2010  Matt Fleming
  7  *
  8  * This file is subject to the terms and conditions of the GNU General Public
  9  * License.  See the file "COPYING" in the main directory of this archive
 10  * for more details.
 11  */
 12 #include <linux/init.h>
 13 #include <linux/module.h>
 14 #include <linux/debugfs.h>
 15 #include <linux/seq_file.h>
 16 #include <asm/processor.h>
 17 #include <asm/mmu_context.h>
 18 #include <asm/tlbflush.h>
 19 
 20 enum tlb_type {
 21         TLB_TYPE_ITLB,
 22         TLB_TYPE_UTLB,
 23 };
 24 
 25 static struct {
 26         int bits;
 27         const char *size;
 28 } tlb_sizes[] = {
 29         { 0x0, "  1KB" },
 30         { 0x1, "  4KB" },
 31         { 0x2, "  8KB" },
 32         { 0x4, " 64KB" },
 33         { 0x5, "256KB" },
 34         { 0x7, "  1MB" },
 35         { 0x8, "  4MB" },
 36         { 0xc, " 64MB" },
 37 };
 38 
 39 static int tlb_seq_show(struct seq_file *file, void *iter)
 40 {
 41         unsigned int tlb_type = (unsigned int)file->private;
 42         unsigned long addr1, addr2, data1, data2;
 43         unsigned long flags;
 44         unsigned long mmucr;
 45         unsigned int nentries, entry;
 46         unsigned int urb;
 47 
 48         mmucr = __raw_readl(MMUCR);
 49         if ((mmucr & 0x1) == 0) {
 50                 seq_printf(file, "address translation disabled\n");
 51                 return 0;
 52         }
 53 
 54         if (tlb_type == TLB_TYPE_ITLB) {
 55                 addr1 = MMU_ITLB_ADDRESS_ARRAY;
 56                 addr2 = MMU_ITLB_ADDRESS_ARRAY2;
 57                 data1 = MMU_ITLB_DATA_ARRAY;
 58                 data2 = MMU_ITLB_DATA_ARRAY2;
 59                 nentries = 4;
 60         } else {
 61                 addr1 = MMU_UTLB_ADDRESS_ARRAY;
 62                 addr2 = MMU_UTLB_ADDRESS_ARRAY2;
 63                 data1 = MMU_UTLB_DATA_ARRAY;
 64                 data2 = MMU_UTLB_DATA_ARRAY2;
 65                 nentries = 64;
 66         }
 67 
 68         local_irq_save(flags);
 69         jump_to_uncached();
 70 
 71         urb = (mmucr & MMUCR_URB) >> MMUCR_URB_SHIFT;
 72 
 73         /* Make the "entry >= urb" test fail. */
 74         if (urb == 0)
 75                 urb = MMUCR_URB_NENTRIES + 1;
 76 
 77         if (tlb_type == TLB_TYPE_ITLB) {
 78                 addr1 = MMU_ITLB_ADDRESS_ARRAY;
 79                 addr2 = MMU_ITLB_ADDRESS_ARRAY2;
 80                 data1 = MMU_ITLB_DATA_ARRAY;
 81                 data2 = MMU_ITLB_DATA_ARRAY2;
 82                 nentries = 4;
 83         } else {
 84                 addr1 = MMU_UTLB_ADDRESS_ARRAY;
 85                 addr2 = MMU_UTLB_ADDRESS_ARRAY2;
 86                 data1 = MMU_UTLB_DATA_ARRAY;
 87                 data2 = MMU_UTLB_DATA_ARRAY2;
 88                 nentries = 64;
 89         }
 90 
 91         seq_printf(file, "entry:     vpn        ppn     asid  size valid wired\n");
 92 
 93         for (entry = 0; entry < nentries; entry++) {
 94                 unsigned long vpn, ppn, asid, size;
 95                 unsigned long valid;
 96                 unsigned long val;
 97                 const char *sz = "    ?";
 98                 int i;
 99 
100                 val = __raw_readl(addr1 | (entry << MMU_TLB_ENTRY_SHIFT));
101                 ctrl_barrier();
102                 vpn = val & 0xfffffc00;
103                 valid = val & 0x100;
104 
105                 val = __raw_readl(addr2 | (entry << MMU_TLB_ENTRY_SHIFT));
106                 ctrl_barrier();
107                 asid = val & MMU_CONTEXT_ASID_MASK;
108 
109                 val = __raw_readl(data1 | (entry << MMU_TLB_ENTRY_SHIFT));
110                 ctrl_barrier();
111                 ppn = (val & 0x0ffffc00) << 4;
112 
113                 val = __raw_readl(data2 | (entry << MMU_TLB_ENTRY_SHIFT));
114                 ctrl_barrier();
115                 size = (val & 0xf0) >> 4;
116 
117                 for (i = 0; i < ARRAY_SIZE(tlb_sizes); i++) {
118                         if (tlb_sizes[i].bits == size)
119                                 break;
120                 }
121 
122                 if (i != ARRAY_SIZE(tlb_sizes))
123                         sz = tlb_sizes[i].size;
124 
125                 seq_printf(file, "%2d:    0x%08lx 0x%08lx %5lu %s   %s     %s\n",
126                            entry, vpn, ppn, asid,
127                            sz, valid ? "V" : "-",
128                            (urb <= entry) ? "W" : "-");
129         }
130 
131         back_to_cached();
132         local_irq_restore(flags);
133 
134         return 0;
135 }
136 
137 static int tlb_debugfs_open(struct inode *inode, struct file *file)
138 {
139         return single_open(file, tlb_seq_show, inode->i_private);
140 }
141 
142 static const struct file_operations tlb_debugfs_fops = {
143         .owner          = THIS_MODULE,
144         .open           = tlb_debugfs_open,
145         .read           = seq_read,
146         .llseek         = seq_lseek,
147         .release        = single_release,
148 };
149 
150 static int __init tlb_debugfs_init(void)
151 {
152         struct dentry *itlb, *utlb;
153 
154         itlb = debugfs_create_file("itlb", S_IRUSR, arch_debugfs_dir,
155                                    (unsigned int *)TLB_TYPE_ITLB,
156                                    &tlb_debugfs_fops);
157         if (unlikely(!itlb))
158                 return -ENOMEM;
159 
160         utlb = debugfs_create_file("utlb", S_IRUSR, arch_debugfs_dir,
161                                    (unsigned int *)TLB_TYPE_UTLB,
162                                    &tlb_debugfs_fops);
163         if (unlikely(!utlb)) {
164                 debugfs_remove(itlb);
165                 return -ENOMEM;
166         }
167 
168         return 0;
169 }
170 module_init(tlb_debugfs_init);
171 
172 MODULE_LICENSE("GPL v2");
173 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp