//! Insert breakpoint //! //! @param type one of memoryBreak, hardBreak, writeWatch, readWatch, accessWatch //! @param address address for breakpoint/watchpoint //! @param size range to watch (watchpoint only) //! //! @return true => OK\n //! false => error //! //! @note writeWatch, readWatch, accessWatch not currently working //! int GdbBreakpoints::insertBreakpoint(BreakType type, uint32_t address, unsigned size) { LOGGING_Q; log.print("(%s, a=%08X, s=%d)\n", getBreakpointName(type), address, size); switch (type) { case memoryBreak: { if (findMemoryBreakpoint(address)) { log.print("- already set - ignored\n"); return true; // Already set - ignore } MemoryBreakInfo *bpPtr = findFreeMemoryBreakpoint(); if (bpPtr == NULL) { return false; // Too many breakpoints } bpPtr->address = address; bpPtr->inUse = true; return true; // Done } break; case hardBreak: { if (findHardwareBreakpoint(address)) { log.print("- already set - ignored\n"); return true; // Already set - ignore } HardwareBreakInfo *bpPtr = findFreeHardwareBreakpoint(); if (bpPtr == NULL) { return false; // Too many breakpoints } bpPtr->address = address; bpPtr->inUse = true; return true; // Done } break; case writeWatch: case readWatch: case accessWatch: { DataBreakInfo *bpPtr = findDataWatchPoint(address); if (bpPtr != NULL) { if (size > bpPtr->size) bpPtr->size = size; if (type != bpPtr->type) bpPtr->type = accessWatch; return true; // Already set - update } bpPtr = findFreeDataWatchPoint(); if (bpPtr == NULL) { return false; // Too many breakpoints } bpPtr->address = address; bpPtr->size = size; bpPtr->type = (BreakType)type; bpPtr->inUse = true; return true; // Done } break; default: return false; // Unknown type } }
//! RAM based breakpoints leave the PC pointing at the instruction following // the HALT instruction. This routine checks for this situation and adjusts //! the target PC. //! void checkAndAdjustBreakpointHalt(void) { // Processor halted unsigned long pcAddress = 0; USBDM_ReadPC(&pcAddress); pcAddress -= 2; if (breakpointsActive && (findMemoryBreakpoint(pcAddress) != NULL)) { print("checkAndAdjustBreakpointHalt() - adjusting PC=%08lX\n", pcAddress); USBDM_WritePC(pcAddress); } }
//! Remove breakpoint //! //! @param type one of memoryBreak, hardBreak, writeWatch, readWatch, accessWatch //! @param address address for breakpoint/watchpoint //! @param size not used //! int GdbBreakpoints::removeBreakpoint(BreakType type, uint32_t address, unsigned size) { LOGGING_Q; log.print("(%s, a=%08X, s=%d)\n", getBreakpointName(type), address, size); switch (type) { case memoryBreak: { MemoryBreakInfo *bpPtr = findMemoryBreakpoint(address); if (bpPtr == NULL) { return false; // Non-existent breakpoint } bpPtr->inUse = false; bpPtr->address = 0; bpPtr->opcode[0] = 0; bpPtr->opcode[1] = 0; log.print("(t=MEM, a=%08X, s=%d) - done\n", address, size); return true; // Done } break; case hardBreak: { HardwareBreakInfo *bpPtr = findHardwareBreakpoint(address); if (bpPtr == NULL) { return false; // Non-existent breakpoint } bpPtr->inUse = false; log.print("(t=HW, a=%08X, s=%d) - done\n", address, size); return true; // Done } break; case writeWatch: case readWatch: case accessWatch: { DataBreakInfo *bpPtr = findDataWatchPoint(address); if (bpPtr == NULL) { return false; // Non-existent breakpoint } bpPtr->inUse = false; return true; // Done } break; default: return false; // Unknown type } }
int atMemoryBreakpoint() { unsigned long pcAddress = 0; USBDM_ReadPC(&pcAddress); return (findMemoryBreakpoint(pcAddress) != NULL); }
bool GdbBreakpoints::atMemoryBreakpoint(unsigned long pcAddress) { return (findMemoryBreakpoint(pcAddress) != NULL); }
bool GdbBreakpoints::atBreakpoint(uint32_t address) { return (findHardwareBreakpoint(address) != 0) || (findMemoryBreakpoint(address) != 0); }