xmon.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:65k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Routines providing a simple monitor for use on the PowerMac.
  3.  *
  4.  * Copyright (C) 1996 Paul Mackerras.
  5.  *
  6.  *      This program is free software; you can redistribute it and/or
  7.  *      modify it under the terms of the GNU General Public License
  8.  *      as published by the Free Software Foundation; either version
  9.  *      2 of the License, or (at your option) any later version.
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/errno.h>
  13. #include <linux/sched.h>
  14. #include <linux/smp.h>
  15. #include <linux/mm.h>
  16. #include <linux/reboot.h>
  17. #include <asm/ptrace.h>
  18. #include <asm/string.h>
  19. #include <asm/prom.h>
  20. #include <asm/machdep.h>
  21. #include <asm/processor.h>
  22. #include <asm/pgtable.h>
  23. #include <asm/mmu.h>
  24. #include <asm/mmu_context.h>
  25. #include <asm/naca.h>
  26. #include <asm/paca.h>
  27. #include <asm/ppcdebug.h>
  28. #include "nonstdio.h"
  29. #include "privinst.h"
  30. #define scanhex xmon_scanhex
  31. #define skipbl xmon_skipbl
  32. #ifdef CONFIG_SMP
  33. static unsigned long cpus_in_xmon = 0;
  34. static unsigned long got_xmon = 0;
  35. static volatile int take_xmon = -1;
  36. #endif /* CONFIG_SMP */
  37. static unsigned long adrs;
  38. static int size = 1;
  39. static unsigned long ndump = 64;
  40. static unsigned long nidump = 16;
  41. static unsigned long ncsum = 4096;
  42. static int termch;
  43. static u_int bus_error_jmp[100];
  44. #define setjmp xmon_setjmp
  45. #define longjmp xmon_longjmp
  46. #define memlist_entry list_entry
  47. #define memlist_next(x) ((x)->next)
  48. #define memlist_prev(x) ((x)->prev)
  49. /* Max number of stack frames we are willing to produce on a backtrace. */
  50. #define MAXFRAMECOUNT 50
  51. /* Breakpoint stuff */
  52. struct bpt {
  53. unsigned long address;
  54. unsigned instr;
  55. unsigned long count;
  56. unsigned char enabled;
  57. char funcname[64]; /* function name for humans */
  58. };
  59. #define NBPTS 16
  60. static struct bpt bpts[NBPTS];
  61. static struct bpt dabr;
  62. static struct bpt iabr;
  63. static unsigned bpinstr = 0x7fe00008; /* trap */
  64. /* Prototypes */
  65. extern void (*debugger_fault_handler)(struct pt_regs *);
  66. static int cmds(struct pt_regs *);
  67. static int mread(unsigned long, void *, int);
  68. static int mwrite(unsigned long, void *, int);
  69. static void handle_fault(struct pt_regs *);
  70. static void byterev(unsigned char *, int);
  71. static void memex(void);
  72. static int bsesc(void);
  73. static void dump(void);
  74. static void prdump(unsigned long, long);
  75. #ifdef __MWERKS__
  76. static void prndump(unsigned, int);
  77. static int nvreadb(unsigned);
  78. #endif
  79. static int ppc_inst_dump(unsigned long, long);
  80. void print_address(unsigned long);
  81. static int getsp(void);
  82. static void dump_hash_table(void);
  83. static void backtrace(struct pt_regs *);
  84. static void excprint(struct pt_regs *);
  85. static void prregs(struct pt_regs *);
  86. static void memops(int);
  87. static void memlocate(void);
  88. static void memzcan(void);
  89. static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
  90. int skipbl(void);
  91. int scanhex(unsigned long *valp);
  92. static void scannl(void);
  93. static int hexdigit(int);
  94. void getstring(char *, int);
  95. static void flush_input(void);
  96. static int inchar(void);
  97. static void take_input(char *);
  98. /* static void openforth(void); */
  99. static unsigned long read_spr(int);
  100. static void write_spr(int, unsigned long);
  101. static void super_regs(void);
  102. static void print_sysmap(void);
  103. static void remove_bpts(void);
  104. static void insert_bpts(void);
  105. static struct bpt *at_breakpoint(unsigned long pc);
  106. static void bpt_cmds(void);
  107. static void cacheflush(void);
  108. #ifdef CONFIG_SMP
  109. static void cpu_cmd(void);
  110. #endif /* CONFIG_SMP */
  111. static void csum(void);
  112. static void mem_translate(void);
  113. static void mem_check(void);
  114. static void mem_find_real(void);
  115. static void mem_find_vsid(void);
  116. static void mem_check_pagetable_vsids (void);
  117. static void mem_map_check_slab(void);
  118. static void mem_map_lock_pages(void);
  119. static void mem_check_dup_rpn (void);
  120. static void debug_trace(void);
  121. extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned long);
  122. extern void printf(const char *fmt, ...);
  123. extern void xmon_vfprintf(void *f, const char *fmt, va_list ap);
  124. extern int xmon_putc(int c, void *f);
  125. extern int putchar(int ch);
  126. extern int xmon_read_poll(void);
  127. extern int setjmp(u_int *);
  128. extern void longjmp(u_int *, int);
  129. extern unsigned long _ASR;
  130. pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va); /* from htab.c */
  131. #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
  132. static char *help_string = "
  133. Commands:n
  134.   b show breakpointsn
  135.   bd set data breakpointn
  136.   bi set instruction breakpointn
  137.   bc clear breakpointn
  138.   d dump bytesn
  139.   di dump instructionsn
  140.   df dump float valuesn
  141.   dd dump double valuesn
  142.   e print exception informationn
  143.   f flush cachen
  144.   h dump hash tablen
  145.   m examine/change memoryn
  146.   mm move a block of memoryn
  147.   ms set a block of memoryn
  148.   md compare two blocks of memoryn
  149.   ml locate a block of memoryn
  150.   mz zero a block of memoryn
  151.   mx translation information for an effective addressn
  152.   mi show information about memory allocationn
  153.   M print System.mapn
  154.   p  show the task listn
  155.   r print registersn
  156.   s single stepn
  157.   S print special registersn
  158.   t print backtracen
  159.   T Enable/Disable PPCDBG flagsn
  160.   x exit monitorn
  161.   z rebootn
  162.   Z haltn
  163. ";
  164. static int xmon_trace[NR_CPUS];
  165. #define SSTEP 1 /* stepping because of 's' command */
  166. #define BRSTEP 2 /* stepping over breakpoint */
  167. /*
  168.  * Stuff for reading and writing memory safely
  169.  */
  170. extern inline void sync(void)
  171. {
  172. asm volatile("sync; isync");
  173. }
  174. /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
  175.  A PPC stack frame looks like this:
  176.  High Address
  177.     Back Chain
  178.     FP reg save area
  179.     GP reg save area
  180.     Local var space
  181.     Parameter save area (SP+48)
  182.     TOC save area (SP+40)
  183.     link editor doubleword (SP+32)
  184.     compiler doubleword (SP+24)
  185.     LR save (SP+16)
  186.     CR save (SP+8)
  187.     Back Chain (SP+0)
  188.  Note that the LR (ret addr) may not be saved in the current frame if
  189.  no functions have been called from the current function.
  190.  */
  191. /*
  192.  A traceback table typically follows each function.
  193.  The find_tb_table() func will fill in this struct.  Note that the struct
  194.  is not an exact match with the encoded table defined by the ABI.  It is
  195.  defined here more for programming convenience.
  196.  */
  197. struct tbtable {
  198. unsigned long flags; /* flags: */
  199. #define TBTAB_FLAGSGLOBALLINK (1L<<47)
  200. #define TBTAB_FLAGSISEPROL (1L<<46)
  201. #define TBTAB_FLAGSHASTBOFF (1L<<45)
  202. #define TBTAB_FLAGSINTPROC (1L<<44)
  203. #define TBTAB_FLAGSHASCTL (1L<<43)
  204. #define TBTAB_FLAGSTOCLESS (1L<<42)
  205. #define TBTAB_FLAGSFPPRESENT (1L<<41)
  206. #define TBTAB_FLAGSNAMEPRESENT (1L<<38)
  207. #define TBTAB_FLAGSUSESALLOCA (1L<<37)
  208. #define TBTAB_FLAGSSAVESCR (1L<<33)
  209. #define TBTAB_FLAGSSAVESLR (1L<<32)
  210. #define TBTAB_FLAGSSTORESBC (1L<<31)
  211. #define TBTAB_FLAGSFIXUP (1L<<30)
  212. #define TBTAB_FLAGSPARMSONSTK (1L<<0)
  213. unsigned char fp_saved; /* num fp regs saved f(32-n)..f31 */
  214. unsigned char gpr_saved; /* num gpr's saved */
  215. unsigned char fixedparms; /* num fixed point parms */
  216. unsigned char floatparms; /* num float parms */
  217. unsigned char parminfo[32]; /* types of args.  null terminated */
  218. #define TBTAB_PARMFIXED 1
  219. #define TBTAB_PARMSFLOAT 2
  220. #define TBTAB_PARMDFLOAT 3
  221. unsigned int tb_offset; /* offset from start of func */
  222. unsigned long funcstart; /* addr of start of function */
  223. char name[64]; /* name of function (null terminated)*/
  224. };
  225. static int find_tb_table(unsigned long codeaddr, struct tbtable *tab);
  226. void
  227. xmon(struct pt_regs *excp)
  228. {
  229. struct pt_regs regs;
  230. int cmd;
  231. unsigned long msr;
  232. if (excp == NULL) {
  233. /* Ok, grab regs as they are now.
  234.  This won't do a particularily good job because the
  235.  prologue has already been executed.
  236.  ToDo: We could reach back into the callers save
  237.  area to do a better job of representing the
  238.  caller's state.
  239.  */
  240. asm volatile ("std 0,0(%0)n
  241. std 1,8(%0)n
  242. std 2,16(%0)n
  243. std 3,24(%0)n
  244. std 4,32(%0)n
  245. std 5,40(%0)n
  246. std 6,48(%0)n
  247. std 7,56(%0)n
  248. std 8,64(%0)n
  249. std 9,72(%0)n
  250. std 10,80(%0)n
  251. std 11,88(%0)n
  252. std 12,96(%0)n
  253. std 13,104(%0)n
  254. std 14,112(%0)n
  255. std 15,120(%0)n
  256. std 16,128(%0)n
  257. std 17,136(%0)n
  258. std 18,144(%0)n
  259. std 19,152(%0)n
  260. std 20,160(%0)n
  261. std 21,168(%0)n
  262. std 22,176(%0)n
  263. std 23,184(%0)n
  264. std 24,192(%0)n
  265. std 25,200(%0)n
  266. std 26,208(%0)n
  267. std 27,216(%0)n
  268. std 28,224(%0)n
  269. std 29,232(%0)n
  270. std 30,240(%0)n
  271. std 31,248(%0)" : : "b" (&regs));
  272. printf("xmon calledn");
  273. /* Fetch the link reg for this stack frame.
  274.  NOTE: the prev printf fills in the lr. */
  275. regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
  276. regs.msr = get_msr();
  277. regs.ctr = get_ctr();
  278. regs.xer = get_xer();
  279. regs.ccr = get_cr();
  280. regs.trap = 0;
  281. excp = &regs;
  282. }
  283. msr = get_msr();
  284. set_msrd(msr & ~MSR_EE); /* disable interrupts */
  285. excprint(excp);
  286. #ifdef CONFIG_SMP
  287. if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon))
  288. for (;;)
  289. ;
  290. while (test_and_set_bit(0, &got_xmon)) {
  291. if (take_xmon == smp_processor_id()) {
  292. take_xmon = -1;
  293. break;
  294. }
  295. }
  296. /*
  297.  * XXX: breakpoints are removed while any cpu is in xmon
  298.  */
  299. #endif /* CONFIG_SMP */
  300. remove_bpts();
  301. cmd = cmds(excp);
  302. if (cmd == 's') {
  303. xmon_trace[smp_processor_id()] = SSTEP;
  304. excp->msr |= 0x400;
  305. } else if (at_breakpoint(excp->nip)) {
  306. xmon_trace[smp_processor_id()] = BRSTEP;
  307. excp->msr |= 0x400;
  308. } else {
  309. xmon_trace[smp_processor_id()] = 0;
  310. insert_bpts();
  311. }
  312. #ifdef CONFIG_SMP
  313. clear_bit(0, &got_xmon);
  314. clear_bit(smp_processor_id(), &cpus_in_xmon);
  315. #endif /* CONFIG_SMP */
  316. set_msrd(msr); /* restore interrupt enable */
  317. }
  318. /* Code can call this to get a backtrace and continue. */
  319. void
  320. xmon_backtrace(const char *fmt, ...)
  321. {
  322. va_list ap;
  323. struct pt_regs regs;
  324. /* Ok, grab regs as they are now.
  325.  This won't do a particularily good job because the
  326.  prologue has already been executed.
  327.  ToDo: We could reach back into the callers save
  328.  area to do a better job of representing the
  329.  caller's state.
  330.  */
  331. asm volatile ("std 0,0(%0)n
  332.     std 1,8(%0)n
  333.     std 2,16(%0)n
  334.     std 3,24(%0)n
  335.     std 4,32(%0)n
  336.     std 5,40(%0)n
  337.     std 6,48(%0)n
  338.     std 7,56(%0)n
  339.     std 8,64(%0)n
  340.     std 9,72(%0)n
  341.     std 10,80(%0)n
  342.     std 11,88(%0)n
  343.     std 12,96(%0)n
  344.     std 13,104(%0)n
  345.     std 14,112(%0)n
  346.     std 15,120(%0)n
  347.     std 16,128(%0)n
  348.     std 17,136(%0)n
  349.     std 18,144(%0)n
  350.     std 19,152(%0)n
  351.     std 20,160(%0)n
  352.     std 21,168(%0)n
  353.     std 22,176(%0)n
  354.     std 23,184(%0)n
  355.     std 24,192(%0)n
  356.     std 25,200(%0)n
  357.     std 26,208(%0)n
  358.     std 27,216(%0)n
  359.     std 28,224(%0)n
  360.     std 29,232(%0)n
  361.     std 30,240(%0)n
  362.     std 31,248(%0)" : : "b" (&regs));
  363. /* Fetch the link reg for this stack frame.
  364.  NOTE: the prev printf fills in the lr. */
  365. regs.nip = regs.link = ((unsigned long *)(regs.gpr[1]))[2];
  366. regs.msr = get_msr();
  367. regs.ctr = get_ctr();
  368. regs.xer = get_xer();
  369. regs.ccr = get_cr();
  370. regs.trap = 0;
  371. va_start(ap, fmt);
  372. xmon_vfprintf(stdout, fmt, ap);
  373. xmon_putc('n', stdout);
  374. va_end(ap);
  375. take_input("n");
  376. backtrace(&regs);
  377. }
  378. /* Call this to poll for ^C during busy operations.
  379.  * Returns true if the user has hit ^C.
  380.  */
  381. int
  382. xmon_interrupted(void)
  383. {
  384. int ret = xmon_read_poll();
  385. if (ret == 3) {
  386. printf("n^C interrupted.n");
  387. return 1;
  388. }
  389. return 0;
  390. }
  391. void
  392. xmon_irq(int irq, void *d, struct pt_regs *regs)
  393. {
  394. unsigned long flags;
  395. __save_flags(flags);
  396. __cli();
  397. printf("Keyboard interruptn");
  398. xmon(regs);
  399. __restore_flags(flags);
  400. }
  401. int
  402. xmon_bpt(struct pt_regs *regs)
  403. {
  404. struct bpt *bp;
  405. bp = at_breakpoint(regs->nip);
  406. if (!bp)
  407. return 0;
  408. if (bp->count) {
  409. --bp->count;
  410. remove_bpts();
  411. excprint(regs);
  412. xmon_trace[smp_processor_id()] = BRSTEP;
  413. regs->msr |= 0x400;
  414. } else {
  415. printf("Stopped at breakpoint %x (%lx %s)n", (bp - bpts)+1, bp->address, bp->funcname);
  416. xmon(regs);
  417. }
  418. return 1;
  419. }
  420. int
  421. xmon_sstep(struct pt_regs *regs)
  422. {
  423. if (!xmon_trace[smp_processor_id()])
  424. return 0;
  425. if (xmon_trace[smp_processor_id()] == BRSTEP) {
  426. xmon_trace[smp_processor_id()] = 0;
  427. insert_bpts();
  428. } else {
  429. xmon(regs);
  430. }
  431. return 1;
  432. }
  433. int
  434. xmon_dabr_match(struct pt_regs *regs)
  435. {
  436. if (dabr.enabled && dabr.count) {
  437. --dabr.count;
  438. remove_bpts();
  439. excprint(regs);
  440. xmon_trace[smp_processor_id()] = BRSTEP;
  441. regs->msr |= 0x400;
  442. } else {
  443. dabr.instr = regs->nip;
  444. xmon(regs);
  445. }
  446. return 1;
  447. }
  448. int
  449. xmon_iabr_match(struct pt_regs *regs)
  450. {
  451. if (iabr.enabled && iabr.count) {
  452. --iabr.count;
  453. remove_bpts();
  454. excprint(regs);
  455. xmon_trace[smp_processor_id()] = BRSTEP;
  456. regs->msr |= 0x400;
  457. } else {
  458. xmon(regs);
  459. }
  460. return 1;
  461. }
  462. static struct bpt *
  463. at_breakpoint(unsigned long pc)
  464. {
  465. int i;
  466. struct bpt *bp;
  467. if (dabr.enabled && pc == dabr.instr)
  468. return &dabr;
  469. if (iabr.enabled && pc == iabr.address)
  470. return &iabr;
  471. bp = bpts;
  472. for (i = 0; i < NBPTS; ++i, ++bp)
  473. if (bp->enabled && pc == bp->address)
  474. return bp;
  475. return 0;
  476. }
  477. static void
  478. insert_bpts()
  479. {
  480. int i;
  481. struct bpt *bp;
  482. if (naca->platform != PLATFORM_PSERIES)
  483. return;
  484. bp = bpts;
  485. for (i = 0; i < NBPTS; ++i, ++bp) {
  486. if (!bp->enabled)
  487. continue;
  488. if (mread(bp->address, &bp->instr, 4) != 4
  489.     || mwrite(bp->address, &bpinstr, 4) != 4) {
  490. printf("Couldn't insert breakpoint at %x, disablingn",
  491.        bp->address);
  492. bp->enabled = 0;
  493. } else {
  494. store_inst((void *)bp->address);
  495. }
  496. }
  497. if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
  498. if (dabr.enabled)
  499. set_dabr(dabr.address);
  500. if (iabr.enabled)
  501. set_iabr(iabr.address);
  502. }
  503. }
  504. static void
  505. remove_bpts()
  506. {
  507. int i;
  508. struct bpt *bp;
  509. unsigned instr;
  510. if (naca->platform != PLATFORM_PSERIES)
  511. return;
  512. if (!__is_processor(PV_POWER4) && !__is_processor(PV_POWER4p)) {
  513. set_dabr(0);
  514. set_iabr(0);
  515. }
  516. bp = bpts;
  517. for (i = 0; i < NBPTS; ++i, ++bp) {
  518. if (!bp->enabled)
  519. continue;
  520. if (mread(bp->address, &instr, 4) == 4
  521.     && instr == bpinstr
  522.     && mwrite(bp->address, &bp->instr, 4) != 4)
  523. printf("Couldn't remove breakpoint at %xn",
  524.        bp->address);
  525. else
  526. store_inst((void *)bp->address);
  527. }
  528. }
  529. static char *last_cmd;
  530. /* Command interpreting routine */
  531. static int
  532. cmds(struct pt_regs *excp)
  533. {
  534. int cmd;
  535. last_cmd = NULL;
  536. for(;;) {
  537. #ifdef CONFIG_SMP
  538. printf("%d:", smp_processor_id());
  539. #endif /* CONFIG_SMP */
  540. printf("mon> ");
  541. fflush(stdout);
  542. flush_input();
  543. termch = 0;
  544. cmd = skipbl();
  545. if( cmd == 'n' ) {
  546. if (last_cmd == NULL)
  547. continue;
  548. take_input(last_cmd);
  549. last_cmd = NULL;
  550. cmd = inchar();
  551. }
  552. switch (cmd) {
  553. case 'z':
  554. printf("Rebooting machine now...");
  555. machine_restart(NULL);
  556. break;
  557. case 'Z':
  558. printf("Halting machine now...");
  559. machine_halt();
  560. break;
  561. case 'm':
  562. cmd = inchar();
  563. switch (cmd) {
  564. case 'm':
  565. case 's':
  566. case 'd':
  567. memops(cmd);
  568. break;
  569. case 'l':
  570. memlocate();
  571. break;
  572. case 'z':
  573. memzcan();
  574. break;
  575. case 'x':
  576. mem_translate();
  577. break;
  578. case 'c':
  579. mem_check();
  580. break;
  581. case 'j':
  582. mem_map_check_slab();
  583. break;
  584. case 'f':
  585. mem_find_real();
  586. break;
  587. case 'e':
  588. mem_find_vsid();
  589. break;
  590. case 'r':
  591. mem_check_dup_rpn();
  592. break;           
  593. case 'i':
  594. show_mem();
  595. break;
  596. case 'o':
  597. mem_check_pagetable_vsids ();
  598. break;
  599. case 'q':
  600. mem_map_lock_pages() ;
  601. break;
  602. default:
  603. termch = cmd;
  604. memex();
  605. }
  606. break;
  607. case 'd':
  608. dump();
  609. break;
  610. case 'r':
  611. if (excp != NULL)
  612. prregs(excp); /* print regs */
  613. break;
  614. case 'e':
  615. if (excp == NULL)
  616. printf("No exception informationn");
  617. else
  618. excprint(excp);
  619. break;
  620. case 'M':
  621. print_sysmap();
  622. break;
  623. case 'S':
  624. super_regs();
  625. break;
  626. case 't':
  627. backtrace(excp);
  628. break;
  629. case 'f':
  630. cacheflush();
  631. break;
  632. case 'h':
  633. dump_hash_table();
  634. break;
  635. case 's':
  636. case 'x':
  637. case EOF:
  638. return cmd;
  639. case '?':
  640. printf(help_string);
  641. break;
  642. case 'p':
  643. show_state();
  644. break;
  645. case 'b':
  646. bpt_cmds();
  647. break;
  648. case 'C':
  649. csum();
  650. break;
  651. #ifdef CONFIG_SMP
  652. case 'c':
  653. cpu_cmd();
  654. break;
  655. #endif /* CONFIG_SMP */
  656. case 'T':
  657. debug_trace();
  658. break;
  659. default:
  660. printf("Unrecognized command: ");
  661.         do {
  662. if( ' ' < cmd && cmd <= '~' )
  663. putchar(cmd);
  664. else
  665. printf("\x%x", cmd);
  666. cmd = inchar();
  667.         } while (cmd != 'n'); 
  668. printf(" (type ? for help)n");
  669. break;
  670. }
  671. }
  672. }
  673. #ifdef CONFIG_SMP
  674. static void cpu_cmd(void)
  675. {
  676. unsigned long cpu;
  677. int timeout;
  678. int cmd;
  679. cmd = inchar();
  680. if (cmd == 'i') {
  681. printf("stopping all cpusn");
  682. /* interrupt other cpu(s) */
  683. cpu = MSG_ALL_BUT_SELF;
  684. smp_send_xmon_break(cpu);
  685. return;
  686. }
  687. termch = cmd;
  688. if (!scanhex(&cpu)) {
  689. /* print cpus waiting or in xmon */
  690. printf("cpus stopped:");
  691. for (cpu = 0; cpu < NR_CPUS; ++cpu) {
  692. if (test_bit(cpu, &cpus_in_xmon)) {
  693. printf(" %d", cpu);
  694. if (cpu == smp_processor_id())
  695. printf("*", cpu);
  696. }
  697. }
  698. printf("n");
  699. return;
  700. }
  701. /* try to switch to cpu specified */
  702. take_xmon = cpu;
  703. timeout = 10000000;
  704. while (take_xmon >= 0) {
  705. if (--timeout == 0) {
  706. /* yes there's a race here */
  707. take_xmon = -1;
  708. printf("cpu %u didn't take controln", cpu);
  709. return;
  710. }
  711. }
  712. /* now have to wait to be given control back */
  713. while (test_and_set_bit(0, &got_xmon)) {
  714. if (take_xmon == smp_processor_id()) {
  715. take_xmon = -1;
  716. break;
  717. }
  718. }
  719. }
  720. #endif /* CONFIG_SMP */
  721. static unsigned short fcstab[256] = {
  722. 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  723. 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  724. 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  725. 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  726. 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  727. 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  728. 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  729. 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  730. 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  731. 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  732. 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  733. 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  734. 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  735. 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  736. 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  737. 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  738. 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  739. 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  740. 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  741. 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  742. 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  743. 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  744. 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  745. 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  746. 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  747. 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  748. 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  749. 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  750. 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  751. 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  752. 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  753. 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  754. };
  755. #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
  756. static void
  757. csum(void)
  758. {
  759. unsigned int i;
  760. unsigned short fcs;
  761. unsigned char v;
  762. if (!scanhex(&adrs))
  763. return;
  764. if (!scanhex(&ncsum))
  765. return;
  766. fcs = 0xffff;
  767. for (i = 0; i < ncsum; ++i) {
  768. if (mread(adrs+i, &v, 1) == 0) {
  769. printf("csum stopped at %xn", adrs+i);
  770. break;
  771. }
  772. fcs = FCS(fcs, v);
  773. }
  774. printf("%xn", fcs);
  775. }
  776. static char *breakpoint_help_string = 
  777.     "Breakpoint command usage:n"
  778.     "b                show breakpointsn"
  779.     "b <addr> [cnt]   set breakpoint at given instr addrn"
  780.     "bc               clear all breakpointsn"
  781.     "bc <n/addr>      clear breakpoint number n or at addrn"
  782.     "bi <addr> [cnt]  set hardware instr breakpoint (broken?)n"
  783.     "bd <addr> [cnt]  set hardware data breakpoint (broken?)n"
  784.     "";
  785. static void
  786. bpt_cmds(void)
  787. {
  788. int cmd;
  789. unsigned long a;
  790. int mode, i;
  791. struct bpt *bp;
  792. struct tbtable tab;
  793. cmd = inchar();
  794. switch (cmd) {
  795. case 'd': /* bd - hardware data breakpoint */
  796. if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
  797. printf("Not implemented on POWER4n");
  798. break;
  799. }
  800. mode = 7;
  801. cmd = inchar();
  802. if (cmd == 'r')
  803. mode = 5;
  804. else if (cmd == 'w')
  805. mode = 6;
  806. else
  807. termch = cmd;
  808. dabr.address = 0;
  809. dabr.count = 0;
  810. dabr.enabled = scanhex(&dabr.address);
  811. scanhex(&dabr.count);
  812. if (dabr.enabled)
  813. dabr.address = (dabr.address & ~7) | mode;
  814. break;
  815. case 'i': /* bi - hardware instr breakpoint */
  816. if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) {
  817. break;
  818. }
  819. iabr.address = 0;
  820. iabr.count = 0;
  821. iabr.enabled = scanhex(&iabr.address);
  822. if (iabr.enabled)
  823. iabr.address |= 3;
  824. scanhex(&iabr.count);
  825. break;
  826. case 'c':
  827. if (!scanhex(&a)) {
  828. /* clear all breakpoints */
  829. for (i = 0; i < NBPTS; ++i)
  830. bpts[i].enabled = 0;
  831. iabr.enabled = 0;
  832. dabr.enabled = 0;
  833. printf("All breakpoints clearedn");
  834. } else {
  835. if (a <= NBPTS && a >= 1) {
  836. /* assume a breakpoint number */
  837. --a; /* bp nums are 1 based */
  838. bp = &bpts[a];
  839. } else {
  840. /* assume a breakpoint address */
  841. bp = at_breakpoint(a);
  842. }
  843. if (bp == 0) {
  844. printf("No breakpoint at %xn", a);
  845. } else {
  846. printf("Cleared breakpoint %x (%lx %s)n", (bp - bpts)+1, bp->address, bp->funcname);
  847. bp->enabled = 0;
  848. }
  849. }
  850. break;
  851. case '?':
  852.         printf(breakpoint_help_string);
  853.         break;
  854. default:
  855. termch = cmd;
  856.         cmd = skipbl();
  857. if (cmd == '?') {
  858. printf(breakpoint_help_string);
  859. break;
  860. }
  861. termch = cmd;
  862. if (!scanhex(&a)) {
  863. /* print all breakpoints */
  864. int bpnum;
  865. printf("   type            address    countn");
  866. if (dabr.enabled) {
  867. printf("   data   %.16lx %8x [", dabr.address & ~7,
  868.        dabr.count);
  869. if (dabr.address & 1)
  870. printf("r");
  871. if (dabr.address & 2)
  872. printf("w");
  873. printf("]n");
  874. }
  875. if (iabr.enabled)
  876. printf("   inst   %.16lx %8xn", iabr.address & ~3,
  877.        iabr.count);
  878. for (bp = bpts, bpnum = 1; bp < &bpts[NBPTS]; ++bp, ++bpnum)
  879. if (bp->enabled)
  880. printf("%2x trap   %.16lx %8x  %sn", bpnum, bp->address, bp->count, bp->funcname);
  881. break;
  882. }
  883. bp = at_breakpoint(a);
  884. if (bp == 0) {
  885. for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
  886. if (!bp->enabled)
  887. break;
  888. if (bp >= &bpts[NBPTS]) {
  889. printf("Sorry, no free breakpoints.  Please clear one first.n");
  890. break;
  891. }
  892. }
  893. bp->enabled = 1;
  894. bp->address = a;
  895. bp->count = 0;
  896. scanhex(&bp->count);
  897. /* Find the function name just once. */
  898. bp->funcname[0] = '';
  899. if (find_tb_table(bp->address, &tab) && tab.name[0]) {
  900. /* Got a nice name for it. */
  901. int delta = bp->address - tab.funcstart;
  902. sprintf(bp->funcname, "%s+0x%x", tab.name, delta);
  903. }
  904. printf("Set breakpoint %2x trap   %.16lx %8x  %sn", (bp-bpts)+1, bp->address, bp->count, bp->funcname);
  905. break;
  906. }
  907. }
  908. /* Very cheap human name for vector lookup. */
  909. static
  910. const char *getvecname(unsigned long vec)
  911. {
  912. char *ret;
  913. switch (vec) {
  914. case 0x100: ret = "(System Reset)"; break; 
  915. case 0x200: ret = "(Machine Check)"; break; 
  916. case 0x300: ret = "(Data Access)"; break; 
  917. case 0x400: ret = "(Instruction Access)"; break; 
  918. case 0x500: ret = "(Hardware Interrupt)"; break; 
  919. case 0x600: ret = "(Alignment)"; break; 
  920. case 0x700: ret = "(Program Check)"; break; 
  921. case 0x800: ret = "(FPU Unavailable)"; break; 
  922. case 0x900: ret = "(Decrementer)"; break; 
  923. case 0xc00: ret = "(System Call)"; break; 
  924. case 0xd00: ret = "(Single Step)"; break; 
  925. case 0xf00: ret = "(Performance Monitor)"; break; 
  926. default: ret = "";
  927. }
  928. return ret;
  929. }
  930. static void
  931. backtrace(struct pt_regs *excp)
  932. {
  933. unsigned long sp;
  934. unsigned long lr;
  935. unsigned long stack[3];
  936. struct pt_regs regs;
  937. struct tbtable tab;
  938. int framecount;
  939. char *funcname;
  940. /* declare these as raw ptrs so we don't get func descriptors */
  941. extern void *ret_from_except, *ret_from_syscall_1;
  942. if (excp != NULL) {
  943.         lr = excp->link;
  944. sp = excp->gpr[1];
  945. } else {
  946.         /* Use care not to call any function before this point
  947.  so the saved lr has a chance of being good. */
  948.         asm volatile ("mflr %0" : "=r" (lr) :);
  949. sp = getsp();
  950. }
  951. scanhex(&sp);
  952. scannl();
  953. for (framecount = 0;
  954.      sp != 0 && framecount < MAXFRAMECOUNT;
  955.      sp = stack[0], framecount++) {
  956. if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
  957. break;
  958. #if 0
  959. if (lr != 0) {
  960.     stack[2] = lr; /* fake out the first saved lr.  It may not be saved yet. */
  961.     lr = 0;
  962. }
  963. #endif
  964. printf("%.16lx  %.16lx", sp, stack[2]);
  965. /* TAI -- for now only the ones cast to unsigned long will match.
  966.  * Need to test the rest...
  967.  */
  968. if ((stack[2] == (unsigned long)ret_from_except &&
  969.             (funcname = "ret_from_except"))
  970.     || (stack[2] == (unsigned long)ret_from_syscall_1 &&
  971.             (funcname = "ret_from_syscall_1"))
  972. #if 0
  973.     || stack[2] == (unsigned) &ret_from_syscall_2
  974.     || stack[2] == (unsigned) &do_signal_ret
  975. #endif
  976.     ) {
  977. printf("  %sn", funcname);
  978. if (mread(sp+112, &regs, sizeof(regs)) != sizeof(regs))
  979. break;
  980. printf("exception: %lx %s regs %lxn", regs.trap, getvecname(regs.trap), sp+112);
  981. printf("                  %.16lx", regs.nip);
  982. if ((regs.nip & 0xffffffff00000000UL) &&
  983.     find_tb_table(regs.nip, &tab)) {
  984. int delta = regs.nip-tab.funcstart;
  985. if (delta < 0)
  986. printf("  <unknown code>");
  987. else
  988. printf("  %s+0x%x", tab.name, delta);
  989. }
  990. printf("n");
  991.                         if (regs.gpr[1] < sp) {
  992.                             printf("<Stack drops into 32-bit userspace %.16lx>n", regs.gpr[1]);
  993.                             break;
  994. }
  995. sp = regs.gpr[1];
  996. if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
  997. break;
  998. } else {
  999. if (stack[2] && find_tb_table(stack[2], &tab)) {
  1000. int delta = stack[2]-tab.funcstart;
  1001. if (delta < 0)
  1002. printf("  <unknown code>");
  1003. else
  1004. printf("  %s+0x%x", tab.name, delta);
  1005. }
  1006. printf("n");
  1007. }
  1008. if (stack[0] && stack[0] <= sp) {
  1009. if ((stack[0] & 0xffffffff00000000UL) == 0)
  1010. printf("<Stack drops into 32-bit userspace %.16lx>n", stack[0]);
  1011. else
  1012. printf("<Corrupt stack.  Next backchain is %.16lx>n", stack[0]);
  1013. break;
  1014. }
  1015. }
  1016. if (framecount >= MAXFRAMECOUNT)
  1017. printf("<Punt. Too many stack frames>n");
  1018. }
  1019. int
  1020. getsp()
  1021. {
  1022. int x;
  1023. asm("mr %0,1" : "=r" (x) :);
  1024. return x;
  1025. }
  1026. spinlock_t exception_print_lock = SPIN_LOCK_UNLOCKED;
  1027. void
  1028. excprint(struct pt_regs *fp)
  1029. {
  1030. struct task_struct *c;
  1031. struct tbtable tab;
  1032. unsigned long flags;
  1033. spin_lock_irqsave(&exception_print_lock, flags);
  1034. #ifdef CONFIG_SMP
  1035. printf("cpu %d: ", smp_processor_id());
  1036. #endif /* CONFIG_SMP */
  1037. printf("Vector: %lx %s at  [%lx]n", fp->trap, getvecname(fp->trap), fp);
  1038. printf("    pc: %lx", fp->nip);
  1039. if (find_tb_table(fp->nip, &tab) && tab.name[0]) {
  1040. /* Got a nice name for it */
  1041. int delta = fp->nip - tab.funcstart;
  1042. printf(" (%s+0x%x)", tab.name, delta);
  1043. }
  1044. printf("n");
  1045. printf("    lr: %lx", fp->link);
  1046. if (find_tb_table(fp->link, &tab) && tab.name[0]) {
  1047. /* Got a nice name for it */
  1048. int delta = fp->link - tab.funcstart;
  1049. printf(" (%s+0x%x)", tab.name, delta);
  1050. }
  1051. printf("n");
  1052. printf("    sp: %lxn", fp->gpr[1]);
  1053. printf("   msr: %lxn", fp->msr);
  1054. if (fp->trap == 0x300 || fp->trap == 0x600) {
  1055. printf("   dar: %lxn", fp->dar);
  1056. printf(" dsisr: %lxn", fp->dsisr);
  1057. }
  1058. /* XXX: need to copy current or we die.  Why? */
  1059. c = current;
  1060. printf("  current = 0x%lxn", c);
  1061. printf("  paca    = 0x%lxn", get_paca());
  1062. if (c) {
  1063. printf("  current = %lx, pid = %ld, comm = %sn",
  1064.        c, c->pid, c->comm);
  1065. }
  1066. spin_unlock_irqrestore(&exception_print_lock, flags);
  1067. }
  1068. void
  1069. prregs(struct pt_regs *fp)
  1070. {
  1071. int n;
  1072. unsigned long base;
  1073. if (scanhex((void *)&base))
  1074. fp = (struct pt_regs *) base;
  1075. for (n = 0; n < 16; ++n)
  1076. printf("R%.2ld = %.16lx   R%.2ld = %.16lxn", n, fp->gpr[n],
  1077.        n+16, fp->gpr[n+16]);
  1078. printf("pc  = %.16lx   msr = %.16lxnlr  = %.16lx   cr  = %.16lxn",
  1079.        fp->nip, fp->msr, fp->link, fp->ccr);
  1080. printf("ctr = %.16lx   xer = %.16lx   trap = %8lxn",
  1081.        fp->ctr, fp->xer, fp->trap);
  1082. }
  1083. void
  1084. cacheflush(void)
  1085. {
  1086. int cmd;
  1087. unsigned long nflush;
  1088. cmd = inchar();
  1089. if (cmd != 'i')
  1090. termch = cmd;
  1091. scanhex((void *)&adrs);
  1092. if (termch != 'n')
  1093. termch = 0;
  1094. nflush = 1;
  1095. scanhex(&nflush);
  1096. nflush = (nflush + 31) / 32;
  1097. if (cmd != 'i') {
  1098. for (; nflush > 0; --nflush, adrs += 0x20)
  1099. cflush((void *) adrs);
  1100. } else {
  1101. for (; nflush > 0; --nflush, adrs += 0x20)
  1102. cinval((void *) adrs);
  1103. }
  1104. }
  1105. unsigned long
  1106. read_spr(int n)
  1107. {
  1108. unsigned int instrs[2];
  1109. unsigned long (*code)(void);
  1110. unsigned long opd[3];
  1111. instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
  1112. instrs[1] = 0x4e800020;
  1113. opd[0] = (unsigned long)instrs;
  1114. opd[1] = 0;
  1115. opd[2] = 0;
  1116. store_inst(instrs);
  1117. store_inst(instrs+1);
  1118. code = (unsigned long (*)(void)) opd;
  1119. return code();
  1120. }
  1121. void
  1122. write_spr(int n, unsigned long val)
  1123. {
  1124. unsigned int instrs[2];
  1125. unsigned long (*code)(unsigned long);
  1126. unsigned long opd[3];
  1127. instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
  1128. instrs[1] = 0x4e800020;
  1129. opd[0] = (unsigned long)instrs;
  1130. opd[1] = 0;
  1131. opd[2] = 0;
  1132. store_inst(instrs);
  1133. store_inst(instrs+1);
  1134. code = (unsigned long (*)(unsigned long)) opd;
  1135. code(val);
  1136. }
  1137. static unsigned long regno;
  1138. extern char exc_prolog;
  1139. extern char dec_exc;
  1140. void
  1141. print_sysmap(void)
  1142. {
  1143. extern char *sysmap;
  1144. if ( sysmap )
  1145. printf("System.map: n%s", sysmap);
  1146. }
  1147. void
  1148. super_regs()
  1149. {
  1150. int i, cmd;
  1151. unsigned long val;
  1152. struct paca_struct*  ptrPaca = NULL;
  1153. struct ItLpPaca*  ptrLpPaca = NULL;
  1154. struct ItLpRegSave*  ptrLpRegSave = NULL;
  1155. cmd = skipbl();
  1156. if (cmd == 'n') {
  1157.         unsigned long sp, toc;
  1158. asm("mr %0,1" : "=r" (sp) :);
  1159. asm("mr %0,2" : "=r" (toc) :);
  1160. printf("msr  = %.16lx  sprg0= %.16lxn", get_msr(), get_sprg0());
  1161. printf("pvr  = %.16lx  sprg1= %.16lxn", get_pvr(), get_sprg1()); 
  1162. printf("dec  = %.16lx  sprg2= %.16lxn", get_dec(), get_sprg2());
  1163. printf("sp   = %.16lx  sprg3= %.16lxn", sp, get_sprg3());
  1164. printf("toc  = %.16lx  dar  = %.16lxn", toc, get_dar());
  1165. printf("srr0 = %.16lx  srr1 = %.16lxn", get_srr0(), get_srr1());
  1166. printf("asr  = %.16lxn", mfasr());
  1167. for (i = 0; i < 8; ++i)
  1168. printf("sr%.2ld = %.16lx  sr%.2ld = %.16lxn", i, get_sr(i), i+8, get_sr(i+8));
  1169. // Dump out relevant Paca data areas.
  1170. printf("Paca: n");
  1171. ptrPaca = get_paca();
  1172.     
  1173. printf("  Local Processor Control Area (LpPaca): n");
  1174. ptrLpPaca = ptrPaca->xLpPacaPtr;
  1175. printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx n", ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);
  1176. printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx n", ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);
  1177. printf("    Saved Gpr5=%.16lx n", ptrLpPaca->xSavedGpr5);
  1178.     
  1179. printf("  Local Processor Register Save Area (LpRegSave): n");
  1180. ptrLpRegSave = ptrPaca->xLpRegSavePtr;
  1181. printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx n", ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
  1182. printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx n", ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
  1183. printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx n", ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
  1184.     
  1185. return;
  1186. }
  1187. scanhex(&regno);
  1188. switch (cmd) {
  1189. case 'w':
  1190. val = read_spr(regno);
  1191. scanhex(&val);
  1192. write_spr(regno, val);
  1193. /* fall through */
  1194. case 'r':
  1195. printf("spr %lx = %lxn", regno, read_spr(regno));
  1196. break;
  1197. case 's':
  1198. val = get_sr(regno);
  1199. scanhex(&val);
  1200. set_sr(regno, val);
  1201. break;
  1202. case 'm':
  1203. val = get_msr();
  1204. scanhex(&val);
  1205. set_msrd(val);
  1206. break;
  1207. }
  1208. scannl();
  1209. }
  1210. #if 0
  1211. static void
  1212. openforth()
  1213. {
  1214. int c;
  1215. char *p;
  1216. char cmd[1024];
  1217. int args[5];
  1218. extern int (*prom_entry)(int *);
  1219. p = cmd;
  1220. c = skipbl();
  1221. while (c != 'n') {
  1222. *p++ = c;
  1223. c = inchar();
  1224. }
  1225. *p = 0;
  1226. args[0] = (int) "interpret";
  1227. args[1] = 1;
  1228. args[2] = 1;
  1229. args[3] = (int) cmd;
  1230. (*prom_entry)(args);
  1231. printf("n");
  1232. if (args[4] != 0)
  1233. printf("error %xn", args[4]);
  1234. }
  1235. #endif
  1236. #ifndef CONFIG_PPC64BRIDGE
  1237. static void
  1238. dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
  1239. {
  1240. extern void *Hash;
  1241. extern unsigned long Hash_size;
  1242. unsigned *htab = Hash;
  1243. unsigned hsize = Hash_size;
  1244. unsigned v, hmask, va, last_va;
  1245. int found, last_found, i;
  1246. unsigned *hg, w1, last_w2, last_va0;
  1247. last_found = 0;
  1248. hmask = hsize / 64 - 1;
  1249. va = start;
  1250. start = (start >> 12) & 0xffff;
  1251. end = (end >> 12) & 0xffff;
  1252. for (v = start; v < end; ++v) {
  1253. found = 0;
  1254. hg = htab + (((v ^ seg) & hmask) * 16);
  1255. w1 = 0x80000000 | (seg << 7) | (v >> 10);
  1256. for (i = 0; i < 8; ++i, hg += 2) {
  1257. if (*hg == w1) {
  1258. found = 1;
  1259. break;
  1260. }
  1261. }
  1262. if (!found) {
  1263. w1 ^= 0x40;
  1264. hg = htab + ((~(v ^ seg) & hmask) * 16);
  1265. for (i = 0; i < 8; ++i, hg += 2) {
  1266. if (*hg == w1) {
  1267. found = 1;
  1268. break;
  1269. }
  1270. }
  1271. }
  1272. if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) {
  1273. if (last_found) {
  1274. if (last_va != last_va0)
  1275. printf(" ... %x", last_va);
  1276. printf("n");
  1277. }
  1278. if (found) {
  1279. printf("%x to %x", va, hg[1]);
  1280. last_va0 = va;
  1281. }
  1282. last_found = found;
  1283. }
  1284. if (found) {
  1285. last_w2 = hg[1] & ~0x180;
  1286. last_va = va;
  1287. }
  1288. va += 4096;
  1289. }
  1290. if (last_found)
  1291. printf(" ... %xn", last_va);
  1292. }
  1293. #else /* CONFIG_PPC64BRIDGE */
  1294. static void
  1295. dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
  1296. {
  1297. extern void *Hash;
  1298. extern unsigned long Hash_size;
  1299. unsigned *htab = Hash;
  1300. unsigned hsize = Hash_size;
  1301. unsigned v, hmask, va, last_va;
  1302. int found, last_found, i;
  1303. unsigned *hg, w1, last_w2, last_va0;
  1304. last_found = 0;
  1305. hmask = hsize / 128 - 1;
  1306. va = start;
  1307. start = (start >> 12) & 0xffff;
  1308. end = (end >> 12) & 0xffff;
  1309. for (v = start; v < end; ++v) {
  1310. found = 0;
  1311. hg = htab + (((v ^ seg) & hmask) * 32);
  1312. w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4);
  1313. for (i = 0; i < 8; ++i, hg += 4) {
  1314. if (hg[1] == w1) {
  1315. found = 1;
  1316. break;
  1317. }
  1318. }
  1319. if (!found) {
  1320. w1 ^= 2;
  1321. hg = htab + ((~(v ^ seg) & hmask) * 32);
  1322. for (i = 0; i < 8; ++i, hg += 4) {
  1323. if (hg[1] == w1) {
  1324. found = 1;
  1325. break;
  1326. }
  1327. }
  1328. }
  1329. if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) {
  1330. if (last_found) {
  1331. if (last_va != last_va0)
  1332. printf(" ... %x", last_va);
  1333. printf("n");
  1334. }
  1335. if (found) {
  1336. printf("%x to %x", va, hg[3]);
  1337. last_va0 = va;
  1338. }
  1339. last_found = found;
  1340. }
  1341. if (found) {
  1342. last_w2 = hg[3] & ~0x180;
  1343. last_va = va;
  1344. }
  1345. va += 4096;
  1346. }
  1347. if (last_found)
  1348. printf(" ... %xn", last_va);
  1349. }
  1350. #endif /* CONFIG_PPC64BRIDGE */
  1351. static unsigned long hash_ctx;
  1352. static unsigned long hash_start;
  1353. static unsigned long hash_end;
  1354. static void
  1355. dump_hash_table()
  1356. {
  1357. int seg;
  1358. unsigned seg_start, seg_end;
  1359. hash_ctx = 0;
  1360. hash_start = 0;
  1361. hash_end = 0xfffff000;
  1362. scanhex(&hash_ctx);
  1363. scanhex(&hash_start);
  1364. scanhex(&hash_end);
  1365. printf("Mappings for context %xn", hash_ctx);
  1366. seg_start = hash_start;
  1367. for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) {
  1368. seg_end = (seg << 28) | 0x0ffff000;
  1369. if (seg_end > hash_end)
  1370. seg_end = hash_end;
  1371. dump_hash_table_seg((hash_ctx << 4) + seg, seg_start, seg_end);
  1372. seg_start = seg_end + 0x1000;
  1373. }
  1374. }
  1375. int
  1376. mread(unsigned long adrs, void *buf, int size)
  1377. {
  1378. volatile int n;
  1379. char *p, *q;
  1380. n = 0;
  1381. if( setjmp(bus_error_jmp) == 0 ){
  1382. debugger_fault_handler = handle_fault;
  1383. sync();
  1384. p = (char *) adrs;
  1385. q = (char *) buf;
  1386. switch (size) {
  1387. case 2: *(short *)q = *(short *)p; break;
  1388. case 4: *(int *)q = *(int *)p; break;
  1389. default:
  1390. for( ; n < size; ++n ) {
  1391. *q++ = *p++;
  1392. sync();
  1393. }
  1394. }
  1395. sync();
  1396. /* wait a little while to see if we get a machine check */
  1397. __delay(200);
  1398. n = size;
  1399. }
  1400. debugger_fault_handler = 0;
  1401. return n;
  1402. }
  1403. int
  1404. mwrite(unsigned long adrs, void *buf, int size)
  1405. {
  1406. volatile int n;
  1407. char *p, *q;
  1408. n = 0;
  1409. if( setjmp(bus_error_jmp) == 0 ){
  1410. debugger_fault_handler = handle_fault;
  1411. sync();
  1412. p = (char *) adrs;
  1413. q = (char *) buf;
  1414. switch (size) {
  1415. case 2: *(short *)p = *(short *)q; break;
  1416. case 4: *(int *)p = *(int *)q; break;
  1417. default:
  1418. for( ; n < size; ++n ) {
  1419. *p++ = *q++;
  1420. sync();
  1421. }
  1422. }
  1423. sync();
  1424. /* wait a little while to see if we get a machine check */
  1425. __delay(200);
  1426. n = size;
  1427. } else {
  1428. printf("*** Error writing address %xn", adrs + n);
  1429. }
  1430. debugger_fault_handler = 0;
  1431. return n;
  1432. }
  1433. static int fault_type;
  1434. static char *fault_chars[] = { "--", "**", "##" };
  1435. static void
  1436. handle_fault(struct pt_regs *regs)
  1437. {
  1438. fault_type = regs->trap == 0x200? 0: regs->trap == 0x300? 1: 2;
  1439. longjmp(bus_error_jmp, 1);
  1440. }
  1441. #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
  1442. void
  1443. byterev(unsigned char *val, int size)
  1444. {
  1445. int t;
  1446. switch (size) {
  1447. case 2:
  1448. SWAP(val[0], val[1], t);
  1449. break;
  1450. case 4:
  1451. SWAP(val[0], val[3], t);
  1452. SWAP(val[1], val[2], t);
  1453. break;
  1454. case 8: /* is there really any use for this? */
  1455. SWAP(val[0], val[7], t);
  1456. SWAP(val[1], val[6], t);
  1457. SWAP(val[2], val[5], t);
  1458. SWAP(val[3], val[4], t);
  1459. break;
  1460. }
  1461. }
  1462. static int brev;
  1463. static int mnoread;
  1464. static char *memex_help_string = 
  1465.     "Memory examine command usage:n"
  1466.     "m [addr] [flags] examine/change memoryn"
  1467.     "  addr is optional.  will start where left off.n"
  1468.     "  flags may include chars from this set:n"
  1469.     "    b   modify by bytes (default)n"
  1470.     "    w   modify by words (2 byte)n"
  1471.     "    l   modify by longs (4 byte)n"
  1472.     "    d   modify by doubleword (8 byte)n"
  1473.     "    r   toggle reverse byte order moden"
  1474.     "    n   do not read memory (for i/o spaces)n"
  1475.     "    .   ok to read (default)n"
  1476.     "NOTE: flags are saved as defaultsn"
  1477.     "";
  1478. static char *memex_subcmd_help_string = 
  1479.     "Memory examine subcommands:n"
  1480.     "  hexval   write this val to current locationn"
  1481.     "  'string' write chars from string to this locationn"
  1482.     "  '        increment addressn"
  1483.     "  ^        decrement addressn"
  1484.     "  /        increment addr by 0x10.  //=0x100, ///=0x1000, etcn"
  1485.     "  \        decrement addr by 0x10.  \\=0x100, \\\=0x1000, etcn"
  1486.     "  `        clear no-read flagn"
  1487.     "  ;        stay at this addrn"
  1488.     "  v        change to byte moden"
  1489.     "  w        change to word (2 byte) moden"
  1490.     "  l        change to long (4 byte) moden"
  1491.     "  u        change to doubleword (8 byte) moden"
  1492.     "  m addr   change current addrn"
  1493.     "  n        toggle no-read flagn"
  1494.     "  r        toggle byte reverse flagn"
  1495.     "  < count  back up count bytesn"
  1496.     "  > count  skip forward count bytesn"
  1497.     "  x        exit this moden"
  1498.     "";
  1499. void
  1500. memex()
  1501. {
  1502. int cmd, inc, i, nslash;
  1503. unsigned long n;
  1504. unsigned char val[16];
  1505. scanhex((void *)&adrs);
  1506. cmd = skipbl();
  1507. if (cmd == '?') {
  1508. printf(memex_help_string);
  1509. return;
  1510. } else {
  1511. termch = cmd;
  1512. }
  1513. last_cmd = "mn";
  1514. while ((cmd = skipbl()) != 'n') {
  1515. switch( cmd ){
  1516. case 'b': size = 1; break;
  1517. case 'w': size = 2; break;
  1518. case 'l': size = 4; break;
  1519. case 'd': size = 8; break;
  1520. case 'r':  brev = !brev; break;
  1521. case 'n': mnoread = 1; break;
  1522. case '.': mnoread = 0; break;
  1523. }
  1524. }
  1525. if( size <= 0 )
  1526. size = 1;
  1527. else if( size > 8 )
  1528. size = 8;
  1529. for(;;){
  1530. if (!mnoread)
  1531. n = mread(adrs, val, size);
  1532. printf("%.16x%c", adrs, brev? 'r': ' ');
  1533. if (!mnoread) {
  1534. if (brev)
  1535. byterev(val, size);
  1536. putchar(' ');
  1537. for (i = 0; i < n; ++i)
  1538. printf("%.2x", val[i]);
  1539. for (; i < size; ++i)
  1540. printf("%s", fault_chars[fault_type]);
  1541. }
  1542. putchar(' ');
  1543. inc = size;
  1544. nslash = 0;
  1545. for(;;){
  1546. if( scanhex(&n) ){
  1547. for (i = 0; i < size; ++i)
  1548. val[i] = n >> (i * 8);
  1549. if (!brev)
  1550. byterev(val, size);
  1551. mwrite(adrs, val, size);
  1552. inc = size;
  1553. }
  1554. cmd = skipbl();
  1555. if (cmd == 'n')
  1556. break;
  1557. inc = 0;
  1558. switch (cmd) {
  1559. case ''':
  1560. for(;;){
  1561. n = inchar();
  1562. if( n == '\' )
  1563. n = bsesc();
  1564. else if( n == ''' )
  1565. break;
  1566. for (i = 0; i < size; ++i)
  1567. val[i] = n >> (i * 8);
  1568. if (!brev)
  1569. byterev(val, size);
  1570. mwrite(adrs, val, size);
  1571. adrs += size;
  1572. }
  1573. adrs -= size;
  1574. inc = size;
  1575. break;
  1576. case ',':
  1577. adrs += size;
  1578. break;
  1579. case '.':
  1580. mnoread = 0;
  1581. break;
  1582. case ';':
  1583. break;
  1584. case 'x':
  1585. case EOF:
  1586. scannl();
  1587. return;
  1588. case 'b':
  1589. case 'v':
  1590. size = 1;
  1591. break;
  1592. case 'w':
  1593. size = 2;
  1594. break;
  1595. case 'l':
  1596. size = 4;
  1597. break;
  1598. case 'u':
  1599. size = 8;
  1600. break;
  1601. case '^':
  1602. adrs -= size;
  1603. break;
  1604. break;
  1605. case '/':
  1606. if (nslash > 0)
  1607. adrs -= 1 << nslash;
  1608. else
  1609. nslash = 0;
  1610. nslash += 4;
  1611. adrs += 1 << nslash;
  1612. break;
  1613. case '\':
  1614. if (nslash < 0)
  1615. adrs += 1 << -nslash;
  1616. else
  1617. nslash = 0;
  1618. nslash -= 4;
  1619. adrs -= 1 << -nslash;
  1620. break;
  1621. case 'm':
  1622. scanhex((void *)&adrs);
  1623. break;
  1624. case 'n':
  1625. mnoread = 1;
  1626. break;
  1627. case 'r':
  1628. brev = !brev;
  1629. break;
  1630. case '<':
  1631. n = size;
  1632. scanhex(&n);
  1633. adrs -= n;
  1634. break;
  1635. case '>':
  1636. n = size;
  1637. scanhex(&n);
  1638. adrs += n;
  1639. break;
  1640. case '?':
  1641. printf(memex_subcmd_help_string);
  1642. break;
  1643. }
  1644. }
  1645. adrs += inc;
  1646. }
  1647. }
  1648. int
  1649. bsesc()
  1650. {
  1651. int c;
  1652. c = inchar();
  1653. switch( c ){
  1654. case 'n': c = 'n'; break;
  1655. case 'r': c = 'r'; break;
  1656. case 'b': c = 'b'; break;
  1657. case 't': c = 't'; break;
  1658. }
  1659. return c;
  1660. }
  1661. #define isxdigit(c) (('0' <= (c) && (c) <= '9') 
  1662.  || ('a' <= (c) && (c) <= 'f') 
  1663.  || ('A' <= (c) && (c) <= 'F'))
  1664. void
  1665. dump()
  1666. {
  1667. int c;
  1668. c = inchar();
  1669. if ((isxdigit(c) && c != 'f' && c != 'd') || c == 'n')
  1670. termch = c;
  1671. scanhex((void *)&adrs);
  1672. if( termch != 'n')
  1673. termch = 0;
  1674. if( c == 'i' ){
  1675. scanhex(&nidump);
  1676. if( nidump == 0 )
  1677. nidump = 16;
  1678. adrs += ppc_inst_dump(adrs, nidump);
  1679. last_cmd = "din";
  1680. } else {
  1681. scanhex(&ndump);
  1682. if( ndump == 0 )
  1683. ndump = 64;
  1684. prdump(adrs, ndump);
  1685. adrs += ndump;
  1686. last_cmd = "dn";
  1687. }
  1688. }
  1689. void
  1690. prdump(unsigned long adrs, long ndump)
  1691. {
  1692. long n, m, c, r, nr;
  1693. unsigned char temp[16];
  1694. for( n = ndump; n > 0; ){
  1695. printf("%.16lx", adrs);
  1696. putchar(' ');
  1697. r = n < 16? n: 16;
  1698. nr = mread(adrs, temp, r);
  1699. adrs += nr;
  1700. for( m = 0; m < r; ++m ){
  1701.         if ((m & 7) == 0 && m > 0)
  1702.     putchar(' ');
  1703. if( m < nr )
  1704. printf("%.2x", temp[m]);
  1705. else
  1706. printf("%s", fault_chars[fault_type]);
  1707. }
  1708. for(; m < 16; ++m )
  1709. printf("   ");
  1710. printf("  |");
  1711. for( m = 0; m < r; ++m ){
  1712. if( m < nr ){
  1713. c = temp[m];
  1714. putchar(' ' <= c && c <= '~'? c: '.');
  1715. } else
  1716. putchar(' ');
  1717. }
  1718. n -= r;
  1719. for(; m < 16; ++m )
  1720. putchar(' ');
  1721. printf("|n");
  1722. if( nr < r )
  1723. break;
  1724. }
  1725. }
  1726. int
  1727. ppc_inst_dump(unsigned long adr, long count)
  1728. {
  1729. int nr, dotted;
  1730. unsigned long first_adr;
  1731. unsigned long inst, last_inst;
  1732. unsigned char val[4];
  1733. dotted = 0;
  1734. for (first_adr = adr; count > 0; --count, adr += 4){
  1735. nr = mread(adr, val, 4);
  1736. if( nr == 0 ){
  1737. const char *x = fault_chars[fault_type];
  1738. printf("%.16lx  %s%s%s%sn", adr, x, x, x, x);
  1739. break;
  1740. }
  1741. inst = GETWORD(val);
  1742. if (adr > first_adr && inst == last_inst) {
  1743. if (!dotted) {
  1744. printf(" ...n");
  1745. dotted = 1;
  1746. }
  1747. continue;
  1748. }
  1749. dotted = 0;
  1750. last_inst = inst;
  1751. printf("%.16lx  ", adr);
  1752. printf("%.8xt", inst);
  1753. print_insn_big_powerpc(stdout, inst, adr); /* always returns 4 */
  1754. printf("n");
  1755. }
  1756. return adr - first_adr;
  1757. }
  1758. void
  1759. print_address(unsigned long addr)
  1760. {
  1761. printf("0x%lx", addr);
  1762. }
  1763. /*
  1764.  * Memory operations - move, set, print differences
  1765.  */
  1766. static unsigned long mdest; /* destination address */
  1767. static unsigned long msrc; /* source address */
  1768. static unsigned long mval; /* byte value to set memory to */
  1769. static unsigned long mcount; /* # bytes to affect */
  1770. static unsigned long mdiffs; /* max # differences to print */
  1771. void
  1772. memops(int cmd)
  1773. {
  1774. scanhex((void *)&mdest);
  1775. if( termch != 'n' )
  1776. termch = 0;
  1777. scanhex((void *)(cmd == 's'? &mval: &msrc));
  1778. if( termch != 'n' )
  1779. termch = 0;
  1780. scanhex((void *)&mcount);
  1781. switch( cmd ){
  1782. case 'm':
  1783. memmove((void *)mdest, (void *)msrc, mcount);
  1784. break;
  1785. case 's':
  1786. memset((void *)mdest, mval, mcount);
  1787. break;
  1788. case 'd':
  1789. if( termch != 'n' )
  1790. termch = 0;
  1791. scanhex((void *)&mdiffs);
  1792. memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
  1793. break;
  1794. }
  1795. }
  1796. void
  1797. memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
  1798. {
  1799. unsigned n, prt;
  1800. prt = 0;
  1801. for( n = nb; n > 0; --n )
  1802. if( *p1++ != *p2++ )
  1803. if( ++prt <= maxpr )
  1804. printf("%.16x %.2x # %.16x %.2xn", p1 - 1,
  1805. p1[-1], p2 - 1, p2[-1]);
  1806. if( prt > maxpr )
  1807. printf("Total of %d differencesn", prt);
  1808. }
  1809. static unsigned mend;
  1810. static unsigned mask;
  1811. void
  1812. memlocate()
  1813. {
  1814. unsigned a, n;
  1815. unsigned char val[4];
  1816. last_cmd = "ml";
  1817. scanhex((void *)&mdest);
  1818. if (termch != 'n') {
  1819. termch = 0;
  1820. scanhex((void *)&mend);
  1821. if (termch != 'n') {
  1822. termch = 0;
  1823. scanhex((void *)&mval);
  1824. mask = ~0;
  1825. if (termch != 'n') termch = 0;
  1826. scanhex((void *)&mask);
  1827. }
  1828. }
  1829. n = 0;
  1830. for (a = mdest; a < mend; a += 4) {
  1831. if (mread(a, val, 4) == 4
  1832. && ((GETWORD(val) ^ mval) & mask) == 0) {
  1833. printf("%.16x:  %.16xn", a, GETWORD(val));
  1834. if (++n >= 10)
  1835. break;
  1836. }
  1837. }
  1838. }
  1839. static unsigned long mskip = 0x1000;
  1840. static unsigned long mlim = 0xffffffff;
  1841. void
  1842. memzcan()
  1843. {
  1844. unsigned char v;
  1845. unsigned a;
  1846. int ok, ook;
  1847. scanhex(&mdest);
  1848. if (termch != 'n') termch = 0;
  1849. scanhex(&mskip);
  1850. if (termch != 'n') termch = 0;
  1851. scanhex(&mlim);
  1852. ook = 0;
  1853. for (a = mdest; a < mlim; a += mskip) {
  1854. ok = mread(a, &v, 1);
  1855. if (ok && !ook) {
  1856. printf("%.8x .. ", a);
  1857. fflush(stdout);
  1858. } else if (!ok && ook)
  1859. printf("%.8xn", a - mskip);
  1860. ook = ok;
  1861. if (a + mskip < a)
  1862. break;
  1863. }
  1864. if (ook)
  1865. printf("%.8xn", a - mskip);
  1866. }
  1867. /* Input scanning routines */
  1868. int
  1869. skipbl()
  1870. {
  1871. int c;
  1872. if( termch != 0 ){
  1873. c = termch;
  1874. termch = 0;
  1875. } else
  1876. c = inchar();
  1877. while( c == ' ' || c == 't' )
  1878. c = inchar();
  1879. return c;
  1880. }
  1881. int
  1882. scanhex(vp)
  1883. unsigned long *vp;
  1884. {
  1885. int c, d;
  1886. unsigned long v;
  1887. c = skipbl();
  1888. d = hexdigit(c);
  1889. if( d == EOF ){
  1890. termch = c;
  1891. return 0;
  1892. }
  1893. v = 0;
  1894. do {
  1895. v = (v << 4) + d;
  1896. c = inchar();
  1897. d = hexdigit(c);
  1898. } while( d != EOF );
  1899. termch = c;
  1900. *vp = v;
  1901. return 1;
  1902. }
  1903. void
  1904. scannl()
  1905. {
  1906. int c;
  1907. c = termch;
  1908. termch = 0;
  1909. while( c != 'n' )
  1910. c = inchar();
  1911. }
  1912. int
  1913. hexdigit(int c)
  1914. {
  1915. if( '0' <= c && c <= '9' )
  1916. return c - '0';
  1917. if( 'A' <= c && c <= 'F' )
  1918. return c - ('A' - 10);
  1919. if( 'a' <= c && c <= 'f' )
  1920. return c - ('a' - 10);
  1921. return EOF;
  1922. }
  1923. void
  1924. getstring(char *s, int size)
  1925. {
  1926. int c;
  1927. c = skipbl();
  1928. do {
  1929. if( size > 1 ){
  1930. *s++ = c;
  1931. --size;
  1932. }
  1933. c = inchar();
  1934. } while( c != ' ' && c != 't' && c != 'n' );
  1935. termch = c;
  1936. *s = 0;
  1937. }
  1938. static char line[256];
  1939. static char *lineptr;
  1940. void
  1941. flush_input()
  1942. {
  1943. lineptr = NULL;
  1944. }
  1945. int
  1946. inchar()
  1947. {
  1948. if (lineptr == NULL || *lineptr == 0) {
  1949. if (fgets(line, sizeof(line), stdin) == NULL) {
  1950. lineptr = NULL;
  1951. return EOF;
  1952. }
  1953. lineptr = line;
  1954. }
  1955. return *lineptr++;
  1956. }
  1957. void
  1958. take_input(str)
  1959. char *str;
  1960. {
  1961. lineptr = str;
  1962. }
  1963. /* Starting at codeaddr scan forward for a tbtable and fill in the
  1964.  given table.  Return non-zero if successful at doing something.
  1965.  */
  1966. static int
  1967. find_tb_table(unsigned long codeaddr, struct tbtable *tab)
  1968. {
  1969. unsigned long codeaddr_max;
  1970. unsigned long tbtab_start;
  1971. int nr;
  1972. int instr;
  1973. int num_parms;
  1974. if (tab == NULL)
  1975. return 0;
  1976. memset(tab, 0, sizeof(tab));
  1977. /* Scan instructions starting at codeaddr for 128k max */
  1978. for (codeaddr_max = codeaddr + 128*1024*4;
  1979.      codeaddr < codeaddr_max;
  1980.      codeaddr += 4) {
  1981. nr = mread(codeaddr, &instr, 4);
  1982. if (nr != 4)
  1983. return 0; /* Bad read.  Give up promptly. */
  1984. if (instr == 0) {
  1985. /* table should follow. */
  1986. int version;
  1987. unsigned long flags;
  1988. tbtab_start = codeaddr; /* save it to compute func start addr */
  1989. codeaddr += 4;
  1990. nr = mread(codeaddr, &flags, 8);
  1991. if (nr != 8)
  1992. return 0; /* Bad read or no tb table. */
  1993. tab->flags = flags;
  1994. version = (flags >> 56) & 0xff;
  1995. if (version != 0)
  1996. continue; /* No tb table here. */
  1997. /* Now, like the version, some of the flags are values
  1998.  that are more conveniently extracted... */
  1999. tab->fp_saved = (flags >> 24) & 0x3f;
  2000. tab->gpr_saved = (flags >> 16) & 0x3f;
  2001. tab->fixedparms = (flags >> 8) & 0xff;
  2002. tab->floatparms = (flags >> 1) & 0x7f;
  2003. codeaddr += 8;
  2004. num_parms = tab->fixedparms + tab->floatparms;
  2005. if (num_parms) {
  2006. unsigned int parminfo;
  2007. int parm;
  2008. if (num_parms > 32)
  2009. return 1; /* incomplete */
  2010. nr = mread(codeaddr, &parminfo, 4);
  2011. if (nr != 4)
  2012. return 1; /* incomplete */
  2013. /* decode parminfo...32 bits.
  2014.  A zero means fixed.  A one means float and the
  2015.  following bit determines single (0) or double (1).
  2016.  */
  2017. for (parm = 0; parm < num_parms; parm++) {
  2018. if (parminfo & 0x80000000) {
  2019. parminfo <<= 1;
  2020. if (parminfo & 0x80000000)
  2021. tab->parminfo[parm] = TBTAB_PARMDFLOAT;
  2022. else
  2023. tab->parminfo[parm] = TBTAB_PARMSFLOAT;
  2024. } else {
  2025. tab->parminfo[parm] = TBTAB_PARMFIXED;
  2026. }
  2027. parminfo <<= 1;
  2028. }
  2029. codeaddr += 4;
  2030. }
  2031. if (flags & TBTAB_FLAGSHASTBOFF) {
  2032. nr = mread(codeaddr, &tab->tb_offset, 4);
  2033. if (nr != 4)
  2034. return 1; /* incomplete */
  2035. if (tab->tb_offset > 0) {
  2036. tab->funcstart = tbtab_start - tab->tb_offset;
  2037. }
  2038. codeaddr += 4;
  2039. }
  2040. /* hand_mask appears to be always be omitted. */
  2041. if (flags & TBTAB_FLAGSHASCTL) {
  2042. /* Assume this will never happen for C or asm */
  2043. return 1; /* incomplete */
  2044. }
  2045. if (flags & TBTAB_FLAGSNAMEPRESENT) {
  2046. short namlen;
  2047. nr = mread(codeaddr, &namlen, 2);
  2048. if (nr != 2)
  2049. return 1; /* incomplete */
  2050. if (namlen >= sizeof(tab->name))
  2051. namlen = sizeof(tab->name)-1;
  2052. codeaddr += 2;
  2053. nr = mread(codeaddr, tab->name, namlen);
  2054. tab->name[namlen] = '';
  2055. codeaddr += namlen;
  2056. }
  2057. return 1;
  2058. }
  2059. }
  2060. return 0; /* hit max...sorry. */
  2061. }
  2062. void
  2063. mem_translate()
  2064. {
  2065. int c;
  2066. unsigned long ea, va, vsid, vpn, page, hpteg_slot_primary, hpteg_slot_secondary, primary_hash, i, *steg, esid, stabl;
  2067. HPTE *  hpte;
  2068. struct mm_struct * mm;
  2069. pte_t  *ptep = NULL;
  2070. void * pgdir;
  2071.  
  2072. c = inchar();
  2073. if ((isxdigit(c) && c != 'f' && c != 'd') || c == 'n')
  2074. termch = c;
  2075. scanhex((void *)&ea);
  2076.   
  2077. if ((ea >= KRANGE_START) && (ea <= (KRANGE_START + (1UL<<60)))) {
  2078. ptep = 0;
  2079. vsid = get_kernel_vsid(ea);
  2080. va = ( vsid << 28 ) | ( ea & 0x0fffffff );
  2081. } else {
  2082. // if in vmalloc range, use the vmalloc page directory
  2083. if ( ( ea >= VMALLOC_START ) && ( ea <= VMALLOC_END ) ) {
  2084. mm = &init_mm;
  2085. vsid = get_kernel_vsid( ea );
  2086. }
  2087. // if in ioremap range, use the ioremap page directory
  2088. else if ( ( ea >= IMALLOC_START ) && ( ea <= IMALLOC_END ) ) {
  2089. mm = &ioremap_mm;
  2090. vsid = get_kernel_vsid( ea );
  2091. }
  2092. // if in user range, use the current task's page directory
  2093. else if ( ( ea >= USER_START ) && ( ea <= USER_END ) ) {
  2094. mm = current->mm;
  2095. vsid = get_vsid(mm->context, ea );
  2096. }
  2097. pgdir = mm->pgd;
  2098. va = ( vsid << 28 ) | ( ea & 0x0fffffff );
  2099. ptep = find_linux_pte( pgdir, ea );
  2100. }
  2101. vpn = ((vsid << 28) | (((ea) & 0xFFFF000))) >> 12;
  2102. page = vpn & 0xffff;
  2103. esid = (ea >> 28)  & 0xFFFFFFFFF;
  2104.   // Search the primary group for an available slot
  2105. primary_hash = ( vsid & 0x7fffffffff ) ^ page;
  2106. hpteg_slot_primary = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
  2107. hpteg_slot_secondary = ( ~primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
  2108. printf("ea             : %.16lxn", ea);
  2109. printf("esid           : %.16lxn", esid);
  2110. printf("vsid           : %.16lxn", vsid);
  2111. printf("nSoftware Page Tablen-------------------n");
  2112. printf("ptep           : %.16lxn", ((unsigned long *)ptep));
  2113. if(ptep) {
  2114. printf("*ptep          : %.16lxn", *((unsigned long *)ptep));
  2115. }
  2116. hpte  = htab_data.htab  + hpteg_slot_primary;
  2117. printf("nHardware Page Tablen-------------------n");
  2118. printf("htab base      : %.16lxn", htab_data.htab);
  2119. printf("slot primary   : %.16lxn", hpteg_slot_primary);
  2120. printf("slot secondary : %.16lxn", hpteg_slot_secondary);
  2121. printf("nPrimary Groupn");
  2122. for (i=0; i<8; ++i) {
  2123. if ( hpte->dw0.dw0.v != 0 ) {
  2124. printf("%d: (hpte)%.16lx %.16lxn", i, hpte->dw0.dword0, hpte->dw1.dword1);
  2125. printf("          vsid: %.13lx   api: %.2lx  hash: %.1lxn", 
  2126.        (hpte->dw0.dw0.avpn)>>5, 
  2127.        (hpte->dw0.dw0.avpn) & 0x1f,
  2128.        (hpte->dw0.dw0.h));
  2129. printf("          rpn: %.13lx n", (hpte->dw1.dw1.rpn));
  2130. printf("           pp: %.1lx n", 
  2131.        ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
  2132. printf("        wimgn: %.2lx  reference: %.1lx  change: %.1lxn", 
  2133.        ((hpte->dw1.dw1.w)<<4)|
  2134.        ((hpte->dw1.dw1.i)<<3)|
  2135.        ((hpte->dw1.dw1.m)<<2)|
  2136.        ((hpte->dw1.dw1.g)<<1)|
  2137.        ((hpte->dw1.dw1.n)<<0),
  2138.        hpte->dw1.dw1.r, hpte->dw1.dw1.c);
  2139. }
  2140. hpte++;
  2141. }
  2142. printf("nSecondary Groupn");
  2143. // Search the secondary group
  2144. hpte  = htab_data.htab  + hpteg_slot_secondary;
  2145. for (i=0; i<8; ++i) {
  2146. if(hpte->dw0.dw0.v) {
  2147. printf("%d: (hpte)%.16lx %.16lxn", i, hpte->dw0.dword0, hpte->dw1.dword1);
  2148. printf("          vsid: %.13lx   api: %.2lx  hash: %.1lxn", 
  2149.        (hpte->dw0.dw0.avpn)>>5, 
  2150.        (hpte->dw0.dw0.avpn) & 0x1f,
  2151.        (hpte->dw0.dw0.h));
  2152. printf("          rpn: %.13lx n", (hpte->dw1.dw1.rpn));
  2153. printf("           pp: %.1lx n", 
  2154.        ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
  2155. printf("        wimgn: %.2lx  reference: %.1lx  change: %.1lxn", 
  2156.        ((hpte->dw1.dw1.w)<<4)|
  2157.        ((hpte->dw1.dw1.i)<<3)|
  2158.        ((hpte->dw1.dw1.m)<<2)|
  2159.        ((hpte->dw1.dw1.g)<<1)|
  2160.        ((hpte->dw1.dw1.n)<<0),
  2161.        hpte->dw1.dw1.r, hpte->dw1.dw1.c);
  2162. }
  2163. hpte++;
  2164. }
  2165. printf("nHardware Segment Tablen-----------------------n");
  2166. stabl = (unsigned long)(KERNELBASE+(_ASR&0xFFFFFFFFFFFFFFFE));
  2167. steg = (unsigned long *)((stabl) | ((esid & 0x1f) << 7));
  2168. printf("stab base      : %.16lxn", stabl);
  2169. printf("slot           : %.16lxn", steg);
  2170. for (i=0; i<8; ++i) {
  2171. printf("%d: (ste) %.16lx %.16lxn", i,
  2172.        *((unsigned long *)(steg+i*2)),*((unsigned long *)(steg+i*2+1)) );
  2173. }
  2174. }
  2175. void mem_check()
  2176. {
  2177. unsigned long htab_size_bytes;
  2178. unsigned long htab_end;
  2179. unsigned long last_rpn;
  2180. HPTE *hpte1, *hpte2;
  2181. htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
  2182. htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
  2183. // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
  2184. last_rpn = 0xfffff;
  2185. printf("nHardware Page Table Checkn-------------------n");
  2186. printf("htab base      : %.16lxn", htab_data.htab);
  2187. printf("htab size      : %.16lxn", htab_size_bytes);
  2188. #if 1
  2189. for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
  2190. if ( hpte1->dw0.dw0.v != 0 ) {
  2191. if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
  2192. for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
  2193. if ( hpte2->dw0.dw0.v != 0 ) {
  2194. if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
  2195. printf(" Duplicate rpn: %.13lx n", (hpte1->dw1.dw1.rpn));
  2196. printf("   hpte1: %16.16lx  *hpte1: %16.16lx %16.16lxn",
  2197.        hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
  2198. printf("   hpte2: %16.16lx  *hpte2: %16.16lx %16.16lxn",
  2199.        hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1);
  2200. }
  2201. }
  2202. }
  2203. } else {
  2204. printf(" Bogus rpn: %.13lx n", (hpte1->dw1.dw1.rpn));
  2205. printf("   hpte: %16.16lx  *hpte: %16.16lx %16.16lxn",
  2206.        hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
  2207. }
  2208. }
  2209. }
  2210. #endif
  2211. printf("nDone -------------------n");
  2212. }
  2213. void mem_find_real()
  2214. {
  2215. unsigned long htab_size_bytes;
  2216. unsigned long htab_end;
  2217. unsigned long last_rpn;
  2218. HPTE *hpte1;
  2219. unsigned long pa, rpn;
  2220. int c;
  2221. c = inchar();
  2222. if ((isxdigit(c) && c != 'f' && c != 'd') || c == 'n')
  2223. termch = c;
  2224. scanhex((void *)&pa);
  2225. rpn = pa >> 12;
  2226.   
  2227. htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
  2228. htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
  2229. // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
  2230. last_rpn = 0xfffff;
  2231. printf("nMem Find RPNn-------------------n");
  2232. printf("htab base      : %.16lxn", htab_data.htab);
  2233. printf("htab size      : %.16lxn", htab_size_bytes);
  2234. for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
  2235. if ( hpte1->dw0.dw0.v != 0 ) {
  2236. if ( hpte1->dw1.dw1.rpn == rpn ) {
  2237. printf(" Found rpn: %.13lx n", (hpte1->dw1.dw1.rpn));
  2238. printf("      hpte: %16.16lx  *hpte1: %16.16lx %16.16lxn",
  2239.        hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
  2240. }
  2241. }
  2242. }
  2243. printf("nDone -------------------n");
  2244. }
  2245. void mem_find_vsid()
  2246. {
  2247. unsigned long htab_size_bytes;
  2248. unsigned long htab_end;
  2249. HPTE *hpte1;
  2250. unsigned long vsid;
  2251. int c;
  2252. c = inchar();
  2253. if ((isxdigit(c) && c != 'f' && c != 'd') || c == 'n')
  2254. termch = c;
  2255. scanhex((void *)&vsid);
  2256.   
  2257. htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
  2258. htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
  2259. printf("nMem Find VSIDn-------------------n");
  2260. printf("htab base      : %.16lxn", htab_data.htab);
  2261. printf("htab size      : %.16lxn", htab_size_bytes);
  2262. for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
  2263. if ( hpte1->dw0.dw0.v != 0 ) {
  2264. if ( ((hpte1->dw0.dw0.avpn)>>5) == vsid ) {
  2265. printf(" Found vsid: %.16lx n", ((hpte1->dw0.dw0.avpn) >> 5));
  2266. printf("       hpte: %16.16lx  *hpte1: %16.16lx %16.16lxn",
  2267.        hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
  2268. }
  2269. }
  2270. }
  2271. printf("nDone -------------------n");
  2272. }
  2273. void mem_map_check_slab()
  2274. {
  2275. int i, slab_count;
  2276. i = max_mapnr;
  2277. slab_count = 0;
  2278. while (i-- > 0)  {
  2279. if (PageSlab(mem_map+i)){
  2280. printf(" slab entry - mem_map entry =%p  n", mem_map+i);
  2281. slab_count ++;
  2282. }
  2283. }
  2284. printf(" count of pages for slab = %d n", slab_count);
  2285. }
  2286. void mem_map_lock_pages()
  2287. {
  2288. int i, lock_count;
  2289. i = max_mapnr;
  2290. lock_count = 0;
  2291. while (i-- > 0)  {
  2292. if (PageLocked(mem_map+i)){
  2293. printf(" locked entry - mem_map entry =%p  n", mem_map+i);
  2294. lock_count ++;
  2295. }
  2296. }
  2297. printf(" count of locked pages = %d n", lock_count); 
  2298. }
  2299. void mem_check_dup_rpn ()
  2300. {
  2301. unsigned long htab_size_bytes;
  2302. unsigned long htab_end;
  2303. unsigned long last_rpn;
  2304. HPTE *hpte1, *hpte2;
  2305. int dup_count;
  2306. struct task_struct *p;
  2307. unsigned long kernel_vsid_c0,kernel_vsid_c1,kernel_vsid_c2,kernel_vsid_c3;
  2308. unsigned long kernel_vsid_c4,kernel_vsid_c5,kernel_vsid_d,kernel_vsid_e;
  2309. unsigned long kernel_vsid_f;
  2310. unsigned long vsid0,vsid1,vsidB,vsid2;
  2311. htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
  2312. htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
  2313. // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
  2314. last_rpn = 0xfffff;
  2315. printf("nHardware Page Table Checkn-------------------n");
  2316. printf("htab base      : %.16lxn", htab_data.htab);
  2317. printf("htab size      : %.16lxn", htab_size_bytes);
  2318. for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
  2319. if ( hpte1->dw0.dw0.v != 0 ) {
  2320. if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
  2321. dup_count = 0;
  2322. for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
  2323. if ( hpte2->dw0.dw0.v != 0 ) {
  2324. if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
  2325. dup_count++;
  2326. }
  2327. }
  2328. }
  2329. if(dup_count > 5) {
  2330. printf(" Duplicate rpn: %.13lx n", (hpte1->dw1.dw1.rpn));
  2331. printf("    mem map array entry %p count = %d n",
  2332.        (mem_map+(hpte1->dw1.dw1.rpn)), (mem_map+(hpte1->dw1.dw1.rpn))->count);
  2333. for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
  2334. if ( hpte2->dw0.dw0.v != 0 ) {
  2335. if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
  2336. printf("   hpte2: %16.16lx  *hpte2: %16.16lx %16.16lxn",
  2337.        hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1);
  2338. }
  2339. }
  2340. }
  2341. }
  2342. } else {
  2343. printf(" Bogus rpn: %.13lx n", (hpte1->dw1.dw1.rpn));
  2344. printf("   hpte: %16.16lx  *hpte: %16.16lx %16.16lxn",
  2345.        hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
  2346. }
  2347. }
  2348. if (xmon_interrupted())
  2349. return;
  2350. }                                                                     
  2351. // print the kernel vsids
  2352. kernel_vsid_c0 =  get_kernel_vsid(0xC000000000000000);
  2353. kernel_vsid_c1 =  get_kernel_vsid(0xC000000010000000);
  2354. kernel_vsid_c2 =  get_kernel_vsid(0xC000000020000000);
  2355. kernel_vsid_c3 =  get_kernel_vsid(0xC000000030000000);
  2356. kernel_vsid_c4 =  get_kernel_vsid(0xC000000040000000);
  2357. kernel_vsid_c5 =  get_kernel_vsid(0xC000000050000000);
  2358. kernel_vsid_d  =  get_kernel_vsid(0xD000000000000000);
  2359. kernel_vsid_e  =  get_kernel_vsid(0xE000000000000000);
  2360. kernel_vsid_f  =  get_kernel_vsid(0xF000000000000000);
  2361. printf(" kernel vsid -  seg c0  = %lxn",  kernel_vsid_c0 );
  2362. printf(" kernel vsid -  seg c1  = %lxn",  kernel_vsid_c1 );
  2363. printf(" kernel vsid -  seg c2  = %lxn",  kernel_vsid_c2 );
  2364. printf(" kernel vsid -  seg c3  = %lxn",  kernel_vsid_c3 );
  2365. printf(" kernel vsid -  seg c4  = %lxn",  kernel_vsid_c4 );
  2366. printf(" kernel vsid -  seg c5  = %lxn",  kernel_vsid_c5 );
  2367. printf(" kernel vsid -  seg d   = %lxn",  kernel_vsid_d );
  2368. printf(" kernel vsid -  seg e   = %lxn",  kernel_vsid_e );
  2369. printf(" kernel vsid -  seg f   = %lxn",  kernel_vsid_f );
  2370.   // print a list of valid vsids for the tasks
  2371. read_lock(&tasklist_lock);
  2372. for_each_task(p)
  2373. if(p->mm) {
  2374. struct mm_struct *mm = p->mm; 
  2375. printf(" task = %p  mm =  %lx  pgd   %lxn", 
  2376.        p, mm, mm->pgd);
  2377. vsid0 = get_vsid( mm->context, 0 );
  2378. vsid1 = get_vsid( mm->context, 0x10000000 );
  2379. vsid2 = get_vsid( mm->context, 0x20000000 );
  2380. vsidB = get_vsid( mm->context, 0xB0000000 );
  2381. printf("            context = %lx  vsid seg 0  = %lxn",  mm->context, vsid0 );
  2382. printf("                           vsid seg 1  = %lxn",  vsid1 );
  2383. printf("                           vsid seg 2  = %lxn",  vsid2 );
  2384. printf("                           vsid seg 2  = %lxn",  vsidB );
  2385.   
  2386. printf("n");
  2387. };
  2388. read_unlock(&tasklist_lock);
  2389. printf("nDone -------------------n");
  2390. }
  2391. void mem_check_pagetable_vsids ()
  2392. {
  2393. unsigned long htab_size_bytes;
  2394. unsigned long htab_end;
  2395. unsigned long last_rpn;
  2396. struct task_struct *p;
  2397. unsigned long valid_table_count,invalid_table_count,bogus_rpn_count;
  2398. int found;
  2399. unsigned long user_address_table_count,kernel_page_table_count;
  2400. unsigned long pt_vsid;
  2401. HPTE *hpte1;
  2402. htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
  2403. htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
  2404. // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
  2405. last_rpn = 0xfffff;
  2406. printf("nHardware Page Table Checkn-------------------n");
  2407. printf("htab base      : %.16lxn", htab_data.htab);
  2408. printf("htab size      : %.16lxn", htab_size_bytes);
  2409. valid_table_count = 0;
  2410. invalid_table_count = 0;
  2411. bogus_rpn_count = 0;
  2412. user_address_table_count = 0;
  2413. kernel_page_table_count = 0;
  2414. for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
  2415. if ( hpte1->dw0.dw0.v != 0 ) {
  2416. valid_table_count++;
  2417. if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
  2418. pt_vsid =  (hpte1->dw0.dw0.avpn) >> 5;
  2419. if ((pt_vsid == get_kernel_vsid(0xC000000000000000)) |
  2420.     (pt_vsid == get_kernel_vsid(0xC000000010000000)) |
  2421.     (pt_vsid == get_kernel_vsid(0xC000000020000000)) |
  2422.     (pt_vsid == get_kernel_vsid(0xC000000030000000)) |
  2423.     (pt_vsid == get_kernel_vsid(0xC000000040000000)) |
  2424.     (pt_vsid == get_kernel_vsid(0xC000000050000000)) |
  2425.     (pt_vsid == get_kernel_vsid(0xD000000000000000)) |
  2426.     (pt_vsid == get_kernel_vsid(0xE000000000000000)) |
  2427.     (pt_vsid == get_kernel_vsid(0xF000000000000000)) ) {
  2428. kernel_page_table_count ++;
  2429. } else {
  2430. read_lock(&tasklist_lock);
  2431. found = 0;
  2432. for_each_task(p) {
  2433. if(p->mm && (found == 0)) {
  2434. struct mm_struct *mm = p->mm; 
  2435.      
  2436. if ((pt_vsid == get_vsid( mm->context, 0 )) |
  2437.     (pt_vsid == get_vsid( mm->context, 0x10000000 )) |
  2438.     (pt_vsid == get_vsid( mm->context, 0x20000000 )) |
  2439.     (pt_vsid == get_vsid( mm->context, 0x30000000 )) |
  2440.     (pt_vsid == get_vsid( mm->context, 0x40000000 )) |
  2441.     (pt_vsid == get_vsid( mm->context, 0x50000000 )) |
  2442.     (pt_vsid == get_vsid( mm->context, 0x60000000 )) |
  2443.     (pt_vsid == get_vsid( mm->context, 0x70000000 )) |
  2444.     (pt_vsid == get_vsid( mm->context, 0x80000000 )) |
  2445.     (pt_vsid == get_vsid( mm->context, 0x90000000 )) |
  2446.     (pt_vsid == get_vsid( mm->context, 0xA0000000 )) |
  2447.     (pt_vsid == get_vsid( mm->context, 0xB0000000 ))) {
  2448. user_address_table_count ++;
  2449. found = 1;
  2450. }
  2451. }
  2452. }
  2453. read_unlock(&tasklist_lock);
  2454. if (found == 0)
  2455. {
  2456. printf(" vsid not found vsid = %lx, hpte = %p  n", 
  2457.        pt_vsid,hpte1);
  2458. printf("    rpn in entry = %lx n", hpte1->dw1.dw1.rpn);
  2459. printf("    mem map address = %lx  n", mem_map + (hpte1->dw1.dw1.rpn));
  2460.            
  2461. } else //  found
  2462. {
  2463. }
  2464. }  // good rpn
  2465.        
  2466. } else {
  2467. bogus_rpn_count ++;
  2468. }
  2469. } else {
  2470. invalid_table_count++;
  2471. }
  2472. }                                                                     
  2473. printf(" page table valid counts - valid entries = %lx  invalid entries =  %lx n",
  2474.        valid_table_count, invalid_table_count);
  2475. printf("  bogus rpn entries ( probably io) = %lx n", bogus_rpn_count);
  2476.  
  2477.   
  2478. printf(" page table counts - kernel entries = %lx  user entries =  %lx n",
  2479.        kernel_page_table_count, user_address_table_count); 
  2480. printf("nDone -------------------n");
  2481. }
  2482. static void debug_trace(void) {
  2483.         unsigned long val, cmd, on;
  2484. cmd = skipbl();
  2485. if (cmd == 'n') {
  2486. /* show current state */
  2487. unsigned long i;
  2488. printf("naca->debug_switch = 0x%lxn", naca->debug_switch);
  2489. for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
  2490. on = PPCDBG_BITVAL(i) & naca->debug_switch;
  2491. printf("%02x %s %12s   ", i, on ? "on " : "off",  trace_names[i] ? trace_names[i] : "");
  2492. if (((i+1) % 3) == 0)
  2493. printf("n");
  2494. }
  2495. printf("n");
  2496. return;
  2497. }
  2498. while (cmd != 'n') {
  2499. on = 1; /* default if no sign given */
  2500. while (cmd == '+' || cmd == '-') {
  2501. on = (cmd == '+');
  2502. cmd = inchar();
  2503. if (cmd == ' ' || cmd == 'n') {  /* Turn on or off based on + or - */
  2504. naca->debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
  2505. printf("Setting all values to %s...n", on ? "on" : "off");
  2506. if (cmd == 'n') return;
  2507. else cmd = skipbl(); 
  2508. }
  2509. else
  2510. termch = cmd;
  2511. }
  2512. termch = cmd; /* not +/- ... let scanhex see it */
  2513. scanhex((void *)&val);
  2514. if (val >= 64) {
  2515. printf("Value %x out of range:n", val);
  2516. return;
  2517. }
  2518. if (on) {
  2519. naca->debug_switch |= PPCDBG_BITVAL(val);
  2520. printf("enable debug %x %sn", val, trace_names[val] ? trace_names[val] : "");
  2521. } else {
  2522. naca->debug_switch &= ~PPCDBG_BITVAL(val);
  2523. printf("disable debug %x %sn", val, trace_names[val] ? trace_names[val] : "");
  2524. }
  2525. cmd = skipbl();
  2526. }
  2527. }