+int breakpoint_add(struct target *target,
+ target_addr_t address,
+ uint32_t length,
+ enum breakpoint_type type)
+{
+ int retval = ERROR_OK;
+ if (target->smp) {
+ struct target_list *head;
+ struct target *curr;
+ head = target->head;
+ if (type == BKPT_SOFT)
+ return breakpoint_add_internal(head->target, address, length, type);
+
+ while (head != (struct target_list *)NULL) {
+ curr = head->target;
+ retval = breakpoint_add_internal(curr, address, length, type);
+ if (retval != ERROR_OK)
+ return retval;
+ head = head->next;
+ }
+ return retval;
+ } else
+ return breakpoint_add_internal(target, address, length, type);
+}
+
+int context_breakpoint_add(struct target *target,
+ uint32_t asid,
+ uint32_t length,
+ enum breakpoint_type type)
+{
+ int retval = ERROR_OK;
+ if (target->smp) {
+ struct target_list *head;
+ struct target *curr;
+ head = target->head;
+ while (head != (struct target_list *)NULL) {
+ curr = head->target;
+ retval = context_breakpoint_add_internal(curr, asid, length, type);
+ if (retval != ERROR_OK)
+ return retval;
+ head = head->next;
+ }
+ return retval;
+ } else
+ return context_breakpoint_add_internal(target, asid, length, type);
+}
+
+int hybrid_breakpoint_add(struct target *target,
+ target_addr_t address,
+ uint32_t asid,
+ uint32_t length,
+ enum breakpoint_type type)
+{
+ int retval = ERROR_OK;
+ if (target->smp) {
+ struct target_list *head;
+ struct target *curr;
+ head = target->head;
+ while (head != (struct target_list *)NULL) {
+ curr = head->target;
+ retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type);
+ if (retval != ERROR_OK)
+ return retval;
+ head = head->next;
+ }
+ return retval;
+ } else
+ return hybrid_breakpoint_add_internal(target, address, asid, length, type);
+}
+
+/* free up a breakpoint */
+static void breakpoint_free(struct target *target, struct breakpoint *breakpoint_to_remove)
+{
+ struct breakpoint *breakpoint = target->breakpoints;
+ struct breakpoint **breakpoint_p = &target->breakpoints;
+ int retval;
+
+ while (breakpoint) {
+ if (breakpoint == breakpoint_to_remove)
+ break;
+ breakpoint_p = &breakpoint->next;
+ breakpoint = breakpoint->next;
+ }
+
+ if (breakpoint == NULL)
+ return;
+
+ retval = target_remove_breakpoint(target, breakpoint);
+
+ LOG_DEBUG("free BPID: %" PRIu32 " --> %d", breakpoint->unique_id, retval);
+ (*breakpoint_p) = breakpoint->next;
+ free(breakpoint->orig_instr);
+ free(breakpoint);
+}
+
+static int breakpoint_remove_internal(struct target *target, target_addr_t address)