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

VxWorks

开发平台:

C/C++

  1. /* wdbBpLib.c - Break point handling for the target server */
  2. /* Copyright 1994-2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01u,14sep01,jhw  Fixed warnings from compiling with gnu -pedantic flag
  7. 01t,16nov98,cdp  enable Thumb support for all ARM CPUs with ARM_THUMB==TRUE.
  8. 01v,21apr99,dbt  removed TEXT_LOCK() and TEXT_UNLOCK() calls in wdbHwBpAdd()
  9.  routine (SPR #26927).
  10. 01t,19jan99,elg  Restore PC for MIPS (SPR 24356)
  11. 01s,10jul98,dbt  test if task mode agent is running before stepping or
  12.                  continue a task.
  13. 01r,11may98,dbt  removed useless wdbTaskLock() and wdbTaskUnlock() calls in 
  14.  wdbSysBpLibInit().
  15. 01q,29apr98,dbt  code cleanup.
  16. 01p,21apr98,dbt  fixed Thumb (ARM7TDMI_T) support.
  17. 01o,11jul97,cdp  added Thumb (ARM7TDMI_T) support.
  18. 01n,09mar98,dbt  fixed a problem with WDB_TASK_LOCK() and WDB_TASK_UNLOCK()
  19.                  defines.
  20. 01m,13feb98,dbt  fixed typo in wdbBpLibInit().
  21. 01l,26jan98,dbt  replaced wdbEventClassConnect() with wdbEvtptClassConnect().
  22.  replaced WDB_EVT_CLASS with WDB_EVTPT_CLASS
  23. 01k,05dec97,dbt  merge with target shell debugger. Added support for hardware
  24.  breakpoints.
  25. 01j,28aug96,tam  modified wdbCont() to fix SPR 7098.
  26. 01k,15jul96,ms   fixed problem with trace mode
  27. 01j,26jun96,ms   added target side code to support windview "e" command.
  28.  removed redundant call to wdbBpRemove().
  29.  2nd paramter to eventpoint call func is now a REG_SET *.
  30. 01i,03jun96,kkk  replaced _sigCtxLoad with WDB_CTX_LOAD.
  31.  replaced pRegister->pc with pRegister->reg_pc.
  32. 01h,24apr96,ms   support generalized eventPoint handling.
  33.  support multiple breakpoints at same address.
  34.  lots of cleanup.
  35. 01g,23jan96,tpr  added cast to compile with DIAB DATA toolkit.
  36. 01f,21sep95,ms   unprotect mem before check for valid BP address (SPR 4935)
  37. 01e,17jul95,ms  changed the boundry test on STEP_RANGE
  38. 01d,03jun95,ms  deleting BP id = -1 means remove all breapoints.
  39. 01c,01jun95,ms  check for WDB_CTX_ANY_TASK on BP add.
  40.  do a memProbe on BP add.
  41.  don't add task BP's in system mode.
  42.  deactivate system BP's when in task mode.
  43.  some cleanup.
  44. 01b,28mar95,ms  wdbBpAdd now uses contextType to determine task vs system BP.
  45. 01a,02nov94,rrr  written.
  46. */
  47. /*
  48. DESCPRIPTION
  49. This library contains break point handling for system mode debugging.
  50. It also contains code which is shared with wdbTaskBpLib.c.
  51. */
  52. /* includes */
  53. #include "vxWorks.h"
  54. #include "string.h"
  55. #include "regs.h"
  56. #include "wdb/wdb.h"
  57. #include "wdb/dll.h"
  58. #include "wdb/wdbLibP.h"
  59. #include "wdb/wdbLib.h"
  60. #include "wdb/wdbBpLib.h"
  61. #include "wdb/wdbSvcLib.h"
  62. #include "wdb/wdbEvtLib.h"
  63. #include "wdb/wdbEvtptLib.h"
  64. #include "wdb/wdbArchIfLib.h"
  65. #include "wdb/wdbDbgLib.h"
  66. /* externals */
  67. extern WDB_IU_REGS wdbExternSystemRegs;
  68. extern BOOL wdbOneShot;
  69. #if DBG_NO_SINGLE_STEP
  70. extern FUNCPTR  _func_trap;
  71. #else /* DBG_NO_SINGLE_STEP */
  72. extern FUNCPTR  _func_breakpoint;
  73. extern FUNCPTR  _func_trace;
  74. #endif /* DBG_NO_SINGLE_STEP */
  75. extern FUNCPTR  _func_wdbIsNowExternal;
  76. /* defines */
  77. #if     CPU_FAMILY==MC680X0
  78. #undef reg_pc
  79. #define reg_pc regSet.pc
  80. #undef reg_sp
  81. #define reg_sp regSet.addrReg[7]
  82. #undef reg_fp
  83. #define reg_fp regSet.addrReg[6]
  84. #endif  /* CPU_FAMILY==MC680X0 */
  85. /* globals */
  86. UINT32  (*_wdbTaskBpAdd) (WDB_EVTPT_ADD_DESC * pEv);
  87. UINT32  (*_wdbTaskStep) (UINT32 contextId, TGT_ADDR_T startAddr,
  88. TGT_ADDR_T endAddr);
  89. UINT32  (*_wdbTaskCont)         (UINT32 contextId); 
  90. #if DBG_NO_SINGLE_STEP
  91. void    (*_wdbTaskBpTrap)       (int level, INSTR * addr, void * pInfo, 
  92.     WDB_IU_REGS * pRegisters, void * pDbgRegs, 
  93.     BOOL hardware);
  94. #else /* DBG_NO_SINGLE_STEP */
  95. void    (*_wdbTaskBpBreakpoint) (int level, void * pInfo, 
  96.     WDB_IU_REGS * pRegisters, void * pDbgRegs,
  97.     BOOL hardware);
  98. void    (*_wdbTaskBpTrace)      (int level, void * pInfo, 
  99.     WDB_IU_REGS * pRegisters);
  100. #endif /* DBG_NO_SINGLE_STEP */
  101. /* locals */
  102. static int wdbBpData; /* store breakpoint informations */
  103. static UINT32 wdbBpAddr; /* store the address of the last */
  104. /* encountered breakpoint */
  105. static int wdbSysBpMode; /* mode of the system context */
  106. static INSTR * wdbSysStepStart; /* start address of step range */
  107. static INSTR * wdbSysStepEnd; /* end address of step range */
  108. #if DBG_NO_SINGLE_STEP
  109. static INSTR * wdbSysNpc;
  110. static INSTR wdbSysNpcInstr;
  111. #endif /* DBG_NO_SINGLE_STEP */
  112. static WDB_EVT_NODE eventSysBpNode; /* system mode breakpoint event node */
  113. static WDB_EVTPT_CLASS wdbEventClassBp;/* breakpoint event class */
  114. #if DBG_HARDWARE_BP
  115. static WDB_EVTPT_CLASS wdbEventClassHwBp;/* hardware breakpoint event class */
  116. #endif /* DBG_HARDWARE_BP */
  117. /* forward static declarations */
  118. static UINT32 wdbStep (WDB_CTX_STEP_DESC * pCtxStep);
  119. static UINT32 wdbCont (WDB_CTX * ctx);
  120. static UINT32 wdbBpAdd (WDB_EVTPT_ADD_DESC * pBp, UINT32 * pId);
  121. static UINT32 wdbBpDelete (TGT_ADDR_T *pId);
  122. static void wdbSysBpEventGet (void * arg, WDB_EVT_DATA * pEventMsg);
  123. static void wdbTrace (int level, void * pInfo, 
  124.     WDB_IU_REGS * pRegisters);
  125. static void wdbBreakpoint (int level, void * pInfo, 
  126.     WDB_IU_REGS * pRegisters, void * pDbgRegs, 
  127.     BOOL hardware);
  128. static void wdbSysBpPost (int addr);
  129. static void wdbTaskLock (void);
  130. static void wdbTaskUnlock (void);
  131. #if DBG_HARDWARE_BP
  132. static UINT32 wdbHwBpAdd (WDB_EVTPT_ADD_DESC * pBp, UINT32 * pId);
  133. #endif /* DBG_HARDWARE_BP */
  134. #if DBG_NO_SINGLE_STEP
  135. static void wdbTrap (int level, INSTR * addr, void * pInfo, 
  136.     WDB_IU_REGS * pRegisters, void * pDbgRegs, 
  137.     BOOL hardware);
  138. #endif /* DBG_NO_SINGLE_STEP */
  139. /******************************************************************************
  140. *
  141. * wdbSysBpLibInit - initialize the library.
  142. *
  143. * This routine initializes the agent debugger library : wdb services,
  144. * breakpoint lists, event nodes and some pointers used by the debugger.
  145. *
  146. * RETURNS : N/A 
  147. * NOMANUAL
  148. */
  149. void wdbSysBpLibInit
  150.     (
  151.     BRKPT * pBps, /* pointer on breakpoint structure */
  152.     int bpCnt /* number of breakpoints */
  153.     )
  154.     {
  155.     static int wdbBpInstalled = FALSE;
  156.     if (!wdbBpInstalled)
  157. {
  158. wdbSvcAdd (WDB_CONTEXT_STEP, wdbStep, xdr_WDB_CTX_STEP_DESC, xdr_void);
  159. wdbSvcAdd (WDB_CONTEXT_CONT, wdbCont, xdr_WDB_CTX, xdr_void);
  160. wdbEventClassBp.evtptType = WDB_EVT_BP;
  161. wdbEventClassBp.evtptAdd = wdbBpAdd;
  162. wdbEventClassBp.evtptDel = wdbBpDelete;
  163. wdbEvtptClassConnect (&wdbEventClassBp);
  164. #if DBG_HARDWARE_BP
  165. wdbEventClassHwBp.evtptType = WDB_EVT_HW_BP;
  166. wdbEventClassHwBp.evtptAdd = wdbHwBpAdd;
  167. wdbEventClassHwBp.evtptDel = wdbBpDelete;
  168. wdbEvtptClassConnect (&wdbEventClassHwBp);
  169. #endif /* DBG_HARDWARE_BP */
  170. #if DBG_NO_SINGLE_STEP
  171. _func_trap = (FUNCPTR) wdbTrap;
  172. #else   /* DBG_NO_SINGLE_STEP */
  173. _func_breakpoint = (FUNCPTR) wdbBreakpoint;
  174. _func_trace = (FUNCPTR) wdbTrace;
  175. #endif  /* DBG_NO_SINGLE_STEP */
  176. _func_wdbIsNowExternal = (FUNCPTR) wdbIsNowExternal;
  177. wdbDbgBpListInit();
  178. while (bpCnt)
  179.     {
  180.     dll_insert (&pBps->bp_chain, &bpFreeList);
  181.     ++pBps;
  182.     --bpCnt;
  183.     }
  184. wdbDbgArchInit();
  185. wdbEventNodeInit (&eventSysBpNode, wdbSysBpEventGet, NULL, 
  186. (void *) &eventSysBpNode);
  187. wdbBpInstalled = TRUE;
  188. }
  189.     }
  190. /******************************************************************************
  191. *
  192. * wdbBpInstall - install system mode breakpoints.
  193. *
  194. * Before the external agent transfers control back to the OS, this routine
  195. * is called to reinsert the breakpoints.
  196. * RETURNS : N/A
  197. *
  198. * NOMANUAL
  199. */ 
  200. void wdbBpInstall (void)
  201.     {
  202.     dll_t * pDll;
  203. #if DBG_HARDWARE_BP
  204.     DBG_REGS dbgRegs;
  205. #endif /* DBG_HARDWARE_BP */
  206.     /* don't install system BP's if we are not in system mode */
  207.     if (wdbIsNowTasking())
  208. return;
  209. #if DBG_HARDWARE_BP
  210.     memset (&dbgRegs, 0, sizeof (DBG_REGS));
  211.     wdbDbgRegsClear (); /* clean debug registers */
  212. #endif /* DBG_HARDWARE_BP */
  213.     /* if stepping, just set trace mode */
  214.     if (wdbSysBpMode != 0)
  215. {
  216. #if DBG_NO_SINGLE_STEP
  217. wdbSysNpc = wdbDbgGetNpc (&wdbExternSystemRegs);
  218. wdbSysNpcInstr = *wdbSysNpc;
  219. usrBreakpointSet (wdbSysNpc, DBG_BREAK_INST);
  220. #endif /* DBG_NO_SINGLE_STEP */
  221. wdbBpData = wdbDbgTraceModeSet ((REG_SET *) &wdbExternSystemRegs);
  222. }
  223.     else /* if not stepping, insert breakpoints */
  224. {
  225. for (pDll = dll_head(&bpList); pDll != dll_end(&bpList);
  226. pDll = dll_next(pDll))
  227.     {
  228.     if (BP_BASE(pDll)->bp_task ==  -1)
  229. {
  230. if ((BP_BASE(pDll)->bp_flags & BRK_HARDWARE) == 0)
  231.     usrBreakpointSet (BP_BASE(pDll)->bp_addr, DBG_BREAK_INST);
  232. #if DBG_HARDWARE_BP
  233. else
  234.     wdbDbgHwBpSet (&dbgRegs, 
  235.    BP_BASE(pDll)->bp_flags & BRK_HARDMASK, 
  236.    (UINT32) BP_BASE(pDll)->bp_addr);
  237. #endif /* DBG_HARDWARE_BP */
  238. BP_BASE(pDll)->bp_flags |= BP_INSTALLED;
  239. }
  240.     }
  241. #if DBG_HARDWARE_BP
  242. wdbDbgRegsSet (&dbgRegs); /* set debug registers. */
  243. #endif /* DBG_HARDWARE_BP */
  244. }
  245.     }
  246. /******************************************************************************
  247. *
  248. * wdbSysBpEventGet - upload a breakpoint event to the host.
  249. *
  250. * This routine upload a system breakpoint event to the host.
  251. *
  252. * RETURNS : N/A
  253. *
  254. * NOMANUAL
  255. */ 
  256. static void wdbSysBpEventGet
  257.     (
  258.     void *    pRegs,
  259.     WDB_EVT_DATA * pEvtData
  260.     )
  261.     {
  262.     WDB_BP_INFO * pBpInfo = (WDB_BP_INFO *)&pEvtData->eventInfo;
  263.     if ((TGT_ADDR_T) wdbExternSystemRegs.reg_pc != wdbBpAddr)
  264. {
  265. /* It should be a watch point */
  266. pEvtData->evtType = WDB_EVT_WP;
  267. pBpInfo->numInts = 6;
  268. pBpInfo->addr  = wdbBpAddr;
  269. }
  270.     else
  271. {
  272. /* It should be a break point */
  273. pEvtData->evtType    = WDB_EVT_BP;
  274. pBpInfo->numInts = 5;
  275. }
  276.     /* fill WDB_BP_INFO structure */
  277.     pBpInfo->context.contextType = WDB_CTX_SYSTEM;
  278.     pBpInfo->context.contextId  = -1;
  279.     pBpInfo->pc = (TGT_ADDR_T) wdbExternSystemRegs.reg_pc;
  280.     pBpInfo->fp = (TGT_ADDR_T) wdbExternSystemRegs.reg_fp;
  281.     pBpInfo->sp = (TGT_ADDR_T) wdbExternSystemRegs.reg_sp;
  282.     }
  283. /******************************************************************************
  284. *
  285. * wdbSysBpPost - post system mode breakpoint event  
  286. *
  287. * This routine posts an event to the host when a system mode breakpoint
  288. * is hit. It is called when the system is suspended.
  289. *
  290. * RETURNS : N/A
  291. *
  292. * NOMANUAL
  293. */ 
  294. static void wdbSysBpPost
  295.     (
  296.     int addr /* breakpoint addr */
  297.     )
  298.     {
  299.     wdbEventPost (&eventSysBpNode);
  300.     }
  301. /*******************************************************************************
  302. *
  303. * wdbStep - Handle a step request
  304. *
  305. * The wdbStep() function is used to step the system or a task.
  306. *
  307. * NOMANUAL
  308. */
  309. static UINT32 wdbStep
  310.     (
  311.     WDB_CTX_STEP_DESC * pCtxt
  312.     )
  313.     {
  314.     switch (pCtxt->context.contextType)
  315. {
  316. case WDB_CTX_SYSTEM:
  317.     if (!wdbIsNowExternal())
  318. return (WDB_ERR_AGENT_MODE);
  319.     if ((pCtxt->startAddr == 0) && (pCtxt->endAddr == 0))
  320. wdbSysBpMode = WDB_STEP;
  321.     else
  322. {
  323. wdbSysBpMode = WDB_STEP_RANGE;
  324. wdbSysStepStart = (INSTR *) pCtxt->startAddr;
  325. wdbSysStepEnd = (INSTR *) pCtxt->endAddr;
  326. }
  327.     wdbOneShot = TRUE;
  328.     return (WDB_OK);
  329. case WDB_CTX_TASK:
  330.     if (!wdbIsNowTasking())
  331. return (WDB_ERR_AGENT_MODE);
  332.     if (_wdbTaskStep != NULL)
  333. return ((*_wdbTaskStep) (pCtxt->context.contextId, 
  334.  pCtxt->startAddr, 
  335.  pCtxt->endAddr));
  336.     return (WDB_ERR_NO_RT_PROC);
  337. default:
  338.     return (WDB_ERR_INVALID_CONTEXT);
  339. }
  340.     }
  341. /*******************************************************************************
  342. *
  343. * wdbCont - Handle a continue request
  344. *
  345. * The wdbCont() function is used to continue the system or a task.
  346. *
  347. * NOMANUAL
  348. */
  349. static UINT32 wdbCont
  350.     (
  351.     WDB_CTX * pCtxt
  352.     )
  353.     {
  354.     switch (pCtxt->contextType)
  355. {
  356. case WDB_CTX_SYSTEM:
  357.     if (!wdbIsNowExternal())
  358. return (WDB_OK);
  359.     /* 
  360.      * Check for breakpoint at extern system pc or wdbBpAddr 
  361.      * (last breakpoint address). This last test is usefull for
  362.      * data breakpoints.
  363.      */
  364.     if ((wdbDbgBpFind 
  365. ((INSTR *) wdbExternSystemRegs.reg_pc, BP_SYS) == OK) ||
  366.          (wdbDbgBpFind ((INSTR *) wdbBpAddr, BP_SYS) == OK))
  367. {
  368.      wdbSysBpMode = WDB_STEP_OVER;
  369. }
  370.     wdbOneShot = TRUE;
  371.     return (WDB_OK);
  372. case WDB_CTX_TASK:
  373.     if (!wdbIsNowTasking())
  374. return (WDB_ERR_AGENT_MODE);
  375.     if (_wdbTaskCont != NULL)
  376. return ((*_wdbTaskCont) (pCtxt->contextId));
  377.     return (WDB_ERR_NO_RT_PROC);
  378. default:
  379.     return (WDB_ERR_INVALID_CONTEXT);
  380. }
  381.     }
  382. /*******************************************************************************
  383. *
  384. * wdbBpAdd - Handle a break point add request
  385. *
  386. * The wdbBpAdd() function is used to add break points from the agent.
  387. *
  388. * NOMANUAL
  389. */
  390. static UINT32 wdbBpAdd
  391.     (
  392.     WDB_EVTPT_ADD_DESC * pBreakPoint,
  393.     UINT32 * pId
  394.     )
  395.     {
  396.     INSTR val;
  397.     BRKPT * pBp;
  398.     INSTR * addr;
  399.     switch (pBreakPoint->numArgs)
  400. {
  401. default:
  402. case 1:
  403. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  404.     addr = (INSTR *) ((UINT32)((pBreakPoint->args[0]) & ~1));
  405. #else /* CPU_FAMILY == ARM */
  406.     addr = (INSTR *) pBreakPoint->args[0];
  407. #endif /* CPU_FAMILY == ARM */
  408.     break;
  409. case 0:
  410.     return (WDB_ERR_INVALID_PARAMS);
  411. }
  412.     /* check validity of breakpoint address */
  413.     TEXT_UNLOCK(addr);
  414.     if (((*pWdbRtIf->memProbe) ((char *)addr, VX_READ,
  415. sizeof(INSTR), (char *)&val) != OK) ||
  416.         ((*pWdbRtIf->memProbe) ((char *)addr, VX_WRITE,
  417. sizeof(INSTR), (char *)&val) != OK))
  418. {
  419. TEXT_LOCK(addr);
  420.         return (WDB_ERR_MEM_ACCES);
  421. }
  422.     TEXT_LOCK(addr);
  423.     /* check the agent mode */
  424.     switch (pBreakPoint->context.contextType)
  425. {
  426. case WDB_CTX_SYSTEM:
  427.     if (!wdbIsNowExternal())
  428. return (WDB_ERR_AGENT_MODE);
  429.     break;
  430. default:
  431.     if (!wdbIsNowTasking())
  432. return (WDB_ERR_AGENT_MODE);
  433. }
  434.     if (dll_empty (&bpFreeList))
  435. return (WDB_ERR_EVENTPOINT_TABLE_FULL);
  436.     wdbTaskLock (); /* disable task switching */
  437.     pBp = BP_BASE(dll_tail (&bpFreeList));
  438.     dll_remove (&pBp->bp_chain);
  439.     wdbTaskUnlock (); /* re-enable task switching */
  440.     pBp->bp_flags = BP_HOST;
  441.     pBp->bp_addr = addr;
  442.     pBp->bp_action = pBreakPoint->action.actionType;
  443. #if ((CPU_FAMILY == ARM) && ARM_THUMB)
  444.     pBp->bp_callRtn = (void (*)())((UINT32)pBreakPoint->action.callRtn | 1);
  445. #else /* CPU_FAMILY == ARM */
  446.     pBp->bp_callRtn = (void (*)())pBreakPoint->action.callRtn;
  447. #endif /* CPU_FAMILY == ARM */
  448.     pBp->bp_callArg = pBreakPoint->action.callArg;
  449.     pBp->bp_instr = *(INSTR *)addr;
  450.     if (pBreakPoint->numArgs > 1) /* second argument is count */
  451.     pBp->bp_count = pBreakPoint->args[1];
  452.     else
  453.     pBp->bp_count = 0;
  454.     /* XXX - hack because host tools pass wrong info */
  455.     if ((pBp->bp_action == 0) || (pBp->bp_action == WDB_ACTION_STOP))
  456. pBp->bp_action = WDB_ACTION_STOP | WDB_ACTION_NOTIFY;
  457.     /* set the context ID */
  458.     switch (pBreakPoint->context.contextType)
  459.         {
  460.         case WDB_CTX_SYSTEM:
  461.     pBp->bp_task = BP_SYS;
  462.             break;
  463.         case WDB_CTX_ANY_TASK:
  464.     pBp->bp_task = BP_ANY_TASK;
  465.             break;
  466.         case WDB_CTX_TASK:
  467.         default:
  468.     pBp->bp_task = pBreakPoint->context.contextId;
  469.         }
  470.     wdbTaskLock (); /* disable task switching */
  471.     dll_insert(&pBp->bp_chain, &bpList);
  472.     wdbTaskUnlock (); /* re-enable task switching */
  473.     if (pBreakPoint->context.contextType != WDB_CTX_SYSTEM)
  474. if (_wdbTaskBpAdd != NULL)
  475.     _wdbTaskBpAdd (pBreakPoint);
  476.     *pId = (UINT32)pBp;
  477.     return (WDB_OK);
  478.     }
  479. #if DBG_HARDWARE_BP
  480. /*******************************************************************************
  481. *
  482. * wdbHwBpAdd - Handle a hardware break point add request
  483. *
  484. * The wdbBpAdd() function is used to add break points form the agent.
  485. *
  486. * NOMANUAL
  487. */
  488. static UINT32 wdbHwBpAdd
  489.     (
  490.     WDB_EVTPT_ADD_DESC * pBreakPoint, /* breakpoint to add */
  491.     UINT32 * pId /* breakpoint ID */
  492.     )
  493.     {
  494.     BRKPT * pBp;
  495.     dll_t * pDll;
  496.     int status;
  497.     DBG_REGS dbgRegs; /* debug registers */
  498.     int contextId; /* context ID */
  499.     UINT32 addr; /* breakpoint address */
  500.     UINT32 count = 0; /* breakpoint count */
  501.     int type = DEFAULT_HW_BP; /* hardware type */
  502.     switch (pBreakPoint->numArgs)
  503. {
  504. default:
  505. case 3:
  506.     type = pBreakPoint->args[2];
  507.     /* FALL THROUGH */
  508. case 2:
  509.     count = pBreakPoint->args[1];
  510.     /* FALL THROUGH */
  511. case 1:
  512.     addr = pBreakPoint->args[0];
  513.     break;
  514. case 0:
  515.     return (WDB_ERR_INVALID_PARAMS);
  516. }
  517.     /* check validity of hardware breakpoint address */
  518.     if (wdbDbgHwAddrCheck (addr, type, (FUNCPTR) pWdbRtIf->memProbe) != OK)
  519.         return (WDB_ERR_MEM_ACCES);
  520.     /* check the agent mode */
  521.     switch (pBreakPoint->context.contextType)
  522. {
  523. case WDB_CTX_SYSTEM:
  524.     if (!wdbIsNowExternal())
  525. return (WDB_ERR_AGENT_MODE);
  526.     break;
  527. default:
  528.     if (!wdbIsNowTasking())
  529. return (WDB_ERR_AGENT_MODE);
  530. }
  531.     /* set the context ID */
  532.     switch (pBreakPoint->context.contextType)
  533.         {
  534.         case WDB_CTX_SYSTEM:
  535.             contextId = BP_SYS;
  536.             break;
  537.         case WDB_CTX_ANY_TASK:
  538.             contextId = BP_ANY_TASK;
  539.             break;
  540.         case WDB_CTX_TASK:
  541.         default:
  542.             contextId = pBreakPoint->context.contextId;
  543.         }
  544.     /* clean dbgRegs structure */
  545.     memset (&dbgRegs, 0, sizeof (DBG_REGS));
  546.     /* fill dbgRegs structure with all hardware breakpoints */
  547.     wdbTaskLock (); /* disable task switching */
  548.     for (pDll = dll_head(&bpList); pDll != dll_end(&bpList);
  549. pDll = dll_next(pDll))
  550. {
  551. pBp = BP_BASE(pDll);
  552. /* check if found breakpoint is applicable to new breakpoint context */
  553. if (((contextId == BP_SYS) && (pBp->bp_task == BP_SYS)) ||
  554. ((contextId == BP_ANY_TASK) && (pBp->bp_task != BP_SYS)) ||
  555. ((contextId != BP_SYS) && (pBp->bp_task == BP_ANY_TASK)))
  556.     {
  557.     if (pBp->bp_flags & BRK_HARDWARE)
  558. {
  559. if ((status = wdbDbgHwBpSet (&dbgRegs, 
  560. pBp->bp_flags & BRK_HARDMASK, 
  561. (UINT32) pBp->bp_addr)) != OK)
  562.     {
  563.     wdbTaskUnlock (); /* re-enable task switching */
  564.     return (status);
  565.     }
  566. }
  567.     }
  568. }
  569.     wdbTaskUnlock (); /* re-enable task switching */
  570.     if ((status = wdbDbgHwBpSet (&dbgRegs, type, addr)) != OK)
  571. return (status);
  572.     if (dll_empty (&bpFreeList))
  573. return (WDB_ERR_EVENTPOINT_TABLE_FULL);
  574.     wdbTaskLock (); /* disable task switching */
  575.     pBp = BP_BASE(dll_tail (&bpFreeList));
  576.     dll_remove (&pBp->bp_chain);
  577.     wdbTaskUnlock (); /* re-enable task switching */
  578.     pBp->bp_flags = BP_HOST | type | BRK_HARDWARE;
  579.     pBp->bp_addr = (INSTR *)addr;
  580.     pBp->bp_action = pBreakPoint->action.actionType;
  581.     pBp->bp_count = count;
  582.     pBp->bp_callRtn = (void (*)())pBreakPoint->action.callRtn;
  583.     pBp->bp_callArg = pBreakPoint->action.callArg;
  584.     pBp->bp_task = contextId;
  585.     /* 
  586.      * XXX - MS hack because host tools pass wrong info.
  587.      * XXX - DBT This has been corrected in tornado 2.0 host tools but we
  588.      * must keep this hack for backward compatibility.
  589.      */
  590.     if ((pBp->bp_action == 0) || (pBp->bp_action == WDB_ACTION_STOP))
  591. pBp->bp_action = WDB_ACTION_STOP | WDB_ACTION_NOTIFY;
  592.     wdbTaskLock (); /* disable task switching */
  593.     dll_insert(&pBp->bp_chain, &bpList);
  594.     wdbTaskUnlock (); /* re-enable task switching */
  595.     if (pBreakPoint->context.contextType != WDB_CTX_SYSTEM)
  596. if (_wdbTaskBpAdd != NULL)
  597.     _wdbTaskBpAdd (pBreakPoint);
  598.     *pId = (UINT32)pBp;
  599.     return (WDB_OK);
  600.     }
  601. #endif /* DBG_HARDWARE_BP */
  602. /*******************************************************************************
  603. *
  604. * wdbBpDelete - Handle a break point delete request
  605. *
  606. * The wdbBpDelete() function is used to delete break points.
  607. *
  608. * NOMANUAL
  609. */
  610. static UINT32 wdbBpDelete
  611.     (
  612.     TGT_ADDR_T * pId
  613.     )
  614.     {
  615.     dll_t * pDll;
  616.     dll_t * pNextDll;
  617.     BRKPT * pBp;
  618.     pBp = *(BRKPT **) pId;
  619.     /* 
  620.      * Breakpoint ID of -1 means remove all breakpoints. 
  621.      * We can only remove breakpoints set by the host tools. Breakpoints
  622.      * set from target shell can't be removed
  623.      */
  624.     wdbTaskLock (); /* disable task switching */
  625.     if ((int ) pBp == -1)
  626. {
  627. for (pDll = dll_head(&bpList);
  628.      pDll != dll_end(&bpList);
  629.      pDll = pNextDll)
  630.     {
  631.     pNextDll = dll_next(pDll);
  632.     if (BP_BASE(pDll)->bp_flags & BP_HOST)
  633. wdbDbgBpRemove (BP_BASE(pDll));
  634.     }
  635. wdbTaskUnlock (); /* re-enable task switching */
  636. return (WDB_OK);
  637. }
  638.     /* else just remove one breakpoint */
  639.     for (pDll = dll_head(&bpList); pDll != dll_end(&bpList);
  640.     pDll = dll_next(pDll))
  641. {
  642. if (BP_BASE(pDll) == pBp)
  643.     {
  644.     wdbDbgBpRemove (pBp);
  645.     wdbTaskUnlock (); /* re-enable task switching */
  646.     return (WDB_OK);
  647.     }
  648. }
  649.     wdbTaskUnlock (); /* re-enable task switching */
  650.     return (WDB_ERR_INVALID_EVENTPOINT);
  651.     }
  652.  
  653. #if DBG_NO_SINGLE_STEP
  654. /*******************************************************************************
  655. *
  656. * wdbTrap - handle hitting of breakpoint
  657. *
  658. * This routine handles the breakpoint trap.  It is called only from its 
  659. * special stub routine (usually in assembly language) which is connected
  660. * to the breakpoint trap. It is used by targets that have to multiplex
  661. * tracing and breakpoint.
  662. *
  663. * NOMANUAL
  664. */
  665. static void wdbTrap
  666.     (
  667.     int level,
  668.     INSTR * addr,
  669.     void * pInfo,
  670.     WDB_IU_REGS * pRegisters,
  671.     void * pDbgRegs,
  672.     BOOL hardware
  673.     )
  674.     {
  675.     /* check for task level breakpoint trap */
  676.     if (wdbIsNowTasking())
  677. {
  678. _wdbTaskBpTrap (level, (INSTR *) pRegisters->reg_pc, pInfo, pRegisters, 
  679.     pDbgRegs, hardware);
  680. /* NOTREACHED */
  681. }
  682.     /* first handle "step mode" (trace emulation) */
  683.     if (wdbSysBpMode != 0)
  684. {
  685. wdbTrace (level, pInfo, pRegisters);
  686. /* NOTREACHED */
  687. }
  688.     /* must be a system level breakpoint */
  689.     wdbDbgBpRemoveAll (); /* remove all breakpoints */
  690.     wdbBreakpoint (level, pInfo, pRegisters, pDbgRegs, hardware);
  691.     /* NOTREACHED */
  692.     }
  693. #endif /* DBG_NO_SINGLE_STEP */
  694. /*******************************************************************************
  695. *
  696. * wdbTrace - handle trace exception
  697. *
  698. * This routine handles the trace trap.  It is called only
  699. * from its special assembly language stub routine which is connected
  700. * to the trace trap.
  701. *
  702. * NOMANUAL
  703. */
  704. static void wdbTrace
  705.     (
  706.     int level,
  707.     void * pInfo,
  708.     WDB_IU_REGS * pRegisters
  709.     )
  710.     {
  711. #if !DBG_NO_SINGLE_STEP
  712.     /* check for task level breakpoint trace */
  713.     if (wdbIsNowTasking())
  714. {
  715. _wdbTaskBpTrace (level, pInfo, pRegisters);
  716. /* NOTREACHED */
  717. }
  718. #else /* !DBG_NO_SINGLE_STEP */
  719.     usrBreakpointSet (wdbSysNpc, wdbSysNpcInstr);
  720. #endif /* DBG_NO_SINGLE_STEP */
  721.     /* system mode step */
  722.     wdbDbgTraceModeClear ((REG_SET *) pRegisters, wdbBpData);
  723.     wdbBpAddr = (TGT_ADDR_T) pRegisters->reg_pc; /* update wdbBpAddr */
  724.     if (wdbSysBpMode == WDB_STEP_OVER)
  725. {
  726. wdbSysBpMode = 0;
  727. wdbBpInstall ();
  728. WDB_CTX_LOAD (pRegisters);
  729. /* NOTREACHED */
  730. }
  731.     if ((wdbSysBpMode == WDB_STEP_RANGE) &&
  732.    (wdbSysStepStart <= (INSTR *) wdbBpAddr) &&
  733.        ((INSTR * ) wdbBpAddr < wdbSysStepEnd))
  734. {
  735. #if DBG_NO_SINGLE_STEP
  736. wdbSysNpc = wdbDbgGetNpc (pRegisters);
  737. wdbSysNpcInstr = *wdbSysNpc;
  738. usrBreakpointSet (wdbSysNpc, DBG_BREAK_INST);
  739. #endif /* DBG_NO_SINGLE_STEP */
  740. wdbBpData = wdbDbgTraceModeSet((REG_SET *) pRegisters);
  741. WDB_CTX_LOAD (pRegisters);
  742. /* NOTREACHED */
  743. }
  744.     /* blindly assume WDB_STEP */
  745.     wdbSysBpMode = 0;
  746.     wdbSuspendSystem (pRegisters, wdbSysBpPost, 0);
  747.     /* NOTREACHED */
  748.     }
  749. /*******************************************************************************
  750. *
  751. * wdbBreakpoint - handle hitting of breakpoint
  752. *
  753. * This routine handles the breakpoint trap.  It is called only from its 
  754. * special stub routine (usually in assembly language) which is connected
  755. * to the breakpoint trap.
  756. *
  757. * NOMANUAL
  758. */
  759. static void wdbBreakpoint
  760.     (
  761.     int level,
  762.     void * pInfo,
  763.     WDB_IU_REGS * pRegisters,
  764.     void * pDbgRegs,
  765.     BOOL hardware
  766.     )
  767.     {
  768.     BRKPT bpInfo; /* breakpoint info structure */
  769.     UINT32 type = 0; /* breakpoint type */
  770.     void  (*callBack)() = NULL;
  771. #if !DBG_NO_SINGLE_STEP
  772.     /* check for task level breakpoint trap */
  773.     if (wdbIsNowTasking())
  774. {
  775. _wdbTaskBpBreakpoint (level, pInfo, pRegisters, pDbgRegs, hardware);
  776. /* NOTREACHED */
  777. }
  778. #endif /* !DBG_NO_SINGLE_STEP */
  779.     wdbBpAddr = (UINT32) pRegisters->reg_pc;
  780. #if DBG_HARDWARE_BP
  781.     /* If it is a hardware breakpoint, update type and addr variable. */
  782.     if (hardware)
  783. wdbDbgHwBpFind (pDbgRegs, &type, &wdbBpAddr);
  784. #endif  /* DBG_HARDWARE_BP */
  785.     /* must be a system level breakpoint */
  786.     wdbDbgBpGet ((INSTR *)wdbBpAddr, BP_SYS, type, &bpInfo);
  787.     /* 
  788.      * On some CPU (eg I960CX), the hardware breakpoint exception is sent only
  789.      * after the instruction was executed. In that case, we consider that
  790.      * the breakpoint address is the address where the processor is stopped,
  791.      * not the real breakpoint address.
  792.      */
  793. #if DBG_HARDWARE_BP && defined (BRK_INST)
  794.     if (type == (BRK_INST | BRK_HARDWARE))
  795. wdbBpAddr = (UINT32) pRegisters->reg_pc;
  796. #endif /* DBG_HARDWARE_BP && defined (BRK_INST) */
  797.     if (bpInfo.bp_action & WDB_ACTION_CALL)
  798. bpInfo.bp_callRtn (bpInfo.bp_callArg, pRegisters);
  799.     if (bpInfo.bp_action & WDB_ACTION_NOTIFY)
  800. callBack = wdbSysBpPost;
  801. #if     CPU_FAMILY == MIPS
  802.     /*
  803.      * On MIPS CPUs, when a breakpoint exception occurs in a branch delay slot,
  804.      * the PC has been changed in the breakpoint handler to match with the
  805.      * breakpoint address.
  806.      * Once the matching has been made, the PC is modified to have its normal
  807.      * value (the preceding jump instruction).
  808.      */
  809.     if (pRegisters->cause & CAUSE_BD)   /* Are we in a branch delay slot ? */
  810.         pRegisters->reg_pc--;
  811. #endif  /* CPU_FAMILY == MIPS */
  812.     if (bpInfo.bp_action & (WDB_ACTION_NOTIFY | WDB_ACTION_STOP))
  813. {
  814. if (!(bpInfo.bp_action & WDB_ACTION_STOP))
  815.     wdbOneShot = TRUE;
  816. wdbSuspendSystem (pRegisters, callBack, 0);
  817. /* NOTREACHED */
  818. }
  819.     /* !WDB_ACTION_STOP means continue (e.g., step over this breakpoint) */
  820. #if DBG_NO_SINGLE_STEP
  821.     wdbSysNpc = wdbDbgGetNpc (pRegisters);
  822.     wdbSysNpcInstr = *wdbSysNpc;
  823.     usrBreakpointSet (wdbSysNpc, DBG_BREAK_INST);
  824. #endif /* DBG_NO_SINGLE_STEP */
  825.     wdbSysBpMode = WDB_STEP_OVER;
  826.     wdbBpData = wdbDbgTraceModeSet((REG_SET *) pRegisters);
  827.     WDB_CTX_LOAD(pRegisters);
  828.     }
  829. /******************************************************************************
  830. *
  831. * wdbE - target side code to support the windview "e" command
  832. */ 
  833. void wdbE
  834.     (
  835.     int * pData,
  836.     WDB_IU_REGS * pRegisters
  837.     )
  838.     {
  839.     int (*conditionFunc)() = (int (*)())pData[0];
  840.     int conditionArg = pData[1];
  841.     int eventNum = pData[2];
  842.     if ((conditionFunc == NULL) || (conditionFunc (conditionArg) == OK))
  843.         EVT_CTX_BUF (eventNum, pRegisters->reg_pc, 0, NULL);
  844.     }
  845. /******************************************************************************
  846. *
  847. * wdbTaskLock - lock the current task if the agent is running in task mode
  848. *
  849. * This routine locks the current task is the agent is running in 
  850. * task mode.
  851. * RETURNS : N/A
  852. *
  853. * NOMANUAL
  854. */ 
  855. LOCAL void wdbTaskLock (void)
  856.     {
  857.     if (wdbIsNowTasking() && (pWdbRtIf->taskLock != NULL))
  858. (*pWdbRtIf->taskLock) ();
  859.     }
  860. /******************************************************************************
  861. *
  862. * wdbTaskUnlock - unlock the current task if the agent is running in task mode
  863. *
  864. * This routine unlocks the current task is the agent is running in 
  865. * task mode.
  866. * RETURNS : N/A
  867. *
  868. * NOMANUAL
  869. */ 
  870. LOCAL void wdbTaskUnlock (void)
  871.     {
  872.     if (wdbIsNowTasking() && (pWdbRtIf->taskUnlock != NULL))
  873. (*pWdbRtIf->taskUnlock) ();
  874.     }