dbgArchLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:163k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* dbgArchLib.c - architecture-dependent debugger library */
  2.   
  3. /* Copyright 1984-2001 Wind River Systems, Inc. */
  4. #include "copyright_wrs.h"
  5. /*
  6. modification history
  7. --------------------
  8. 01p,05jun02,wsl  remove references to SPARC and i960
  9. 01o,26nov01,hdn  updated the x86 section
  10. 01n,22nov01,hbh  Updated for simulatorrs.
  11. 01m,16nov01,tlc  Update for MIPS architecture.
  12. 01l,30oct01,zl   corrected arch names in library description, updated SH
  13.                  section.
  14. 01k,03mar00,zl   merged SH support into T2
  15. 01j,27feb97,jpd  Added ARM-specific documentation.
  16. 01i,25nov95,jdi  removed 29k stuff.
  17. 01h,10oct95,jdi  doc: changed .tG Shell back to .pG "Target Shell".
  18. 01g,06oct95,jdi  changed Debugging .pG's to .tG Shell.
  19. 01f,12mar95,dvs  changed sr() to srShow() for am29k (SPR #4084) and gr() -> 
  20.  grShow() for consistancy.
  21. 01e,10feb95,jdi  changed 80960 to i960; synchronized with ../<arch>/dbgArchLibs.
  22. 01d,27jan95,rhp  added MIPS R3000/R4000 and Intel i386/i486;
  23.                  minor doc cleanup on Am29K.
  24. 01c,02dec93,pme  added Am29K family support.
  25. 01b,14mar93,jdi  changed underscores in fsrShow() and psrShow() examples to
  26.  dashes, for aesthetics and compatibility with pretroff.
  27. 01a,13feb93,jdi  written, based on dbgArchLib.c for mc68k, sparc, and i960.
  28. */
  29. /*
  30. DESCRIPTION
  31. This module provides architecture-specific support functions for dbgLib.
  32. It also includes user-callable functions for accessing the contents of
  33. registers in a task's TCB (task control block).  These routines include:
  34. .TS
  35. tab(|);
  36. l0 l0 l.
  37. &`MC680x0':
  38.          | a0() - a7()  | - address registers (`a0' - `a7')
  39.          | d0() - d7()  | - data registers (`d0' - `d7')
  40.          | sr()         | - status register (`sr')
  41. &`MIPS':
  42.   | dbgBpTypeBind() | - bind a breakpoint handler to a breakpoint type
  43. &`x86/SimNT':
  44.          | edi() - eax() | - named register values
  45.          | eflags()      | - status register value
  46. &`SH':    
  47.          | r0() - r15() | - general registers (`r0' - `r15')
  48.          | sr()         | - status register (`sr')
  49.          | gbr()        | - global base register (`gbr')
  50.          | vbr()        | - vector base register (`vbr')
  51.          | mach()       | - multiply and accumulate register high (`mach')
  52.          | macl()       | - multiply and accumulate register low (`macl')
  53.          | pr()         | - procedure register (`pr')
  54. &`ARM':
  55.          | r0() - r14() | - general-purpose registers (`r0' - `r14')
  56.          | cpsr()       | - current processor status reg (`cpsr')
  57.          | psrShow()    | - `psr' value, symbolically
  58. &`SimSolaris':
  59.          | g0() - g7()  | - global registers (`g0' - `g7')
  60.          | o0() - o7()  | - out registers (`o0' - `o7', note lower-case "o")
  61.          | l0() - l7()  | - local registers (`l0' - `l7', note lower-case "l")
  62.          | i0() - i7()  | - in registers (`i0' - `i7')
  63.          | npc()        | - next program counter (`npc')
  64.          | psr()        | - processor status register (`psr')
  65.          | wim()        | - window invalid mask (`wim')
  66.          | y()          | - `y' register 
  67. .TE
  68. NOTE:  The routine pc(), for accessing the program counter, is found
  69. in usrLib.
  70. SEE ALSO: dbgLib,
  71. .pG "Target Shell"
  72. INTERNAL
  73. Note that the program counter (pc) is handled by a non-architecture-specific
  74. routine in usrLib.
  75. This module is created by cat'ing together the following files AFTER the
  76. first entry below - sr(), g0().
  77. mc68k/dbgArchLib.c
  78. XX sparc/dbgArchLib.c
  79. XX i960/dbgArchLib.c
  80. mips/dbgArchLib.c
  81. i86/dbgArchLib.c
  82. sh/dbgArchLib.c
  83. arm/dbgArchLib.c
  84. simsolaris/dbgArchLib.c
  85. simnt/dbgArchLib.c
  86. */
  87. /*******************************************************************************
  88. *
  89. * g0 - return the contents of register `g0', also `g1' - `g7' (SPARC) and `g1' - `g14' (i960)
  90. *
  91. * This command extracts the contents of global register `g0' from the TCB of a
  92. * specified task.  If <taskId> is omitted or 0, the current default task is
  93. * assumed.
  94. *
  95. * Routines are provided for all global registers:
  96. * .TS
  97. * tab(|);
  98. * l l l.
  99. * &`SPARC':      | g0() - g7()  | (`g0' - `g7')
  100. * &`i960':       | g0() - g14() | (`g0' - `g14')
  101. * &`SimSolaris': | g0() - g7()  | (`g0' - `g7')
  102. * .TE
  103. *
  104. * RETURNS: The contents of register `g0' (or the requested register).
  105. *
  106. * SEE ALSO:
  107. * .pG "Target Shell"
  108. *
  109. * NOMANUAL
  110. */
  111. int g0
  112.     (
  113.     int taskId /* task ID, 0 means default task */
  114.     )
  115.     
  116.     { ... }
  117. /* cat arch libraries after here */
  118. /* dbgArchLib.c - MC680x0-dependent debugger library */
  119.   
  120. /* Copyright 1984-1995 Wind River Systems, Inc. */
  121. #include "copyright_wrs.h"
  122. /*
  123. modification history
  124. --------------------
  125. 01h,10feb95,jdi  doc cleanup for 5.2.
  126. 01g,13feb93,jdi  documentation cleanup for 5.1; added discrete entry for d0().
  127. 01f,22sep92,kdl  added single-register display routines, from 5.0 usrLib.
  128. 01e,19sep92,kdl  made dbgRegsAdjust() clear padding bytes before SR in reg set.
  129. 01d,23aug92,jcf  changed filename.
  130. 01c,06jul92,yao  removed dbgCacheClear().  made user uncallable globals
  131.  started with '_'.
  132. 01b,03jul92,jwt  first pass at converting cache calls to 5.1 cache library.
  133. 01a,18jun92,yao  written based on mc68k/dbgLib.c ver08g.
  134. */
  135. /*
  136. DESCRIPTION
  137. This module provides the Motorola 680x0 specific support functions for dbgLib.
  138. NOMANUAL
  139. */
  140. #include "vxWorks.h"
  141. #include "private/dbgLibP.h"
  142. #include "taskLib.h"
  143. #include "taskArchLib.h"
  144. #include "intLib.h"
  145. #include "regs.h"
  146. #include "iv.h"
  147. #include "cacheLib.h"
  148. #include "ioLib.h"
  149. #include "dsmLib.h"
  150. #include "vxLib.h"
  151. #include "usrLib.h"
  152. /* externals */
  153. /* interrupt driver routines from dbgALib.s */
  154. IMPORT dbgBpStub (); /* breakpoint interrupt driver */
  155. IMPORT dbgTraceStub (); /* trace interrupt driver */
  156. IMPORT int dsmNbytes ();
  157. IMPORT int dsmInst ();
  158. /* globals */
  159. extern char * _archHelp_msg = "";
  160. LOCAL USHORT interruptSR; /* old SR value before interrupt break */
  161. /*******************************************************************************
  162. *
  163. * _dbgArchInit - architecture dependent initialization routine
  164. *
  165. * This routine initialize global function pointers that are architecture 
  166. * specific.
  167. *
  168. * RETURNS: N/A
  169. *
  170. * NOMANUAL
  171. */
  172. void _dbgArchInit (void)
  173.     {
  174.     _dbgDsmInstRtn = (FUNCPTR) dsmInst;
  175.     }
  176. /*******************************************************************************
  177. *
  178. * _dbgVecInit - insert new breakpoint and trace vectors
  179. *
  180. * RETURNS: N/A
  181. *
  182. * NOMANUAL
  183. */
  184. void _dbgVecInit (void)
  185.     
  186.     {
  187.     /* insert the new breakpoint and trace vectors */
  188.     intVecSet ((FUNCPTR *) TRAPNUM_TO_IVEC (DBG_TRAP_NUM), dbgBpStub);
  189.     intVecSet ((FUNCPTR *) IV_TRACE, dbgTraceStub);
  190.     }
  191. /*******************************************************************************
  192. *
  193. * _dbgInstSizeGet - set up breakpoint instruction
  194. *
  195. * RETURNS: size of the instruction at specified location.
  196. *
  197. * NOMANUAL
  198. */
  199. int _dbgInstSizeGet
  200.     (
  201.     INSTR * pBrkInst /* pointer to hold breakpoint instruction */
  202.     )
  203.     {
  204.     return (dsmNbytes (pBrkInst) / sizeof (INSTR));
  205.     }
  206. /*******************************************************************************
  207. *
  208. * _dbgRetAdrsGet - get return address for current routine
  209. *
  210. * RETURNS: return address for current routine.
  211. *
  212. * NOMANUAL
  213. */
  214. INSTR * _dbgRetAdrsGet
  215.     (
  216.     REG_SET * pRegSet /* pointer to register set */
  217.     )
  218.     {
  219.     /* if next instruction is a LINK or RTS, return address is on top of stack;
  220.      * otherwise it follows saved frame pointer */
  221.     if (INST_CMP(pRegSet->pc,LINK,LINK_MASK) || 
  222. INST_CMP(pRegSet->pc,RTS,RTS_MASK))
  223.         return (*(INSTR **)pRegSet->spReg);
  224.     else
  225. return (*((INSTR **)pRegSet->fpReg + 1));
  226.     }
  227. /*******************************************************************************
  228. *
  229. * _dbgSStepClear - clear single step mode
  230. *
  231. * RETURNS: N/A
  232. *
  233. * NOMANUAL
  234. */
  235. void _dbgSStepClear (void)
  236.     {
  237.     }
  238. /*******************************************************************************
  239. *
  240. * _dbgSStepSet - set single step mode
  241. *
  242. * RETURNS: N/A
  243. *
  244. * NOMANUAL
  245. */
  246. void _dbgSStepSet 
  247.     (
  248.     BREAK_ESF * pInfo /* pointer to info saved on stack */
  249.     )
  250.     {
  251.     pInfo->sr |= TRACE_BIT | 0x700; /* set trace bit and lock interrupts */
  252.     }
  253. /******************************************************************************
  254. *
  255. * _dbgTaskSStepSet - set single step mode of task
  256. *
  257. * Set the `pcw' and `tcw' of the given task for trace (instruction) break
  258. * mode, so that when the task is switched in, it will execute the
  259. * next instruction and break.
  260. *
  261. * NOTE
  262. * Interrupts are locked out for this task, until single stepping
  263. * for the task is cleared.
  264. *
  265. * RETURNS: OK or ERROR if invalid <tid>.
  266. *
  267. * NOMANUAL
  268. */
  269. void _dbgTaskSStepSet
  270.     (
  271.     int tid /* task's id */
  272.     )
  273.     {
  274.     REG_SET regSet;
  275.     taskRegsGet (tid, &regSet);
  276.     taskSRSet (tid, regSet.sr | TRACE_BIT);
  277.     }
  278. /******************************************************************************
  279. *
  280. * _dbgTaskBPModeSet - set breakpoint mode of task
  281. *
  282. * NOMANUAL
  283. */
  284. void _dbgTaskBPModeSet 
  285.     (
  286.     int tid /* task's id */
  287.     )
  288.     {
  289.     }
  290. /******************************************************************************
  291. *
  292. * _dbgTaskBPModeClear - clear breakpoint mode of task
  293. *
  294. * NOMANUAL
  295. */
  296. void _dbgTaskBPModeClear 
  297.     (
  298.     int tid
  299.     )
  300.     {
  301.     }
  302. /*******************************************************************************
  303. *
  304. * _dbgFuncCallCheck - check next instruction
  305. *
  306. * This routine checks to see if the next instruction is a JSR or BSR.
  307. * If it is, it returns TRUE, otherwise, returns FALSE.
  308. *
  309. * RETURNS: TRUE if next instruction is JSR or BSR, or FALSE otherwise.
  310. *
  311. * NOMANUAL
  312. */
  313. BOOL _dbgFuncCallCheck
  314.     (
  315.     INSTR * addr /* pointer to instruction */
  316.     )
  317.     {
  318.     return (INST_CMP (addr, JSR, JSR_MASK) || INST_CMP (addr, BSR, BSR_MASK));
  319.     }
  320. /*******************************************************************************
  321. *
  322. * _dbgRegsAdjust - set register set
  323. *
  324. * RETURNS: N/A
  325. *
  326. * NOMANUAL
  327. */
  328. void _dbgRegsAdjust
  329.     (
  330.     FAST int   tid, /* id of task that hit breakpoint */
  331.     TRACE_ESF * pInfo, /* pointer to esf info saved on stack */
  332.     int *       regs, /* pointer to buf containing saved regs */
  333.     BOOL stepBreakFlag /* TRUE if this was a trace exception */
  334. /* FALSE if this was a SO or CRET breakpoint */
  335.     )
  336.     {
  337.     REG_SET regSet;
  338.     int ix;
  339.     for (ix = 0; ix < 8; ++ix)
  340. regSet.dataReg [ix] = regs[ix];
  341.     for (ix =0; ix < 7; ++ix)
  342. regSet.addrReg [ix] = regs[ix+8];
  343.     if (stepBreakFlag)
  344. regSet.spReg = (ULONG) ((char *)pInfo + sizeof (TRACE_ESF));
  345.     else
  346. regSet.spReg = (ULONG) ((char *)pInfo + sizeof (BREAK_ESF));
  347.     regSet.pc    = pInfo->pc;
  348.     regSet.pad   = 0;
  349.     regSet.sr    = pInfo->sr;
  350.     taskRegsSet (tid, &regSet);
  351.     }
  352. /*******************************************************************************
  353. *
  354. * _dbgIntrInfoSave - restore register set
  355. *
  356. * RETURNS: N/A
  357. *
  358. * NOMANUAL
  359. */
  360. void _dbgIntrInfoSave
  361.     (
  362.     BREAK_ESF * pInfo /* pointer to info saved on stack */
  363.     )
  364.     {
  365.     interruptSR = pInfo->sr; /* save SR */
  366.     }
  367. /******************************************************************************
  368. *
  369. * _dbgIntrInfoRestore - restore the info saved by dbgIntrInfoSave
  370. *
  371. * NOMANUAL
  372. */
  373. void _dbgIntrInfoRestore
  374.     (
  375.     TRACE_ESF * pBrkInfo /* pointer to execption frame */
  376.     )
  377.     {
  378.     pBrkInfo->sr = interruptSR;
  379.     }
  380. /******************************************************************************
  381. *
  382. * _dbgInstPtrAlign - align pointer to appropriate boundary
  383. *
  384. * REUTRNS: align given instruction pointer to appropriate boundary
  385. *
  386. * NOMANUAL
  387. */
  388. INSTR * _dbgInstPtrAlign 
  389.     (
  390.     INSTR * addr /* instuction pointer */
  391.     )
  392.     {
  393. #if (CPU==MC68000 || CPU==MC68010 || CPU==CPU32)
  394.     addr = (INSTR *) ((int)addr & ~(0x01)); /* force address even */
  395. #endif /* (CPU==MC68000 || CPU==MC68010 || CPU==CPU32) */
  396.     return (addr);
  397.     }
  398. /*******************************************************************************
  399. *
  400. * _dbgInfoPCGet - get pc
  401. *
  402. * RETURNS: value of pc saved on stack
  403. *
  404. * NOMANUAL
  405. */
  406. INSTR * _dbgInfoPCGet
  407.     (
  408.     BREAK_ESF * pInfo /* pointer to info saved on stack */
  409.     )
  410.     {
  411.     return (pInfo->pc);
  412.     }
  413. /*******************************************************************************
  414. *
  415. * _dbgTaskPCSet - set task's pc
  416. *
  417. * RETURNS: N/A
  418. *
  419. * NOMANUAL
  420. */
  421. void _dbgTaskPCSet
  422.     (
  423.     int    tid, /* task id */
  424.     INSTR* pc, /* task's pc */
  425.     INSTR* npc /* not supoorted on MC680X0 */
  426.     )
  427.     {
  428.     REG_SET regSet; /* task's register set */
  429.     taskRegsGet (tid, &regSet);
  430.     regSet.pc = pc;
  431.     taskRegsSet (tid, &regSet);
  432.     }
  433. /*******************************************************************************
  434. *
  435. * _dbgTaskPCGet - restore register set
  436. *
  437. * RETURNS: N/A
  438. *
  439. * NOMANUAL
  440. */
  441. INSTR * _dbgTaskPCGet
  442.     (
  443.     int tid /* task id */
  444.     )
  445.     {
  446.     REG_SET regSet; /* task's register set */
  447.     taskRegsGet (tid, &regSet);
  448.     return (regSet.pc);
  449.     }
  450. /*******************************************************************************
  451. *
  452. * _dbgTraceDisable - disable trace mode
  453. *
  454. * NOMANUAL
  455. */
  456. void _dbgTraceDisable (void)
  457.     {
  458.     /* already disabled in dbgTraceStub */
  459.     }
  460. /*******************************************************************************
  461. *
  462. * getOneReg - return the contents of one register
  463. *
  464. * Given a task's ID, this routine returns the contents of the register
  465. * specified by the register code.  This routine is used by `a0', `d0', `sr',
  466. * etc.  The register codes are defined in dbgMc68kLib.h.
  467. *
  468. * RETURNS: register contents, or ERROR.
  469. */
  470. LOCAL int getOneReg (taskId, regCode)
  471.     int taskId; /* task's id, 0 means default task */
  472.     int regCode; /* code for specifying register */
  473.     {
  474.     REG_SET regSet; /* get task's regs into here */
  475.     taskId = taskIdFigure (taskId); /* translate super name to id */
  476.     if (taskId == ERROR) /* couldn't figure out super name */
  477. return (ERROR);
  478.     taskId = taskIdDefault (taskId); /* set the default id */
  479.     if (taskRegsGet (taskId, &regSet) != OK)
  480. return (ERROR);
  481.     switch (regCode)
  482. {
  483. case D0: return (regSet.dataReg [0]); /* data registers */
  484. case D1: return (regSet.dataReg [1]);
  485. case D2: return (regSet.dataReg [2]);
  486. case D3: return (regSet.dataReg [3]);
  487. case D4: return (regSet.dataReg [4]);
  488. case D5: return (regSet.dataReg [5]);
  489. case D6: return (regSet.dataReg [6]);
  490. case D7: return (regSet.dataReg [7]);
  491. case A0: return (regSet.addrReg [0]); /* address registers */
  492. case A1: return (regSet.addrReg [1]);
  493. case A2: return (regSet.addrReg [2]);
  494. case A3: return (regSet.addrReg [3]);
  495. case A4: return (regSet.addrReg [4]);
  496. case A5: return (regSet.addrReg [5]);
  497. case A6: return (regSet.addrReg [6]);
  498. case A7: return (regSet.addrReg [7]); /* a7 is the stack pointer */
  499. case SR: return (regSet.sr);
  500. }
  501.     return (ERROR); /* unknown regCode */
  502.     }
  503. /*******************************************************************************
  504. *
  505. * a0 - return the contents of register `a0' (also `a1' - `a7') (MC680x0)
  506. *
  507. * This command extracts the contents of register `a0' from the TCB of a specified
  508. * task.  If <taskId> is omitted or zero, the last task referenced is assumed.
  509. *
  510. * Similar routines are provided for all address registers (`a0' - `a7'):
  511. * a0() - a7().
  512. *
  513. * The stack pointer is accessed via a7().
  514. *
  515. * RETURNS: The contents of register `a0' (or the requested register).
  516. *
  517. * SEE ALSO:
  518. * .pG "Target Shell"
  519. */
  520. int a0
  521.     (
  522.     int taskId /* task ID, 0 means default task */
  523.     )
  524.     {
  525.     return (getOneReg (taskId, A0));
  526.     }
  527. int a1 (taskId) int taskId; { return (getOneReg (taskId, A1)); }
  528. int a2 (taskId) int taskId; { return (getOneReg (taskId, A2)); }
  529. int a3 (taskId) int taskId; { return (getOneReg (taskId, A3)); }
  530. int a4 (taskId) int taskId; { return (getOneReg (taskId, A4)); }
  531. int a5 (taskId) int taskId; { return (getOneReg (taskId, A5)); }
  532. int a6 (taskId) int taskId; { return (getOneReg (taskId, A6)); }
  533. int a7 (taskId) int taskId; { return (getOneReg (taskId, A7)); }
  534. /*******************************************************************************
  535. *
  536. * d0 - return the contents of register `d0' (also `d1' - `d7') (MC680x0)
  537. *
  538. * This command extracts the contents of register `d0' from the TCB of a specified
  539. * task.  If <taskId> is omitted or zero, the last task referenced is assumed.
  540. *
  541. * Similar routines are provided for all data registers (`d0' - `d7'):
  542. * d0() - d7().
  543. *
  544. * RETURNS: The contents of register `d0' (or the requested register).
  545. *
  546. * SEE ALSO:
  547. * .pG "Target Shell"
  548. */
  549. int d0
  550.     (
  551.     int taskId /* task ID, 0 means default task */
  552.     )
  553.     {
  554.     return (getOneReg (taskId, D0));
  555.     }
  556. int d1 (taskId) int taskId; { return (getOneReg (taskId, D1)); }
  557. int d2 (taskId) int taskId; { return (getOneReg (taskId, D2)); }
  558. int d3 (taskId) int taskId; { return (getOneReg (taskId, D3)); }
  559. int d4 (taskId) int taskId; { return (getOneReg (taskId, D4)); }
  560. int d5 (taskId) int taskId; { return (getOneReg (taskId, D5)); }
  561. int d6 (taskId) int taskId; { return (getOneReg (taskId, D6)); }
  562. int d7 (taskId) int taskId; { return (getOneReg (taskId, D7)); }
  563. /*******************************************************************************
  564. *
  565. * sr - return the contents of the status register (MC680x0, SH)
  566. *
  567. * This command extracts the contents of the status register from the TCB of a
  568. * specified task.  If <taskId> is omitted or zero, the last task referenced is
  569. * assumed.
  570. *
  571. * RETURNS: The contents of the status register.
  572. *
  573. * SEE ALSO:
  574. * .pG "Target Shell"
  575. */
  576. int sr
  577.     (
  578.     int taskId /* task ID, 0 means default task */
  579.     )
  580.     {
  581.     return (getOneReg (taskId, SR));
  582.     }
  583. /* dbgArchLib.c - SPARC-dependent debugger library */
  584.   
  585. /* Copyright 1984-1995 Wind River Systems, Inc. */
  586. #include "copyright_wrs.h"
  587. /*
  588. modification history
  589. --------------------
  590. 01i,10feb95,jdi  doc cleanup for 5.2.
  591. 01i,13feb93,jdi  documentation cleanup for 5.1; created discrete entries for
  592. <                register routines.
  593. 01h,09feb92,yao  pulled in register show routines from 5.0.
  594. 01g,15oct92,jwt  cleaned up ANSI compiler warnings.
  595. 01f,01oct92,yao  removed redundant delcaration for _dbgStepAdd().
  596.  changed to pass pointer to information and registers
  597.  saved on stack to _dbgStepAdd().
  598. 01e,23aug92,jcf  changed filename.
  599. 01d,15jul92,jwt  moved fsrShow() to dbgSparcLib.c - scalable kernel.
  600. 01c,06jul92,yao  removed dbgArchCacheClear(). made user uncallable globals
  601.  started with '_'.
  602. 01b,03jul92,jwt  converted to 5.1 cache library support; cleanup;
  603.                  added more Fujitsu chips to psrShow().
  604. 01a,18jun92,yao  written based on sparc/dbgLib.c ver2f.
  605. */
  606. /*
  607. DESCRIPTION
  608. This module provides the SPARC specific support functions for dbgLib.
  609. NOMANUAL
  610. */
  611. #include "vxWorks.h"
  612. #include "private/dbgLibP.h"
  613. #include "taskLib.h"
  614. #include "fppLib.h"
  615. #include "taskArchLib.h"
  616. #include "intLib.h"
  617. #include "regs.h"
  618. #include "arch/sparc/psl.h"
  619. #include "iv.h"
  620. #include "cacheLib.h"
  621. #include "ioLib.h"
  622. #include "dsmLib.h"
  623. #include "vxLib.h"
  624. #include "stdio.h"
  625. #include "usrLib.h"
  626. LOCAL void fsrExcShow ();
  627. void fsrShow ();
  628. /* interrupt driver routines from dbgALib.s */
  629. IMPORT dbgBpStub (); /* breakpoint interrupt driver */
  630. IMPORT int dsmNbytes ();
  631. IMPORT int dsmInst ();
  632. /* globals */
  633. char * _archHelp_msg =
  634.     "i0-i7,l0-l7,o0-o7,g1-g7,n"
  635.     "pc,npc,psr,wim,y  [task]        Display a register of a taskn"
  636.     "psrShow   value                 Display meaning of psr valuen";
  637. LOCAL oldIntLevel; /* old interrupt level */
  638. /*******************************************************************************
  639. *
  640. * _dbgArchInit - architecture dependent initialization routine
  641. *
  642. * This routine initialize global function pointers that are architecture 
  643. * specific.
  644. *
  645. * RETURNS: N/A
  646. *
  647. * NOMANUAL
  648. */
  649. void _dbgArchInit (void)
  650.     {
  651.     _dbgDsmInstRtn = (FUNCPTR) dsmInst;
  652.     }
  653. /*******************************************************************************
  654. *
  655. * _dbgVecInit - insert new breakpoint and trace vectors
  656. *
  657. * RETURNS: N/A
  658. *
  659. * NOMANUAL
  660. */
  661. void _dbgVecInit (void)
  662.     
  663.     {
  664.     /* insert the new breakpoint and trace vectors */
  665.     intVecSet ((FUNCPTR *) TRAPNUM_TO_IVEC (DBG_TRAP_NUM), (FUNCPTR) dbgBpStub);
  666.     }
  667. /*******************************************************************************
  668. *
  669. * _dbgInstSizeGet - set up breakpoint instruction
  670. *
  671. * RETURNS: size of the instruction at specified location.
  672. *
  673. * NOMANUAL
  674. */
  675. int _dbgInstSizeGet
  676.     (
  677.     INSTR * pBrkInst /* pointer to hold breakpoint instruction */
  678.     )
  679.     {
  680.     return ((2 * sizeof (INSTR)) / sizeof (INSTR));
  681.     }
  682. /*******************************************************************************
  683. *
  684. * _dbgRetAdrsGet - get return address for current routine
  685. *
  686. * RETURNS: return address for current routine.
  687. *
  688. * NOMANUAL
  689. */
  690. INSTR * _dbgRetAdrsGet
  691.     (
  692.     REG_SET * pRegSet /* pointer to register set */
  693.     )
  694.     {
  695.     int* sp = (int *) pRegSet->spReg;
  696.     if (INST_CMP (I7_CONTENTS (sp), INST_CALL, INST_CALL_MASK) || 
  697. INST_CMP (I7_CONTENTS (sp), JMPL_o7, JMPL_o7_MASK))
  698. {
  699.         return ((INSTR *) (I7_CONTENTS(sp) + 2));
  700. }
  701.     else
  702. return (NULL);
  703.     }
  704. /*******************************************************************************
  705. *
  706. * _dbgTraceDisable - disable trace mode
  707. *
  708. * Since trace mode is not supported on SPARC, this routine does nothing.
  709. *
  710. * NOMANUAL
  711. */
  712. void _dbgTraceDisable (void)
  713.     {
  714.     }
  715. /*******************************************************************************
  716. *
  717. * _dbgTaskBPModeClear - clear breakpoint enable mode
  718. *
  719. * NOMANUAL
  720. */
  721. void _dbgTaskBPModeClear 
  722.     (
  723.     int tid /* task id */
  724.     )
  725.     {
  726.     /* THIS ROUTINE MUST BE USED IN PAIR WITH dbgTaskBPModeSet. */
  727.     oldIntLevel = intLock ();
  728.     }
  729. /*******************************************************************************
  730. *
  731. * _dbgSStepClear - clear single step mode
  732. *
  733. * RETURNS: N/A
  734. *
  735. * NOMANUAL
  736. */
  737. void _dbgSStepClear (void)
  738.     {
  739.     }
  740. /*******************************************************************************
  741. *
  742. * _dbgSStepSet - set single step mode
  743. *
  744. * RETURNS: N/A
  745. *
  746. * NOMANUAL
  747. */
  748. void _dbgSStepSet 
  749.     (
  750.     BREAK_ESF * pInfo /* pointer to info saved on stack */
  751.     )
  752.     {
  753.     int tid = taskIdSelf ();
  754.     _dbgStepAdd  (tid, BRK_TEMP, NULL, NULL);
  755.     }
  756. /******************************************************************************
  757. *
  758. * _dbgTaskSStepSet - set single step mode of task
  759. *
  760. * RETURNS: N/A
  761. *
  762. * NOMANUAL
  763. */
  764. void _dbgTaskSStepSet
  765.     (
  766.     int tid /* task's id */
  767.     )
  768.     {
  769.     }
  770. /******************************************************************************
  771. *
  772. * _dbgTaskBPModeSet - set breakpoint mode of task
  773. *
  774. * RETURNS: N/A
  775. *
  776. * NOMANUAL
  777. */
  778. void _dbgTaskBPModeSet 
  779.     (
  780.     int tid /* task's id */
  781.     )
  782.     {
  783.     /* THIS ROUTINE MUST BE USED IN PAIR WITH dbgTaskBPModeClear. */
  784.     intUnlock (oldIntLevel);
  785.     }
  786. /*******************************************************************************
  787. *
  788. * _dbgFuncCallCheck - check next instruction
  789. *
  790. * This routine checks to see if the next instruction is a JSR or BSR.
  791. * If it is, it returns TRUE, otherwise, returns FALSE.
  792. *
  793. * RETURNS: TRUE if next instruction is JSR or BSR, or FALSE otherwise.
  794. *
  795. * NOMANUAL
  796. */
  797. BOOL _dbgFuncCallCheck
  798.     (
  799.     INSTR * addr /* pointer to instruction */
  800.     )
  801.     {
  802.     return (INST_CMP (addr, INST_CALL, INST_CALL_MASK) || 
  803.     INST_CMP (addr, JMPL_o7, JMPL_o7_MASK));
  804.     }
  805. /*******************************************************************************
  806. *
  807. * _dbgRegsAdjust - set register set
  808. *
  809. * RETURNS: N/A
  810. *
  811. * NOMANUAL
  812. */
  813. void _dbgRegsAdjust
  814.     (
  815.     FAST int  tid, /* id of task that hit breakpoint */
  816.     TRACE_ESF * pInfo, /* pointer to esf info saved on stack */
  817.     int *  pRegs, /* pointer to buf containing saved regs */
  818.     BOOL  stepBreakFlag /* TRUE if this was a trace exception */
  819. /* FALSE if this was a SO or CRET breakpoint */
  820.     )
  821.     {
  822.     REG_SET regSet;
  823.     int ix;
  824.     ESF * pESF = (ESF *) pRegs;
  825.     for (ix = 0; ix < 8; ++ix)
  826. regSet.global [ix] = pESF->esf.global[ix];
  827.     for (ix =0; ix < 8; ++ix)
  828. regSet.out [ix] = pESF->esf.out[ix];
  829.     for (ix =0; ix < 8; ++ix)
  830. regSet.local [ix] = pESF->esf.local[ix];
  831.     for (ix =0; ix < 8; ++ix)
  832. regSet.in [ix] = pESF->esf.in[ix];
  833.     regSet.pc  = pESF->esf.pc;
  834.     regSet.npc = pESF->esf.npc;
  835.     regSet.psr = pESF->esf.psr;
  836.     regSet.wim = pESF->esf.wim;
  837.     regSet.tbr = pESF->esf.tbr;
  838.     regSet.y   = pESF->esf.y;
  839.     taskRegsSet (tid, &regSet);
  840.     }
  841. /*******************************************************************************
  842. *
  843. * _dbgIntrInfoSave - restore register set
  844. *
  845. * RETURNS: N/A
  846. *
  847. * NOMANUAL
  848. */
  849. void _dbgIntrInfoSave
  850.     (
  851.     BREAK_ESF * pInfo /* pointer to info saved on stack */
  852.     )
  853.     {
  854.     /* does nothing */
  855.     }
  856. /******************************************************************************
  857. *
  858. * _dbgIntrInfoRestore - restore the info saved by dbgIntrInfoSave
  859. *
  860. * NOMANUAL
  861. */
  862. void _dbgIntrInfoRestore
  863.     (
  864.     TRACE_ESF *  pInfo /* pointer to execption frame */
  865.     )
  866.     {
  867.     /* does nothing */
  868.     }
  869. /*******************************************************************************
  870. *
  871. * _dbgInfoPCGet - get pc from stack
  872. *
  873. * RETURNS: value of pc saved on stack
  874. *
  875. * NOMANUAL
  876. */
  877. INSTR * _dbgInfoPCGet
  878.     (
  879.     BREAK_ESF * pInfo /* pointer to info saved on stack */
  880.     )
  881.     {
  882.     return (pInfo->pc);
  883.     }
  884. /*******************************************************************************
  885. *
  886. * _dbgTaskPCSet - set task's pc
  887. *
  888. * RETURNS: N/A
  889. *
  890. * NOMANUAL
  891. */
  892. void _dbgTaskPCSet
  893.     (
  894.     int     tid, /* task id */
  895.     INSTR * pc, /* task's pc */
  896.     INSTR * npc /* task's npc */
  897.     )
  898.     {
  899.     REG_SET regSet; /* task's register set */
  900.     taskRegsGet (tid, &regSet);
  901.     regSet.pc = pc;
  902.     if (npc == NULL)
  903. regSet.npc = pc + 1;
  904.     else
  905. regSet.npc = npc;
  906.     taskRegsSet (tid, &regSet);
  907.     }
  908. /*******************************************************************************
  909. *
  910. * _dbgTaskPCGet - get task's pc
  911. *
  912. * RETURNS: N/A
  913. *
  914. * NOMANUAL
  915. */
  916. INSTR * _dbgTaskPCGet
  917.     (
  918.     int tid /* task's id */
  919.     )
  920.     {
  921.     REG_SET regSet;
  922.     taskRegsGet (tid, &regSet);
  923.     return ((INSTR *) regSet.pc);
  924.     }
  925. /*******************************************************************************
  926. *
  927. * _dbgStepAdd -  installs a break point of the given type at the next
  928. *     executable address of the given task.
  929. *
  930. * NOMANUAL
  931. */
  932. STATUS _dbgStepAdd 
  933.     (
  934.     int tid, /* task id */
  935.     int breakType, /* breakpoint type */
  936.     BREAK_ESF * pInfo, /* pointer to info saved on stack */
  937.     int *  pRegSet /* pointer to saved register set */
  938.     )
  939.     {
  940.     INSTR      machInstr; /* Machine instruction */
  941.     INSTR *    npc; /* next program counter */
  942.     char       branchCondition; /* Branch condition */
  943.     REG_SET    regSet; /* pointer to task registers */
  944.     REG_SET *  pRegs = &regSet; /* pointer to task registers */
  945.     BRKENTRY * bp;
  946.     UINT       op2;
  947.     if (taskRegsGet (tid, pRegs) != OK)
  948.         {
  949. return (ERROR);
  950. }
  951.     npc = pRegs->npc;             /* Default nPC */
  952.     if ((bp = dbgBrkGet (pRegs->pc, tid, FALSE)) != NULL)
  953. machInstr = bp->code;
  954.     else
  955.      machInstr = *(pRegs->pc);
  956.     /* Conditional branch instruction with annul bit set */
  957.     if (((machInstr & 0xe0000000) == A_1) &&
  958.  (((op2 = (machInstr >> 22) & 0x7) == 2) || (op2 == 6) || (op2 == 7)))
  959. {
  960. /* bits:25-28 common to all branch types */
  961. branchCondition   = ( machInstr >> 25 ) & 0xF; 
  962. /* Switch on the type of branch (Bicc, CBccc, FBfcc).  No coprocessor 
  963.  * is defined at this time (CBccc).  The location of status bits for 
  964.  * coprocessors is implementation specific 
  965.  */
  966. switch (op2)
  967.     {
  968.     case (2): /* Bicc  - Integer Conditional Branch */
  969. {
  970. BOOL  carryFlag;
  971. BOOL overflowFlag;
  972. BOOL zeroFlag;
  973. BOOL negativeFlag;
  974. carryFlag    = ((pRegs -> psr) >> 20) & 1; /* Carry */
  975. overflowFlag = ((pRegs -> psr) >> 21) & 1; /* oVerflow */
  976. zeroFlag     = ((pRegs -> psr) >> 22) & 1; /* Zero */
  977. negativeFlag = ((pRegs -> psr) >> 23) & 1; /* Negative */
  978. switch (branchCondition)
  979.     {
  980.     case (0): /* Branch Never */
  981.     ++npc;
  982. break;
  983.     case (1): /* Branch On equal */
  984. if ( !zeroFlag )
  985.     ++npc;
  986. break;
  987.     case (2): /* Branch On Less or Equal */
  988. if ( !(zeroFlag | ( negativeFlag ^ overflowFlag )))
  989.     ++npc;
  990. break;
  991.     case (3): /* Branch on less than */
  992. if (!(negativeFlag ^ overflowFlag))
  993.     ++npc;
  994. break;
  995.     case (4): /* Branch on less, or equal, unsigned */
  996. if (!(carryFlag | zeroFlag))
  997.     ++npc;
  998. break;
  999.     case (5): /* Branch on carry set (less than, unsigned) */
  1000. if (!carryFlag )
  1001.     ++npc;
  1002. break;
  1003.     case (6): /* Branch on negative */
  1004. if ( ! negativeFlag )
  1005.     ++npc;
  1006. break;
  1007.     case (7): /* Branch on oVerflow */
  1008. if ( ! overflowFlag )
  1009.     ++npc;
  1010. break;
  1011.     case (8): /* Branch Always */
  1012. if ((machInstr & DISP22_SIGN) == DISP22_SIGN)
  1013.     {
  1014.     /* Negative displacement - sign-extend, 
  1015.      * two's complement 
  1016.      */
  1017.     machInstr = ~DISP22 | (machInstr & DISP22);
  1018.     machInstr = ~machInstr + 1;
  1019.     npc = (INSTR *)((INSTR)pRegs->pc
  1020.     - (machInstr << DISP22_SHIFT_CT));
  1021.     }
  1022. else
  1023.     {
  1024.     /* Positive displacement */
  1025.     machInstr &= DISP22;
  1026.     npc = (INSTR *)((INSTR)pRegs->pc
  1027.     + (machInstr << DISP22_SHIFT_CT));
  1028.     }
  1029. break;
  1030.     case (9): /* Branch on Not Equal */
  1031. if ( zeroFlag )
  1032.     ++npc;
  1033. break;
  1034.     case (0xa): /* Branch on Greater */
  1035. if ( ( zeroFlag | ( negativeFlag ^ overflowFlag )))
  1036.     ++npc;
  1037. break;
  1038.     case (0xb): /* Branch on Greater or Equal */
  1039. if ( negativeFlag ^ overflowFlag )
  1040.     ++npc;
  1041. break;
  1042.     case (0xc): /* Branch on Greater, Unsigned */
  1043. if ( carryFlag | zeroFlag )
  1044.     ++npc;
  1045. break;
  1046.     case (0xd): /* Branch on Carry Clear */
  1047. if ( carryFlag )
  1048.     ++npc;
  1049. break;
  1050.     case (0xe): /* Branch on Positive */
  1051. if ( negativeFlag )
  1052.     ++npc;
  1053. break;
  1054.     case (0xf): /* Branch on oVerflow Clear*/
  1055. if ( overflowFlag )
  1056.     ++npc;
  1057. break;
  1058.     }
  1059. }
  1060. break;
  1061.     case (6): /* FBfcc - Floating-Point Conditional Branch */
  1062. {
  1063. BOOL equalState = FALSE;
  1064. BOOL lessState = FALSE;
  1065. BOOL greaterState = FALSE;
  1066. BOOL unorderedState = FALSE;
  1067. UINT state  = (((struct fpContext *)
  1068.     ( taskTcb(tid) -> pFpContext ))
  1069.       -> fsr & 0xc00 ) >> 10;
  1070. switch (state)
  1071.     {
  1072.     case (0):
  1073. equalState = TRUE;
  1074. break;
  1075.     case (1):
  1076. lessState = TRUE;
  1077. break;
  1078.     case (2):
  1079. greaterState = TRUE;
  1080. break;
  1081.     case (3):
  1082. unorderedState = TRUE;
  1083. break;
  1084.     default:
  1085. printf ("Impossible state:%dn", state);
  1086. return (ERROR);
  1087.     }
  1088. switch (branchCondition)
  1089.     {
  1090.     case (0): /* Branch Never */
  1091.         npc++;
  1092. break;
  1093.     case (1): /* Branch On Not equal */
  1094. if ( !( unorderedState | lessState | greaterState ))
  1095.     ++npc;
  1096. break;
  1097.     case (2): /* Branch On Less or Greater */
  1098. if ( ! ( lessState | greaterState ))
  1099.     ++npc;
  1100. break;
  1101.     case (3): /* Branch on Unordered or Less */
  1102. if ( ! ( unorderedState | lessState ))
  1103.     ++npc;
  1104. break;
  1105.     case (4): /* Branch on less */
  1106. if ( !lessState )
  1107.     ++npc;
  1108. break;
  1109.     case (5): /* Branch on Unordered or Greater */
  1110. if ( ! (unorderedState | greaterState ))
  1111.     ++npc;
  1112. break;
  1113.     case (6): /* Branch on Greater */
  1114. if ( !greaterState )
  1115.     ++npc;
  1116. break;
  1117.     case (7): /* Branch on Unordered */
  1118. if ( !unorderedState )
  1119.     ++npc;
  1120. break;
  1121.     case (8): /* Branch Always */
  1122. if ((machInstr & DISP22_SIGN) == DISP22_SIGN)
  1123.     {
  1124.     /* Negative displacement - sign-extend, 
  1125.      * two's complement 
  1126.      */
  1127.     machInstr = ~DISP22 | (machInstr & DISP22);
  1128.     machInstr = ~machInstr + 1;
  1129.     npc = (INSTR *)((INSTR)pRegs->pc
  1130.     - (machInstr << DISP22_SHIFT_CT));
  1131.     }
  1132. else
  1133.     {
  1134.     /* Positive displacement */
  1135.     machInstr &= DISP22;
  1136.     npc = (INSTR *)((INSTR)pRegs->pc
  1137.     + (machInstr << DISP22_SHIFT_CT));
  1138.     }
  1139. break;
  1140.     case (9): /* Branch Equal */
  1141. if ( !equalState )
  1142.     ++npc;
  1143. break;
  1144.     case (0xa): /* Branch on Unordered or Equal */
  1145. if ( !(unorderedState | equalState ))
  1146.     ++npc;
  1147. break;
  1148.     case (0xb): /* Branch on Greater or Equal */
  1149. if (!(greaterState | equalState))
  1150.     ++npc;
  1151. break;
  1152.     case (0xc): /* Branch on Unordered or Greater, or Equal */
  1153. if ( !( unorderedState | greaterState | equalState ))
  1154.     ++npc;
  1155. break;
  1156.     case (0xd): /* Branch on Less or Equal */
  1157. if ( !(lessState | equalState))
  1158.     ++npc;
  1159. break;
  1160.     case (0xe): /* Branch on Unordered or Less or Equal */
  1161. if ( !(unorderedState | lessState | equalState))
  1162.     ++npc;
  1163. break;
  1164.     case (0xf): /* Branch on Unordered */
  1165. if ( !(lessState | greaterState | equalState))
  1166.     ++npc;
  1167. break;
  1168.     }
  1169. }
  1170. break;
  1171.     case (7):  /* CBccc - Coprocessor Conditional Branch */
  1172. printf ("Coprocessor conditional branches not supportedn");
  1173.         return (ERROR);
  1174.         break;
  1175.     default:
  1176. printf ("Invalid conditional branch instructionn");
  1177. return (ERROR);
  1178. break;
  1179.     }
  1180. }
  1181.     if (dbgBrkAdd (npc, tid, 0, breakType) != OK)
  1182. {
  1183. printf ("error inserting breakpointn");
  1184. return (ERROR);
  1185. }
  1186.     return (OK);
  1187.     }
  1188. /*******************************************************************************
  1189. *
  1190. * psrShow - display the meaning of a specified `psr' value, symbolically (SPARC)
  1191. *
  1192. * This routine displays the meaning of all the fields in a specified `psr' value,
  1193. * symbolically.
  1194. *
  1195. * Extracted from psl.h:
  1196. * .CS
  1197. * Definition of bits in the Sun-4 PSR (Processor Status Register)
  1198. *  ------------------------------------------------------------------------
  1199. * | IMPL | VER |      ICC      | resvd | EC | EF | PIL | S | PS | ET | CWP |
  1200. * |      |     | N | Z | V | C |       |    |    |     |   |    |    |     |
  1201. * |------|-----|---|---|---|---|-------|----|----|-----|---|----|----|-----|
  1202. *  31  28 27 24  23  22  21  20 19   14  13   12  11  8   7   6    5  4   0
  1203. * .CE
  1204. * For compatibility with future revisions, reserved bits are defined to be
  1205. * initialized to zero and, if written, must be preserved.
  1206. *
  1207. * EXAMPLE
  1208. * .CS
  1209. *      -> psrShow 0x00001FE7
  1210. *     Implementation 0, mask version 0:
  1211. *     Fujitsu MB86900 or LSI L64801, 7 windows
  1212. *             no SWAP, FSQRT, CP, extended fp instructions
  1213. *         Condition codes: . . . .
  1214. *         Coprocessor enables: . EF
  1215. *         Processor interrupt level: f
  1216. *         Flags: S PS ET
  1217. *         Current window pointer: 0x07
  1218. *      ->
  1219. * .CE
  1220. *
  1221. * RETURNS: N/A
  1222. *
  1223. * SEE ALSO: psr(),
  1224. * .I "SPARC Architecture Manual"
  1225. *
  1226. * NOMANUAL
  1227. */
  1228. void psrShow 
  1229.     (
  1230.     ULONG psrValue /* psr value to show */
  1231.     )
  1232.     {
  1233.     printf ("Implementation %x, mask version %x:n",
  1234.     (psrValue & PSR_IMPL) >> 28,
  1235.     (psrValue & PSR_VER) >> 28);
  1236.     switch ((psrValue & PSR_IMPL) >> 28)
  1237. {
  1238. case (0x0):
  1239.     if (((psrValue & PSR_VER) >> 24) == 0)
  1240. {
  1241. printf ("Fujitsu MB86900 or LSI L64801, 7 windowsn");
  1242. }
  1243.     else if (((psrValue & PSR_VER) >> 24) == 2)
  1244. {
  1245. printf ("Fujitsu MB86930, 8 windowsn");
  1246. }
  1247.     break;
  1248. case (0x1):
  1249.     printf ("Cypress CY7C601, 8 windows.n");
  1250.     printf ("        no extended fp instructionsn");
  1251.     if (((psrValue & PSR_VER) >> 24) > 1)
  1252. printf ("        (or possibly a Cypress/Ross successor).n");
  1253.     break;
  1254. case (0x2):
  1255.     printf ("BIT B5000, 7 windowsn");
  1256.     printf ("        no extended fp instructionsn");
  1257.     printf ("        'some new hardware traps'n");
  1258.     if (((psrValue & PSR_VER) >> 24) > 0)
  1259. printf ("        (or possibly a BIT successor).n");
  1260.     break;
  1261. case (0x9):
  1262.     if (((psrValue & PSR_VER) >> 24) == 0)
  1263. {
  1264. printf ("Fujitsu MB86903, 8 windowsn");
  1265. }
  1266.     break;
  1267. default:
  1268.     break;
  1269. }
  1270.     printf ("    Condition codes: ");
  1271.     if (psrValue & PSR_N)
  1272. printf ("N ");
  1273.     else
  1274. printf (". ");
  1275.     if (psrValue & PSR_Z)
  1276. printf ("Z ");
  1277.     else
  1278. printf (". ");
  1279.     if (psrValue & PSR_V)
  1280. printf ("V ");
  1281.     else
  1282. printf (". ");
  1283.     if (psrValue & PSR_C)
  1284. printf ("Cn");
  1285.     else
  1286. printf (".n");
  1287.     printf ("    Coprocessor enables: ");
  1288.     if (psrValue & PSR_EC)
  1289. printf ("EC ");
  1290.     else
  1291. printf (". ");
  1292.     if (psrValue & PSR_EF)
  1293. printf ("EFn");
  1294.     else
  1295. printf (".n");
  1296.     printf ("    Processor interrupt level: %xn",
  1297. (psrValue & PSR_PIL) >> 8);
  1298.     printf ("    Flags: ");
  1299.     if (psrValue & PSR_S)
  1300. printf ("S ");
  1301.     else
  1302. printf (". ");
  1303.     if (psrValue & PSR_PS)
  1304. printf ("PS ");
  1305.     else
  1306. printf (". ");
  1307.     if (psrValue & PSR_ET)
  1308. printf ("ETn");
  1309.     else
  1310. printf (".n");
  1311.     printf ("    Current window pointer: 0x%02xn",
  1312. psrValue & PSR_CWP);
  1313.     }
  1314. /*******************************************************************************
  1315. *
  1316. * fsrShow - display the meaning of a specified fsr value, symbolically (SPARC)
  1317. *
  1318. * This routine displays the meaning of all the fields in a specified `fsr' value,
  1319. * symbolically.
  1320. *
  1321. * Extracted from reg.h:
  1322. * .CS
  1323. * Definition of bits in the Sun-4 FSR (Floating-point Status Register)
  1324. *   -------------------------------------------------------------
  1325. *  |  RD |  RP | TEM |  res | FTT | QNE | PR | FCC | AEXC | CEXC |
  1326. *  |-----|---- |-----|------|-----|-----|----|-----|------|------|
  1327. *   31 30 29 28 27 23 22  17 16 14   13   12  11 10 9    5 4    0
  1328. * .CE
  1329. * For compatibility with future revisions, reserved bits are defined to be
  1330. * initialized to zero and, if written, must be preserved.
  1331. *
  1332. * EXAMPLE
  1333. * .CS
  1334. *     -> fsrShow 0x12345678
  1335. *     Rounding Direction: nearest or even if tie.
  1336. *     Rounding Precision: single.
  1337. *     Trap Enable Mask:
  1338. *        underflow.
  1339. *     Floating-point Trap Type: IEEE exception.
  1340. *     Queue Not Empty: FALSE;
  1341. *     Partial Remainder: TRUE;
  1342. *     Condition Codes: less than.
  1343. *     Accumulated exceptions:
  1344. *        inexact divide-by-zero invalid.
  1345. *     Current exceptions:
  1346. *        overflow invalid
  1347. * .CE
  1348. *
  1349. * RETURNS: N/A
  1350. *
  1351. * SEE ALSO:
  1352. * .I "SPARC Architecture Manual"
  1353. *
  1354. * NOMANUAL
  1355. */
  1356. void fsrShow
  1357.     (
  1358.     UINT fsrValue /* fsr value to show */
  1359.     )
  1360.     {
  1361.     printf ("    Rounding Direction: ");
  1362.     switch ((fsrValue & FSR_RD) >> FSR_RD_SHIFT)
  1363. {
  1364. case (RD_NEAR):
  1365.     printf ("nearest or even if tie.");
  1366.     break;
  1367. case (RD_ZER0):
  1368.     printf ("to zero.");
  1369.     break;
  1370. case (RD_POSINF):
  1371.     printf ("positive infinity.");
  1372.     break;
  1373. case (RD_NEGINF):
  1374.     printf ("negative infinity.");
  1375.     break;
  1376. }
  1377.     printf ("n    Rounding Precision: ");
  1378.     switch ((fsrValue & FSR_RP) >> FSR_RP_SHIFT)
  1379. {
  1380. case (RP_DBLEXT):
  1381.     printf ("double-extended.");
  1382.     break;
  1383. case (RP_SINGLE):
  1384.     printf ("single.");
  1385.     break;
  1386. case (RP_DOUBLE):
  1387.     printf ("double.");
  1388.     break;
  1389. case (RP_RESERVED):
  1390.     printf ("unused and reserved.");
  1391.     break;
  1392. }
  1393.     printf ("    Trap Enable Mask:");
  1394.     fsrExcShow ((fsrValue & FSR_TEM) >> FSR_TEM_SHIFT);
  1395.     printf ("    Floating-point Trap Type: ");
  1396.     switch ((fsrValue & FSR_FTT) >> FSR_FTT_SHIFT)
  1397. {
  1398. case (FTT_NONE):
  1399.     printf ("none.");
  1400.     break;
  1401. case (FTT_IEEE):
  1402.     printf ("IEEE exception.");
  1403.     break;
  1404. case (FTT_UNFIN):
  1405.     printf ("unfinished fpop.");
  1406.     break;
  1407. case (FTT_UNIMP):
  1408.     printf ("unimplemented fpop.");
  1409.     break;
  1410. case (FTT_SEQ):
  1411.     printf ("sequence error.");
  1412.     break;
  1413. case (FTT_ALIGN):
  1414.     printf ("alignment, by software convention.");
  1415.     break;
  1416. case (FTT_DFAULT):
  1417.     printf ("data fault, by software convention.");
  1418.     break;
  1419. default:
  1420.     printf ("unknown exception %x.",
  1421. (fsrValue & FSR_FTT_SHIFT) >> FSR_FTT_SHIFT);
  1422. }
  1423.     printf ("n    Queue Not Empty: ");
  1424.     if (fsrValue & FSR_QNE)
  1425. printf ("TRUE");
  1426.     else
  1427. printf ("FALSE");
  1428.     printf ("n    Partial Remainder: ");
  1429.     if (fsrValue & FSR_PR)
  1430. printf ("TRUE");
  1431.     else
  1432. printf ("FALSE");
  1433.     printf ("n    Condition Codes: ");
  1434.     if ((fsrValue & FSR_FCC) == FSR_FCC_EQUAL)
  1435. printf ("equal.");
  1436.     if ((fsrValue & FSR_FCC) == FSR_FCC_LT)
  1437. printf ("less than.");
  1438.     if ((fsrValue & FSR_FCC) == FSR_FCC_GT)
  1439. printf ("greater than.");
  1440.     if ((fsrValue & FSR_FCC) == FSR_FCC_UNORD)
  1441. printf ("unordered.");
  1442.     printf ("n    Accumulated exceptions:");
  1443.     fsrExcShow ((fsrValue & FSR_AEXC) >> FSR_AEXC_SHIFT);
  1444.     printf ("    Current exceptions:");
  1445.     fsrExcShow (fsrValue & FSR_CEXC);
  1446.     }
  1447. /*******************************************************************************
  1448. *
  1449. * fsrExcShow - display the meaning of a specified `fsr' exception field
  1450. *
  1451. * This routine displays the meaning of all the fields in a specified `fsr'
  1452. * exception field, symbolically.
  1453. *
  1454. * SEE ALSO: SPARC Architecture manual.
  1455. *
  1456. * NOMANUAL
  1457. */
  1458. LOCAL void fsrExcShow (fsrExcField)
  1459.     UINT fsrExcField;
  1460.     {
  1461.     printf ("       ");
  1462.     if ((fsrExcField & FSR_CEXC) == 0)
  1463. printf ("none");
  1464.     else
  1465. {
  1466. if (fsrExcField & FSR_CEXC_NX)
  1467.     printf (" inexact");
  1468. if (fsrExcField & FSR_CEXC_DZ)
  1469.     printf (" divide-by-zero");
  1470. if (fsrExcField & FSR_CEXC_UF)
  1471.     printf (" underflow");
  1472. if (fsrExcField & FSR_CEXC_OF)
  1473.     printf (" overflow");
  1474. if (fsrExcField & FSR_CEXC_NV)
  1475.     printf (" invalid");
  1476. }
  1477.     printf (".n");
  1478.     }
  1479. /*******************************************************************************
  1480. *
  1481. * getOneReg - return the contents of one register
  1482. *
  1483. * Given a task's ID, this routine returns the contents of the register
  1484. * specified by the register code.  This routine is used by g0(), i0(), psr(), 
  1485. * and so on.
  1486. * The register codes are defined in regsSparc.h.
  1487. *
  1488. * RETURNS: register contents, or ERROR.
  1489. */
  1490. LOCAL int getOneReg
  1491.     (
  1492.     int taskId, /* task ID, 0 means default task */
  1493.     int regCode /* code for specifying register */
  1494.     )
  1495.     {
  1496.     REG_SET regSet; /* get task's regs into here */
  1497.     taskId = taskIdFigure (taskId); /* translate super name to ID */
  1498.     if (taskId == ERROR) /* couldn't figure out super name */
  1499. return (ERROR);
  1500.     taskId = taskIdDefault (taskId); /* set the default ID */
  1501.     if (taskRegsGet (taskId, &regSet) != OK)
  1502. return (ERROR);
  1503.     return (*(int *)((int)&regSet + regCode));
  1504.     }
  1505. /*******************************************************************************
  1506. *
  1507. * g0 - return the contents of register `g0' (also `g1' - `g7') (SPARC)
  1508. *
  1509. * This command extracts the contents of global register `g0' from the TCB of a
  1510. * specified task.  If <taskId> is omitted or 0, the current default task is
  1511. * assumed.
  1512. *
  1513. * Similar routines are provided for all global registers (`g0' - `g7'):
  1514. * g0() - g7().
  1515. *
  1516. * RETURNS: The contents of register `g0' (or the requested register).
  1517. *
  1518. * SEE ALSO:
  1519. * .pG "Target Shell"
  1520. *
  1521. * INTERNAL
  1522. * Although this routine is hereby marked NOMANUAL, it actually gets
  1523. * published, but from arch/doc/dbgArchLib.c.
  1524. * ...not any more -- SPARC no longer supported.
  1525. *
  1526. * NOMANUAL
  1527. */
  1528. int g0
  1529.     (
  1530.     int taskId /* task ID, 0 means default task */
  1531.     )
  1532.     
  1533.     {
  1534.     return (getOneReg (taskId, REG_SET_GLOBAL(0)));
  1535.     }
  1536. int g1 (int taskId) { return (getOneReg (taskId, REG_SET_GLOBAL(1))); }
  1537. int g2 (int taskId) { return (getOneReg (taskId, REG_SET_GLOBAL(2))); }
  1538. int g3 (int taskId) { return (getOneReg (taskId, REG_SET_GLOBAL(3))); }
  1539. int g4 (int taskId) { return (getOneReg (taskId, REG_SET_GLOBAL(4))); }
  1540. int g5 (int taskId) { return (getOneReg (taskId, REG_SET_GLOBAL(5))); }
  1541. int g6 (int taskId) { return (getOneReg (taskId, REG_SET_GLOBAL(6))); }
  1542. int g7 (int taskId) { return (getOneReg (taskId, REG_SET_GLOBAL(7))); }
  1543. /*******************************************************************************
  1544. *
  1545. * o0 - return the contents of register `o0' (also `o1' - `o7') (SPARC)
  1546. *
  1547. * This command extracts the contents of out register `o0' from the TCB of a
  1548. * specified task.  If <taskId> is omitted or 0, the current default task is
  1549. * assumed.
  1550. *
  1551. * Similar routines are provided for all out registers (`o0' - `o7'):
  1552. * o0() - o7().
  1553. *
  1554. * The stack pointer is accessed via `o6'.
  1555. *
  1556. * RETURNS: The contents of register `o0' (or the requested register).
  1557. *
  1558. * SEE ALSO:
  1559. * .pG "Target Shell"
  1560. *
  1561. * NOMANUAL
  1562. */
  1563. int o0
  1564.     (
  1565.     int taskId /* task ID, 0 means default task */
  1566.     )
  1567.     
  1568.     {
  1569.     return (getOneReg (taskId, REG_SET_OUT(0)));
  1570.     }
  1571. int o1 (int taskId) { return (getOneReg (taskId, REG_SET_OUT(1))); }
  1572. int o2 (int taskId) { return (getOneReg (taskId, REG_SET_OUT(2))); }
  1573. int o3 (int taskId) { return (getOneReg (taskId, REG_SET_OUT(3))); }
  1574. int o4 (int taskId) { return (getOneReg (taskId, REG_SET_OUT(4))); }
  1575. int o5 (int taskId) { return (getOneReg (taskId, REG_SET_OUT(5))); }
  1576. int o6 (int taskId) { return (getOneReg (taskId, REG_SET_OUT(6))); }
  1577. int o7 (int taskId) { return (getOneReg (taskId, REG_SET_OUT(7))); }
  1578. /*******************************************************************************
  1579. *
  1580. * l0 - return the contents of register `l0' (also `l1' - `l7') (SPARC)
  1581. *
  1582. * This command extracts the contents of local register `l0' from the TCB of a
  1583. * specified task.  If <taskId> is omitted or 0, the current default task is
  1584. * assumed.
  1585. *
  1586. * Similar routines are provided for all local registers (`l0' - `l7'):
  1587. * l0() - l7().
  1588. *
  1589. * RETURNS: The contents of register `l0' (or the requested register).
  1590. *
  1591. * SEE ALSO:
  1592. * .pG "Target Shell"
  1593. *
  1594. * NOMANUAL
  1595. */
  1596. int l0
  1597.     (
  1598.     int taskId /* task ID, 0 means default task */
  1599.     )
  1600.     
  1601.     {
  1602.     return (getOneReg (taskId, REG_SET_LOCAL(0)));
  1603.     }
  1604. int l1 (int taskId) { return (getOneReg (taskId, REG_SET_LOCAL(1))); }
  1605. int l2 (int taskId) { return (getOneReg (taskId, REG_SET_LOCAL(2))); }
  1606. int l3 (int taskId) { return (getOneReg (taskId, REG_SET_LOCAL(3))); }
  1607. int l4 (int taskId) { return (getOneReg (taskId, REG_SET_LOCAL(4))); }
  1608. int l5 (int taskId) { return (getOneReg (taskId, REG_SET_LOCAL(5))); }
  1609. int l6 (int taskId) { return (getOneReg (taskId, REG_SET_LOCAL(6))); }
  1610. int l7 (int taskId) { return (getOneReg (taskId, REG_SET_LOCAL(7))); }
  1611. /*******************************************************************************
  1612. *
  1613. * i0 - return the contents of register `i0' (also `i1' - `i7') (SPARC)
  1614. *
  1615. * This command extracts the contents of in register `i0' from the TCB of a
  1616. * specified task.  If <taskId> is omitted or 0, the current default task is
  1617. * assumed.
  1618. *
  1619. * Similar routines are provided for all in registers (`i0' - `i7'):
  1620. * i0() - i7().
  1621. *
  1622. * The frame pointer is accessed via `i6'.
  1623. *
  1624. * RETURNS: The contents of register `i0' (or the requested register).
  1625. *
  1626. * SEE ALSO:
  1627. * .pG "Target Shell"
  1628. *
  1629. * NOMANUAL
  1630. */
  1631. int i0
  1632.     (
  1633.     int taskId /* task ID, 0 means default task */
  1634.     )
  1635.     
  1636.     {
  1637.     return (getOneReg (taskId, REG_SET_IN(0)));
  1638.     }
  1639. int i1 (int taskId) { return (getOneReg (taskId, REG_SET_IN(1))); }
  1640. int i2 (int taskId) { return (getOneReg (taskId, REG_SET_IN(2))); }
  1641. int i3 (int taskId) { return (getOneReg (taskId, REG_SET_IN(3))); }
  1642. int i4 (int taskId) { return (getOneReg (taskId, REG_SET_IN(4))); }
  1643. int i5 (int taskId) { return (getOneReg (taskId, REG_SET_IN(5))); }
  1644. int i6 (int taskId) { return (getOneReg (taskId, REG_SET_IN(6))); }
  1645. int i7 (int taskId) { return (getOneReg (taskId, REG_SET_IN(7))); }
  1646. /*******************************************************************************
  1647. *
  1648. * npc - return the contents of the next program counter (SPARC)
  1649. *
  1650. * This command extracts the contents of the next program counter from the TCB
  1651. * of a specified task.  If <taskId> is omitted or 0, the current default
  1652. * task is assumed.
  1653. *
  1654. * RETURNS: The contents of the next program counter.
  1655. *
  1656. * SEE ALSO: ti()
  1657. *
  1658. * NOMANUAL
  1659. */
  1660. int npc
  1661.     (
  1662.     int taskId                 /* task ID, 0 means default task */
  1663.     )
  1664.     {
  1665.     return (getOneReg (taskId, REG_SET_NPC));
  1666.     }
  1667. /*******************************************************************************
  1668. *
  1669. * psr - return the contents of the processor status register (SPARC)
  1670. *
  1671. * This command extracts the contents of the processor status register from
  1672. * the TCB of a specified task.  If <taskId> is omitted or 0, the default
  1673. * task is assumed.
  1674. *
  1675. * RETURNS: The contents of the processor status register.
  1676. *
  1677. * SEE ALSO: psrShow(),
  1678. * .pG "Target Shell"
  1679. *
  1680. * NOMANUAL
  1681. */
  1682. int psr
  1683.     (
  1684.     int taskId /* task ID, 0 means default task */
  1685.     )
  1686.     {
  1687.     return (getOneReg (taskId, REG_SET_PSR));
  1688.     }
  1689. /*******************************************************************************
  1690. *
  1691. * wim - return the contents of the window invalid mask register (SPARC)
  1692. *
  1693. * This command extracts the contents of the window invalid mask register from
  1694. * the TCB of a specified task.  If <taskId> is omitted or 0, the default
  1695. * task is assumed.
  1696. *
  1697. * RETURNS: The contents of the window invalid mask register.
  1698. *
  1699. * SEE ALSO:
  1700. * .pG "Target Shell"
  1701. *
  1702. * NOMANUAL
  1703. */
  1704. int wim
  1705.     (
  1706.     int taskId  /* task ID, 0 means default task */
  1707.     )
  1708.     {
  1709.     return (getOneReg (taskId, REG_SET_WIM));
  1710.     }
  1711. /*******************************************************************************
  1712. *
  1713. * y - return the contents of the `y' register (SPARC)
  1714. *
  1715. * This command extracts the contents of the `y' register from the TCB of a
  1716. * specified task.  If <taskId> is omitted or 0, the default task is assumed.
  1717. *
  1718. * RETURNS: The contents of the y register.
  1719. *
  1720. * SEE ALSO:
  1721. * .pG "Target Shell"
  1722. *
  1723. * NOMANUAL
  1724. */
  1725. int y
  1726.     (
  1727.     int taskId  /* task ID, 0 means default task */
  1728.     )
  1729.     {
  1730.     return (getOneReg (taskId, REG_SET_Y));
  1731.     }
  1732. /* dbgArchLib.c - Intel i960 architecture-dependent debugger library */
  1733. /* Copyright 1984-1995 Wind River Systems, Inc. */
  1734. #include "copyright_wrs.h"
  1735. /*
  1736. modification history
  1737. --------------------
  1738. 01u,10feb95,jdi  changed 80960 to i960; added missing parens to register names.
  1739. 01t,13feb93,jdi  documentation cleanup for 5.1; created discrete entries
  1740.  for register routines.
  1741. 01s,10feb93,yao  installed register display routines based on 5.0.6.
  1742. 01r,25sep92,wmd  fix ansi warnings.
  1743. 01q,23aug92,jcf  made filenames consistant.
  1744. 01p,13aug92,yao  fixed bug in dbgTraceFaultHandle() which restores register
  1745.  sets incorrectly.
  1746. 01o,10jul92,yao  changed reference of pTcb->pDbgState->pDbgSave->taskPCW
  1747.  to pTcb->dbgPCWSave.
  1748. 01n,06jul92,yao  removed dbgCacheClear().  made user uncallable globals
  1749.  started with '_'.
  1750. 01m,04jul92,jcf  scalable/ANSI/cleanup effort.
  1751. 01l,09jun92,yao  made dbgInterruptPCW LOCAL.  added dbgInit(), dbgHwAdrsCheck().
  1752.  removed dbgDsmInst(), dbgBreakInstGet(), dbgHwBpFree(), 
  1753.  dbgHwBpList, dbgCodeInsert(), dbgHwBpGet(), dbgHwBpInit(), 
  1754.  dbgRegSetPCGet(), dbgTaskProcStatusSave(),dbgTaskPC{S,G}et().
  1755.  changed dbgTaskBPModeSet(), dbgTaskSStepSet() to void.  added
  1756.  dbgArchHwBpFree().
  1757. 01k,26may92,rrr  the tree shuffle
  1758. 01j,23apr92,wmd  fixed ansi warnings.
  1759. 01i,02mar92,wmd  added conditionals for ICE support for i960KB.
  1760. 01h,04oct91,rrr  passed through the ansification filter
  1761.   -fixed #else and #endif
  1762.   -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY O_RDWR
  1763.   -changed VOID to void
  1764.   -changed copyright notice
  1765. 01g,14aug91,del  changes by intel to support KA/KB processors.
  1766. 01f,12jul91,gae  changed many sys{IMR,IPND,...} to vx{...} names;
  1767.  removal of 68k code comments left for reference.
  1768. 01e,20apr91,del  added code to dbgReturnAddrGet to deal with leaf procedures.
  1769. 01d,19mar91,del  redesigned hardware breakpoints.
  1770. 01c,08jan91,del  documentation.
  1771. 01b,06jan91,del  changed to work with new REG_SET structure. cleanup.
  1772. 01a,21oct89,del  written.
  1773. */
  1774. /*
  1775. DESCRIPTION
  1776. This module provides the Intel i960-specific support functions for dbgLib.
  1777. NOMANUAL
  1778. */
  1779. #include "vxWorks.h"
  1780. #include "private/taskLibP.h"
  1781. #include "private/windLibP.h"
  1782. #include "private/kernelLibP.h"
  1783. #include "private/dbgLibP.h"
  1784. #include "lstLib.h"
  1785. #include "symLib.h"
  1786. #include "sysSymTbl.h"
  1787. #include "logLib.h"
  1788. #include "string.h"
  1789. #include "vxLib.h"
  1790. #include "stdio.h"
  1791. #include "ioLib.h"
  1792. #include "usrLib.h"
  1793. #include "fppLib.h"
  1794. #if CPU==I960CA
  1795. #define REG_NUM_IPB0 0 /* instruction address breakpoint register 0 */
  1796. #define REG_NUM_IPB1 1 /* instruction  address breakpoint register 1 */
  1797. #define REG_NUM_DAB0 2 /* data address breakpoint register 0 */
  1798. #define REG_NUM_DAB1 3 /* data address breakpoint register 1 */
  1799. #endif /* CPU==I960CA */
  1800. #define MOV_G14_MASK 0xff87ffff /* mov g14, gx instruction mask */
  1801. #define INST_MOV_G14 0x5c80161e /* mov g14, gx instruction */
  1802. #define SRC_REG_MASK 0x00f80000 /* register mask */
  1803. /* externals */
  1804.  
  1805. IMPORT void    dbgBreakpoint (); /* higher level of bp handling */
  1806. IMPORT void    dbgTrace (); /* higher level of trace handling */
  1807. IMPORT  void     dbgBpStub (); /* lowest level of bp handling */
  1808. IMPORT  BRKENTRY * dbgBrkGet ();
  1809. IMPORT int         dsm960Inst (); /* 960 disassembler routine */
  1810. IMPORT BOOL        dsmMemInstrCheck ();
  1811. IMPORT UINT32      dsmMEMInstrRefAddrGet ();
  1812. IMPORT int         dsmInstrSizeGet ();
  1813. IMPORT UINT32      sysFaultVecSet ();
  1814. IMPORT BOOL        dsmFuncCallCheck ();
  1815. IMPORT UINT32      sysCtrlTable[];
  1816. IMPORT int    ansiFix; /* fix ansi warnings */
  1817. /* globals */
  1818. extern char * _archHelp_msg =  /* help message */
  1819.     "pfp, tsp, rip, fp  [task]       Display pfp, sp, rip, and fp of a taskn"
  1820.     "r3-r15, g0-g14     [task]       Display a register of a taskn"
  1821. #if CPU == I960CA
  1822.     "bh addr[,access[,task[,count[,quite]]]] Set hardware breakpointn"
  1823.     "                           0 - store only       1 - load/storen"
  1824.     "                           2 - data/inst fetch  3 - any accessn" 
  1825.     "                           4 - instructn"
  1826. #endif /* CPU == I960CA */
  1827. #if (CPU == I960KB)
  1828.     "fp0-fp3            [task]  Display floating point register of a taskn"
  1829. #endif /* CPU == I960KB */
  1830.     ;
  1831. /* forward declaration */
  1832. LOCAL int dbgInterruptPCW; /* used by dbgIntrInfoSave/Restore */
  1833. LOCAL int dbgHwRegStatus; /* keep status of hardware regs being used */
  1834. /*******************************************************************************
  1835. *
  1836. * _dbgArchInit - architecture dependent initialization routine
  1837. *
  1838. * This routine initialize global function pointers that are architecture 
  1839. * specific.
  1840. *
  1841. * RETURNS: N/A
  1842. *
  1843. * NOMANUAL
  1844. */
  1845. void _dbgArchInit (void)
  1846.     {
  1847.     _dbgDsmInstRtn = (FUNCPTR) dsm960Inst;
  1848.     }
  1849. /******************************************************************************
  1850. *
  1851. *  _dbgTraceDisable - disable trace mode
  1852. *
  1853. * NOMANUAL
  1854. */
  1855. void _dbgTraceDisable (void)
  1856.     {
  1857.     vxPCWClear (PCW_TRACE_ENABLE_MASK);
  1858.     }
  1859. /******************************************************************************
  1860. *
  1861. * _dbgFuncCallCheck - check if opcode is a function call
  1862. *
  1863. * RETURNS: TRUE if op code at the given addr is a subroutine call.
  1864. *
  1865. * NOMANUAL
  1866. */
  1867. BOOL _dbgFuncCallCheck 
  1868.     (
  1869.     INSTR * pInst /* pointer to instruction to check */
  1870.     )
  1871.     {
  1872.     return (dsmFuncCallCheck (pInst));
  1873.     }
  1874. #if (BRK_HW_BP != 0)
  1875. /****************************************************************************** *
  1876. * _dbgHwAdrsCheck - verify address is valid
  1877. *
  1878. * Checks to make sure the given adrs is on a 32-bit boundary, and
  1879. * that it is accessable.
  1880. *
  1881. * RETURNS: OK or ERROR if address not on a 32-bit boundary or unaccessible.
  1882. *
  1883. * NOMANUAL
  1884. */
  1885. STATUS _dbgHwAdrsCheck 
  1886.     (
  1887.     INSTR * adrs, /* address to check */
  1888.     int access /* access type */
  1889.     )
  1890.     {
  1891.     UINT32 val; /* dummy for vxMemProbe */
  1892.     if ((int) adrs & 0x03)
  1893. return (ERROR);
  1894. #if CPU==I960CA
  1895.     switch (access)
  1896. {
  1897. case DAB_ACCESS_STORE:
  1898.     if (vxMemProbe ((char *)adrs, O_WRONLY, 4, (char *) &val) != OK)
  1899. {
  1900. return (ERROR);
  1901. }
  1902.     break;
  1903. case HW_INST_BRK:
  1904.     if (vxMemProbe ((char *)adrs, O_RDONLY, 4, (char *) &val) != OK)
  1905. {
  1906. return (ERROR);
  1907. }
  1908.     break;
  1909.         case DAB_ACCESS_DATA_LOAD_OR_STORE:
  1910. case DAB_ACCESS_DATA_OR_INSTR_FETCH: 
  1911. case DAB_ACCESS_ANY_ACCESS: 
  1912.      if (vxMemProbe ((char *)adrs, O_RDONLY, 4, (char *) &val) != OK ||
  1913.          vxMemProbe ((char *)adrs, O_WRONLY, 4, (char *) &val) != OK)
  1914.  {
  1915.  return (ERROR);
  1916.  }
  1917.     break;
  1918. default:
  1919.     break;
  1920. }
  1921. #endif /* CPU==I960CA */
  1922.     return (OK);
  1923.     }
  1924. /******************************************************************************
  1925. *
  1926. * _dbgHwDisplay - display a hardware breakpoint 
  1927. *
  1928. * NOMANUAL
  1929. */
  1930. void _dbgHwDisplay 
  1931.     (
  1932.     BRKENTRY * bp /* breakpoint table entry */
  1933.     )
  1934.     {
  1935.     if ((bp->type & BRK_HW_BP) == 0)
  1936. return;
  1937.     printf (" (hard-");
  1938. #if CPU==I960CA
  1939.     switch (bp->pHwBp->hbAccess)
  1940. {
  1941. case DAB_ACCESS_STORE:
  1942.     printf ("store only)");
  1943.     break;
  1944. case DAB_ACCESS_DATA_LOAD_OR_STORE:
  1945.     printf ("data only)");
  1946.     break;
  1947. case DAB_ACCESS_DATA_OR_INSTR_FETCH:
  1948.     printf ("data/instr fetch)");
  1949.     break;
  1950. case DAB_ACCESS_ANY_ACCESS:
  1951.     printf ("any access)");
  1952.     break;
  1953. case HW_INST_BRK:
  1954.     printf ("instruction)");
  1955.     break;
  1956. default:
  1957.     printf ("unknown)");
  1958.     break;
  1959. }
  1960. #endif /* CPU==I960CA */
  1961.     }
  1962. /******************************************************************************
  1963. *
  1964. * _dbgHwBpSet - set a data breakpoint register
  1965. *
  1966. * Access is the type of access that will generate a breakpoint.
  1967. *  000 - store only
  1968. *  001 - data only (load or store)
  1969. *  010 - data or instruction fetch
  1970. *  011 - any access
  1971. *  100 - instruction breakpoint
  1972. *
  1973. * NOMANUAL
  1974. */
  1975. void _dbgHwBpSet 
  1976.     (
  1977.     INSTR *  addr, /* address on which to break */
  1978.     HWBP * pHwBp /* hardware breakpoint */
  1979.     )
  1980.     {
  1981. #if CPU==I960CA
  1982.     switch (pHwBp->hbRegNum)
  1983. {
  1984. case REG_NUM_DAB0:
  1985.     dbgDAB0Set ((char *) addr);
  1986.     dbgDAB0Enable (pHwBp->hbAccess);
  1987.     break;
  1988. case REG_NUM_DAB1:
  1989.     dbgDAB1Set ((char *) addr);
  1990.     dbgDAB1Enable (pHwBp->hbAccess);
  1991.     break;
  1992. case REG_NUM_IPB0:
  1993.     (void) dbgIPB0Set ((char *)addr);
  1994.     break;
  1995. case REG_NUM_IPB1:
  1996.     (void) dbgIPB1Set ((char *)addr);
  1997.     break;
  1998. default:
  1999.     break;
  2000. }
  2001. #endif /* CPU==I960CA */
  2002.     }
  2003. /******************************************************************************
  2004. *
  2005. * _dbgHwBpCheck - check if instruction could have caused a data breakpoint
  2006. *
  2007. * Check to see if the instruction at the given address caused a
  2008. * memory reference that matches one of the DAB registers.
  2009. * Or if the address of the instruction itself caused a break.
  2010. * This would be true if the access type was for instruction fetch.
  2011. *
  2012. * RETURNS: TRUE if match, FALSE if no match.
  2013. *
  2014. * NOMANUAL
  2015. */
  2016. BOOL _dbgHwBpCheck
  2017.     (
  2018.     INSTR * pInstr, /* ptr to instruction to check  */
  2019.     BRKENTRY * bp, /* pointer to breakpoint entry */
  2020.     int tid, /* task's id */
  2021.     volatile BOOL checkFlag /* flag to check if breakpoint hit */
  2022.     )
  2023.     {
  2024. #if CPU==I960CA
  2025.     UINT32  addr1;
  2026.     REG_SET regSet;
  2027.     if ((bp->type & BRK_HW_BP) == 0)
  2028. return (FALSE);
  2029.     /* check to see if instruction addr caused break */
  2030.     if (pInstr == bp->addr)
  2031. return (TRUE);
  2032.     taskRegsGet (tid, &regSet);
  2033.     /* check to see if memory reference caused break */
  2034.     if (dsmMemInstrCheck(pInstr))
  2035. {
  2036. addr1 = dsmMEMInstrRefAddrGet(pInstr, (UINT32 *)&regSet);
  2037. if (bp->addr == (INSTR *) addr1)
  2038.     return (TRUE);
  2039. }
  2040.     if ((UINT32)bp->addr == (sysCtrlTable[0]&0xfffffffc))
  2041. return (TRUE);
  2042.     if ((UINT32)bp->addr == (sysCtrlTable[1]&0xfffffffc))
  2043. return (TRUE);
  2044. #endif /* CPU==I960CA */
  2045.     return (FALSE);
  2046.     }
  2047. /******************************************************************************
  2048. *
  2049. * _dbgHwBpClear - clear a data breakpoint
  2050. *
  2051. * Clears a data breakpoint based on given regiser number, but does not
  2052. * free the resource. This is the mechanism used to clear disable
  2053. * hardware breakpoints when a task is unbreakable.
  2054. *
  2055. * NOMANUAL
  2056. */
  2057. void _dbgHwBpClear 
  2058.     (
  2059.     HWBP * pHwBp /* hardware breakpoint */
  2060.     )
  2061.     {
  2062. #if CPU==I960CA
  2063.     switch (pHwBp->hbRegNum)
  2064. {
  2065. case REG_NUM_DAB0:
  2066.     dbgDAB0Set ((char *) -1);
  2067.     dbgDAB0Disable ();
  2068.     break;
  2069. case REG_NUM_DAB1:
  2070.     dbgDAB1Set ((char *) -1);
  2071.     dbgDAB1Disable ();
  2072.     break;
  2073. case REG_NUM_IPB0:
  2074.     (void) dbgIPB0Disable ();
  2075.     break;
  2076. case REG_NUM_IPB1:
  2077.     (void) dbgIPB1Disable ();
  2078.     break;
  2079. }
  2080. #endif /* CPU==I960CA */
  2081.     }
  2082. /******************************************************************************
  2083. *
  2084. * _dbgArchHwBpFree - free hardware breakpoint data entry
  2085. *
  2086. * NOMANUAL
  2087. */
  2088. void _dbgArchHwBpFree
  2089.     (
  2090.     HWBP * pHwBp /* pointer to hardware breakpoint data structure */
  2091.     )
  2092.     {
  2093.     dbgHwRegStatus &= ~(1<< pHwBp->hbRegNum);
  2094.     }
  2095. #endif /*  (BRK_HW_BP != 0) */
  2096. /******************************************************************************
  2097. *
  2098. * _dbgInfoPCGet - exception frame's PC/IP (program counter/instruction 
  2099. *                    pointer)
  2100. *
  2101. * RETURNS: PC/IP
  2102. *
  2103. * NOMANUAL
  2104. */
  2105. INSTR * _dbgInfoPCGet
  2106.     (
  2107.     BREAK_ESF * pBrkInfo /* pointer to exception frame */
  2108.     )
  2109.     {
  2110.     return ((INSTR *) pBrkInfo->faultIP);
  2111.     }
  2112. /******************************************************************************
  2113. *
  2114. * _dbgInstSizeGet - get size of instruction in sizeof(INSTR)'s
  2115. *
  2116. * RETURNS: The size of the instruction.
  2117. *
  2118. * NOMANUAL
  2119. */
  2120. int _dbgInstSizeGet 
  2121.     (
  2122.     INSTR * pInst /* pointer to instruction to check */
  2123.     )
  2124.     {
  2125.     return (dsmNbytes (pInst) / sizeof (INSTR));
  2126.     }
  2127. /******************************************************************************
  2128. *
  2129. * _dbgIntrInfoRestore - restore the info saved by dbgIntrInfoSave
  2130. *
  2131. * NOMANUAL
  2132. */
  2133. void _dbgIntrInfoRestore
  2134.     ( 
  2135.     BREAK_ESF * pBrkInfo /* pointer to execption frame */
  2136.     )
  2137.     {
  2138.     pBrkInfo->procCtrl = dbgInterruptPCW;
  2139.     }
  2140. /******************************************************************************
  2141. *
  2142. * _dbgIntrInfoSave - save info when breakpoints are hit at interrupt level.
  2143. *
  2144. * NOMANUAL
  2145. */
  2146. void _dbgIntrInfoSave
  2147.     (
  2148.     BREAK_ESF * pBrkInfo /* pointer to breakpoint ESF */
  2149.     )
  2150.     {
  2151.     dbgInterruptPCW = pBrkInfo->procCtrl;
  2152.     }
  2153. /******************************************************************************
  2154. *
  2155. * _dbgRegsAdjust - adjust stack pointer
  2156. *
  2157. * Adjust the stack pointer of the given REG_SET to remove the 
  2158. * exception frame, caused by the TRACE FAULT.
  2159. *
  2160. * NOMANUAL
  2161. */
  2162. void _dbgRegsAdjust
  2163.     (
  2164.     int tid, /* task's id */
  2165.     TRACE_ESF * pBrkInfo, /* pointer to exception frame   */
  2166.     int * pRegSet, /* pointer to tasks register set */
  2167.     volatile BOOL flag /* tells what type of ESF to use */
  2168.     )
  2169.     {
  2170.     ansiFix = (int)pBrkInfo->faultIP;  /* fix ansi warning */
  2171.     /* NOP for 80960 because fault record (ESF) is
  2172.      * stuck in just before the stack frame for the
  2173.      * fault handler.
  2174.      */
  2175.     taskRegsSet (tid, (REG_SET *) pRegSet);
  2176.     }
  2177. /******************************************************************************
  2178. *
  2179. * _dbgTaskPCSet - set task's pc
  2180. *
  2181. * NOMANUAL
  2182. */
  2183. void _dbgTaskPCSet
  2184.     (
  2185.     int tid, /* task's id */
  2186.     INSTR * pc, /* pc to set */
  2187.     INSTR * npc  /* npc to set (not supported by 960) */
  2188.     )
  2189.     {
  2190.     REG_SET regSet;
  2191.     ansiFix = (int)npc; /* fix ansi warning */
  2192.     if (taskRegsGet (tid, &regSet) ==OK)
  2193. {
  2194. regSet.rip = (UINT32) pc;
  2195. taskRegsSet (tid, &regSet);
  2196. }
  2197.     }
  2198. /******************************************************************************
  2199. *
  2200. * _dbgTaskPCGet - get task's pc
  2201. *
  2202. * NOMANUAL
  2203. */
  2204. INSTR * _dbgTaskPCGet
  2205.     (
  2206.     int tid /* task's id */
  2207.     )
  2208.     {
  2209.     REG_SET regSet;
  2210.     taskRegsGet (tid, &regSet);
  2211.     return ((INSTR *) regSet.rip);
  2212.     }
  2213. /******************************************************************************
  2214. *
  2215. * _dbgRetAdrsGet - address of the subroutine in which has hit a breakpoint
  2216. *
  2217. * RETURNS: Address of the next instruction to be executed upon
  2218. *      return of the current subroutine.
  2219. *
  2220. * INTERNAL
  2221. * BAL instruction will need to be taken into account here.
  2222. *
  2223. * NOMANUAL
  2224. */
  2225. INSTR * _dbgRetAdrsGet
  2226.     (
  2227.     REG_SET * pRegSet /* reg set of broken task */
  2228.     )
  2229.     {
  2230. #define MAX_NAME_LEN 80
  2231.     UINT32 retVal;
  2232.     UINT32 type  = 0x00;
  2233.     UINT32 regNum;
  2234.     INT8 name[MAX_NAME_LEN];
  2235.     REG_SET * pPrevRegSet = (REG_SET *)pRegSet->pfp;
  2236.     INSTR *  pInstr0 = (INSTR *)(pRegSet->rip & 0xfffffffc);
  2237.     INSTR *  pInstr1 = pInstr0;
  2238.     /* from this address, find the symbol in the symbol table that
  2239.      * is closest yet lower than the address. If this symbol is a leaf-proc
  2240.      * entry, then get the return address either from gx or g14,
  2241.      * depending on whether or not the mov g14, gx instruction has been
  2242.      * executed. If the symbol is not a leaf_proc entry point,
  2243.      * it is a regular function entry. Get the return address from
  2244.      * the rip of the previous frame. Caveat: if an assembly language
  2245.      * symbol starts with an `_', this could fool this algo. into
  2246.      * thinking it is the start of a function.
  2247.      */
  2248.     strcpy (name, "");
  2249.     symFindByValue (sysSymTbl, (UINT) pInstr0, (char *) &name, 
  2250.     (int *) &pInstr0, (SYM_TYPE *) &type);
  2251.     if (!strncmp (&name[strlen(name) - 3], ".lf", 3))
  2252. {
  2253. /* this is a leaf_proc. first we must check to see if we
  2254.  * are sitting on the mov g14, gx instruction If we are,
  2255.  * return the value in g14, otherwise, disect the instruction
  2256.  * and figure out what register is holding the return value */
  2257. if ((*pInstr1 & MOV_G14_MASK) == INST_MOV_G14)
  2258.     retVal = pRegSet->g14;
  2259. else
  2260.     {
  2261.     regNum = (*pInstr0 & SRC_REG_MASK) >> 0x13;
  2262.     retVal = *(((UINT32 *)pRegSet) + regNum);
  2263.     printf ("regNum: 0x%x, retVal: 0x%x 0x%x n",
  2264.     regNum, retVal, *pInstr0);
  2265.     }
  2266. /* we still have to figure out if we got to this point in the leaf-proc
  2267.  * via a 'call' or 'bal' instruction. If we came via a call instruction,
  2268.  * the address 'retVal' will point to the 'ret' instruction at the
  2269.  * end of the function. Otherwise, it will be the address of the
  2270.  * instruction following the 'bal'. If 'retVal' does not point to a
  2271.  * 'ret' instruction, we can just return it.
  2272.  *
  2273.  * NOTE: We could still be fooled if caller's 'bal' or 'balx' is
  2274.  * followed by 'ret.' Perhaps we should also check to see if the
  2275.  * instruction preceding 'ret' is 'bx gx' and or some similar check.
  2276.  */
  2277. if (((*(INSTR *)retVal) & 0xff000000) != 0x0a000000)
  2278.     return ((INSTR *)retVal);
  2279. }
  2280.     /* non-leaf_proc function or 'called' leaf-proc */
  2281.     return ((INSTR *)(pPrevRegSet->rip & 0xfffffffc));
  2282.     }
  2283. /******************************************************************************
  2284. *
  2285. * _dbgSStepSet - set single step mode
  2286. *
  2287. * Function to set things up so that instruction trace mode (single step)
  2288. * will occur when the 'broken' task is run.
  2289. * This is done by setting the Trace Enable bit of the PCW in the
  2290. * exception frame, and setting the TCW to Instruction Trace mode.
  2291. *
  2292. * NOTE
  2293. * Trace mode is disabled in the process control word so that
  2294. * we don't start instruction tracing until we return to the
  2295. * the task that broke.
  2296. *
  2297. * NOMANUAL
  2298. */
  2299. void _dbgSStepSet
  2300.     (
  2301.     BREAK_ESF * pBrkInfo /* pointer to exception frame */
  2302.     )
  2303.     {
  2304.     vxPCWClear (PCW_TRACE_ENABLE_MASK); 
  2305. #ifndef ICE960KB
  2306.     pBrkInfo->procCtrl |= PCW_TRACE_ENABLE_MASK; 
  2307. #endif
  2308.     vxTCWSet (TCW_MODE_INSTR_MASK);
  2309.     }
  2310. /******************************************************************************
  2311. *
  2312. * _dbgSStepClear - clear single step mode
  2313. *
  2314. * Turn off instruction trace mode (single stepping).
  2315. *
  2316. * NOMANUAL
  2317. */
  2318. void _dbgSStepClear (void)
  2319.     {
  2320.     vxTCWClear (TCW_MODE_INSTR_MASK);
  2321.     }
  2322. /******************************************************************************
  2323. *
  2324. * _dbgTaskBPModeSet - set breakpoint mode of task
  2325. *
  2326. * Function to set the PCW and TCW in the given TCB so breakpoints will
  2327. * be enabled when the task is switched in.
  2328. *
  2329. * RETURNS: OK or ERROR if invalid <tid>.
  2330. *
  2331. * NOMANUAL
  2332. */
  2333. void _dbgTaskBPModeSet
  2334.     (
  2335.     int  tid /* task's id */
  2336.     )
  2337.     {
  2338.     WIND_TCB* pTcb = taskTcb (tid);
  2339.     if (pTcb == NULL)
  2340. return;
  2341. #ifndef ICE960KB
  2342. /* enable tracing in PCW of task */
  2343.     pTcb->regs.pcw |= PCW_TRACE_ENABLE_MASK;
  2344. /* enable break point tracing in TCW of task */
  2345.     pTcb->regs.tcw |= TCW_MODE_BP_MASK;
  2346. #endif
  2347.     }
  2348. /******************************************************************************
  2349. *
  2350. * _dbgTaskBPModeClear - clear breakpoint mode of task
  2351. *
  2352. * NOMANUAL
  2353. */
  2354. void _dbgTaskBPModeClear
  2355.     (
  2356.     volatile int tid /* task's id */
  2357.     )
  2358.     {
  2359.     }
  2360. /******************************************************************************
  2361. *
  2362. * _dbgTaskSStepClear - clear single step mode in task
  2363. *
  2364. * Set the PCW and TCW of the given task for trace (instruction) break
  2365. * mode, so that when the task is switched in, it will execute the
  2366. * next instruction and break.
  2367. *
  2368. * RETURNS: N/A
  2369. *
  2370. * NOMANUAL
  2371. */
  2372. void _dbgTaskSStepClear
  2373.     (
  2374.     int tid /* id of task to set */
  2375.     )
  2376.     {
  2377.     WIND_TCB * pTcb = taskTcb (tid);
  2378.     if (pTcb == NULL)
  2379. return;
  2380.     if (pTcb->regs.tcw & TCW_MODE_INSTR_MASK)
  2381. {
  2382. pTcb->regs.tcw &= ~TCW_MODE_INSTR_MASK;
  2383. pTcb->regs.pcw = pTcb->dbgPCWSave;
  2384. }
  2385.     }
  2386. /******************************************************************************
  2387. *
  2388. * _dbgTaskSStepSet - set single step mode of task
  2389. *
  2390. * Set the PCW and TCW of the given task for trace (instruction) break
  2391. * mode, so that when the task is switched in, it will execute the
  2392. * next instruction and break.
  2393. *
  2394. * NOTE
  2395. * Interrupts are locked out for this task, until single stepping
  2396. * for the task is cleared.
  2397. *
  2398. * RETURNS: N/A
  2399. *
  2400. * NOMANUAL
  2401. */
  2402. void _dbgTaskSStepSet
  2403.     (
  2404.     int tid /* id of task to set */
  2405.     )
  2406.     {
  2407.     WIND_TCB * pTcb = taskTcb (tid);
  2408.     if (pTcb == NULL)
  2409. return;
  2410.     pTcb->dbgPCWSave = pTcb->regs.pcw;
  2411. #ifdef ICE960KB
  2412.     pTcb->regs.pcw |= PCW_INT_LOCK;
  2413. #else
  2414.     pTcb->regs.pcw |= PCW_TRACE_ENABLE_MASK | PCW_INT_LOCK;
  2415.     pTcb->regs.tcw |= TCW_MODE_INSTR_MASK;
  2416. #endif
  2417.     }
  2418. /******************************************************************************
  2419. *
  2420. * _dbgVecInit - initialize the trace fault handler vector
  2421. *
  2422. * NOMANUAL
  2423. */
  2424. void _dbgVecInit (void)
  2425.     {
  2426.     sysFaultVecSet (dbgBpStub, FT_TRACE, FTE_SYSTEM_CALL);
  2427.     }
  2428. #if (BRK_HW_BP != 0)
  2429. /*******************************************************************************
  2430. * _dbgHwBrkExists - check if hardware breakpoint already exists
  2431. *
  2432. * RETURNS: TRUE if instuction pointer matches given hardware breakpoint entry
  2433. *          (always FALSE for KB).
  2434. *
  2435. * NOMANUAL
  2436. */
  2437. BOOL _dbgHwBrkExists 
  2438.     (
  2439.     INSTR * addr, /* pointer to instruction hit break */
  2440.     BRKENTRY * pBrkEntry, /* pointer to breakpoint entry */
  2441.     int  access, /* access type */
  2442.     void * pHwInfo /* pointer to hardware brkpoint info */
  2443.     )
  2444.     {
  2445.     ansiFix = (int)pHwInfo; /* fix ansi warning */
  2446. #if CPU==I960CA
  2447.     if (pBrkEntry == NULL)
  2448.         return (FALSE);
  2449.     else
  2450. return((pBrkEntry->addr == addr) && 
  2451.        (pBrkEntry->pHwBp->hbAccess == access));
  2452. #else
  2453.     return (FALSE);
  2454. #endif /* CPU==I960CA */
  2455.     }
  2456. /******************************************************************************
  2457. *
  2458. * _dbgHwBpGet - get a free hardware breakpoint register
  2459. *
  2460. * Increment the count of data breakpoints in the system, and check for
  2461. * max number reached.
  2462. *
  2463. * RETURNS: pointer to a free hardware breakpoint or NULL if out of resources.
  2464. *
  2465. * NOMANUAL
  2466. */
  2467. HWBP * _dbgHwBpGet 
  2468.     (
  2469.     int    access, /* access type */
  2470.     LIST * pDbgHwBpList /* hardware breakpoint list */
  2471.     )
  2472.     {
  2473.     HWBP * pHwBp;
  2474.     int    regNum;
  2475.     switch (access)
  2476. {
  2477. case DAB_ACCESS_STORE:
  2478. case DAB_ACCESS_DATA_LOAD_OR_STORE:
  2479. case DAB_ACCESS_DATA_OR_INSTR_FETCH:
  2480. case DAB_ACCESS_ANY_ACCESS:
  2481.     /* data address breakpoint registers */
  2482.     if ((dbgHwRegStatus & (1 << REG_NUM_DAB0)) == 0)
  2483. regNum = REG_NUM_DAB0;
  2484.     else if ((dbgHwRegStatus & (1 << REG_NUM_DAB1)) == 0)
  2485. regNum = REG_NUM_DAB1;
  2486.     else
  2487. regNum = -1;
  2488.     break;
  2489. case HW_INST_BRK:
  2490.     /* instruction address breakpoint registers */
  2491.     if ((dbgHwRegStatus & (1 << REG_NUM_IPB0)) == 0)
  2492. regNum = REG_NUM_IPB0;
  2493.     else if ((dbgHwRegStatus & (1 << REG_NUM_IPB1)) == 0)
  2494. regNum = REG_NUM_IPB1;
  2495.     else
  2496. regNum = -1;
  2497.     break;
  2498. default:
  2499.     regNum = -1;
  2500. }
  2501.     if (regNum < 0)
  2502. return ((HWBP *) NULL);
  2503.     else
  2504. {
  2505. dbgHwRegStatus |= 1 << regNum;
  2506. pHwBp = (HWBP *) lstGet (pDbgHwBpList);
  2507. if (pHwBp != NULL)
  2508.     pHwBp->hbRegNum = regNum;
  2509. }
  2510.     return (pHwBp);
  2511.     }
  2512. #endif  /* BRK_HW_BP */
  2513. /* interrupt level stuff */
  2514. /******************************************************************************
  2515. *
  2516. * dbgLocalRegsToRegSet - save local registers to given register set
  2517. *
  2518. * NOMANUAL
  2519. */
  2520. void dbgLocalRegsToRegSet
  2521.     (
  2522.     int * pRegs, /* saved local registers */
  2523.     REG_SET * pRegSet /* pointer to register set to fill */
  2524.     )
  2525.     {
  2526.     bcopy ((char *) pRegs, (char *) &pRegSet->pfp, NUM_I960_LOCAL_REGS * 4);
  2527.     }
  2528. /******************************************************************************
  2529. *
  2530. * dbgGlobalRegsToRegSet - save local registers to given register set
  2531. *
  2532. * NOMANUAL
  2533. */
  2534. void dbgGlobalRegsToRegSet
  2535.     (
  2536.     FAST int * pRegs, /* saved local registers */
  2537.     FAST REG_SET * pRegSet /* REG_SET to fill */
  2538.     )
  2539.     {
  2540.     bcopy ((char *) pRegs, (char *) &pRegSet->g0, NUM_I960_GLOBAL_REGS * 4);
  2541.     }
  2542. /******************************************************************************
  2543. *
  2544. * dbgRegSetToLocalRegs - move local registers to memory
  2545. *
  2546. * NOMANUAL
  2547. */
  2548. void dbgRegSetToLocalRegs
  2549.     (
  2550.     FAST int * pRegs, /* location to put regs */
  2551.     FAST REG_SET * pRegSet /* pointer to reg set to copy */
  2552.     )
  2553.     {
  2554.     bcopy ((char *) &pRegSet->pfp, (char *) pRegs, NUM_I960_LOCAL_REGS * 4);
  2555.     }
  2556. /******************************************************************************
  2557. *
  2558. * dbgRegSetToGlobalRegs - move global registers to memory
  2559. *
  2560. * NOMANUAL
  2561. */
  2562. void dbgRegSetToGlobalRegs
  2563.     (
  2564.     FAST int * pRegs, /* location to put regs */
  2565.     FAST REG_SET * pRegSet /* pointer reg set to copy */
  2566.     )
  2567.     {
  2568.     bcopy ((char *) &pRegSet->g0, (char *) pRegs, NUM_I960_GLOBAL_REGS * 4);
  2569.     }
  2570. /******************************************************************************
  2571. *
  2572. * dbgRegSetFramePtrAdjust - adjust frame pointer
  2573. *
  2574. * Change the frame pointer in the given REG_SET to the given value.
  2575. * Used to 'chain back' so the saved REG_SET reflects the exact values
  2576. * of the task environment at the time of the trace fault.
  2577. *
  2578. * NOMANUAL
  2579. */
  2580. void dbgRegSetFramePtrAdjust
  2581.     (
  2582.     REG_SET * pRegSet, /* register set to modify */
  2583.     UINT32 * pFrame /* value to set REG_SET FP */
  2584.     )
  2585.     {
  2586.     pRegSet->fp = (UINT32)pFrame;
  2587.     }
  2588. /******************************************************************************
  2589. *
  2590. * dbgTraceFaultAck - clear trace fault pending bit according to fault subtype
  2591. */
  2592. LOCAL void dbgTraceFaultAck
  2593.     (
  2594.     UINT32 subType /* trace fault subtype */
  2595.     )
  2596.     {
  2597.     vxTCWClear (subType << 0x10);
  2598.     }
  2599. /******************************************************************************
  2600. *
  2601. * dbgTraceFaultHandle - interrupt level handling of trace fault
  2602. *
  2603. * Function to determine what type of trace fault has occured.
  2604. * Trace fault subtypes are; breakpoint, instruction (ss), return,
  2605. * prereturn, call, branch, supervisor.
  2606. *
  2607. * NOMANUAL
  2608. */
  2609. INSTR * dbgTraceFaultHandle
  2610.     (
  2611.     TRACE_ESF * pBrkInfo, /* trace fault exception frame */
  2612.     int * pLocalRegs, /* local registers */
  2613.     int * pGlobalRegs /* global registers */
  2614.     )
  2615.     {
  2616.     REG_SET dbgRegSet;
  2617.     WIND_TCB * pTcb = taskTcb (taskIdSelf ());
  2618.     /* save local and global regs to temporary REG_SET */
  2619.     dbgLocalRegsToRegSet (pLocalRegs, &dbgRegSet);
  2620.     dbgGlobalRegsToRegSet (pGlobalRegs, &dbgRegSet);
  2621.     dbgRegSetFramePtrAdjust ((REG_SET *) &dbgRegSet, (UINT32 *) pLocalRegs);
  2622.     switch (pBrkInfo->faultSubtype)
  2623. {
  2624. case TRACE_FAULT_SUBTYPE_INSTR:
  2625.     dbgTraceFaultAck (TRACE_FAULT_SUBTYPE_INSTR);
  2626.     _dbgSStepClear (); /* make sure single stepping is off */
  2627.     _dbgTaskSStepClear (taskIdSelf ());
  2628.     dbgRegSet.pcw = pTcb->regs.pcw;
  2629.     dbgRegSet.acw = pBrkInfo->arithCtrl;
  2630.     dbgRegSet.tcw = vxTCWGet ();
  2631.     dbgTrace (pBrkInfo, &dbgRegSet);
  2632.     /* we come here when we single-stepped from a breakpoint. */
  2633.     dbgRegSetToLocalRegs ((int *) pLocalRegs, (REG_SET *) &dbgRegSet);
  2634.     dbgRegSetToGlobalRegs ((int *) pGlobalRegs, (REG_SET *) &dbgRegSet);
  2635.     taskRegsGet (taskIdSelf (), &dbgRegSet);
  2636.     pBrkInfo->procCtrl = dbgRegSet.pcw;
  2637.     return ((INSTR *)(((REG_SET *)pLocalRegs)->rip & 0xfffffffc));
  2638.     break;
  2639. case TRACE_FAULT_SUBTYPE_BP:
  2640.     dbgTraceFaultAck (TRACE_FAULT_SUBTYPE_BP);
  2641.     dbgRegSet.pcw = pBrkInfo->procCtrl;
  2642.     dbgRegSet.acw = pBrkInfo->arithCtrl;
  2643.     dbgRegSet.tcw = vxTCWGet ();
  2644.     /* if we hit a breakpoint, we need to set the rip back to
  2645.      * the address of the fault */
  2646.     dbgRegSet.rip = ((UINT32) _dbgInfoPCGet (pBrkInfo) & 0xfffffffc)
  2647.     | (dbgRegSet.rip & 0x03);
  2648.     dbgBreakpoint (pBrkInfo, &dbgRegSet);
  2649.     /* we come here ONLY if bp was hit at interrupt level */
  2650.     dbgRegSetToLocalRegs ((int *) pLocalRegs, (REG_SET *) &dbgRegSet);
  2651.     dbgRegSetToGlobalRegs ((int *) pGlobalRegs, (REG_SET *) &dbgRegSet);
  2652.     return ((INSTR *)(((REG_SET *)pLocalRegs)->rip & 0xfffffffc));
  2653.     break;
  2654. case TRACE_FAULT_SUBTYPE_BRANCH:
  2655.     /* not implemented yet */
  2656. case TRACE_FAULT_SUBTYPE_CALL:
  2657.     /* not implemented yet */
  2658. case TRACE_FAULT_SUBTYPE_RETURN:
  2659.     /* not implemented yet */
  2660. case TRACE_FAULT_SUBTYPE_PRERET:
  2661.     /* not implemented yet */
  2662. case TRACE_FAULT_SUBTYPE_SPV:
  2663.     /* not implemented yet */
  2664. default:
  2665.     logMsg ("faultSubtype: 0x%xn", pBrkInfo->faultSubtype, 0, 0, 0, 0, 0);
  2666.     break;
  2667. }
  2668.     return ((INSTR *) -1);
  2669.     }
  2670. /*******************************************************************************
  2671. *
  2672. * getOneReg - return the contents of one register
  2673. *
  2674. * Given a task's ID, this routine returns the contents of the register
  2675. * specified by the register code.  This routine is used by `a0', `d0', `sr', etc.
  2676. * The register codes are defined in regsI960.h.
  2677. *
  2678. * RETURNS: register contents, or ERROR.
  2679. *
  2680. * NOMANUAL
  2681. */
  2682. static int getOneReg
  2683.     (
  2684.     int taskId, /* task ID, 0 means default task */
  2685.     int regOffset /* code for specifying register */
  2686.     )
  2687.     {
  2688.     REG_SET regSet; /* get task's regs into here */
  2689.     taskId = taskIdFigure (taskId); /* translate super name to ID */
  2690.     if (taskId == ERROR) /* couldn't figure out super name */
  2691. return (ERROR);
  2692.     taskId = taskIdDefault (taskId); /* set the default ID */
  2693.     if (taskRegsGet (taskId, &regSet) != OK)
  2694. return (ERROR);
  2695.     return (*(int *)((int)&regSet + regOffset));
  2696.     }
  2697. #if CPU==I960KB
  2698. /*******************************************************************************
  2699. *
  2700. * getOneFPReg - return the contents of an FP register
  2701. *
  2702. * Given a task's ID, this routine returns the contents of the FP register
  2703. * specified by the register code.  This routine is used by fp[0-3]. The 
  2704. * register codes are defined in fppI960Lib.h.
  2705. *
  2706. * RETURNS: register contents, or ERROR.
  2707. *
  2708. * NOMANUAL
  2709. */
  2710. static double getOneFPReg
  2711.     (
  2712.     volatile int taskId,               /* task's ID, 0 means default task */
  2713.     int regOffset
  2714.     )
  2715.     {
  2716.     FPREG_SET fpregs;      /* floating point data registers */
  2717.     taskId = taskIdFigure (taskId);     /* translate super name to ID */
  2718.     if (taskId == ERROR)                /* couldn't figure out super name */
  2719. return ((double) ERROR);
  2720.     taskId = taskIdDefault (taskId);    /* set the default ID */
  2721.     if (fppTaskRegsGet (taskId, (FPREG_SET *) &fpregs) != OK)
  2722.         {
  2723.         int status[] = { ERROR, ERROR };
  2724.         return (*((double *) status));
  2725.         }
  2726.     return  (*(double *) ((int)&fpregs + regOffset));
  2727.     }
  2728. #endif /* CPU == I960KB */
  2729. /*******************************************************************************
  2730. *
  2731. * pfp - return the contents of register `pfp' (i960)
  2732. *
  2733. * This command extracts the contents of register `pfp', the previous frame
  2734. * pointer, from the TCB of a specified task.
  2735. * If <taskId> is omitted or 0, the current default task is assumed.
  2736. *
  2737. * RETURNS: The contents of the `pfp' register.
  2738. *
  2739. * SEE ALSO:
  2740. * .pG "Target Shell"
  2741. *
  2742. * NOMANUAL
  2743. */
  2744. int pfp
  2745.     (
  2746.     int taskId /* task ID, 0 means default task */
  2747.     )
  2748.     {
  2749.     return (getOneReg (taskId, PFP_OFFSET));
  2750.     }
  2751. /*******************************************************************************
  2752. *
  2753. * tsp - return the contents of register `sp' (i960)
  2754. *
  2755. * This command extracts the contents of register `sp', the stack pointer,
  2756. * from the TCB of a specified task.
  2757. * If <taskId> is omitted or 0, the current default task is assumed.
  2758. *
  2759. * Note:  The name tsp() is used because sp() (the logical name choice)
  2760. * conflicts with the routine sp() for spawning a task with default parameters.
  2761. *
  2762. * RETURNS: The contents of the `sp' register.
  2763. *
  2764. * SEE ALSO:
  2765. * .pG "Target Shell"
  2766. *
  2767. * NOMANUAL
  2768. */
  2769. int tsp
  2770.     (
  2771.     int taskId /* task ID, 0 means default task */
  2772.     )
  2773.     
  2774.     {
  2775.     return (getOneReg (taskId, SP_OFFSET));
  2776.     }
  2777. /*******************************************************************************
  2778. *
  2779. * rip - return the contents of register `rip' (i960)
  2780. *
  2781. * This command extracts the contents of register `rip', the return
  2782. * instruction pointer, from the TCB of a specified task.
  2783. * If <taskId> is omitted or 0, the current default task is assumed.
  2784. *
  2785. * RETURNS: The contents of the `rip' register.
  2786. *
  2787. * SEE ALSO:
  2788. * .pG "Target Shell"
  2789. *
  2790. * NOMANUAL
  2791. */
  2792. int rip
  2793.     (
  2794.     int taskId /* task ID, 0 means default task */
  2795.     )
  2796.     
  2797.     {
  2798.     return (getOneReg (taskId, RIP_OFFSET));
  2799.     }
  2800. /*******************************************************************************
  2801. *
  2802. * r3 - return the contents of register `r3' (also `r4' - `r15') (i960)
  2803. *
  2804. * This command extracts the contents of register `r3' from the TCB of a
  2805. * specified task.
  2806. * If <taskId> is omitted or 0, the current default task is assumed.
  2807. *
  2808. * Routines are provided for all local registers (`r3' - `r15'):
  2809. * r3() - r15().
  2810. *
  2811. * RETURNS: The contents of the `r3' register (or the requested register).
  2812. *
  2813. * SEE ALSO:
  2814. * .pG "Target Shell"
  2815. *
  2816. * NOMANUAL
  2817. */
  2818. int r3
  2819.     (
  2820.     int taskId /* task ID, 0 means default task */
  2821.     )
  2822.