dbg.c 11 KB

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