X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Ftarget%2Fbreakpoints.c;h=8439ff395ea4f366be90bdce26dc7733f4d82341;hb=f998a2aaf19c14b46fd7f7dd50607a0904f40bd3;hp=94e8a823d07fdb225e8b3f0aed68fbf5a72added;hpb=fd8a3c9516d6580ab749e4127f6dab0077a8b078;p=fw%2Fopenocd diff --git a/src/target/breakpoints.c b/src/target/breakpoints.c index 94e8a823d..8439ff395 100644 --- a/src/target/breakpoints.c +++ b/src/target/breakpoints.c @@ -26,6 +26,7 @@ #include "target.h" #include #include "breakpoints.h" +#include "smp.h" static const char * const breakpoint_type_strings[] = { "hardware", @@ -41,7 +42,7 @@ static const char * const watchpoint_rw_strings[] = { /* monotonic counter/id-number for breakpoints and watch points */ static int bpwp_unique_id; -int breakpoint_add_internal(struct target *target, +static int breakpoint_add_internal(struct target *target, target_addr_t address, uint32_t length, enum breakpoint_type type) @@ -50,11 +51,8 @@ int breakpoint_add_internal(struct target *target, struct breakpoint **breakpoint_p = &target->breakpoints; const char *reason; int retval; - int n; - n = 0; while (breakpoint) { - n++; if (breakpoint->address == address) { /* FIXME don't assume "same address" means "same * breakpoint" ... check all the parameters before @@ -98,7 +96,9 @@ fail: return retval; } - LOG_DEBUG("added %s breakpoint at " TARGET_ADDR_FMT " of length 0x%8.8x, (BPID: %" PRIu32 ")", + LOG_DEBUG("[%d] added %s breakpoint at " TARGET_ADDR_FMT + " of length 0x%8.8x, (BPID: %" PRIu32 ")", + target->coreid, breakpoint_type_strings[(*breakpoint_p)->type], (*breakpoint_p)->address, (*breakpoint_p)->length, (*breakpoint_p)->unique_id); @@ -106,7 +106,7 @@ fail: return ERROR_OK; } -int context_breakpoint_add_internal(struct target *target, +static int context_breakpoint_add_internal(struct target *target, uint32_t asid, uint32_t length, enum breakpoint_type type) @@ -114,11 +114,8 @@ int context_breakpoint_add_internal(struct target *target, struct breakpoint *breakpoint = target->breakpoints; struct breakpoint **breakpoint_p = &target->breakpoints; int retval; - int n; - n = 0; while (breakpoint) { - n++; if (breakpoint->asid == asid) { /* FIXME don't assume "same address" means "same * breakpoint" ... check all the parameters before @@ -158,7 +155,7 @@ int context_breakpoint_add_internal(struct target *target, return ERROR_OK; } -int hybrid_breakpoint_add_internal(struct target *target, +static int hybrid_breakpoint_add_internal(struct target *target, target_addr_t address, uint32_t asid, uint32_t length, @@ -167,10 +164,8 @@ int hybrid_breakpoint_add_internal(struct target *target, struct breakpoint *breakpoint = target->breakpoints; struct breakpoint **breakpoint_p = &target->breakpoints; int retval; - int n; - n = 0; + while (breakpoint) { - n++; if ((breakpoint->asid == asid) && (breakpoint->address == address)) { /* FIXME don't assume "same address" means "same * breakpoint" ... check all the parameters before @@ -222,65 +217,65 @@ int breakpoint_add(struct target *target, 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) + + if (type == BKPT_SOFT) { + head = list_first_entry(target->smp_targets, struct target_list, lh); 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); + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + int retval = breakpoint_add_internal(curr, address, length, type); if (retval != ERROR_OK) return retval; - head = head->next; } - return retval; - } else + + return ERROR_OK; + } 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); + + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + int retval = context_breakpoint_add_internal(curr, asid, length, type); if (retval != ERROR_OK) return retval; - head = head->next; } - return retval; - } else + + return ERROR_OK; + } 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); + + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + int retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type); if (retval != ERROR_OK) return retval; - head = head->next; } - return retval; + + return ERROR_OK; } else return hybrid_breakpoint_add_internal(target, address, asid, length, type); } @@ -299,7 +294,7 @@ static void breakpoint_free(struct target *target, struct breakpoint *breakpoint breakpoint = breakpoint->next; } - if (breakpoint == NULL) + if (!breakpoint) return; retval = target_remove_breakpoint(target, breakpoint); @@ -310,7 +305,7 @@ static void breakpoint_free(struct target *target, struct breakpoint *breakpoint free(breakpoint); } -int breakpoint_remove_internal(struct target *target, target_addr_t address) +static int breakpoint_remove_internal(struct target *target, target_addr_t address) { struct breakpoint *breakpoint = target->breakpoints; @@ -330,29 +325,54 @@ int breakpoint_remove_internal(struct target *target, target_addr_t address) return 0; } } + +static void breakpoint_remove_all_internal(struct target *target) +{ + struct breakpoint *breakpoint = target->breakpoints; + + while (breakpoint) { + struct breakpoint *tmp = breakpoint; + breakpoint = breakpoint->next; + breakpoint_free(target, tmp); + } +} + void breakpoint_remove(struct target *target, target_addr_t address) { - int found = 0; if (target->smp) { + unsigned int num_breakpoints = 0; struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; - found += breakpoint_remove_internal(curr, address); - head = head->next; + + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + num_breakpoints += breakpoint_remove_internal(curr, address); } - if (found == 0) + if (!num_breakpoints) LOG_ERROR("no breakpoint at address " TARGET_ADDR_FMT " found", address); - } else + } else { breakpoint_remove_internal(target, address); + } +} + +void breakpoint_remove_all(struct target *target) +{ + if (target->smp) { + struct target_list *head; + + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + breakpoint_remove_all_internal(curr); + } + } else { + breakpoint_remove_all_internal(target); + } } -void breakpoint_clear_target_internal(struct target *target) +static void breakpoint_clear_target_internal(struct target *target) { LOG_DEBUG("Delete all breakpoints for target: %s", target_name(target)); - while (target->breakpoints != NULL) + while (target->breakpoints) breakpoint_free(target, target->breakpoints); } @@ -360,16 +380,14 @@ void breakpoint_clear_target(struct target *target) { if (target->smp) { struct target_list *head; - struct target *curr; - head = target->head; - while (head != (struct target_list *)NULL) { - curr = head->target; + + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; breakpoint_clear_target_internal(curr); - head = head->next; } - } else + } else { breakpoint_clear_target_internal(target); - + } } struct breakpoint *breakpoint_find(struct target *target, target_addr_t address) @@ -385,8 +403,8 @@ struct breakpoint *breakpoint_find(struct target *target, target_addr_t address) return NULL; } -int watchpoint_add(struct target *target, target_addr_t address, uint32_t length, - enum watchpoint_rw rw, uint32_t value, uint32_t mask) +int watchpoint_add_internal(struct target *target, target_addr_t address, + uint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask) { struct watchpoint *watchpoint = target->watchpoints; struct watchpoint **watchpoint_p = &target->watchpoints; @@ -441,8 +459,9 @@ bye: return retval; } - LOG_DEBUG("added %s watchpoint at " TARGET_ADDR_FMT - " of length 0x%8.8" PRIx32 " (WPID: %d)", + LOG_DEBUG("[%d] added %s watchpoint at " TARGET_ADDR_FMT + " of length 0x%8.8" PRIx32 " (WPID: %d)", + target->coreid, watchpoint_rw_strings[(*watchpoint_p)->rw], (*watchpoint_p)->address, (*watchpoint_p)->length, @@ -451,6 +470,26 @@ bye: return ERROR_OK; } +int watchpoint_add(struct target *target, target_addr_t address, + uint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask) +{ + if (target->smp) { + struct target_list *head; + + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + int retval = watchpoint_add_internal(curr, address, length, rw, value, mask); + if (retval != ERROR_OK) + return retval; + } + + return ERROR_OK; + } else { + return watchpoint_add_internal(target, address, length, rw, value, + mask); + } +} + static void watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove) { struct watchpoint *watchpoint = target->watchpoints; @@ -464,7 +503,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint watchpoint = watchpoint->next; } - if (watchpoint == NULL) + if (!watchpoint) return; retval = target_remove_watchpoint(target, watchpoint); LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval); @@ -472,7 +511,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint free(watchpoint); } -void watchpoint_remove(struct target *target, target_addr_t address) +int watchpoint_remove_internal(struct target *target, target_addr_t address) { struct watchpoint *watchpoint = target->watchpoints; @@ -482,17 +521,38 @@ void watchpoint_remove(struct target *target, target_addr_t address) watchpoint = watchpoint->next; } - if (watchpoint) + if (watchpoint) { watchpoint_free(target, watchpoint); - else - LOG_ERROR("no watchpoint at address " TARGET_ADDR_FMT " found", address); + return 1; + } else { + if (!target->smp) + LOG_ERROR("no watchpoint at address " TARGET_ADDR_FMT " found", address); + return 0; + } +} + +void watchpoint_remove(struct target *target, target_addr_t address) +{ + if (target->smp) { + unsigned int num_watchpoints = 0; + struct target_list *head; + + foreach_smp_target(head, target->smp_targets) { + struct target *curr = head->target; + num_watchpoints += watchpoint_remove_internal(curr, address); + } + if (num_watchpoints == 0) + LOG_ERROR("no watchpoint at address " TARGET_ADDR_FMT " num_watchpoints", address); + } else { + watchpoint_remove_internal(target, address); + } } void watchpoint_clear_target(struct target *target) { LOG_DEBUG("Delete all watchpoints for target: %s", target_name(target)); - while (target->watchpoints != NULL) + while (target->watchpoints) watchpoint_free(target, target->watchpoints); }