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

VxWorks

开发平台:

C/C++

  1. /* dbgTaskLib.c - Task breakpoint handling */
  2. /* Copyright 1997-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01h,19apr02,jhw  Prevent breakpoint removal when running in System 
  7.  Mode (SPR 75987).
  8. 01g,09nov01,jhw  Revert WDB_INFO to be inside of WIND_TCB.
  9. 01f,17oct01,jhw  Access WDB_INFO from WIND_TCB pointer pWdbInfo.
  10. 01e,03feb99,cpd  Fix for SPR24102: Added Windview instrumentation when 
  11.                  lockCnt is directly decremented, rather than taskUnlock.
  12. 01d,19jan99,elg  Restore PC for MIPS (SPR 24356)
  13. 01c,21apr98,dbt  code cleanup.
  14. 01b,13mar98,dbt  moved _func_wdbIsNowExternal to wdbDbgLib.c (scalability
  15.                  problem).
  16. 01a,05dec97,dbt  written based on wdbTaskBpLib.c.
  17. */
  18. /*
  19. DESCRIPTION
  20. This library contains routines for task mode debugging. Those routines
  21. are all OS specific and are used by both target shell debugger and 
  22. WDB debugger in task mode.
  23. The facilities provided by routines in this library are :
  24. - task deletion and switch handling.
  25. - breakpoint exceptions handling.
  26. - task continue and task step handling.
  27. INTERNAL
  28. We should avoid all direct calls to WDB routines without using a pointer.
  29. This is necessary because target shell debugger and WDB debugger must be
  30. independant.
  31. Since target shell debugger is based on WDB debugger, it is normal to see
  32. references to some WDB defines (WDB_CTX_LOAD for example) in this file.
  33. */
  34. #include "vxWorks.h"
  35. #include "taskLib.h"
  36. #include "regs.h"
  37. #include "stddef.h"
  38. #include "sigLib.h"
  39. #include "taskLib.h"
  40. #include "taskHookLib.h"
  41. #include "intLib.h"
  42. #include "stdio.h"
  43. #include "string.h"
  44. #include "wdb/wdbDbgLib.h"
  45. #include "private/taskLibP.h"
  46. #include "private/kernelLibP.h"
  47. /* defines */
  48. #define DBG_INFO(p) (&(((WIND_TCB *)(p))->wdbInfo))
  49. /* externals */
  50. extern FUNCPTR _func_wdbIsNowExternal; /* pointer on wdbIsNowExternal()
  51.    routine */
  52. /* globals */
  53. int dbgLockUnbreakable; /* taskLock()'ed tasks are unbreakable */
  54. int dbgSafeUnbreakable; /* taskSafe()'ed tasks are unbreakable */
  55. int dbgUnbreakableOld; /* unbreakable even if !WDB_ACTION_STOP */
  56. FUNCPTR _func_dbgHostNotify = NULL; /* routine to call to notify the host
  57.    when a breakpoint is encountered */
  58. FUNCPTR _func_dbgTargetNotify = NULL; /* routine to call to notify the target
  59.    when a breakpoint is encountered */
  60. /* locals */
  61. static int  taskTraceData;
  62. static int  isrTraceData;
  63. #if DBG_NO_SINGLE_STEP
  64. static INSTR * taskNpc; /* next pc of the task */
  65. static INSTR  taskNpcInstr; /* next instruction of the task */
  66. static INSTR * isrNpc; /* next pc at interrrupt level */
  67. static INSTR  isrNpcInstr; /* next instruction at int. level */
  68. #endif /* DBG_NO_SINGLE_STEP */
  69. /* forward static declarations */
  70. LOCAL void dbgTaskDoIgnore (REG_SET * pRegs);
  71. LOCAL void dbgTaskDoneIgnore (REG_SET * pRegs);
  72. LOCAL void dbgTaskSwitch (WIND_TCB * pOldTcb, WIND_TCB * pNewTcb);
  73. LOCAL void dbgTaskDeleteHook (WIND_TCB * pTcb);
  74. LOCAL void dbgTaskBpInstall (int tid);
  75. LOCAL BOOL dbgBrkIgnoreDefault (void);
  76. /******************************************************************************
  77. *
  78. * dbgTaskBpHooksInstall - install tasking breakpoint hooks
  79. *
  80. * This routine installs breakpoint hooks. One for task switch, one for
  81. * task deletion and one for modification of task flags.
  82. *
  83. * RETURNS : N/A.
  84. *
  85. * NOMANUAL
  86. */ 
  87. void dbgTaskBpHooksInstall 
  88.     (
  89.     void
  90.     )
  91.     {
  92.     static BOOL dbgTaskBpHooksInstalled = FALSE;
  93.     if (!dbgTaskBpHooksInstalled)
  94. {
  95. /* task switch hook */
  96. taskSwitchHookAdd ((FUNCPTR) dbgTaskSwitch);
  97. /* task delete hook */
  98. taskDeleteHookAdd ((FUNCPTR) dbgTaskDeleteHook);
  99. /* set break remove/install hook routine for taskOptionsSet */
  100. taskBpHookSet ((FUNCPTR) dbgTaskBpInstall);
  101. dbgTaskBpHooksInstalled = TRUE;
  102. }
  103.     }
  104. /*******************************************************************************
  105. *
  106. * dbgTaskCont - Handle a continue request
  107. *
  108. * The dbgTaskCont() function is used to continue a task.
  109. *
  110. * RETURNS : 
  111. * WDB_ERR_INVALID_CONTEXT if the task is not suspended or 
  112. * if we can't resume it. OK otherwise.
  113. *
  114. * NOMANUAL
  115. */
  116. STATUS dbgTaskCont
  117.     (
  118.     UINT32 taskId /* Id of task to continue */
  119.     )
  120.     {
  121.     if (!taskIsSuspended(taskId))
  122. return (WDB_ERR_INVALID_CONTEXT);
  123.     /* 
  124.      * Check if there is a breakpoint at current pc or if the last 
  125.      * encountered breakpoint still exist (needed for data access 
  126.      * breakpoints).
  127.      */
  128.     taskLock (); /* LOCK PREEMPTION */
  129.     if ((wdbDbgBpFind ((INSTR *)(((WIND_TCB *)taskId)->regs.reg_pc),
  130. taskId) == OK) || 
  131. (wdbDbgBpFind ((INSTR *)(DBG_INFO(taskId)->bpAddr),
  132. taskId) == OK))
  133. {
  134. DBG_INFO(taskId)->wdbState |= WDB_STEP_OVER;
  135. }
  136.     taskUnlock (); /* UNLOCK PREEMPTION */
  137.     if (taskResume (taskId) != OK)
  138. return (WDB_ERR_INVALID_CONTEXT);
  139.     return (OK);
  140.     }
  141. /*******************************************************************************
  142. *
  143. * dbgTaskStep - Handle a step request
  144. *
  145. * The dbgTaskStep() function is used to step a task.
  146. *
  147. * RETURNS : 
  148. * WDB_ERR_INVALID_CONTEXT if the task is not suspended or 
  149. * if we can't resume it. OK otherwise.
  150. *
  151. * NOMANUAL
  152. */
  153. STATUS dbgTaskStep
  154.     (
  155.     UINT32 contextId, /* Id of task to step */
  156.     UINT32 startAddr, /* start address */
  157.     UINT32 endAddr /* end address */
  158.     )
  159.     {
  160.     if (!taskIsSuspended(contextId))
  161. return (WDB_ERR_INVALID_CONTEXT);
  162.     if (startAddr == 0 && endAddr == 0)
  163. DBG_INFO(contextId)->wdbState |= WDB_STEP;
  164.     else
  165. {
  166. if (DBG_INFO(contextId)->wdbState & WDB_QUEUED)
  167.     return (WDB_ERR_INVALID_CONTEXT);
  168. DBG_INFO(contextId)->wdbState |= WDB_STEP_RANGE;
  169. DBG_INFO(contextId)->wdbEvtList.wdb1 = (void *) startAddr;
  170. DBG_INFO(contextId)->wdbEvtList.wdb2 = (void *) endAddr;
  171. }
  172.     if (taskResume (contextId) != OK)
  173. return (WDB_ERR_INVALID_CONTEXT);
  174.     return (OK);
  175.     }
  176. /******************************************************************************
  177. *
  178. * dbgTaskDeleteHook - remove task-specific BP's when a task exits
  179. *
  180. * This hook removes the task-specific breakpoints when a task exits.
  181. *
  182. * RETURNS : N/A
  183. *
  184. * NOMANUAL
  185. */ 
  186. LOCAL void dbgTaskDeleteHook
  187.     (
  188.     WIND_TCB * pTcb /* TCB of the deleted task */
  189.     )
  190.     {
  191.     dll_t * pDll;
  192.     dll_t * pDllNext;
  193.     int level;
  194.     /* remove events still queued in the task TCB */
  195.     level = intLock ();
  196.     if (DBG_INFO(pTcb)->wdbState & WDB_QUEUED)
  197. {
  198. DBG_INFO(taskIdCurrent)->wdbState &= ~WDB_QUEUED;
  199. dll_remove ((dll_t *)&(DBG_INFO(pTcb)->wdbEvtList));
  200. }
  201.     intUnlock (level);
  202.     /* delete task specific breakpoints */
  203.     taskLock (); /* LOCK PREEMPTION */
  204.     for (pDll = dll_head(&bpList); pDll != dll_end(&bpList); pDll = pDllNext)
  205. {
  206. pDllNext = dll_next(pDll);
  207. /* We remove only breakpoints specific to deleted task. */
  208. if (BP_BASE(pDll)->bp_task == (int) pTcb)
  209.     wdbDbgBpRemove (BP_BASE(pDll));
  210. }
  211.     
  212.     taskUnlock (); /* UNLOCK PREEMPTION */
  213.     }
  214. /******************************************************************************
  215. *
  216. * dbgTaskBpInstall - install breakpoints for the current task
  217. *
  218. * This routine installs BP's for the new task and remove ones for 
  219. * the old task.
  220. *
  221. * RETURNS : N/A.
  222. *
  223. * NOMANUAL
  224. */ 
  225. LOCAL void dbgTaskBpInstall
  226.     (
  227.     int tid /* id of the task */
  228.     )
  229.     {
  230.     dll_t * pDll;
  231.     BOOL  stepping; /* task is stepping */
  232.     BOOL breakable; /* task is breakable */
  233.     BOOL bpi; /* breakpoint is installed */
  234.     int level; /* interrupt lock level */
  235.     BRKPT * pBp;
  236.     WIND_TCB * pTcb = (tid == 0 ? taskIdCurrent : (WIND_TCB *)tid);
  237. #if DBG_HARDWARE_BP
  238.     DBG_REGS dbgRegs;
  239. #endif
  240.     /* do not install or remove breakpoints when in system mode */
  241.     if ((_func_wdbIsNowExternal != NULL) && _func_wdbIsNowExternal())
  242. return;
  243.     /* clean local debug register buffer and the debug registers */
  244. #if DBG_HARDWARE_BP
  245.     memset (&dbgRegs, 0, sizeof (DBG_REGS));
  246.     wdbDbgRegsClear ();
  247. #endif  /* DBG_HARDWARE_BP */
  248.     /* set local flags */
  249.     stepping = DBG_INFO(pTcb)->wdbState & WDB_STEPING;
  250.     breakable = !(pTcb->options & VX_UNBREAKABLE);
  251.     /*
  252.      * Iterate through the breakpoint list and remove/install the 
  253.      * breakpoints appropriate to the current task.
  254.      */
  255.     for (pDll = dll_head(&bpList); pDll != dll_end(&bpList);
  256.     pDll = dll_next(pDll))
  257. {
  258. pBp = BP_BASE(pDll);
  259. /* should the breakpoint be installed? */
  260. bpi = !(stepping ||
  261.     ((pBp->bp_task != BP_ANY_TASK) && (pBp->bp_task != (int)pTcb)) ||
  262.     ((!breakable) && (pBp->bp_action & WDB_ACTION_STOP)) ||
  263.     ((!breakable) && dbgUnbreakableOld));
  264. /* does the current BP state match the requested BP state? */
  265. if ((pBp->bp_flags & BP_INSTALLED) != bpi)
  266.     {
  267.     level = intLock ();
  268.     if (bpi)
  269. {
  270. pBp->bp_flags |= BP_INSTALLED;
  271. /* install software breakpoint only */
  272. if ((pBp->bp_flags & BRK_HARDWARE) == 0)
  273.     usrBreakpointSet (pBp->bp_addr, DBG_BREAK_INST);
  274. }
  275.     else
  276. {
  277. /* remove software breakpoint only */
  278. if ((pBp->bp_flags & BRK_HARDWARE) == 0)
  279.     usrBreakpointSet (BP_BASE(pDll)->bp_addr, 
  280. BP_BASE(pDll)->bp_instr);
  281. BP_BASE(pDll)->bp_flags &= ~BP_INSTALLED;
  282. }
  283.     intUnlock(level);
  284.     }
  285. #if DBG_HARDWARE_BP
  286. /* fill local dbgRegs structure with the HW breakpoint info */
  287. if (bpi && (pBp->bp_flags & BRK_HARDWARE))
  288.     wdbDbgHwBpSet (&dbgRegs, pBp->bp_flags & BRK_HARDMASK, 
  289. (UINT32) pBp->bp_addr);
  290. #endif /* DBG_HARDWARE_BP */
  291. }
  292. #if DBG_HARDWARE_BP
  293.     /* 
  294.      * Set CPU debug registers with the new info. 
  295.      * This structure contains only hardware breakpoints for the new task.
  296.      */
  297.     wdbDbgRegsSet (&dbgRegs); /* set debug registers. */
  298. #endif /* DBG_HARDWARE_BP */
  299.     }
  300. /*******************************************************************************
  301. *
  302. * dbgTaskSwitch - system task switch routine
  303. *
  304. * Tasking breakpoints are set during context switches using this routine.
  305. * This allows breakpoints to not affect certain tasks.
  306. *
  307. * RETURNS : N/A.
  308. *
  309. * NOMANUAL
  310. */
  311. LOCAL void dbgTaskSwitch 
  312.     (
  313.     WIND_TCB * pOldTcb,     /* pointer to tcb of switch-from task */
  314.     WIND_TCB * pNewTcb      /* pointer to tcb of switch-to task */
  315.     )
  316.     {
  317.     /* 
  318.      * Don't do task BP switch hook if the agent is in system mode.
  319.      * This test is only usefull if we use WDB breakpoints.
  320.      */
  321.     if ((_func_wdbIsNowExternal != NULL) && _func_wdbIsNowExternal())
  322. return;
  323.     /* perform some cleanup on the old task */
  324.     if (TASK_ID_VERIFY(pOldTcb) == OK) /* suicide runs delete hook 1st */
  325. {
  326. if (DBG_INFO(pOldTcb)->wdbState & WDB_CLEANME)
  327.     {
  328.     taskSuspend((int) pOldTcb);
  329.     taskRegsSet((int) pOldTcb, DBG_INFO(pOldTcb)->wdbRegisters);
  330. #if CPU_FAMILY==MC680X0
  331.     pOldTcb->foroff = 0;
  332. #endif /* CPU_FAMILY==MC680X0 */
  333.     DBG_INFO(pOldTcb)->wdbState &= ~WDB_CLEANME;
  334.     }
  335. if (DBG_INFO(pOldTcb)->wdbState & WDB_STEPING)
  336.     {
  337. #if DBG_NO_SINGLE_STEP
  338.     usrBreakpointSet (taskNpc, taskNpcInstr);
  339. #endif /* DBG_NO_SINGLE_STEP */
  340.     wdbDbgTraceModeClear (&pOldTcb->regs, taskTraceData);
  341.     }
  342. }
  343.     /*
  344.      * If we are stepping, remove all BP's and set trace mode.
  345.      *
  346.      * else, if we are not stepping, remove breakpoints for the old task and
  347.      * install them for new task.
  348.      */
  349.     if (DBG_INFO(pNewTcb)->wdbState & WDB_STEPING)
  350. {
  351. /* remove all the breakpoints for this task */
  352. wdbDbgBpRemoveAll();
  353. /*
  354.  * if Single Step Mode (i.e. Trace Mode) doesn't exist on the CPU, 
  355.  * insert a breakpoint on the next instruction.
  356.  */
  357. #if DBG_NO_SINGLE_STEP
  358. taskNpc = wdbDbgGetNpc(&pNewTcb->regs);
  359. taskNpcInstr = *taskNpc;
  360. usrBreakpointSet (taskNpc, DBG_BREAK_INST);
  361. #endif /* DBG_NO_SINGLE_STEP */
  362. taskTraceData = wdbDbgTraceModeSet (&pNewTcb->regs);
  363. }
  364.     else
  365. {
  366. /* remove breakpoints for old task and install them for new task */
  367. dbgTaskBpInstall((int)pNewTcb);
  368. }
  369.     }
  370. /*******************************************************************************
  371. *
  372. * dbgBrkIgnoreDefault - true if in situation to ignore breakpoint
  373. *
  374. * This is the default boolean function whose output determines whether the
  375. * current task is in a situation where a breakpoint is to be ignored.  This
  376. * routine is called indirectly via the global variable dbgBrkIgnore from the
  377. * routine dbgBreakpoint.
  378. *
  379. * This routine specifies to ignore breakpoints if the breakpoint occurred in
  380. * any of these situations:
  381. *     (1) at interrupt level
  382. *     (2) within kernel
  383. *     (3) while task was unbreakable
  384. *     (4) while preemption was disabled and dbgLockUnbreakable is TRUE
  385. *     (5) while task was safe from deletion and dbgSafeUnbreakable is TRUE
  386. *
  387. * Note that (3) is actually an assertion because currently breakpoints are
  388. * removed when a task is unbreakable.  But it might change someday.
  389. *
  390. * MS - removed check for (3) since I want to optionally allow non-breaking
  391. * windview "eventpoints" in VX_UNBREAKABLE tasks (e.g., VX_UNBREAKABLE
  392. * just means that the eventpoint can't cause the task to stop).
  393. *
  394. * RETURNS :
  395. * TRUE if we should ignore the breakpoint FALSE otherwise
  396. *
  397. * NOMANUAL
  398. */
  399. LOCAL BOOL dbgBrkIgnoreDefault 
  400.     (
  401.     void
  402.     )
  403.     {
  404.     return ((intCnt > 0) ||
  405.     (kernelState == TRUE) ||
  406. #if FALSE
  407.     (taskIdCurrent->options & VX_UNBREAKABLE) ||
  408. #endif /* FALSE */
  409.     ((taskIdCurrent->lockCnt != 0) && (dbgLockUnbreakable)) ||
  410.     ((taskIdCurrent->safeCnt != 0) && (dbgSafeUnbreakable)));
  411.     }
  412. /******************************************************************************
  413. *
  414. * dbgTaskBpBreakpoint - generic task breakpoint handling
  415. *
  416. * This routines is the handler for breakpoints. It executes the actions
  417. * binded to the breakpoint (notify the host, notify the target, call a 
  418. * user's specified routine or stop the task).
  419. *
  420. * RETURNS : N/A.
  421. *
  422. * NOMANUAL
  423. */ 
  424. void dbgTaskBpBreakpoint
  425.     (
  426.     int level, /* level of interupt lock */
  427.     void * pInfo, /* pointer on info */
  428.     REG_SET * pRegisters, /* task registers before breakpoint exception */
  429.     void * pDbgRegs, /* pointer to debug registers */
  430.     BOOL hardware /* indicates if it is a hardware breakpoint */
  431.     )
  432.     {
  433.     BRKPT bpInfo; /* breakpoint info structure */
  434.     UINT32 type = 0; /* breakpoint type */
  435.     UINT32 addr; /* breakpoint address */
  436. #if !DBG_NO_SINGLE_STEP
  437.     /* If the os wants us to ignore the break point, then do so */
  438.     if (dbgBrkIgnoreDefault ())
  439. {
  440. dbgTaskDoIgnore (pRegisters);
  441. }
  442. #endif /* DBG_NO_SINGLE_STEP */
  443.     taskLock(); /* LOCK PREEMPTION */
  444.     intUnlock(level);
  445.     /*
  446.      * By default (software break point), the break point address is the
  447.      * pc of the task.
  448.      */
  449.     addr = (UINT32) pRegisters->reg_pc;
  450. #if DBG_HARDWARE_BP
  451.     /* If it is a hardware break point, update type and addr variable. */
  452.     if (hardware)
  453. wdbDbgHwBpFind (pDbgRegs, &type, &addr);
  454. #endif  /* DBG_HARDWARE_BP */
  455.     /* 
  456.      * Find in the break point list the one we have encountered and fill in the 
  457.      * bpInfo structure. 
  458.      */ 
  459.     wdbDbgBpGet ((INSTR *) addr, (int)taskIdCurrent, type, &bpInfo);
  460.     /* 
  461.      * On some CPU (eg I960CX), the hardware breakpoint exception is sent only
  462.      * after the instruction was executed. In that case, we consider that
  463.      * the breakpoint address is the address where the processor is stopped.
  464.      */
  465. #if DBG_HARDWARE_BP && defined (BRK_INST)
  466.     if (type == (BRK_INST | BRK_HARDWARE))
  467. addr = (UINT32) pRegisters->reg_pc;
  468. #endif /* DBG_HARDWARE_BP && defined (BRK_INST) */
  469.     /* 
  470.      * Remove ACTION_STOP action if task is unbreakable. This is usefull
  471.      * when two or more breakpoints are set at the same address, one with
  472.      * action stop specified and one without.
  473.      * XXX : this should be tested in wdbDbgBpGet() but in order to remove
  474.      * all OS references in this routine used by the standalone agent debugger,
  475.      * we can't check unbreakable flag in the task TCB.
  476.      */
  477.     if (taskIdCurrent->options & VX_UNBREAKABLE)
  478. bpInfo.bp_action &= ~WDB_ACTION_STOP;
  479.     /* store the break point address */
  480.     
  481.     DBG_INFO(taskIdCurrent)->bpAddr = addr;
  482.     /* check the action associated to the break point */
  483.     if (bpInfo.bp_action & WDB_ACTION_CALL)
  484. bpInfo.bp_callRtn (bpInfo.bp_callArg, pRegisters);
  485.     if (bpInfo.bp_action & WDB_ACTION_NOTIFY)
  486. {
  487. /* notify the host if the notify function pointer is initialised */
  488. if (_func_dbgHostNotify != NULL)
  489.     _func_dbgHostNotify (taskIdCurrent, pRegisters, addr);
  490. /* notify the target if the notify function pointer is initialised */
  491. if (_func_dbgTargetNotify != NULL)
  492.     _func_dbgTargetNotify (bpInfo.bp_flags, addr, pRegisters);
  493. }
  494. #if CPU_FAMILY == MIPS
  495.     /*
  496.      * On MIPS CPUs, when a breakpoint exception occurs in a branch delay slot,
  497.      * the PC has been changed in the breakpoint handler to match with the
  498.      * breakpoint address.
  499.      * Once the matching has been made, the PC is modified to have its normal
  500.      * value (the preceding jump instruction).
  501.      */
  502.     if (pRegisters->cause & CAUSE_BD) /* Are we in a branch delay slot ? */
  503.         pRegisters->reg_pc--;
  504. #endif /* CPU_FAMILY == MIPS */
  505.     if (bpInfo.bp_action & WDB_ACTION_STOP)
  506. {
  507. DBG_INFO(taskIdCurrent)->wdbRegisters = pRegisters;
  508. DBG_INFO(taskIdCurrent)->wdbState |= WDB_CLEANME; 
  509. taskUnlock(); /* UNLOCK PREEMPTION */
  510. for (;;)
  511.     taskSuspend((int)taskIdCurrent);
  512. }
  513.     /* !WDB_ACTION_STOP means continue (e.g., step over this break point) */
  514.     DBG_INFO(taskIdCurrent)->wdbState |= WDB_STEP_OVER;
  515.     wdbDbgBpRemoveAll();
  516. #if DBG_NO_SINGLE_STEP
  517.     taskNpc = wdbDbgGetNpc (pRegisters);
  518.     taskNpcInstr = *taskNpc;
  519.     usrBreakpointSet (taskNpc, DBG_BREAK_INST);
  520. #endif /* DBG_NO_SINGLE_STEP */
  521.     taskTraceData = wdbDbgTraceModeSet (pRegisters);
  522.     intLock();
  523.     /* Unlock task without rescheduling */
  524.     taskIdCurrent->lockCnt--;
  525.     
  526.     /* Indicate change of taskLock state to WindView */
  527.     
  528. #ifdef WV_INSTRUMENTATION
  529.     /* windview -level 3 event logging */
  530.     EVT_CTX_0 (EVENT_TASKUNLOCK);
  531.     /* windview -level 2 event logging */
  532.     EVT_TASK_1 (EVENT_OBJ_TASK, taskIdCurrent);
  533. #endif    
  534.     
  535.     WDB_CTX_LOAD (pRegisters);
  536.     }
  537. /******************************************************************************
  538. *
  539. * dbgTaskBpTrace - generic task trace (step) handling
  540. *
  541. * This routines is the handler for trace break point.
  542. *
  543. * RETURNS : N/A.
  544. *
  545. * NOMANUAL
  546. */ 
  547. void dbgTaskBpTrace
  548.     (
  549.     int level, /* level of interupt lock */
  550.     void * pInfo, /* pointer to info saved on stack */
  551.     REG_SET * pRegisters /* pointer to saved registers */
  552.     )
  553.     {
  554.     int  wdbState;
  555. #if !DBG_NO_SINGLE_STEP
  556.     if (isrTraceData != 0)
  557. dbgTaskDoneIgnore (pRegisters);
  558. #else /* DBG_NO_SINGLE_STEP */
  559.     usrBreakpointSet (taskNpc, taskNpcInstr);
  560. #endif /* !DBG_NO_SINGLE_STEP */
  561.     wdbDbgTraceModeClear (pRegisters, taskTraceData);
  562.     DBG_INFO(taskIdCurrent)->bpAddr = (UINT32) pRegisters->reg_pc;
  563.     if (DBG_INFO(taskIdCurrent)->wdbState & WDB_STEP_OVER)
  564. {
  565. DBG_INFO(taskIdCurrent)->wdbState &= ~WDB_STEP_OVER;
  566. dbgTaskBpInstall ((int)taskIdCurrent);
  567. WDB_CTX_LOAD (pRegisters);
  568. }
  569.     if ((DBG_INFO(taskIdCurrent)->wdbState & WDB_STEP_RANGE) &&
  570. (DBG_INFO(taskIdCurrent)->wdbEvtList.wdb1 <= 
  571.     (void *) pRegisters->reg_pc) && 
  572. ((void *) pRegisters->reg_pc < 
  573.     DBG_INFO(taskIdCurrent)->wdbEvtList.wdb2))
  574. {
  575. #if DBG_NO_SINGLE_STEP
  576. taskNpc = wdbDbgGetNpc(pRegisters);
  577. taskNpcInstr = *taskNpc;
  578. usrBreakpointSet (taskNpc, DBG_BREAK_INST);
  579. #endif /* DBG_NO_SINGLE_STEP */
  580. taskTraceData = wdbDbgTraceModeSet (pRegisters);
  581. WDB_CTX_LOAD (pRegisters);
  582. }
  583.     taskLock(); /* LOCK PREEMPTION */
  584.     intUnlock(level);
  585.     /* blindly assume WDB_STEP or WDB_STEP_RANGE was set */
  586.     wdbState = DBG_INFO(taskIdCurrent)->wdbState;
  587.     DBG_INFO(taskIdCurrent)->wdbState &= ~(WDB_STEP_TARGET | WDB_STEP_RANGE);
  588.     DBG_INFO(taskIdCurrent)->wdbRegisters = pRegisters;
  589.     DBG_INFO(taskIdCurrent)->wdbState |= WDB_CLEANME;
  590.     /* check if step was issued from target shell or WDB */
  591.     if ((wdbState & WDB_STEP_TARGET) == WDB_STEP_TARGET)
  592. {
  593. if (_func_dbgTargetNotify != NULL)
  594.     _func_dbgTargetNotify (BP_STEP, pRegisters->reg_pc, pRegisters);
  595. }
  596.     else
  597. {
  598. if (_func_dbgHostNotify != NULL)
  599.     _func_dbgHostNotify (taskIdCurrent, pRegisters, pRegisters->reg_pc);
  600. }
  601.     taskUnlock(); /* UNLOCK PREEMPTION */
  602.     for (;;)
  603. taskSuspend((int) taskIdCurrent);
  604.     }
  605. #if DBG_NO_SINGLE_STEP
  606. /******************************************************************************
  607. *
  608. * dbgTaskBpTrap - Trap handler.
  609. *
  610. * This routine handles bp's and trace's with one function if no trace mode
  611. *
  612. * RETURNS : N/A.
  613. *
  614. * NOMANUAL
  615. */ 
  616. void dbgTaskBpTrap
  617.     (
  618.     int level, /* level of interupt lock */
  619.     INSTR * addr, /* break point address */
  620.     void * pInfo, /* pointer on info */
  621.     REG_SET * pRegisters, /* task regs before break point exception */
  622.     void * pDbgRegs, /* pointer to debug register set */
  623.     BOOL hardware /* indicates if it is a hardware break point */
  624.     )
  625.     {
  626.     /* remove all break point */
  627.     wdbDbgBpRemoveAll ();
  628.     /* step from a break point we were forced to ignore (e.g., in an ISR)? */
  629.     if (isrTraceData != 0)
  630. {
  631. dbgTaskDoneIgnore (pRegisters);
  632. }
  633.     /* do we have to ignore this break point (e.g., it's in an ISR)? */
  634.     if (dbgBrkIgnoreDefault ())
  635. {
  636. dbgTaskDoIgnore (pRegisters);
  637. }
  638.     if (DBG_INFO(taskIdCurrent)->wdbState & WDB_STEPING)
  639. dbgTaskBpTrace (level, pInfo, pRegisters);
  640.     else
  641. dbgTaskBpBreakpoint (level, pInfo, pRegisters, pDbgRegs, hardware);
  642.     /* NOTREACHED */
  643.     }
  644. #endif /* DBG_NO_SINGLE_STEP */
  645. /******************************************************************************
  646. *
  647. * dbgTaskDoIgnore - ignore current BP by stepping over it
  648. *
  649. * This routine assumes break point are uninstalled and interrupts
  650. * are locked.
  651. *
  652. * RETURNS : N/A.
  653. *
  654. * NOMANUAL
  655. */ 
  656. LOCAL void dbgTaskDoIgnore
  657.     (
  658.     REG_SET * pRegs /* pointer to saved registers */
  659.     )
  660.     {
  661. #if DBG_NO_SINGLE_STEP
  662.     if (DBG_INFO(taskIdCurrent)->wdbState & WDB_STEPING)
  663. usrBreakpointSet (taskNpc, taskNpcInstr);
  664.     isrNpc = wdbDbgGetNpc (pRegs);
  665.     isrNpcInstr = *isrNpc;
  666.     usrBreakpointSet (isrNpc, DBG_BREAK_INST);
  667. #endif /* DBG_NO_SINGLE_STEP */
  668.     isrTraceData = wdbDbgTraceModeSet (pRegs);
  669.     WDB_CTX_LOAD (pRegs);
  670.     }
  671. /******************************************************************************
  672. *
  673. * dbgTaskDoneIgnore - the step over from "dbgTaskDoIgnore" has completed
  674. *
  675. * The step over from "dbgTaskDoIgnore" has completed. We can now clear 
  676. * trace mode and restore the task break point if we are not stepping.
  677. *
  678. * RETURNS : N/A.
  679. *
  680. * NOMANUAL
  681. */ 
  682. LOCAL void dbgTaskDoneIgnore
  683.     (
  684.     REG_SET * pRegs /* task registers before exception */
  685.     )
  686.     {
  687.     /* clear trace mode */
  688.     wdbDbgTraceModeClear (pRegs, isrTraceData);
  689.     /* we are no longer stepping from ISR */
  690.     isrTraceData = 0;
  691. #if DBG_NO_SINGLE_STEP
  692.     /* restore instructions */
  693.     usrBreakpointSet (isrNpc, isrNpcInstr);
  694.     if (DBG_INFO(taskIdCurrent)->wdbState & WDB_STEPING)
  695. {
  696. if (INT_CONTEXT())
  697.     usrBreakpointSet (taskNpc, DBG_BREAK_INST);
  698. else
  699.     DBG_INFO(taskIdCurrent)->wdbState &= ~WDB_STEPING;
  700. }
  701. #endif /* DBG_NO_SINGLE_STEP */
  702.     /* If we are not stepping, install break point for the current task */
  703.     if (!(DBG_INFO(taskIdCurrent)->wdbState & WDB_STEPING))
  704. dbgTaskBpInstall ((int)taskIdCurrent);
  705.     /* reload task context */
  706.     WDB_CTX_LOAD (pRegs);
  707.     }