This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-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 #include "syscalltab.h"
140
141 struct ring_node {
142         int evt;
143         int ret_addr;
144         int event;
145         int tra;
146         int pid;
147         unsigned long sp;
148         unsigned long pc;
149 };
150
151 static struct ring_node event_ring[16];
152 static int event_ptr = 0;
153
154 void evt_debug(int evt, int ret_addr, int event, int tra, struct pt_regs *regs)
155 {
156         int syscallno = tra & 0xff;
157         unsigned long sp;
158         unsigned long stack_bottom;
159         int pid;
160         struct ring_node *rr;
161
162         pid = current->pid;
163         stack_bottom = (unsigned long) current->thread_info;
164         asm volatile("ori r15, 0, %0" : "=r" (sp));
165         rr = event_ring + event_ptr;
166         rr->evt = evt;
167         rr->ret_addr = ret_addr;
168         rr->event = event;
169         rr->tra = tra;
170         rr->pid = pid;
171         rr->sp = sp;
172         rr->pc = regs->pc;
173
174         if (sp < stack_bottom + 3092) {
175                 printk("evt_debug : stack underflow report\n");
176                 int i, j;
177                 for (j=0, i = event_ptr; j<16; j++) {
178                         rr = event_ring + i;
179                         printk("evt=%08x event=%08x tra=%08x pid=%5d sp=%08lx pc=%08lx\n",
180                                 rr->evt, rr->event, rr->tra, rr->pid, rr->sp, rr->pc);
181                         i--;
182                         i &= 15;
183                 }
184                 panic("STACK UNDERFLOW\n");
185         }
186
187         event_ptr = (event_ptr + 1) & 15;
188
189         if ((event == 2) && (evt == 0x160)) {
190                 if (syscallno < NUM_SYSCALL_INFO_ENTRIES)
191                         printk("Task %d: %s()\n",
192                                current->pid,
193                                syscall_info_table[syscallno].name);
194         }
195 }
196
197 void evt_debug2(unsigned int ret)
198 {
199         printk("Task %d: syscall returns %08x\n", current->pid, ret);
200 }
201
202 void evt_debug_ret_from_irq(struct pt_regs *regs)
203 {
204         int pid;
205         struct ring_node *rr;
206
207         pid = current->pid;
208         rr = event_ring + event_ptr;
209         rr->evt = 0xffff;
210         rr->ret_addr = 0;
211         rr->event = 0;
212         rr->tra = 0;
213         rr->pid = pid;
214         rr->pc = regs->pc;
215         event_ptr = (event_ptr + 1) & 15;
216 }
217
218 void evt_debug_ret_from_exc(struct pt_regs *regs)
219 {
220         int pid;
221         struct ring_node *rr;
222
223         pid = current->pid;
224         rr = event_ring + event_ptr;
225         rr->evt = 0xfffe;
226         rr->ret_addr = 0;
227         rr->event = 0;
228         rr->tra = 0;
229         rr->pid = pid;
230         rr->pc = regs->pc;
231         event_ptr = (event_ptr + 1) & 15;
232 }
233
234 /* ======================================================================= */
235
236 void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs)
237 {
238
239         unsigned long long ah, al, bh, bl, ch, cl;
240
241         printk("\n");
242         printk("EXCEPTION - %s: task %d; Linux trap # %d; signal = %d\n",
243                ((from) ? from : "???"), current->pid, trapnr, signr);
244
245         asm volatile ("getcon   " __EXPEVT ", %0":"=r"(ah));
246         asm volatile ("getcon   " __EXPEVT ", %0":"=r"(al));
247         ah = (ah) >> 32;
248         al = (al) & 0xffffffff;
249         asm volatile ("getcon   " __KCR1 ", %0":"=r"(bh));
250         asm volatile ("getcon   " __KCR1 ", %0":"=r"(bl));
251         bh = (bh) >> 32;
252         bl = (bl) & 0xffffffff;
253         asm volatile ("getcon   " __INTEVT ", %0":"=r"(ch));
254         asm volatile ("getcon   " __INTEVT ", %0":"=r"(cl));
255         ch = (ch) >> 32;
256         cl = (cl) & 0xffffffff;
257         printk("EXPE: %08Lx%08Lx KCR1: %08Lx%08Lx INTE: %08Lx%08Lx\n",
258                ah, al, bh, bl, ch, cl);
259
260         asm volatile ("getcon   " __PEXPEVT ", %0":"=r"(ah));
261         asm volatile ("getcon   " __PEXPEVT ", %0":"=r"(al));
262         ah = (ah) >> 32;
263         al = (al) & 0xffffffff;
264         asm volatile ("getcon   " __PSPC ", %0":"=r"(bh));
265         asm volatile ("getcon   " __PSPC ", %0":"=r"(bl));
266         bh = (bh) >> 32;
267         bl = (bl) & 0xffffffff;
268         asm volatile ("getcon   " __PSSR ", %0":"=r"(ch));
269         asm volatile ("getcon   " __PSSR ", %0":"=r"(cl));
270         ch = (ch) >> 32;
271         cl = (cl) & 0xffffffff;
272         printk("PEXP: %08Lx%08Lx PSPC: %08Lx%08Lx PSSR: %08Lx%08Lx\n",
273                ah, al, bh, bl, ch, cl);
274
275         ah = (regs->pc) >> 32;
276         al = (regs->pc) & 0xffffffff;
277         bh = (regs->regs[18]) >> 32;
278         bl = (regs->regs[18]) & 0xffffffff;
279         ch = (regs->regs[15]) >> 32;
280         cl = (regs->regs[15]) & 0xffffffff;
281         printk("PC  : %08Lx%08Lx LINK: %08Lx%08Lx SP  : %08Lx%08Lx\n",
282                ah, al, bh, bl, ch, cl);
283
284         ah = (regs->sr) >> 32;
285         al = (regs->sr) & 0xffffffff;
286         asm volatile ("getcon   " __TEA ", %0":"=r"(bh));
287         asm volatile ("getcon   " __TEA ", %0":"=r"(bl));
288         bh = (bh) >> 32;
289         bl = (bl) & 0xffffffff;
290         asm volatile ("getcon   " __KCR0 ", %0":"=r"(ch));
291         asm volatile ("getcon   " __KCR0 ", %0":"=r"(cl));
292         ch = (ch) >> 32;
293         cl = (cl) & 0xffffffff;
294         printk("SR  : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n",
295                ah, al, bh, bl, ch, cl);
296
297         ah = (regs->regs[0]) >> 32;
298         al = (regs->regs[0]) & 0xffffffff;
299         bh = (regs->regs[1]) >> 32;
300         bl = (regs->regs[1]) & 0xffffffff;
301         ch = (regs->regs[2]) >> 32;
302         cl = (regs->regs[2]) & 0xffffffff;
303         printk("R0  : %08Lx%08Lx R1  : %08Lx%08Lx R2  : %08Lx%08Lx\n",
304                ah, al, bh, bl, ch, cl);
305
306         ah = (regs->regs[3]) >> 32;
307         al = (regs->regs[3]) & 0xffffffff;
308         bh = (regs->regs[4]) >> 32;
309         bl = (regs->regs[4]) & 0xffffffff;
310         ch = (regs->regs[5]) >> 32;
311         cl = (regs->regs[5]) & 0xffffffff;
312         printk("R3  : %08Lx%08Lx R4  : %08Lx%08Lx R5  : %08Lx%08Lx\n",
313                ah, al, bh, bl, ch, cl);
314
315         ah = (regs->regs[6]) >> 32;
316         al = (regs->regs[6]) & 0xffffffff;
317         bh = (regs->regs[7]) >> 32;
318         bl = (regs->regs[7]) & 0xffffffff;
319         ch = (regs->regs[8]) >> 32;
320         cl = (regs->regs[8]) & 0xffffffff;
321         printk("R6  : %08Lx%08Lx R7  : %08Lx%08Lx R8  : %08Lx%08Lx\n",
322                ah, al, bh, bl, ch, cl);
323
324         ah = (regs->regs[9]) >> 32;
325         al = (regs->regs[9]) & 0xffffffff;
326         bh = (regs->regs[10]) >> 32;
327         bl = (regs->regs[10]) & 0xffffffff;
328         ch = (regs->regs[11]) >> 32;
329         cl = (regs->regs[11]) & 0xffffffff;
330         printk("R9  : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n",
331                ah, al, bh, bl, ch, cl);
332         printk("....\n");
333
334         ah = (regs->tregs[0]) >> 32;
335         al = (regs->tregs[0]) & 0xffffffff;
336         bh = (regs->tregs[1]) >> 32;
337         bl = (regs->tregs[1]) & 0xffffffff;
338         ch = (regs->tregs[2]) >> 32;
339         cl = (regs->tregs[2]) & 0xffffffff;
340         printk("T0  : %08Lx%08Lx T1  : %08Lx%08Lx T2  : %08Lx%08Lx\n",
341                ah, al, bh, bl, ch, cl);
342         printk("....\n");
343
344         print_dtlb();
345         print_itlb();
346 }
347
348 /* ======================================================================= */
349
350 /*
351 ** Depending on <base> scan the MMU, Data or Instrction side
352 ** looking for a valid mapping matching Eaddr & asid.
353 ** Return -1 if not found or the TLB id entry otherwise.
354 ** Note: it works only for 4k pages!
355 */
356 static unsigned long
357 lookup_mmu_side(unsigned long base, unsigned long Eaddr, unsigned long asid)
358 {
359         regType_t pteH;
360         unsigned long epn;
361         int count;
362
363         epn = Eaddr & 0xfffff000;
364
365         for (count = 0; count < MAX_TLBs; count++, base += TLB_STEP) {
366                 pteH = getConfigReg(base);
367                 if (GET_VALID(pteH))
368                         if ((unsigned long) GET_EPN(pteH) == epn)
369                                 if ((unsigned long) GET_ASID(pteH) == asid)
370                                         break;
371         }
372         return ((unsigned long) ((count < MAX_TLBs) ? base : -1));
373 }
374
375 unsigned long lookup_dtlb(unsigned long Eaddr)
376 {
377         unsigned long asid = get_asid();
378         return (lookup_mmu_side((u64) DTLB_BASE, Eaddr, asid));
379 }
380
381 unsigned long lookup_itlb(unsigned long Eaddr)
382 {
383         unsigned long asid = get_asid();
384         return (lookup_mmu_side((u64) ITLB_BASE, Eaddr, asid));
385 }
386
387 void print_page(struct page *page)
388 {
389         printk("  page[%p] -> index 0x%lx,  count 0x%x,  flags 0x%lx\n",
390                page, page->index, page_count(page), page->flags);
391         printk("       address_space = %p, pages =%ld\n", page->mapping,
392                page->mapping->nrpages);
393
394 }