2 * arch/sh/mm/tlb-debugfs.c
4 * debugfs ops for SH-4 ITLB/UTLBs.
6 * Copyright (C) 2010 Matt Fleming
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
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>
39 static int tlb_seq_show(struct seq_file
*file
, void *iter
)
41 unsigned int tlb_type
= (unsigned int)file
->private;
42 unsigned long addr1
, addr2
, data1
, data2
;
45 unsigned int nentries
, entry
;
48 mmucr
= __raw_readl(MMUCR
);
49 if ((mmucr
& 0x1) == 0) {
50 seq_printf(file
, "address translation disabled\n");
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
;
61 addr1
= MMU_UTLB_ADDRESS_ARRAY
;
62 addr2
= MMU_UTLB_ADDRESS_ARRAY2
;
63 data1
= MMU_UTLB_DATA_ARRAY
;
64 data2
= MMU_UTLB_DATA_ARRAY2
;
68 local_irq_save(flags
);
71 urb
= (mmucr
& MMUCR_URB
) >> MMUCR_URB_SHIFT
;
73 /* Make the "entry >= urb" test fail. */
75 urb
= MMUCR_URB_NENTRIES
+ 1;
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
;
84 addr1
= MMU_UTLB_ADDRESS_ARRAY
;
85 addr2
= MMU_UTLB_ADDRESS_ARRAY2
;
86 data1
= MMU_UTLB_DATA_ARRAY
;
87 data2
= MMU_UTLB_DATA_ARRAY2
;
91 seq_printf(file
, "entry: vpn ppn asid size valid wired\n");
93 for (entry
= 0; entry
< nentries
; entry
++) {
94 unsigned long vpn
, ppn
, asid
, size
;
97 const char *sz
= " ?";
100 val
= __raw_readl(addr1
| (entry
<< MMU_TLB_ENTRY_SHIFT
));
102 vpn
= val
& 0xfffffc00;
105 val
= __raw_readl(addr2
| (entry
<< MMU_TLB_ENTRY_SHIFT
));
107 asid
= val
& MMU_CONTEXT_ASID_MASK
;
109 val
= __raw_readl(data1
| (entry
<< MMU_TLB_ENTRY_SHIFT
));
111 ppn
= (val
& 0x0ffffc00) << 4;
113 val
= __raw_readl(data2
| (entry
<< MMU_TLB_ENTRY_SHIFT
));
115 size
= (val
& 0xf0) >> 4;
117 for (i
= 0; i
< ARRAY_SIZE(tlb_sizes
); i
++) {
118 if (tlb_sizes
[i
].bits
== size
)
122 if (i
!= ARRAY_SIZE(tlb_sizes
))
123 sz
= tlb_sizes
[i
].size
;
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" : "-");
132 local_irq_restore(flags
);
137 static int tlb_debugfs_open(struct inode
*inode
, struct file
*file
)
139 return single_open(file
, tlb_seq_show
, inode
->i_private
);
142 static const struct file_operations tlb_debugfs_fops
= {
143 .owner
= THIS_MODULE
,
144 .open
= tlb_debugfs_open
,
147 .release
= single_release
,
150 static int __init
tlb_debugfs_init(void)
152 struct dentry
*itlb
, *utlb
;
154 itlb
= debugfs_create_file("itlb", S_IRUSR
, arch_debugfs_dir
,
155 (unsigned int *)TLB_TYPE_ITLB
,
160 utlb
= debugfs_create_file("utlb", S_IRUSR
, arch_debugfs_dir
,
161 (unsigned int *)TLB_TYPE_UTLB
,
163 if (unlikely(!utlb
)) {
164 debugfs_remove(itlb
);
170 module_init(tlb_debugfs_init
);
172 MODULE_LICENSE("GPL v2");