Pull button into test branch
[sfrench/cifs-2.6.git] / arch / sh64 / lib / dbg.c
1 /*--------------------------------------------------------------------------
2 --
3 -- Identity : Linux50 Debug Funcions
4 --
5 -- File     : arch/sh64/lib/dbg.C
6 --
7 -- Copyright 2000, 2001 STMicroelectronics Limited.
8 -- Copyright 2004 Richard Curnow (evt_debug etc)
9 --
10 --------------------------------------------------------------------------*/
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/mm.h>
15 #include <asm/mmu_context.h>
16
17 typedef u64 regType_t;
18
19 static regType_t getConfigReg(u64 id)
20 {
21         register u64 reg __asm__("r2");
22         asm volatile ("getcfg   %1, 0, %0":"=r" (reg):"r"(id));
23         return (reg);
24 }
25
26 /* ======================================================================= */
27
28 static char *szTab[] = { "4k", "64k", "1M", "512M" };
29 static char *protTab[] = { "----",
30         "---R",
31         "--X-",
32         "--XR",
33         "-W--",
34         "-W-R",
35         "-WX-",
36         "-WXR",
37         "U---",
38         "U--R",
39         "U-X-",
40         "U-XR",
41         "UW--",
42         "UW-R",
43         "UWX-",
44         "UWXR"
45 };
46 #define  ITLB_BASE      0x00000000
47 #define  DTLB_BASE      0x00800000
48 #define  MAX_TLBs               64
49 /* PTE High */
50 #define  GET_VALID(pte)        ((pte) & 0x1)
51 #define  GET_SHARED(pte)       ((pte) & 0x2)
52 #define  GET_ASID(pte)         ((pte >> 2) & 0x0ff)
53 #define  GET_EPN(pte)          ((pte) & 0xfffff000)
54
55 /* PTE Low */
56 #define  GET_CBEHAVIOR(pte)    ((pte) & 0x3)
57 #define  GET_PAGE_SIZE(pte)    szTab[((pte >> 3) & 0x3)]
58 #define  GET_PROTECTION(pte)   protTab[((pte >> 6) & 0xf)]
59 #define  GET_PPN(pte)          ((pte) & 0xfffff000)
60
61 #define PAGE_1K_MASK           0x00000000
62 #define PAGE_4K_MASK           0x00000010
63 #define PAGE_64K_MASK          0x00000080
64 #define MMU_PAGESIZE_MASK      (PAGE_64K_MASK | PAGE_4K_MASK)
65 #define PAGE_1MB_MASK          MMU_PAGESIZE_MASK
66 #define PAGE_1K                (1024)
67 #define PAGE_4K                (1024 * 4)
68 #define PAGE_64K               (1024 * 64)
69 #define PAGE_1MB               (1024 * 1024)
70
71 #define HOW_TO_READ_TLB_CONTENT  \
72        "[ ID]  PPN         EPN        ASID  Share  CB  P.Size   PROT.\n"
73
74 void print_single_tlb(unsigned long tlb, int single_print)
75 {
76         regType_t pteH;
77         regType_t pteL;
78         unsigned int valid, shared, asid, epn, cb, ppn;
79         char *pSize;
80         char *pProt;
81
82         /*
83            ** in case of single print <single_print> is true, this implies:
84            **   1) print the TLB in any case also if NOT VALID
85            **   2) print out the header
86          */
87
88         pteH = getConfigReg(tlb);
89         valid = GET_VALID(pteH);
90         if (single_print)
91                 printk(HOW_TO_READ_TLB_CONTENT);
92         else if (!valid)
93                 return;
94
95         pteL = getConfigReg(tlb + 1);
96
97         shared = GET_SHARED(pteH);
98         asid = GET_ASID(pteH);
99         epn = GET_EPN(pteH);
100         cb = GET_CBEHAVIOR(pteL);
101         pSize = GET_PAGE_SIZE(pteL);
102         pProt = GET_PROTECTION(pteL);
103         ppn = GET_PPN(pteL);
104         printk("[%c%2ld]  0x%08x  0x%08x  %03d   %02x    %02x   %4s    %s\n",
105                ((valid) ? ' ' : 'u'), ((tlb & 0x0ffff) / TLB_STEP),
106                ppn, epn, asid, shared, cb, pSize, pProt);
107 }
108
109 void print_dtlb(void)
110 {
111         int count;
112         unsigned long tlb;
113
114         printk(" ================= SH-5 D-TLBs Status ===================\n");
115         printk(HOW_TO_READ_TLB_CONTENT);
116         tlb = DTLB_BASE;
117         for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP)
118                 print_single_tlb(tlb, 0);
119         printk
120             (" =============================================================\n");
121 }
122
123 void print_itlb(void)
124 {
125         int count;
126         unsigned long tlb;
127
128         printk(" ================= SH-5 I-TLBs Status ===================\n");
129         printk(HOW_TO_READ_TLB_CONTENT);
130         tlb = ITLB_BASE;
131         for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP)
132                 print_single_tlb(tlb, 0);
133         printk
134             (" =============================================================\n");
135 }
136
137 /* ======================================================================= */
138
139 #ifdef CONFIG_POOR_MANS_STRACE
140
141 #include "syscalltab.h"
142
143 struct ring_node {
144         int evt;
145         int ret_addr;
146         int event;
147         int tra;
148         int pid;
149         unsigned long sp;
150         unsigned long pc;
151 };
152
153 static struct ring_node event_ring[16];
154 static int event_ptr = 0;
155
156 struct stored_syscall_data {
157         int pid;
158         int syscall_number;
159 };
160
161 #define N_STORED_SYSCALLS 16
162
163 static struct stored_syscall_data stored_syscalls[N_STORED_SYSCALLS];
164 static int syscall_next=0;
165 static int syscall_next_print=0;
166
167 void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs)
168 {
169         int syscallno = tra & 0xff;
170         unsigned long sp;
171         unsigned long stack_bottom;
172         int pid;
173         struct ring_node *rr;
174
175         pid = current->pid;
176         stack_bottom = (unsigned long) task_stack_page(current);
177         asm volatile("ori r15, 0, %0" : "=r" (sp));
178         rr = event_ring + event_ptr;
179         rr->evt = evt;
180         rr->ret_addr = ret_addr;
181         rr->event = event;
182         rr->tra = tra;
183         rr->pid = pid;
184         rr->sp = sp;
185         rr->pc = regs->pc;
186
187         if (sp < stack_bottom + 3092) {
188                 printk("evt_debug : stack underflow report\n");
189                 int i, j;
190                 for (j=0, i = event_ptr; j<16; j++) {
191                         rr = event_ring + i;
192                         printk("evt=%08x event=%08x tra=%08x pid=%5d sp=%08lx pc=%08lx\n",
193                                 rr->evt, rr->event, rr->tra, rr->pid, rr->sp, rr->pc);
194                         i--;
195                         i &= 15;
196                 }
197                 panic("STACK UNDERFLOW\n");
198         }
199
200         event_ptr = (event_ptr + 1) & 15;
201
202         if ((event == 2) && (evt == 0x160)) {
203                 if (syscallno < NUM_SYSCALL_INFO_ENTRIES) {
204                         /* Store the syscall information to print later.  We
205                          * can't print this now - currently we're running with
206                          * SR.BL=1, so we can't take a tlbmiss (which could occur
207                          * in the console drivers under printk).
208                          *
209                          * Just overwrite old entries on ring overflow - this
210                          * is only for last-hope debugging. */
211                         stored_syscalls[syscall_next].pid = current->pid;
212                         stored_syscalls[syscall_next].syscall_number = syscallno;
213                         syscall_next++;
214                         syscall_next &= (N_STORED_SYSCALLS - 1);
215                 }
216         }
217 }
218
219 static void drain_syscalls(void) {
220         while (syscall_next_print != syscall_next) {
221                 printk("Task %d: %s()\n",
222                         stored_syscalls[syscall_next_print].pid,
223                         syscall_info_table[stored_syscalls[syscall_next_print].syscall_number].name);
224                         syscall_next_print++;
225                         syscall_next_print &= (N_STORED_SYSCALLS - 1);
226         }
227 }
228
229 void evt_debug2(unsigned int ret)
230 {
231         drain_syscalls();
232         printk("Task %d: syscall returns %08x\n", current->pid, ret);
233 }
234
235 void evt_debug_ret_from_irq(struct pt_regs *regs)
236 {
237         int pid;
238         struct ring_node *rr;
239
240         pid = current->pid;
241         rr = event_ring + event_ptr;
242         rr->evt = 0xffff;
243         rr->ret_addr = 0;
244         rr->event = 0;
245         rr->tra = 0;
246         rr->pid = pid;
247         rr->pc = regs->pc;
248         event_ptr = (event_ptr + 1) & 15;
249 }
250
251 void evt_debug_ret_from_exc(struct pt_regs *regs)
252 {
253         int pid;
254         struct ring_node *rr;
255
256         pid = current->pid;
257         rr = event_ring + event_ptr;
258         rr->evt = 0xfffe;
259         rr->ret_addr = 0;
260         rr->event = 0;
261         rr->tra = 0;
262         rr->pid = pid;
263         rr->pc = regs->pc;
264         event_ptr = (event_ptr + 1) & 15;
265 }
266
267 #endif /* CONFIG_POOR_MANS_STRACE */
268
269 /* ======================================================================= */
270
271 void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs)
272 {
273
274         unsigned long long ah, al, bh, bl, ch, cl;
275
276         printk("\n");
277         printk("EXCEPTION - %s: task %d; Linux trap # %d; signal = %d\n",
278                ((from) ? from : "???"), current->pid, trapnr, signr);
279
280         asm volatile ("getcon   " __EXPEVT ", %0":"=r"(ah));
281         asm volatile ("getcon   " __EXPEVT ", %0":"=r"(al));
282         ah = (ah) >> 32;
283         al = (al) & 0xffffffff;
284         asm volatile ("getcon   " __KCR1 ", %0":"=r"(bh));
285         asm volatile ("getcon   " __KCR1 ", %0":"=r"(bl));
286         bh = (bh) >> 32;
287         bl = (bl) & 0xffffffff;
288         asm volatile ("getcon   " __INTEVT ", %0":"=r"(ch));
289         asm volatile ("getcon   " __INTEVT ", %0":"=r"(cl));
290         ch = (ch) >> 32;
291         cl = (cl) & 0xffffffff;
292         printk("EXPE: %08Lx%08Lx KCR1: %08Lx%08Lx INTE: %08Lx%08Lx\n",
293                ah, al, bh, bl, ch, cl);
294
295         asm volatile ("getcon   " __PEXPEVT ", %0":"=r"(ah));
296         asm volatile ("getcon   " __PEXPEVT ", %0":"=r"(al));
297         ah = (ah) >> 32;
298         al = (al) & 0xffffffff;
299         asm volatile ("getcon   " __PSPC ", %0":"=r"(bh));
300         asm volatile ("getcon   " __PSPC ", %0":"=r"(bl));
301         bh = (bh) >> 32;
302         bl = (bl) & 0xffffffff;
303         asm volatile ("getcon   " __PSSR ", %0":"=r"(ch));
304         asm volatile ("getcon   " __PSSR ", %0":"=r"(cl));
305         ch = (ch) >> 32;
306         cl = (cl) & 0xffffffff;
307         printk("PEXP: %08Lx%08Lx PSPC: %08Lx%08Lx PSSR: %08Lx%08Lx\n",
308                ah, al, bh, bl, ch, cl);
309
310         ah = (regs->pc) >> 32;
311         al = (regs->pc) & 0xffffffff;
312         bh = (regs->regs[18]) >> 32;
313         bl = (regs->regs[18]) & 0xffffffff;
314         ch = (regs->regs[15]) >> 32;
315         cl = (regs->regs[15]) & 0xffffffff;
316         printk("PC  : %08Lx%08Lx LINK: %08Lx%08Lx SP  : %08Lx%08Lx\n",
317                ah, al, bh, bl, ch, cl);
318
319         ah = (regs->sr) >> 32;
320         al = (regs->sr) & 0xffffffff;
321         asm volatile ("getcon   " __TEA ", %0":"=r"(bh));
322         asm volatile ("getcon   " __TEA ", %0":"=r"(bl));
323         bh = (bh) >> 32;
324         bl = (bl) & 0xffffffff;
325         asm volatile ("getcon   " __KCR0 ", %0":"=r"(ch));
326         asm volatile ("getcon   " __KCR0 ", %0":"=r"(cl));
327         ch = (ch) >> 32;
328         cl = (cl) & 0xffffffff;
329         printk("SR  : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n",
330                ah, al, bh, bl, ch, cl);
331
332         ah = (regs->regs[0]) >> 32;
333         al = (regs->regs[0]) & 0xffffffff;
334         bh = (regs->regs[1]) >> 32;
335         bl = (regs->regs[1]) & 0xffffffff;
336         ch = (regs->regs[2]) >> 32;
337         cl = (regs->regs[2]) & 0xffffffff;
338         printk("R0  : %08Lx%08Lx R1  : %08Lx%08Lx R2  : %08Lx%08Lx\n",
339                ah, al, bh, bl, ch, cl);
340
341         ah = (regs->regs[3]) >> 32;
342         al = (regs->regs[3]) & 0xffffffff;
343         bh = (regs->regs[4]) >> 32;
344         bl = (regs->regs[4]) & 0xffffffff;
345         ch = (regs->regs[5]) >> 32;
346         cl = (regs->regs[5]) & 0xffffffff;
347         printk("R3  : %08Lx%08Lx R4  : %08Lx%08Lx R5  : %08Lx%08Lx\n",
348                ah, al, bh, bl, ch, cl);
349
350         ah = (regs->regs[6]) >> 32;
351         al = (regs->regs[6]) & 0xffffffff;
352         bh = (regs->regs[7]) >> 32;
353         bl = (regs->regs[7]) & 0xffffffff;
354         ch = (regs->regs[8]) >> 32;
355         cl = (regs->regs[8]) & 0xffffffff;
356         printk("R6  : %08Lx%08Lx R7  : %08Lx%08Lx R8  : %08Lx%08Lx\n",
357                ah, al, bh, bl, ch, cl);
358
359         ah = (regs->regs[9]) >> 32;
360         al = (regs->regs[9]) & 0xffffffff;
361         bh = (regs->regs[10]) >> 32;
362         bl = (regs->regs[10]) & 0xffffffff;
363         ch = (regs->regs[11]) >> 32;
364         cl = (regs->regs[11]) & 0xffffffff;
365         printk("R9  : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n",
366                ah, al, bh, bl, ch, cl);
367         printk("....\n");
368
369         ah = (regs->tregs[0]) >> 32;
370         al = (regs->tregs[0]) & 0xffffffff;
371         bh = (regs->tregs[1]) >> 32;
372         bl = (regs->tregs[1]) & 0xffffffff;
373         ch = (regs->tregs[2]) >> 32;
374         cl = (regs->tregs[2]) & 0xffffffff;
375         printk("T0  : %08Lx%08Lx T1  : %08Lx%08Lx T2  : %08Lx%08Lx\n",
376                ah, al, bh, bl, ch, cl);
377         printk("....\n");
378
379         print_dtlb();
380         print_itlb();
381 }
382
383 /* ======================================================================= */
384
385 /*
386 ** Depending on <base> scan the MMU, Data or Instruction side
387 ** looking for a valid mapping matching Eaddr & asid.
388 ** Return -1 if not found or the TLB id entry otherwise.
389 ** Note: it works only for 4k pages!
390 */
391 static unsigned long
392 lookup_mmu_side(unsigned long base, unsigned long Eaddr, unsigned long asid)
393 {
394         regType_t pteH;
395         unsigned long epn;
396         int count;
397
398         epn = Eaddr & 0xfffff000;
399
400         for (count = 0; count < MAX_TLBs; count++, base += TLB_STEP) {
401                 pteH = getConfigReg(base);
402                 if (GET_VALID(pteH))
403                         if ((unsigned long) GET_EPN(pteH) == epn)
404                                 if ((unsigned long) GET_ASID(pteH) == asid)
405                                         break;
406         }
407         return ((unsigned long) ((count < MAX_TLBs) ? base : -1));
408 }
409
410 unsigned long lookup_dtlb(unsigned long Eaddr)
411 {
412         unsigned long asid = get_asid();
413         return (lookup_mmu_side((u64) DTLB_BASE, Eaddr, asid));
414 }
415
416 unsigned long lookup_itlb(unsigned long Eaddr)
417 {
418         unsigned long asid = get_asid();
419         return (lookup_mmu_side((u64) ITLB_BASE, Eaddr, asid));
420 }
421
422 void print_page(struct page *page)
423 {
424         printk("  page[%p] -> index 0x%lx,  count 0x%x,  flags 0x%lx\n",
425                page, page->index, page_count(page), page->flags);
426         printk("       address_space = %p, pages =%ld\n", page->mapping,
427                page->mapping->nrpages);
428
429 }