1 /*--------------------------------------------------------------------------
3 -- Identity : Linux50 Debug Funcions
5 -- File : arch/sh64/lib/dbg.C
7 -- Copyright 2000, 2001 STMicroelectronics Limited.
8 -- Copyright 2004 Richard Curnow (evt_debug etc)
10 --------------------------------------------------------------------------*/
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
15 #include <asm/mmu_context.h>
17 typedef u64 regType_t
;
19 static regType_t
getConfigReg(u64 id
)
21 register u64 reg
__asm__("r2");
22 asm volatile ("getcfg %1, 0, %0":"=r" (reg
):"r"(id
));
26 /* ======================================================================= */
28 static char *szTab
[] = { "4k", "64k", "1M", "512M" };
29 static char *protTab
[] = { "----",
46 #define ITLB_BASE 0x00000000
47 #define DTLB_BASE 0x00800000
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)
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)
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)
71 #define HOW_TO_READ_TLB_CONTENT \
72 "[ ID] PPN EPN ASID Share CB P.Size PROT.\n"
74 void print_single_tlb(unsigned long tlb
, int single_print
)
78 unsigned int valid
, shared
, asid
, epn
, cb
, ppn
;
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
88 pteH
= getConfigReg(tlb
);
89 valid
= GET_VALID(pteH
);
91 printk(HOW_TO_READ_TLB_CONTENT
);
95 pteL
= getConfigReg(tlb
+ 1);
97 shared
= GET_SHARED(pteH
);
98 asid
= GET_ASID(pteH
);
100 cb
= GET_CBEHAVIOR(pteL
);
101 pSize
= GET_PAGE_SIZE(pteL
);
102 pProt
= GET_PROTECTION(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
);
109 void print_dtlb(void)
114 printk(" ================= SH-5 D-TLBs Status ===================\n");
115 printk(HOW_TO_READ_TLB_CONTENT
);
117 for (count
= 0; count
< MAX_TLBs
; count
++, tlb
+= TLB_STEP
)
118 print_single_tlb(tlb
, 0);
120 (" =============================================================\n");
123 void print_itlb(void)
128 printk(" ================= SH-5 I-TLBs Status ===================\n");
129 printk(HOW_TO_READ_TLB_CONTENT
);
131 for (count
= 0; count
< MAX_TLBs
; count
++, tlb
+= TLB_STEP
)
132 print_single_tlb(tlb
, 0);
134 (" =============================================================\n");
137 /* ======================================================================= */
139 #ifdef CONFIG_POOR_MANS_STRACE
141 #include "syscalltab.h"
153 static struct ring_node event_ring
[16];
154 static int event_ptr
= 0;
156 struct stored_syscall_data
{
161 #define N_STORED_SYSCALLS 16
163 static struct stored_syscall_data stored_syscalls
[N_STORED_SYSCALLS
];
164 static int syscall_next
=0;
165 static int syscall_next_print
=0;
167 void evt_debug(int evt
, int ret_addr
, int event
, int tra
, struct pt_regs
*regs
)
169 int syscallno
= tra
& 0xff;
171 unsigned long stack_bottom
;
173 struct ring_node
*rr
;
176 stack_bottom
= (unsigned long) task_stack_page(current
);
177 asm volatile("ori r15, 0, %0" : "=r" (sp
));
178 rr
= event_ring
+ event_ptr
;
180 rr
->ret_addr
= ret_addr
;
187 if (sp
< stack_bottom
+ 3092) {
188 printk("evt_debug : stack underflow report\n");
190 for (j
=0, i
= event_ptr
; j
<16; j
++) {
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
);
197 panic("STACK UNDERFLOW\n");
200 event_ptr
= (event_ptr
+ 1) & 15;
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).
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
;
214 syscall_next
&= (N_STORED_SYSCALLS
- 1);
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);
229 void evt_debug2(unsigned int ret
)
232 printk("Task %d: syscall returns %08x\n", current
->pid
, ret
);
235 void evt_debug_ret_from_irq(struct pt_regs
*regs
)
238 struct ring_node
*rr
;
241 rr
= event_ring
+ event_ptr
;
248 event_ptr
= (event_ptr
+ 1) & 15;
251 void evt_debug_ret_from_exc(struct pt_regs
*regs
)
254 struct ring_node
*rr
;
257 rr
= event_ring
+ event_ptr
;
264 event_ptr
= (event_ptr
+ 1) & 15;
267 #endif /* CONFIG_POOR_MANS_STRACE */
269 /* ======================================================================= */
271 void show_excp_regs(char *from
, int trapnr
, int signr
, struct pt_regs
*regs
)
274 unsigned long long ah
, al
, bh
, bl
, ch
, cl
;
277 printk("EXCEPTION - %s: task %d; Linux trap # %d; signal = %d\n",
278 ((from
) ? from
: "???"), current
->pid
, trapnr
, signr
);
280 asm volatile ("getcon " __EXPEVT
", %0":"=r"(ah
));
281 asm volatile ("getcon " __EXPEVT
", %0":"=r"(al
));
283 al
= (al
) & 0xffffffff;
284 asm volatile ("getcon " __KCR1
", %0":"=r"(bh
));
285 asm volatile ("getcon " __KCR1
", %0":"=r"(bl
));
287 bl
= (bl
) & 0xffffffff;
288 asm volatile ("getcon " __INTEVT
", %0":"=r"(ch
));
289 asm volatile ("getcon " __INTEVT
", %0":"=r"(cl
));
291 cl
= (cl
) & 0xffffffff;
292 printk("EXPE: %08Lx%08Lx KCR1: %08Lx%08Lx INTE: %08Lx%08Lx\n",
293 ah
, al
, bh
, bl
, ch
, cl
);
295 asm volatile ("getcon " __PEXPEVT
", %0":"=r"(ah
));
296 asm volatile ("getcon " __PEXPEVT
", %0":"=r"(al
));
298 al
= (al
) & 0xffffffff;
299 asm volatile ("getcon " __PSPC
", %0":"=r"(bh
));
300 asm volatile ("getcon " __PSPC
", %0":"=r"(bl
));
302 bl
= (bl
) & 0xffffffff;
303 asm volatile ("getcon " __PSSR
", %0":"=r"(ch
));
304 asm volatile ("getcon " __PSSR
", %0":"=r"(cl
));
306 cl
= (cl
) & 0xffffffff;
307 printk("PEXP: %08Lx%08Lx PSPC: %08Lx%08Lx PSSR: %08Lx%08Lx\n",
308 ah
, al
, bh
, bl
, ch
, cl
);
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
);
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
));
324 bl
= (bl
) & 0xffffffff;
325 asm volatile ("getcon " __KCR0
", %0":"=r"(ch
));
326 asm volatile ("getcon " __KCR0
", %0":"=r"(cl
));
328 cl
= (cl
) & 0xffffffff;
329 printk("SR : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n",
330 ah
, al
, bh
, bl
, ch
, cl
);
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
);
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
);
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
);
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
);
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
);
383 /* ======================================================================= */
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!
392 lookup_mmu_side(unsigned long base
, unsigned long Eaddr
, unsigned long asid
)
398 epn
= Eaddr
& 0xfffff000;
400 for (count
= 0; count
< MAX_TLBs
; count
++, base
+= TLB_STEP
) {
401 pteH
= getConfigReg(base
);
403 if ((unsigned long) GET_EPN(pteH
) == epn
)
404 if ((unsigned long) GET_ASID(pteH
) == asid
)
407 return ((unsigned long) ((count
< MAX_TLBs
) ? base
: -1));
410 unsigned long lookup_dtlb(unsigned long Eaddr
)
412 unsigned long asid
= get_asid();
413 return (lookup_mmu_side((u64
) DTLB_BASE
, Eaddr
, asid
));
416 unsigned long lookup_itlb(unsigned long Eaddr
)
418 unsigned long asid
= get_asid();
419 return (lookup_mmu_side((u64
) ITLB_BASE
, Eaddr
, asid
));
422 void print_page(struct page
*page
)
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
);