xmon.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:36k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.xmon.c 1.18 12/01/01 20:09:07 benh
  3.  */
  4. /*
  5.  * Routines providing a simple monitor for use on the PowerMac.
  6.  *
  7.  * Copyright (C) 1996 Paul Mackerras.
  8.  */
  9. #include <linux/config.h>
  10. #include <linux/errno.h>
  11. #include <linux/sched.h>
  12. #include <linux/smp.h>
  13. #include <asm/ptrace.h>
  14. #include <asm/string.h>
  15. #include <asm/prom.h>
  16. #include <asm/bitops.h>
  17. #include "nonstdio.h"
  18. #include "privinst.h"
  19. #define scanhex xmon_scanhex
  20. #define skipbl xmon_skipbl
  21. #ifdef CONFIG_SMP
  22. static unsigned long cpus_in_xmon = 0;
  23. static unsigned long got_xmon = 0;
  24. static volatile int take_xmon = -1;
  25. #endif /* CONFIG_SMP */
  26. static unsigned adrs;
  27. static int size = 1;
  28. static unsigned ndump = 64;
  29. static unsigned nidump = 16;
  30. static unsigned ncsum = 4096;
  31. static int termch;
  32. static u_int bus_error_jmp[100];
  33. #define setjmp xmon_setjmp
  34. #define longjmp xmon_longjmp
  35. /* Breakpoint stuff */
  36. struct bpt {
  37. unsigned address;
  38. unsigned instr;
  39. unsigned count;
  40. unsigned char enabled;
  41. };
  42. #define NBPTS 16
  43. static struct bpt bpts[NBPTS];
  44. static struct bpt dabr;
  45. static struct bpt iabr;
  46. static unsigned bpinstr = 0x7fe00008; /* trap */
  47. /* Prototypes */
  48. extern void (*debugger_fault_handler)(struct pt_regs *);
  49. static int cmds(struct pt_regs *);
  50. static int mread(unsigned, void *, int);
  51. static int mwrite(unsigned, void *, int);
  52. static void handle_fault(struct pt_regs *);
  53. static void byterev(unsigned char *, int);
  54. static void memex(void);
  55. static int bsesc(void);
  56. static void dump(void);
  57. static void prdump(unsigned, int);
  58. #ifdef __MWERKS__
  59. static void prndump(unsigned, int);
  60. static int nvreadb(unsigned);
  61. #endif
  62. static int ppc_inst_dump(unsigned, int);
  63. void print_address(unsigned);
  64. static int getsp(void);
  65. static void dump_hash_table(void);
  66. static void backtrace(struct pt_regs *);
  67. static void excprint(struct pt_regs *);
  68. static void prregs(struct pt_regs *);
  69. static void memops(int);
  70. static void memlocate(void);
  71. static void memzcan(void);
  72. static void memdiffs(unsigned char *, unsigned char *, unsigned, unsigned);
  73. int skipbl(void);
  74. int scanhex(unsigned *valp);
  75. static void scannl(void);
  76. static int hexdigit(int);
  77. void getstring(char *, int);
  78. static void flush_input(void);
  79. static int inchar(void);
  80. static void take_input(char *);
  81. /* static void openforth(void); */
  82. static unsigned read_spr(int);
  83. static void write_spr(int, unsigned);
  84. static void super_regs(void);
  85. static void print_sysmap(void);
  86. static void sysmap_lookup(void);
  87. static void remove_bpts(void);
  88. static void insert_bpts(void);
  89. static struct bpt *at_breakpoint(unsigned pc);
  90. static void bpt_cmds(void);
  91. static void cacheflush(void);
  92. #ifdef CONFIG_SMP
  93. static void cpu_cmd(void);
  94. #endif /* CONFIG_SMP */
  95. static int pretty_print_addr(unsigned long addr);
  96. static void csum(void);
  97. extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
  98. extern void printf(const char *fmt, ...);
  99. extern int putchar(int ch);
  100. extern int setjmp(u_int *);
  101. extern void longjmp(u_int *, int);
  102. extern void xmon_enter(void);
  103. extern void xmon_leave(void);
  104. extern char* xmon_find_symbol(unsigned long addr, unsigned long* saddr);
  105. extern unsigned long xmon_symbol_to_addr(char* symbol);
  106. #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
  107. #define isxdigit(c) (('0' <= (c) && (c) <= '9') 
  108.  || ('a' <= (c) && (c) <= 'f') 
  109.  || ('A' <= (c) && (c) <= 'F'))
  110. #define isalnum(c) (('0' <= (c) && (c) <= '9') 
  111.  || ('a' <= (c) && (c) <= 'z') 
  112.  || ('A' <= (c) && (c) <= 'Z'))
  113. #define isspace(c) (c == ' ' || c == 't' || c == 10 || c == 13 || c == 0)
  114. static char *help_string = "
  115. Commands:n
  116.   d dump bytesn
  117.   di dump instructionsn
  118.   df dump float valuesn
  119.   dd dump double valuesn
  120.   e print exception informationn
  121.   h dump hash tablen
  122.   m examine/change memoryn
  123.   mm move a block of memoryn
  124.   ms set a block of memoryn
  125.   md compare two blocks of memoryn
  126.   M print System.mapn
  127.   r print registersn
  128.   S print special registersn
  129.   t print backtracen
  130.   la lookup address in system.mapn
  131.   ls lookup symbol in system.mapn
  132.   x exit monitorn
  133. ";
  134. static int xmon_trace[NR_CPUS];
  135. #define SSTEP 1 /* stepping because of 's' command */
  136. #define BRSTEP 2 /* stepping over breakpoint */
  137. static struct pt_regs *xmon_regs[NR_CPUS];
  138. extern inline void sync(void)
  139. {
  140. asm volatile("sync; isync");
  141. }
  142. extern inline void __delay(unsigned int loops)
  143. {
  144. if (loops != 0)
  145. __asm__ __volatile__("mtctr %0; 1: bdnz 1b" : :
  146.      "r" (loops) : "ctr");
  147. }
  148. void
  149. xmon(struct pt_regs *excp)
  150. {
  151. struct pt_regs regs;
  152. int msr, cmd;
  153. if (excp == NULL) {
  154. asm volatile ("stw 0,0(%0)n
  155. lwz 0,0(1)n
  156. stw 0,4(%0)n
  157. stmw 2,8(%0)" : : "b" (&regs));
  158. regs.nip = regs.link = ((unsigned long *)regs.gpr[1])[1];
  159. regs.msr = get_msr();
  160. regs.ctr = get_ctr();
  161. regs.xer = get_xer();
  162. regs.ccr = get_cr();
  163. regs.trap = 0;
  164. excp = &regs;
  165. }
  166. msr = get_msr();
  167. set_msr(msr & ~0x8000); /* disable interrupts */
  168. xmon_regs[smp_processor_id()] = excp;
  169. xmon_enter();
  170. excprint(excp);
  171. #ifdef CONFIG_SMP
  172. if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon))
  173. for (;;)
  174. ;
  175. while (test_and_set_bit(0, &got_xmon)) {
  176. if (take_xmon == smp_processor_id()) {
  177. take_xmon = -1;
  178. break;
  179. }
  180. }
  181. /*
  182.  * XXX: breakpoints are removed while any cpu is in xmon
  183.  */
  184. #endif /* CONFIG_SMP */
  185. remove_bpts();
  186. cmd = cmds(excp);
  187. if (cmd == 's') {
  188. xmon_trace[smp_processor_id()] = SSTEP;
  189. excp->msr |= 0x400;
  190. } else if (at_breakpoint(excp->nip)) {
  191. xmon_trace[smp_processor_id()] = BRSTEP;
  192. excp->msr |= 0x400;
  193. } else {
  194. xmon_trace[smp_processor_id()] = 0;
  195. insert_bpts();
  196. }
  197. xmon_leave();
  198. xmon_regs[smp_processor_id()] = 0;
  199. #ifdef CONFIG_SMP
  200. clear_bit(0, &got_xmon);
  201. clear_bit(smp_processor_id(), &cpus_in_xmon);
  202. #endif /* CONFIG_SMP */
  203. set_msr(msr); /* restore interrupt enable */
  204. }
  205. void
  206. xmon_irq(int irq, void *d, struct pt_regs *regs)
  207. {
  208. unsigned long flags;
  209. __save_flags(flags);
  210. __cli();
  211. printf("Keyboard interruptn");
  212. xmon(regs);
  213. __restore_flags(flags);
  214. }
  215. int
  216. xmon_bpt(struct pt_regs *regs)
  217. {
  218. struct bpt *bp;
  219. bp = at_breakpoint(regs->nip);
  220. if (!bp)
  221. return 0;
  222. if (bp->count) {
  223. --bp->count;
  224. remove_bpts();
  225. excprint(regs);
  226. xmon_trace[smp_processor_id()] = BRSTEP;
  227. regs->msr |= 0x400;
  228. } else {
  229. xmon(regs);
  230. }
  231. return 1;
  232. }
  233. int
  234. xmon_sstep(struct pt_regs *regs)
  235. {
  236. if (!xmon_trace[smp_processor_id()])
  237. return 0;
  238. if (xmon_trace[smp_processor_id()] == BRSTEP) {
  239. xmon_trace[smp_processor_id()] = 0;
  240. insert_bpts();
  241. } else {
  242. xmon(regs);
  243. }
  244. return 1;
  245. }
  246. int
  247. xmon_dabr_match(struct pt_regs *regs)
  248. {
  249. if (dabr.enabled && dabr.count) {
  250. --dabr.count;
  251. remove_bpts();
  252. excprint(regs);
  253. xmon_trace[smp_processor_id()] = BRSTEP;
  254. regs->msr |= 0x400;
  255. } else {
  256. dabr.instr = regs->nip;
  257. xmon(regs);
  258. }
  259. return 1;
  260. }
  261. int
  262. xmon_iabr_match(struct pt_regs *regs)
  263. {
  264. if (iabr.enabled && iabr.count) {
  265. --iabr.count;
  266. remove_bpts();
  267. excprint(regs);
  268. xmon_trace[smp_processor_id()] = BRSTEP;
  269. regs->msr |= 0x400;
  270. } else {
  271. xmon(regs);
  272. }
  273. return 1;
  274. }
  275. static struct bpt *
  276. at_breakpoint(unsigned pc)
  277. {
  278. int i;
  279. struct bpt *bp;
  280. if (dabr.enabled && pc == dabr.instr)
  281. return &dabr;
  282. if (iabr.enabled && pc == iabr.address)
  283. return &iabr;
  284. bp = bpts;
  285. for (i = 0; i < NBPTS; ++i, ++bp)
  286. if (bp->enabled && pc == bp->address)
  287. return bp;
  288. return 0;
  289. }
  290. static void
  291. insert_bpts()
  292. {
  293. int i;
  294. struct bpt *bp;
  295. bp = bpts;
  296. for (i = 0; i < NBPTS; ++i, ++bp) {
  297. if (!bp->enabled)
  298. continue;
  299. if (mread(bp->address, &bp->instr, 4) != 4
  300.     || mwrite(bp->address, &bpinstr, 4) != 4) {
  301. printf("Couldn't insert breakpoint at %x, disablingn",
  302.        bp->address);
  303. bp->enabled = 0;
  304. }
  305. store_inst((void *) bp->address);
  306. }
  307. #if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
  308. if (dabr.enabled)
  309. set_dabr(dabr.address);
  310. if (iabr.enabled)
  311. set_iabr(iabr.address);
  312. #endif
  313. }
  314. static void
  315. remove_bpts()
  316. {
  317. int i;
  318. struct bpt *bp;
  319. unsigned instr;
  320. #if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
  321. set_dabr(0);
  322. set_iabr(0);
  323. #endif
  324. bp = bpts;
  325. for (i = 0; i < NBPTS; ++i, ++bp) {
  326. if (!bp->enabled)
  327. continue;
  328. if (mread(bp->address, &instr, 4) == 4
  329.     && instr == bpinstr
  330.     && mwrite(bp->address, &bp->instr, 4) != 4)
  331. printf("Couldn't remove breakpoint at %xn",
  332.        bp->address);
  333. store_inst((void *) bp->address);
  334. }
  335. }
  336. static char *last_cmd;
  337. /* Command interpreting routine */
  338. static int
  339. cmds(struct pt_regs *excp)
  340. {
  341. int cmd;
  342. last_cmd = NULL;
  343. for(;;) {
  344. #ifdef CONFIG_SMP
  345. printf("%d:", smp_processor_id());
  346. #endif /* CONFIG_SMP */
  347. printf("mon> ");
  348. fflush(stdout);
  349. flush_input();
  350. termch = 0;
  351. cmd = skipbl();
  352. if( cmd == 'n' ) {
  353. if (last_cmd == NULL)
  354. continue;
  355. take_input(last_cmd);
  356. last_cmd = NULL;
  357. cmd = inchar();
  358. }
  359. switch (cmd) {
  360. case 'm':
  361. cmd = inchar();
  362. switch (cmd) {
  363. case 'm':
  364. case 's':
  365. case 'd':
  366. memops(cmd);
  367. break;
  368. case 'l':
  369. memlocate();
  370. break;
  371. case 'z':
  372. memzcan();
  373. break;
  374. default:
  375. termch = cmd;
  376. memex();
  377. }
  378. break;
  379. case 'd':
  380. dump();
  381. break;
  382. case 'l':
  383. sysmap_lookup();
  384. break;
  385. case 'r':
  386. if (excp != NULL)
  387. prregs(excp); /* print regs */
  388. break;
  389. case 'e':
  390. if (excp == NULL)
  391. printf("No exception informationn");
  392. else
  393. excprint(excp);
  394. break;
  395. case 'M':
  396. print_sysmap();
  397. break;
  398. case 'S':
  399. super_regs();
  400. break;
  401. case 't':
  402. backtrace(excp);
  403. break;
  404. case 'f':
  405. cacheflush();
  406. break;
  407. case 'h':
  408. dump_hash_table();
  409. break;
  410. case 's':
  411. case 'x':
  412. case EOF:
  413. return cmd;
  414. case '?':
  415. printf(help_string);
  416. break;
  417. default:
  418. printf("Unrecognized command: ");
  419. if( ' ' < cmd && cmd <= '~' )
  420. putchar(cmd);
  421. else
  422. printf("\x%x", cmd);
  423. printf(" (type ? for help)n");
  424. break;
  425. case 'b':
  426. bpt_cmds();
  427. break;
  428. case 'C':
  429. csum();
  430. break;
  431. #ifdef CONFIG_SMP
  432. case 'c':
  433. cpu_cmd();
  434. break;
  435. #endif /* CONFIG_SMP */
  436. }
  437. }
  438. }
  439. #ifdef CONFIG_SMP
  440. static void cpu_cmd(void)
  441. {
  442. unsigned cpu;
  443. int timeout;
  444. int cmd;
  445. cmd = inchar();
  446. if (cmd == 'i') {
  447. /* interrupt other cpu(s) */
  448. cpu = MSG_ALL_BUT_SELF;
  449. if (scanhex(&cpu))
  450. smp_send_xmon_break(cpu);
  451. return;
  452. }
  453. termch = cmd;
  454. if (!scanhex(&cpu)) {
  455. /* print cpus waiting or in xmon */
  456. printf("cpus stopped:");
  457. for (cpu = 0; cpu < NR_CPUS; ++cpu) {
  458. if (test_bit(cpu, &cpus_in_xmon)) {
  459. printf(" %d", cpu);
  460. if (cpu == smp_processor_id())
  461. printf("*", cpu);
  462. }
  463. }
  464. printf("n");
  465. return;
  466. }
  467. /* try to switch to cpu specified */
  468. take_xmon = cpu;
  469. timeout = 10000000;
  470. while (take_xmon >= 0) {
  471. if (--timeout == 0) {
  472. /* yes there's a race here */
  473. take_xmon = -1;
  474. printf("cpu %u didn't take controln", cpu);
  475. return;
  476. }
  477. }
  478. /* now have to wait to be given control back */
  479. while (test_and_set_bit(0, &got_xmon)) {
  480. if (take_xmon == smp_processor_id()) {
  481. take_xmon = -1;
  482. break;
  483. }
  484. }
  485. }
  486. #endif /* CONFIG_SMP */
  487. static unsigned short fcstab[256] = {
  488. 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  489. 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  490. 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  491. 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  492. 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  493. 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  494. 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  495. 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  496. 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  497. 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  498. 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  499. 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  500. 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  501. 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  502. 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  503. 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  504. 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  505. 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  506. 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  507. 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  508. 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  509. 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  510. 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  511. 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  512. 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  513. 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  514. 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  515. 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  516. 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  517. 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  518. 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  519. 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  520. };
  521. #define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])
  522. static void
  523. csum(void)
  524. {
  525. unsigned int i;
  526. unsigned short fcs;
  527. unsigned char v;
  528. if (!scanhex(&adrs))
  529. return;
  530. if (!scanhex(&ncsum))
  531. return;
  532. fcs = 0xffff;
  533. for (i = 0; i < ncsum; ++i) {
  534. if (mread(adrs+i, &v, 1) == 0) {
  535. printf("csum stopped at %xn", adrs+i);
  536. break;
  537. }
  538. fcs = FCS(fcs, v);
  539. }
  540. printf("%xn", fcs);
  541. }
  542. static void
  543. bpt_cmds(void)
  544. {
  545. int cmd;
  546. unsigned a;
  547. int mode, i;
  548. struct bpt *bp;
  549. cmd = inchar();
  550. switch (cmd) {
  551. #if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
  552. case 'd':
  553. mode = 7;
  554. cmd = inchar();
  555. if (cmd == 'r')
  556. mode = 5;
  557. else if (cmd == 'w')
  558. mode = 6;
  559. else
  560. termch = cmd;
  561. cmd = inchar();
  562. if (cmd == 'p')
  563. mode &= ~4;
  564. else
  565. termch = cmd;
  566. dabr.address = 0;
  567. dabr.count = 0;
  568. dabr.enabled = scanhex(&dabr.address);
  569. scanhex(&dabr.count);
  570. if (dabr.enabled)
  571. dabr.address = (dabr.address & ~7) | mode;
  572. break;
  573. case 'i':
  574. cmd = inchar();
  575. if (cmd == 'p')
  576. mode = 2;
  577. else
  578. mode = 3;
  579. iabr.address = 0;
  580. iabr.count = 0;
  581. iabr.enabled = scanhex(&iabr.address);
  582. if (iabr.enabled)
  583. iabr.address |= mode;
  584. scanhex(&iabr.count);
  585. break;
  586. #endif
  587. case 'c':
  588. if (!scanhex(&a)) {
  589. /* clear all breakpoints */
  590. for (i = 0; i < NBPTS; ++i)
  591. bpts[i].enabled = 0;
  592. iabr.enabled = 0;
  593. dabr.enabled = 0;
  594. printf("All breakpoints clearedn");
  595. } else {
  596. bp = at_breakpoint(a);
  597. if (bp == 0) {
  598. printf("No breakpoint at %xn", a);
  599. } else {
  600. bp->enabled = 0;
  601. }
  602. }
  603. break;
  604. default:
  605. termch = cmd;
  606. if (!scanhex(&a)) {
  607. /* print all breakpoints */
  608. printf("type  address   countn");
  609. if (dabr.enabled) {
  610. printf("data %.8x %8x [", dabr.address & ~7,
  611.        dabr.count);
  612. if (dabr.address & 1)
  613. printf("r");
  614. if (dabr.address & 2)
  615. printf("w");
  616. if (dabr.address & 4)
  617. printf("p");
  618. printf("]n");
  619. }
  620. if (iabr.enabled)
  621. printf("inst %.8x %8xn", iabr.address & ~3,
  622.        iabr.count);
  623. for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
  624. if (bp->enabled)
  625. printf("trap %.8x %8xn", bp->address,
  626.        bp->count);
  627. break;
  628. }
  629. bp = at_breakpoint(a);
  630. if (bp == 0) {
  631. for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
  632. if (!bp->enabled)
  633. break;
  634. if (bp >= &bpts[NBPTS]) {
  635. printf("Sorry, no free breakpointsn");
  636. break;
  637. }
  638. }
  639. bp->enabled = 1;
  640. bp->address = a;
  641. bp->count = 0;
  642. scanhex(&bp->count);
  643. break;
  644. }
  645. }
  646. static void
  647. backtrace(struct pt_regs *excp)
  648. {
  649. unsigned sp;
  650. unsigned stack[2];
  651. struct pt_regs regs;
  652. extern char ret_from_intercept, ret_from_syscall_1, ret_from_syscall_2;
  653. extern char do_signal_ret, ret_from_except;
  654. printf("backtrace:n");
  655. if (excp != NULL)
  656. sp = excp->gpr[1];
  657. else
  658. sp = getsp();
  659. scanhex(&sp);
  660. scannl();
  661. for (; sp != 0; sp = stack[0]) {
  662. if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
  663. break;
  664. pretty_print_addr(stack[1]);
  665. printf(" ");
  666. if (stack[1] == (unsigned) &ret_from_intercept
  667.     || stack[1] == (unsigned) &ret_from_except
  668.     || stack[1] == (unsigned) &ret_from_syscall_1
  669.     || stack[1] == (unsigned) &ret_from_syscall_2
  670.     || stack[1] == (unsigned) &do_signal_ret) {
  671. if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs))
  672. break;
  673. printf("nexception:%x [%x] %x ", regs.trap, sp+16,
  674.        regs.nip);
  675. sp = regs.gpr[1];
  676. if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
  677. break;
  678. }
  679. printf("n");
  680. }
  681. }
  682. int
  683. getsp()
  684. {
  685.     int x;
  686.     asm("mr %0,1" : "=r" (x) :);
  687.     return x;
  688. }
  689. void
  690. excprint(struct pt_regs *fp)
  691. {
  692. #ifdef CONFIG_SMP
  693. printf("cpu %d: ", smp_processor_id());
  694. #endif /* CONFIG_SMP */
  695. printf("vector: %x at pc = ", fp->trap);
  696. pretty_print_addr(fp->nip);
  697. printf(", lr = ");
  698. pretty_print_addr(fp->link);
  699. printf("nmsr = %x, sp = %x [%x]n", fp->msr, fp->gpr[1], fp);
  700. if (fp->trap == 0x300 || fp->trap == 0x600)
  701. printf("dar = %x, dsisr = %xn", fp->dar, fp->dsisr);
  702. if (current)
  703. printf("current = %x, pid = %d, comm = %sn",
  704.        current, current->pid, current->comm);
  705. }
  706. void
  707. prregs(struct pt_regs *fp)
  708. {
  709. int n;
  710. unsigned base;
  711. if (scanhex(&base))
  712. fp = (struct pt_regs *) base;
  713. for (n = 0; n < 32; ++n)
  714. printf("R%.2d = %.8x%s", n, fp->gpr[n],
  715.        (n & 3) == 3? "n": "   ");
  716. printf("pc  = %.8x   msr = %.8x   lr  = %.8x   cr  = %.8xn",
  717.        fp->nip, fp->msr, fp->link, fp->ccr);
  718. printf("ctr = %.8x   xer = %.8x   trap = %4xn",
  719.        fp->ctr, fp->xer, fp->trap);
  720. }
  721. void
  722. cacheflush(void)
  723. {
  724. int cmd;
  725. unsigned nflush;
  726. cmd = inchar();
  727. if (cmd != 'i')
  728. termch = cmd;
  729. scanhex(&adrs);
  730. if (termch != 'n')
  731. termch = 0;
  732. nflush = 1;
  733. scanhex(&nflush);
  734. nflush = (nflush + 31) / 32;
  735. if (cmd != 'i') {
  736. for (; nflush > 0; --nflush, adrs += 0x20)
  737. cflush((void *) adrs);
  738. } else {
  739. for (; nflush > 0; --nflush, adrs += 0x20)
  740. cinval((void *) adrs);
  741. }
  742. }
  743. unsigned int
  744. read_spr(int n)
  745. {
  746.     unsigned int instrs[2];
  747.     int (*code)(void);
  748.     instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
  749.     instrs[1] = 0x4e800020;
  750.     store_inst(instrs);
  751.     store_inst(instrs+1);
  752.     code = (int (*)(void)) instrs;
  753.     return code();
  754. }
  755. void
  756. write_spr(int n, unsigned int val)
  757. {
  758.     unsigned int instrs[2];
  759.     int (*code)(unsigned int);
  760.     instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
  761.     instrs[1] = 0x4e800020;
  762.     store_inst(instrs);
  763.     store_inst(instrs+1);
  764.     code = (int (*)(unsigned int)) instrs;
  765.     code(val);
  766. }
  767. static unsigned int regno;
  768. extern char exc_prolog;
  769. extern char dec_exc;
  770. void
  771. print_sysmap(void)
  772. {
  773. extern char *sysmap;
  774. if ( sysmap ) {
  775. printf("System.map: n");
  776. if( setjmp(bus_error_jmp) == 0 ) {
  777. debugger_fault_handler = handle_fault;
  778. sync();
  779. xmon_puts(sysmap);
  780. sync();
  781. }
  782. debugger_fault_handler = 0;
  783. }
  784. else
  785. printf("No System.mapn");
  786. }
  787. void
  788. super_regs()
  789. {
  790. int i, cmd;
  791. unsigned val;
  792. cmd = skipbl();
  793. if (cmd == 'n') {
  794. printf("msr = %x, pvr = %xn", get_msr(), get_pvr());
  795. printf("sprg0-3 = %x %x %x %xn", get_sprg0(), get_sprg1(),
  796.        get_sprg2(), get_sprg3());
  797. printf("srr0 = %x, srr1 = %xn", get_srr0(), get_srr1());
  798. #ifdef CONFIG_PPC_STD_MMU
  799. printf("sr0-15 =");
  800. for (i = 0; i < 16; ++i)
  801. printf(" %x", get_sr(i));
  802. printf("n");
  803. #endif
  804. asm("mr %0,1" : "=r" (i) :);
  805. printf("sp = %x ", i);
  806. asm("mr %0,2" : "=r" (i) :);
  807. printf("toc = %xn", i);
  808. return;
  809. }
  810. scanhex(&regno);
  811. switch (cmd) {
  812. case 'w':
  813. val = read_spr(regno);
  814. scanhex(&val);
  815. write_spr(regno, val);
  816. /* fall through */
  817. case 'r':
  818. printf("spr %x = %xn", regno, read_spr(regno));
  819. break;
  820. case 's':
  821. val = get_sr(regno);
  822. scanhex(&val);
  823. set_sr(regno, val);
  824. break;
  825. case 'm':
  826. val = get_msr();
  827. scanhex(&val);
  828. set_msr(val);
  829. break;
  830. }
  831. scannl();
  832. }
  833. #if 0
  834. static void
  835. openforth()
  836. {
  837.     int c;
  838.     char *p;
  839.     char cmd[1024];
  840.     int args[5];
  841.     extern int (*prom_entry)(int *);
  842.     p = cmd;
  843.     c = skipbl();
  844.     while (c != 'n') {
  845. *p++ = c;
  846. c = inchar();
  847.     }
  848.     *p = 0;
  849.     args[0] = (int) "interpret";
  850.     args[1] = 1;
  851.     args[2] = 1;
  852.     args[3] = (int) cmd;
  853.     (*prom_entry)(args);
  854.     printf("n");
  855.     if (args[4] != 0)
  856. printf("error %xn", args[4]);
  857. }
  858. #endif
  859. #ifndef CONFIG_PPC64BRIDGE
  860. static void
  861. dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
  862. {
  863. extern void *Hash;
  864. extern unsigned long Hash_size;
  865. unsigned *htab = Hash;
  866. unsigned hsize = Hash_size;
  867. unsigned v, hmask, va, last_va;
  868. int found, last_found, i;
  869. unsigned *hg, w1, last_w2, last_va0;
  870. last_found = 0;
  871. hmask = hsize / 64 - 1;
  872. va = start;
  873. start = (start >> 12) & 0xffff;
  874. end = (end >> 12) & 0xffff;
  875. for (v = start; v < end; ++v) {
  876. found = 0;
  877. hg = htab + (((v ^ seg) & hmask) * 16);
  878. w1 = 0x80000000 | (seg << 7) | (v >> 10);
  879. for (i = 0; i < 8; ++i, hg += 2) {
  880. if (*hg == w1) {
  881. found = 1;
  882. break;
  883. }
  884. }
  885. if (!found) {
  886. w1 ^= 0x40;
  887. hg = htab + ((~(v ^ seg) & hmask) * 16);
  888. for (i = 0; i < 8; ++i, hg += 2) {
  889. if (*hg == w1) {
  890. found = 1;
  891. break;
  892. }
  893. }
  894. }
  895. if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) {
  896. if (last_found) {
  897. if (last_va != last_va0)
  898. printf(" ... %x", last_va);
  899. printf("n");
  900. }
  901. if (found) {
  902. printf("%x to %x", va, hg[1]);
  903. last_va0 = va;
  904. }
  905. last_found = found;
  906. }
  907. if (found) {
  908. last_w2 = hg[1] & ~0x180;
  909. last_va = va;
  910. }
  911. va += 4096;
  912. }
  913. if (last_found)
  914. printf(" ... %xn", last_va);
  915. }
  916. #else /* CONFIG_PPC64BRIDGE */
  917. static void
  918. dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
  919. {
  920. extern void *Hash;
  921. extern unsigned long Hash_size;
  922. unsigned *htab = Hash;
  923. unsigned hsize = Hash_size;
  924. unsigned v, hmask, va, last_va;
  925. int found, last_found, i;
  926. unsigned *hg, w1, last_w2, last_va0;
  927. last_found = 0;
  928. hmask = hsize / 128 - 1;
  929. va = start;
  930. start = (start >> 12) & 0xffff;
  931. end = (end >> 12) & 0xffff;
  932. for (v = start; v < end; ++v) {
  933. found = 0;
  934. hg = htab + (((v ^ seg) & hmask) * 32);
  935. w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4);
  936. for (i = 0; i < 8; ++i, hg += 4) {
  937. if (hg[1] == w1) {
  938. found = 1;
  939. break;
  940. }
  941. }
  942. if (!found) {
  943. w1 ^= 2;
  944. hg = htab + ((~(v ^ seg) & hmask) * 32);
  945. for (i = 0; i < 8; ++i, hg += 4) {
  946. if (hg[1] == w1) {
  947. found = 1;
  948. break;
  949. }
  950. }
  951. }
  952. if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) {
  953. if (last_found) {
  954. if (last_va != last_va0)
  955. printf(" ... %x", last_va);
  956. printf("n");
  957. }
  958. if (found) {
  959. printf("%x to %x", va, hg[3]);
  960. last_va0 = va;
  961. }
  962. last_found = found;
  963. }
  964. if (found) {
  965. last_w2 = hg[3] & ~0x180;
  966. last_va = va;
  967. }
  968. va += 4096;
  969. }
  970. if (last_found)
  971. printf(" ... %xn", last_va);
  972. }
  973. #endif /* CONFIG_PPC64BRIDGE */
  974. static unsigned hash_ctx;
  975. static unsigned hash_start;
  976. static unsigned hash_end;
  977. static void
  978. dump_hash_table()
  979. {
  980. int seg;
  981. unsigned seg_start, seg_end;
  982. hash_ctx = 0;
  983. hash_start = 0;
  984. hash_end = 0xfffff000;
  985. scanhex(&hash_ctx);
  986. scanhex(&hash_start);
  987. scanhex(&hash_end);
  988. printf("Mappings for context %xn", hash_ctx);
  989. seg_start = hash_start;
  990. for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) {
  991. seg_end = (seg << 28) | 0x0ffff000;
  992. if (seg_end > hash_end)
  993. seg_end = hash_end;
  994. dump_hash_table_seg((hash_ctx << 4) + (seg * 0x111),
  995.     seg_start, seg_end);
  996. seg_start = seg_end + 0x1000;
  997. }
  998. }
  999. /*
  1000.  * Stuff for reading and writing memory safely
  1001.  */
  1002. int
  1003. mread(unsigned adrs, void *buf, int size)
  1004. {
  1005. volatile int n;
  1006. char *p, *q;
  1007. n = 0;
  1008. if( setjmp(bus_error_jmp) == 0 ){
  1009. debugger_fault_handler = handle_fault;
  1010. sync();
  1011. p = (char *) adrs;
  1012. q = (char *) buf;
  1013. switch (size) {
  1014. case 2: *(short *)q = *(short *)p; break;
  1015. case 4: *(int *)q = *(int *)p; break;
  1016. default:
  1017. for( ; n < size; ++n ) {
  1018. *q++ = *p++;
  1019. sync();
  1020. }
  1021. }
  1022. sync();
  1023. /* wait a little while to see if we get a machine check */
  1024. __delay(200);
  1025. n = size;
  1026. }
  1027. debugger_fault_handler = 0;
  1028. return n;
  1029. }
  1030. int
  1031. mwrite(unsigned adrs, void *buf, int size)
  1032. {
  1033. volatile int n;
  1034. char *p, *q;
  1035. n = 0;
  1036. if( setjmp(bus_error_jmp) == 0 ){
  1037. debugger_fault_handler = handle_fault;
  1038. sync();
  1039. p = (char *) adrs;
  1040. q = (char *) buf;
  1041. switch (size) {
  1042. case 2: *(short *)p = *(short *)q; break;
  1043. case 4: *(int *)p = *(int *)q; break;
  1044. default:
  1045. for( ; n < size; ++n ) {
  1046. *p++ = *q++;
  1047. sync();
  1048. }
  1049. }
  1050. sync();
  1051. n = size;
  1052. } else {
  1053. printf("*** Error writing address %xn", adrs + n);
  1054. }
  1055. debugger_fault_handler = 0;
  1056. return n;
  1057. }
  1058. static int fault_type;
  1059. static char *fault_chars[] = { "--", "**", "##" };
  1060. static void
  1061. handle_fault(struct pt_regs *regs)
  1062. {
  1063. fault_type = regs->trap == 0x200? 0: regs->trap == 0x300? 1: 2;
  1064. longjmp(bus_error_jmp, 1);
  1065. }
  1066. #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
  1067. void
  1068. byterev(unsigned char *val, int size)
  1069. {
  1070. int t;
  1071. switch (size) {
  1072. case 2:
  1073. SWAP(val[0], val[1], t);
  1074. break;
  1075. case 4:
  1076. SWAP(val[0], val[3], t);
  1077. SWAP(val[1], val[2], t);
  1078. break;
  1079. }
  1080. }
  1081. static int brev;
  1082. static int mnoread;
  1083. void
  1084. memex()
  1085. {
  1086.     int cmd, inc, i, nslash;
  1087.     unsigned n;
  1088.     unsigned char val[4];
  1089.     last_cmd = "mn";
  1090.     scanhex(&adrs);
  1091.     while ((cmd = skipbl()) != 'n') {
  1092. switch( cmd ){
  1093. case 'b': size = 1; break;
  1094. case 'w': size = 2; break;
  1095. case 'l': size = 4; break;
  1096. case 'r':  brev = !brev; break;
  1097. case 'n': mnoread = 1; break;
  1098. case '.': mnoread = 0; break;
  1099. }
  1100.     }
  1101.     if( size <= 0 )
  1102. size = 1;
  1103.     else if( size > 4 )
  1104. size = 4;
  1105.     for(;;){
  1106. if (!mnoread)
  1107.     n = mread(adrs, val, size);
  1108. printf("%.8x%c", adrs, brev? 'r': ' ');
  1109. if (!mnoread) {
  1110.     if (brev)
  1111. byterev(val, size);
  1112.     putchar(' ');
  1113.     for (i = 0; i < n; ++i)
  1114. printf("%.2x", val[i]);
  1115.     for (; i < size; ++i)
  1116. printf("%s", fault_chars[fault_type]);
  1117. }
  1118. putchar(' ');
  1119. inc = size;
  1120. nslash = 0;
  1121. for(;;){
  1122.     if( scanhex(&n) ){
  1123. for (i = 0; i < size; ++i)
  1124.     val[i] = n >> (i * 8);
  1125. if (!brev)
  1126.     byterev(val, size);
  1127. mwrite(adrs, val, size);
  1128. inc = size;
  1129.     }
  1130.     cmd = skipbl();
  1131.     if (cmd == 'n')
  1132. break;
  1133.     inc = 0;
  1134.     switch (cmd) {
  1135.     case ''':
  1136. for(;;){
  1137.     n = inchar();
  1138.     if( n == '\' )
  1139. n = bsesc();
  1140.     else if( n == ''' )
  1141. break;
  1142.     for (i = 0; i < size; ++i)
  1143. val[i] = n >> (i * 8);
  1144.     if (!brev)
  1145. byterev(val, size);
  1146.     mwrite(adrs, val, size);
  1147.     adrs += size;
  1148. }
  1149. adrs -= size;
  1150. inc = size;
  1151. break;
  1152.     case ',':
  1153. adrs += size;
  1154. break;
  1155.     case '.':
  1156. mnoread = 0;
  1157. break;
  1158.     case ';':
  1159. break;
  1160.     case 'x':
  1161.     case EOF:
  1162. scannl();
  1163. return;
  1164.     case 'b':
  1165.     case 'v':
  1166. size = 1;
  1167. break;
  1168.     case 'w':
  1169. size = 2;
  1170. break;
  1171.     case 'l':
  1172. size = 4;
  1173. break;
  1174.     case '^':
  1175. adrs -= size;
  1176. break;
  1177. break;
  1178.     case '/':
  1179. if (nslash > 0)
  1180.     adrs -= 1 << nslash;
  1181. else
  1182.     nslash = 0;
  1183. nslash += 4;
  1184. adrs += 1 << nslash;
  1185. break;
  1186.     case '\':
  1187. if (nslash < 0)
  1188.     adrs += 1 << -nslash;
  1189. else
  1190.     nslash = 0;
  1191. nslash -= 4;
  1192. adrs -= 1 << -nslash;
  1193. break;
  1194.     case 'm':
  1195. scanhex(&adrs);
  1196. break;
  1197.     case 'n':
  1198. mnoread = 1;
  1199. break;
  1200.     case 'r':
  1201. brev = !brev;
  1202. break;
  1203.     case '<':
  1204. n = size;
  1205. scanhex(&n);
  1206. adrs -= n;
  1207. break;
  1208.     case '>':
  1209. n = size;
  1210. scanhex(&n);
  1211. adrs += n;
  1212. break;
  1213.     }
  1214. }
  1215. adrs += inc;
  1216.     }
  1217. }
  1218. int
  1219. bsesc()
  1220. {
  1221. int c;
  1222. c = inchar();
  1223. switch( c ){
  1224. case 'n': c = 'n'; break;
  1225. case 'r': c = 'r'; break;
  1226. case 'b': c = 'b'; break;
  1227. case 't': c = 't'; break;
  1228. }
  1229. return c;
  1230. }
  1231. void
  1232. dump()
  1233. {
  1234. int c;
  1235. c = inchar();
  1236. if ((isxdigit(c) && c != 'f' && c != 'd') || c == 'n')
  1237. termch = c;
  1238. scanhex(&adrs);
  1239. if( termch != 'n')
  1240. termch = 0;
  1241. if( c == 'i' ){
  1242. scanhex(&nidump);
  1243. if( nidump == 0 )
  1244. nidump = 16;
  1245. adrs += ppc_inst_dump(adrs, nidump);
  1246. last_cmd = "din";
  1247. } else {
  1248. scanhex(&ndump);
  1249. if( ndump == 0 )
  1250. ndump = 64;
  1251. prdump(adrs, ndump);
  1252. adrs += ndump;
  1253. last_cmd = "dn";
  1254. }
  1255. }
  1256. void
  1257. prdump(unsigned adrs, int ndump)
  1258. {
  1259. register int n, m, c, r, nr;
  1260. unsigned char temp[16];
  1261. for( n = ndump; n > 0; ){
  1262. printf("%.8x", adrs);
  1263. putchar(' ');
  1264. r = n < 16? n: 16;
  1265. nr = mread(adrs, temp, r);
  1266. adrs += nr;
  1267. for( m = 0; m < r; ++m ){
  1268. putchar((m & 3) == 0 && m > 0? '.': ' ');
  1269. if( m < nr )
  1270. printf("%.2x", temp[m]);
  1271. else
  1272. printf("%s", fault_chars[fault_type]);
  1273. }
  1274. for(; m < 16; ++m )
  1275. printf("   ");
  1276. printf("  |");
  1277. for( m = 0; m < r; ++m ){
  1278. if( m < nr ){
  1279. c = temp[m];
  1280. putchar(' ' <= c && c <= '~'? c: '.');
  1281. } else
  1282. putchar(' ');
  1283. }
  1284. n -= r;
  1285. for(; m < 16; ++m )
  1286. putchar(' ');
  1287. printf("|n");
  1288. if( nr < r )
  1289. break;
  1290. }
  1291. }
  1292. int
  1293. ppc_inst_dump(unsigned adr, int count)
  1294. {
  1295. int nr, dotted;
  1296. unsigned first_adr;
  1297. unsigned long inst, last_inst;
  1298. unsigned char val[4];
  1299. dotted = 0;
  1300. for (first_adr = adr; count > 0; --count, adr += 4){
  1301. nr = mread(adr, val, 4);
  1302. if( nr == 0 ){
  1303. const char *x = fault_chars[fault_type];
  1304. printf("%.8x  %s%s%s%sn", adr, x, x, x, x);
  1305. break;
  1306. }
  1307. inst = GETWORD(val);
  1308. if (adr > first_adr && inst == last_inst) {
  1309. if (!dotted) {
  1310. printf(" ...n");
  1311. dotted = 1;
  1312. }
  1313. continue;
  1314. }
  1315. dotted = 0;
  1316. last_inst = inst;
  1317. printf("%.8x  ", adr);
  1318. printf("%.8xt", inst);
  1319. print_insn_big_powerpc(stdout, inst, adr); /* always returns 4 */
  1320. printf("n");
  1321. }
  1322. return adr - first_adr;
  1323. }
  1324. void
  1325. print_address(addr)
  1326. unsigned addr;
  1327. {
  1328. printf("0x%x", addr);
  1329. }
  1330. /*
  1331.  * Memory operations - move, set, print differences
  1332.  */
  1333. static unsigned mdest; /* destination address */
  1334. static unsigned msrc; /* source address */
  1335. static unsigned mval; /* byte value to set memory to */
  1336. static unsigned mcount; /* # bytes to affect */
  1337. static unsigned mdiffs; /* max # differences to print */
  1338. void
  1339. memops(int cmd)
  1340. {
  1341. scanhex(&mdest);
  1342. if( termch != 'n' )
  1343. termch = 0;
  1344. scanhex(cmd == 's'? &mval: &msrc);
  1345. if( termch != 'n' )
  1346. termch = 0;
  1347. scanhex(&mcount);
  1348. switch( cmd ){
  1349. case 'm':
  1350. memmove((void *)mdest, (void *)msrc, mcount);
  1351. break;
  1352. case 's':
  1353. memset((void *)mdest, mval, mcount);
  1354. break;
  1355. case 'd':
  1356. if( termch != 'n' )
  1357. termch = 0;
  1358. scanhex(&mdiffs);
  1359. memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);
  1360. break;
  1361. }
  1362. }
  1363. void
  1364. memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
  1365. {
  1366. unsigned n, prt;
  1367. prt = 0;
  1368. for( n = nb; n > 0; --n )
  1369. if( *p1++ != *p2++ )
  1370. if( ++prt <= maxpr )
  1371. printf("%.8x %.2x # %.8x %.2xn", (unsigned)p1 - 1,
  1372. p1[-1], (unsigned)p2 - 1, p2[-1]);
  1373. if( prt > maxpr )
  1374. printf("Total of %d differencesn", prt);
  1375. }
  1376. static unsigned mend;
  1377. static unsigned mask;
  1378. void
  1379. memlocate()
  1380. {
  1381. unsigned a, n;
  1382. unsigned char val[4];
  1383. last_cmd = "ml";
  1384. scanhex(&mdest);
  1385. if (termch != 'n') {
  1386. termch = 0;
  1387. scanhex(&mend);
  1388. if (termch != 'n') {
  1389. termch = 0;
  1390. scanhex(&mval);
  1391. mask = ~0;
  1392. if (termch != 'n') termch = 0;
  1393. scanhex(&mask);
  1394. }
  1395. }
  1396. n = 0;
  1397. for (a = mdest; a < mend; a += 4) {
  1398. if (mread(a, val, 4) == 4
  1399. && ((GETWORD(val) ^ mval) & mask) == 0) {
  1400. printf("%.8x:  %.8xn", a, GETWORD(val));
  1401. if (++n >= 10)
  1402. break;
  1403. }
  1404. }
  1405. }
  1406. static unsigned mskip = 0x1000;
  1407. static unsigned mlim = 0xffffffff;
  1408. void
  1409. memzcan()
  1410. {
  1411. unsigned char v;
  1412. unsigned a;
  1413. int ok, ook;
  1414. scanhex(&mdest);
  1415. if (termch != 'n') termch = 0;
  1416. scanhex(&mskip);
  1417. if (termch != 'n') termch = 0;
  1418. scanhex(&mlim);
  1419. ook = 0;
  1420. for (a = mdest; a < mlim; a += mskip) {
  1421. ok = mread(a, &v, 1);
  1422. if (ok && !ook) {
  1423. printf("%.8x .. ", a);
  1424. fflush(stdout);
  1425. } else if (!ok && ook)
  1426. printf("%.8xn", a - mskip);
  1427. ook = ok;
  1428. if (a + mskip < a)
  1429. break;
  1430. }
  1431. if (ook)
  1432. printf("%.8xn", a - mskip);
  1433. }
  1434. /* Input scanning routines */
  1435. int
  1436. skipbl()
  1437. {
  1438. int c;
  1439. if( termch != 0 ){
  1440. c = termch;
  1441. termch = 0;
  1442. } else
  1443. c = inchar();
  1444. while( c == ' ' || c == 't' )
  1445. c = inchar();
  1446. return c;
  1447. }
  1448. #define N_PTREGS 44
  1449. static char *regnames[N_PTREGS] = {
  1450. "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  1451. "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  1452. "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  1453. "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
  1454. "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "mq",
  1455. "trap", "dar", "dsisr", "res"
  1456. };
  1457. int
  1458. scanhex(vp)
  1459. unsigned *vp;
  1460. {
  1461. int c, d;
  1462. unsigned v;
  1463. c = skipbl();
  1464. if (c == '%') {
  1465. /* parse register name */
  1466. char regname[8];
  1467. int i;
  1468. for (i = 0; i < sizeof(regname) - 1; ++i) {
  1469. c = inchar();
  1470. if (!isalnum(c)) {
  1471. termch = c;
  1472. break;
  1473. }
  1474. regname[i] = c;
  1475. }
  1476. regname[i] = 0;
  1477. for (i = 0; i < N_PTREGS; ++i) {
  1478. if (strcmp(regnames[i], regname) == 0) {
  1479. unsigned *rp = (unsigned *)
  1480. xmon_regs[smp_processor_id()];
  1481. if (rp == NULL) {
  1482. printf("regs not availablen");
  1483. return 0;
  1484. }
  1485. *vp = rp[i];
  1486. return 1;
  1487. }
  1488. }
  1489. printf("invalid register name '%%%s'n", regname);
  1490. return 0;
  1491. } else if (c == '$') {
  1492. static char symname[64];
  1493. int i;
  1494. for (i=0; i<63; i++) {
  1495. c = inchar();
  1496. if (isspace(c)) {
  1497. termch = c;
  1498. break;
  1499. }
  1500. symname[i] = c;
  1501. }
  1502. symname[i++] = 0;
  1503. *vp = xmon_symbol_to_addr(symname);
  1504. if (!(*vp)) {
  1505. printf("unknown symboln");
  1506. return 0;
  1507. }
  1508. return 1;
  1509. }
  1510. d = hexdigit(c);
  1511. if( d == EOF ){
  1512. termch = c;
  1513. return 0;
  1514. }
  1515. v = 0;
  1516. do {
  1517. v = (v << 4) + d;
  1518. c = inchar();
  1519. d = hexdigit(c);
  1520. } while( d != EOF );
  1521. termch = c;
  1522. *vp = v;
  1523. return 1;
  1524. }
  1525. void
  1526. scannl()
  1527. {
  1528. int c;
  1529. c = termch;
  1530. termch = 0;
  1531. while( c != 'n' )
  1532. c = inchar();
  1533. }
  1534. int
  1535. hexdigit(c)
  1536. {
  1537. if( '0' <= c && c <= '9' )
  1538. return c - '0';
  1539. if( 'A' <= c && c <= 'F' )
  1540. return c - ('A' - 10);
  1541. if( 'a' <= c && c <= 'f' )
  1542. return c - ('a' - 10);
  1543. return EOF;
  1544. }
  1545. void
  1546. getstring(char *s, int size)
  1547. {
  1548. int c;
  1549. c = skipbl();
  1550. do {
  1551. if( size > 1 ){
  1552. *s++ = c;
  1553. --size;
  1554. }
  1555. c = inchar();
  1556. } while( c != ' ' && c != 't' && c != 'n' );
  1557. termch = c;
  1558. *s = 0;
  1559. }
  1560. static char line[256];
  1561. static char *lineptr;
  1562. void
  1563. flush_input()
  1564. {
  1565. lineptr = NULL;
  1566. }
  1567. int
  1568. inchar()
  1569. {
  1570. if (lineptr == NULL || *lineptr == 0) {
  1571. if (fgets(line, sizeof(line), stdin) == NULL) {
  1572. lineptr = NULL;
  1573. return EOF;
  1574. }
  1575. lineptr = line;
  1576. }
  1577. return *lineptr++;
  1578. }
  1579. void
  1580. take_input(str)
  1581. char *str;
  1582. {
  1583. lineptr = str;
  1584. }
  1585. void
  1586. sysmap_lookup(void)
  1587. {
  1588. int type = inchar();
  1589. unsigned addr;
  1590. static char tmp[64];
  1591. char* cur;
  1592. extern char *sysmap;
  1593. extern unsigned long sysmap_size;
  1594. if ( !sysmap || !sysmap_size )
  1595. return;
  1596. switch(type) {
  1597. case 'a':
  1598. if (scanhex(&addr)) {
  1599. pretty_print_addr(addr);
  1600. printf("n");
  1601. }
  1602. termch = 0;
  1603. break;
  1604. case 's':
  1605. getstring(tmp, 64);
  1606. if( setjmp(bus_error_jmp) == 0 ) {
  1607. debugger_fault_handler = handle_fault;
  1608. sync();
  1609. cur = sysmap;
  1610. do {
  1611. cur = strstr(cur, tmp);
  1612. if (cur) {
  1613. static char res[64];
  1614. char *p, *d;
  1615. p = cur;
  1616. while(p > sysmap && *p != 10)
  1617. p--;
  1618. if (*p == 10) p++;
  1619. d = res;
  1620. while(*p && p < (sysmap + sysmap_size) && *p != 10)
  1621. *(d++) = *(p++);
  1622. *(d++) = 0;
  1623. printf("%sn", res);
  1624. cur++;
  1625. }
  1626. } while (cur);
  1627. sync();
  1628. }
  1629. debugger_fault_handler = 0;
  1630. termch = 0;
  1631. break;
  1632. }
  1633. }
  1634. static int
  1635. pretty_print_addr(unsigned long addr)
  1636. {
  1637. char *sym;
  1638. unsigned long saddr;
  1639. printf("%08x", addr);
  1640. sym = xmon_find_symbol(addr, &saddr);
  1641. if (sym)
  1642. printf(" (%s+0x%x)", sym, addr-saddr);
  1643. return (sym != 0);
  1644. }
  1645. char*
  1646. xmon_find_symbol(unsigned long addr, unsigned long* saddr)
  1647. {
  1648. static char rbuffer[64];
  1649. char *p, *ep, *limit;
  1650. unsigned long prev, next;
  1651. char* psym;
  1652. extern char *sysmap;
  1653. extern unsigned long sysmap_size;
  1654. if ( !sysmap || !sysmap_size )
  1655. return NULL;
  1656. prev = 0;
  1657. psym = NULL;
  1658. p = sysmap;
  1659. limit = p + sysmap_size;
  1660. if( setjmp(bus_error_jmp) == 0 ) {
  1661. debugger_fault_handler = handle_fault;
  1662. sync();
  1663. do {
  1664. next = simple_strtoul(p, &p, 16);
  1665. if (next > addr && prev <= addr) {
  1666. if (!psym)
  1667. goto bail;
  1668. ep = rbuffer;
  1669. p = psym;
  1670. while(*p && p < limit && *p == 32)
  1671. p++;
  1672. while(*p && p < limit && *p != 10 && (ep - rbuffer) < 63)
  1673. *(ep++) = *(p++);
  1674. *(ep++) = 0;
  1675. if (saddr)
  1676. *saddr = prev;
  1677. debugger_fault_handler = 0;
  1678. return rbuffer;
  1679. }
  1680. prev = next;
  1681. psym = p;
  1682. while(*p && p < limit && *p != 10)
  1683. p++;
  1684. if (*p) p++;
  1685. } while(*p && p < limit && next);
  1686. bail:
  1687. sync();
  1688. }
  1689. debugger_fault_handler = 0;
  1690. return NULL;
  1691. }
  1692. unsigned long
  1693. xmon_symbol_to_addr(char* symbol)
  1694. {
  1695. char *p, *cur;
  1696. char *match;
  1697. int goodness = 0;
  1698. int result = 0;
  1699. extern char *sysmap;
  1700. extern unsigned long sysmap_size;
  1701. if ( !sysmap || !sysmap_size )
  1702. return 0;
  1703. if( setjmp(bus_error_jmp) == 0 ) {
  1704. debugger_fault_handler = handle_fault;
  1705. sync();
  1706. cur = sysmap;
  1707. while(cur) {
  1708. cur = strstr(cur, symbol);
  1709. if (cur) {
  1710. int gd = 1;
  1711. /* best match if equal, better match if
  1712.  * begins with
  1713.  */
  1714. if (cur == sysmap || *(cur-1) == ' ') {
  1715. gd++;
  1716. if (cur[strlen(symbol)] == 10)
  1717. gd++;
  1718. }
  1719. if (gd > goodness) {
  1720. match = cur;
  1721. goodness = gd;
  1722. if (gd == 3)
  1723. break;
  1724. }
  1725. cur++;
  1726. }
  1727. }
  1728. if (goodness) {
  1729. p = match;
  1730. while(p > sysmap && *p != 10)
  1731. p--;
  1732. if (*p == 10) p++;
  1733. result = simple_strtoul(p, &p, 16);
  1734. }
  1735. sync();
  1736. }
  1737. debugger_fault_handler = 0;
  1738. return result;
  1739. }