📄 wdbdbgarchlib.c
字号:
*pChan = 1; else return WDB_ERR_HW_REGS_EXHAUSTED; } else { if (pDbgRegs->type[0] == 0) *pChan = 0; else if (pDbgRegs->type[1] == 0) *pChan = 1; else return WDB_ERR_HW_REGS_EXHAUSTED; } break; case BRCR_32_4: /* SH7615 */ if ((access & BH_BUS_MASK) != 0) { /* only chan C and D support X/Y */ if (pDbgRegs->type[2] == 0) *pChan = 2; else if (pDbgRegs->type[3] == 0) *pChan = 3; else return WDB_ERR_HW_REGS_EXHAUSTED; } else { if (pDbgRegs->type[0] == 0) *pChan = 0; else if (pDbgRegs->type[1] == 0) *pChan = 1; else if (pDbgRegs->type[2] == 0) *pChan = 2; else if (pDbgRegs->type[3] == 0) *pChan = 3; else return WDB_ERR_HW_REGS_EXHAUSTED; } break; case BRCR_NONE: /* None */ default: return (WDB_ERR_INVALID_HW_BP); } return OK; }/******************************************************************************** wdbDbgHwBpSet - configure hardware breakpoint** addr is the address of the data or insn for the breakpoint.* access is the type of access that will generate a breakpoint. This does* not attempt to identify all "meaningless" breakpoints, e.g., break on* byte wide insn fetch of the X data channel.** RETURNS: OK, or WDB_ERR_X if breakpoint already set or cannot be configured.** NOMANUAL*/STATUS wdbDbgHwBpSet ( DBG_REGS * pDbgRegs, /* debug registers */ UINT32 access, /* access type */ UINT32 addr /* breakpoint addr */ ) { STATUS stat; int chan; UINT16 bbrValue = 0; static BOOL beenHere = FALSE; /* first time detect UBC type and initialize it's registers */ if (!beenHere) { wdbDbgUbcInit(); beenHere = TRUE; } /* Get new break channel */ if ((stat = wdbDbgChannelGet (pDbgRegs, access, &chan)) != OK) return (stat); /* Tear apart the access bits & configure pDbgRegs for bp list. */ switch (access & BH_BREAK_MASK) { case BH_BREAK_INSN: bbrValue |= UBC_BBR_ID0; /* set insn break */ break; case BH_BREAK_DATA: bbrValue |= UBC_BBR_ID1; /* set data break */ break; case BH_BREAK_ANY: /* default any type */ default: bbrValue |= (UBC_BBR_ID0 | UBC_BBR_ID1); } switch (access & BH_CYCLE_MASK) { case BH_CYCLE_READ: bbrValue |= UBC_BBR_RW0; /* break on read */ break; case BH_CYCLE_WRITE: bbrValue |= UBC_BBR_RW1; /* break on write */ break; case BH_CYCLE_ANY: /* default to R/W */ case BH_CYCLE_RW: bbrValue |= (UBC_BBR_RW0 | UBC_BBR_RW1); break; } switch (access & BH_SIZE_MASK) { case BH_ANY: /* default any size */ break; case BH_8: bbrValue |= UBC_BBR_SZ0; /* byte access only */ break; case BH_16: bbrValue |= UBC_BBR_SZ1; /* word access only */ break; case BH_32: bbrValue |= (UBC_BBR_SZ0 | UBC_BBR_SZ1); /* dword access only */ break; } if (ubc.brcrSize == BRCR_16_2) /* !SH7709, !SH7750 */ { /* must avoid because */ if ((access & BH_CPU_MASK) != 0) /* on SH7750 these */ return (WDB_ERR_INVALID_HW_BP); /* have different */ } /* meaning (SZ2) */ else { switch (access & BH_CPU_MASK) { case BH_CPU: /* default is CPU */ bbrValue |= UBC_BBR_CD0; break; case BH_DMAC: /* DMAC */ bbrValue |= UBC_BBR_CD1; break; case BH_DMAC_CPU: /* DMAC and CPU */ bbrValue |= UBC_BBR_CD0 | UBC_BBR_CD1; break; default: return (WDB_ERR_INVALID_HW_BP); } } switch (access & BH_BUS_MASK) { case BH_IBUS: /* I bus (default) */ break; case BH_XBUS: bbrValue |= UBC_BBR_XYE; /* X bus enable */ addr = (addr & 0xffff) << 16; /* X in upper 16 */ break; case BH_YBUS: bbrValue |= UBC_BBR_XYE | UBC_BBR_XYS; /* Y bus */ addr = (addr & 0xffff); /* X in lower 16 */ break; default: return (WDB_ERR_INVALID_HW_BP); } /* save type for global state */ pDbgRegs->type[chan] = access | BRK_HARDWARE; /* address register and bus cycle register */ pDbgRegs->bar[chan] = addr; pDbgRegs->bbr[chan] = bbrValue; return (OK); }/******************************************************************************** wdbDbgHwBpFind - Find the hardware breakpoint** This routine finds the type and the address of the* hardware breakpoint that is set in the DBG_REGS structure.* This information is stored in the pType and pAddr arguments.* pAddr is the address *as set in the breakpoint*, not the* current/stopped PC.** Note that multiple break conditions may be met, e.g., both A and B * chan break, at the same time, but we can only return the match for * one of the H/W breakpoints.** RETURNS: OK, or ERROR if unable to find a hardware breakpoint** NOMANUAL*/STATUS wdbDbgHwBpFind ( DBG_REGS * pDbgRegs, /* debug registers */ UINT32 * pType, /* return type info via this pointer */ UINT32 * pAddr /* return address info via this pointer */ ) { UINT32 cond; switch (ubc.brcrSize) { case BRCR_0_1: /* SH7050, SH7000 */ case BRCR_16_1: /* SH7055, SH7604 */ *pType = pDbgRegs->type[0]; *pAddr = pDbgRegs->bar[0]; return (OK); case BRCR_16_2: /* SH7750, SH7709 */ cond = pDbgRegs->brcr & UBC_BRCR_CONDITION_MASK_16_2; if (cond & UBC_BRCR_CMFA) /* Ch A */ { *pType = pDbgRegs->type[0]; *pAddr = pDbgRegs->bar[0]; return (OK); } if (cond & UBC_BRCR_CMFB) /* Ch B */ { *pType = pDbgRegs->type[1]; *pAddr = pDbgRegs->bar[1]; return (OK); } break; case BRCR_32_2: /* SH7709A, SH7729 */ cond = pDbgRegs->brcr & UBC_BRCR_CONDITION_MASK_32_2; if ((cond & UBC_BRCR_SCMFCA) || /* Ch A, CPU */ (cond & UBC_BRCR_SCMFDA)) /* Ch A, DMAC */ { *pType = pDbgRegs->type[0]; *pAddr = pDbgRegs->bar[0]; return (OK); } if ((cond & UBC_BRCR_SCMFCB) || /* Ch B, CPU */ (cond & UBC_BRCR_SCMFDB)) /* Ch B, DMAC */ { *pType = pDbgRegs->type[1]; *pAddr = pDbgRegs->bar[1]; return (OK); } break; case BRCR_32_4: /* SH7615 */ cond = pDbgRegs->brcr & UBC_BRCR_CONDITION_MASK_32_4; if ((cond & UBC_BRCR_CMFCA) || /* Ch A, CPU */ (cond & UBC_BRCR_CMFPA)) /* Ch A, DMAC */ { *pType = pDbgRegs->type[0]; *pAddr = pDbgRegs->bar[0]; return (OK); } if ((cond & UBC_BRCR_CMFCB) || /* Ch B, CPU */ (cond & UBC_BRCR_CMFPB)) /* Ch B, DMAC */ { *pType = pDbgRegs->type[1]; *pAddr = pDbgRegs->bar[1]; return (OK); } if ((cond & UBC_BRCR_CMFCC) || /* Ch C, CPU */ (cond & UBC_BRCR_CMFPC)) /* Ch C, DMAC */ { *pType = pDbgRegs->type[2]; *pAddr = pDbgRegs->bar[2]; return (OK); } if ((cond & UBC_BRCR_CMFCD) || /* Ch D, CPU */ (cond & UBC_BRCR_CMFPD)) /* Ch D, DMAC */ { *pType = pDbgRegs->type[3]; *pAddr = pDbgRegs->bar[3]; return (OK); } } return (ERROR); }/******************************************************************************** wdbDbgRegsSet - config the hardware for a given breakpoint.** This is called at context switch to set the HW registers for the* given breakpoint.** RETURNS: N/A** NOMANUAL*/ void wdbDbgRegsSet ( DBG_REGS * pRegs ) { int chan = 0; /* Set BRCR safe before setting up other registers */ switch (ubc.brcrSize) { case BRCR_0_1: /* SH7050, SH7000 */ chan = 1; break; case BRCR_16_1: /* SH7055, SH7604 */ *_UBC_BRCR16 = ubc.brcrInit; chan = 1; break; case BRCR_16_2: /* SH7750, SH7709 */ *_UBC_BRCR16 = ubc.brcrInit; chan = 2; break; case BRCR_32_2: /* SH7709A, SH7729 */ *_UBC_BRCR32 = ubc.brcrInit; chan = 2; break; case BRCR_32_4: /* SH7615 */ *_UBC_BRCR32 = ubc.brcrInit; chan = 4; break; } while (chan > 0) { chan--; _UBC_TYPE(chan) = pRegs->type[chan]; *_UBC_BAR(chan) = pRegs->bar[chan]; *_UBC_BBR(chan) = pRegs->bbr[chan]; } }/******************************************************************************** wdbDbgRegsGet - get the hardware regs for a given breakpoint.** This is called by the breakpoint handler to get the HW registers for the* given breakpoint.** RETURNS: N/A** NOMANUAL*/void wdbDbgRegsGet ( DBG_REGS * pRegs ) { int chan = 0; switch (ubc.brcrSize) { case BRCR_0_1: /* SH7050, SH7000 */ chan = 1; break; case BRCR_16_1: /* SH7055, SH7604 */ chan = 1; pRegs->brcr = *_UBC_BRCR16; break; case BRCR_16_2: /* SH7750, SH7709 */ chan = 2; pRegs->brcr = *_UBC_BRCR16; break; case BRCR_32_2: /* SH7709A, SH7729 */ chan = 2; pRegs->brcr = *_UBC_BRCR32; break; case BRCR_32_4: /* SH7615 */ chan = 4; pRegs->brcr = *_UBC_BRCR32; break; } while (chan > 0) { chan--; pRegs->type[chan] = _UBC_TYPE(chan); pRegs->bar[chan] = *_UBC_BAR(chan); pRegs->bbr[chan] = *_UBC_BBR(chan); } }/******************************************************************************** wdbDbgRegsClear - clear hardware break point registers** This routine clears the hardware breakpoint registers. Interrupt and task* switch locking is handled by wdbLib.** RETURNS: N/A.** NOMANUAL*/void wdbDbgRegsClear (void) { int chan = 0; switch (ubc.brcrSize) { case BRCR_0_1: /* SH7050, SH7000 */ chan = 1; break; case BRCR_16_1: /* SH7055, SH7604 */ *_UBC_BRCR16 = ubc.brcrInit; chan = 1; break; case BRCR_16_2: /* SH7750, SH7709 */ *_UBC_BRCR16 = ubc.brcrInit; chan = 2; break; case BRCR_32_2: /* SH7709A, SH7729 */ *_UBC_BRCR32 = ubc.brcrInit; chan = 2; break; case BRCR_32_4: /* SH7615 */ *_UBC_BRCR32 = ubc.brcrInit; chan = 4; break; } while (chan > 0) { chan--; _UBC_TYPE(chan) = 0; *_UBC_BAR(chan) = 0; *_UBC_BBR(chan) = 0; } }#ifdef WDB_DBG_DEBUG/******************************************************************************** wdbDbgRegsPrint - display hardware break point registers** This routine displays the hardware breakpoint registers.** RETURNS: N/A.** NOMANUAL*/void wdbDbgRegsPrint (void) { int chan = 0; int i; switch (ubc.brcrSize) { case BRCR_0_1: /* SH7050, SH7000 */ chan = 1; break; case BRCR_16_1: /* SH7055 */ *_UBC_BRCR16 = ubc.brcrInit; chan = 1; break; case BRCR_16_2: /* SH7750, SH7709 */ *_UBC_BRCR16 = ubc.brcrInit; chan = 2; break; case BRCR_32_2: /* SH7709A, SH7729 */ *_UBC_BRCR32 = ubc.brcrInit; chan = 2; break; case BRCR_32_4: /* SH7615 */ *_UBC_BRCR32 = ubc.brcrInit; chan = 4; break; } printf ("\n"); for (i = 0 ; i < chan; i++) { printf ("Break channel %d: BAR=0x%08x BBR=0x%08x (type=0x%08x) \n", i, *_UBC_BAR(i), *_UBC_BBR(i), _UBC_TYPE(i)); } }#endif /* WDB_DBG_DEBUG */#else /* DBG_HARDWARE_BP */ void wdbDbgHwBreakpoint() {} /* This is just a stub to satisfy wdbALib.s */#endif /* DBG_HARDWARE_BP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -