Skip to content

Commit df4afd0

Browse files
committed
esp/gcov: Halt target before on-the-fly gcov dump
1 parent 92cd6cc commit df4afd0

File tree

3 files changed

+105
-41
lines changed

3 files changed

+105
-41
lines changed

src/target/esp32_apptrace.c

Lines changed: 59 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "xtensa_algorithm.h"
5050
#include "esp_xtensa.h"
5151
#include "esp_xtensa_apptrace.h"
52+
#include "esp_xtensa_smp.h"
5253
#include "esp32_apptrace.h"
5354

5455

@@ -2737,6 +2738,27 @@ int esp_gcov_poll(struct target *target, void *priv)
27372738
return res;
27382739
}
27392740

2741+
static struct esp_dbg_stubs *get_stubs_from_target(struct target **target)
2742+
{
2743+
struct esp_dbg_stubs *dbg_stubs = NULL;
2744+
2745+
if ((*target)->smp) {
2746+
struct target_list *head;
2747+
struct target *curr;
2748+
foreach_smp_target(head, (*target)->head) {
2749+
curr = head->target;
2750+
dbg_stubs = &(target_to_esp_xtensa(curr)->dbg_stubs);
2751+
if (target_was_examined(curr) && dbg_stubs->base &&
2752+
dbg_stubs->entries_count > 0) {
2753+
*target = curr;
2754+
break;
2755+
}
2756+
}
2757+
} else
2758+
dbg_stubs = &(target_to_esp_xtensa(*target)->dbg_stubs);
2759+
return dbg_stubs;
2760+
}
2761+
27402762
COMMAND_HANDLER(esp32_cmd_gcov)
27412763
{
27422764
static struct esp32_apptrace_cmd_ctx s_at_cmd_ctx;
@@ -2762,68 +2784,63 @@ COMMAND_HANDLER(esp32_cmd_gcov)
27622784
LOG_ERROR("Failed to init cmd ctx (%d)!", res);
27632785
return res;
27642786
}
2765-
if (dump) {
2766-
/* command can be invoked on unexamined core, if so find examined one */
2767-
if (target->smp && !target_was_examined(target)) {
2768-
struct target_list *head;
2769-
struct target *curr;
2770-
LOG_WARNING("Current target '%s' was not examined!", target_name(target));
2771-
foreach_smp_target(head, target->head) {
2772-
curr = head->target;
2773-
if (target_was_examined(curr)) {
2774-
target = curr;
2775-
LOG_WARNING("Run command on target '%s'",
2776-
target_name(target));
2777-
break;
2778-
}
2787+
/* command can be invoked on unexamined core, if so find examined one */
2788+
if (target->smp && !target_was_examined(target)) {
2789+
struct target_list *head;
2790+
struct target *curr = target;
2791+
LOG_WARNING("Current target '%s' was not examined!", target_name(target));
2792+
foreach_smp_target(head, target->head) {
2793+
curr = head->target;
2794+
if (target_was_examined(curr)) {
2795+
LOG_WARNING("Run command on target '%s'",
2796+
target_name(target));
2797+
break;
27792798
}
27802799
}
2781-
old_state = target->state;
2800+
if (curr == target) {
2801+
LOG_ERROR("There is no examined core to run command!");
2802+
return ERROR_FAIL;
2803+
}
2804+
target = curr;
2805+
}
2806+
old_state = target->state;
2807+
if (dump) {
27822808
/* connect */
2783-
res = esp32_apptrace_connect_targets(&s_at_cmd_ctx, true, dump);
2809+
res = esp32_apptrace_connect_targets(&s_at_cmd_ctx, true, true);
27842810
if (res != ERROR_OK) {
27852811
LOG_ERROR("Failed to connect to targets (%d)!", res);
27862812
esp_gcov_cmd_cleanup(&s_at_cmd_ctx);
27872813
return res;
27882814
}
27892815
esp_gcov_poll(target, &s_at_cmd_ctx);
27902816
} else {
2791-
struct esp_dbg_stubs *dbg_stubs = NULL;
2792-
if (target->smp) {
2793-
struct target_list *head;
2794-
struct target *curr;
2795-
foreach_smp_target(head, target->head) {
2796-
curr = head->target;
2797-
dbg_stubs = &(target_to_esp_xtensa(curr)->dbg_stubs);
2798-
if (target_was_examined(curr) && dbg_stubs->base &&
2799-
dbg_stubs->entries_count > 0) {
2800-
target = curr;
2801-
break;
2802-
}
2803-
}
2804-
} else
2805-
dbg_stubs = &(target_to_esp_xtensa(target)->dbg_stubs);
2806-
old_state = target->state;
2807-
if (dbg_stubs->entries_count < 1 || dbg_stubs->desc.data_alloc == 0) {
2817+
struct target *run_target = target;
2818+
/* connect and halt target, debug stubs info will be read if this is the first time
2819+
*target is halted */
2820+
res = esp32_apptrace_connect_targets(&s_at_cmd_ctx, true, false);
2821+
if (res != ERROR_OK) {
2822+
LOG_ERROR("Failed to connect to targets (%d)!", res);
2823+
esp_gcov_cmd_cleanup(&s_at_cmd_ctx);
2824+
return res;
2825+
}
2826+
struct esp_dbg_stubs *dbg_stubs = get_stubs_from_target(&run_target);
2827+
if (dbg_stubs == NULL || dbg_stubs->entries_count < 1 ||
2828+
dbg_stubs->desc.data_alloc == 0) {
28082829
LOG_ERROR("No dbg stubs found!");
2830+
esp_gcov_cmd_cleanup(&s_at_cmd_ctx);
28092831
return ERROR_FAIL;
28102832
}
28112833
if (dbg_stubs->entries_count < ESP_DBG_STUB_ENTRY_GCOV+1) {
28122834
LOG_ERROR("No GCOV stubs found!");
2835+
esp_gcov_cmd_cleanup(&s_at_cmd_ctx);
28132836
return ERROR_FAIL;
28142837
}
28152838
func_addr = dbg_stubs->entries[ESP_DBG_STUB_ENTRY_GCOV];
28162839
LOG_DEBUG("GCOV_FUNC = 0x%x", func_addr);
28172840
if (func_addr == 0) {
28182841
LOG_ERROR("GCOV stub not found!");
2819-
return ERROR_FAIL;
2820-
}
2821-
/* connect */
2822-
res = esp32_apptrace_connect_targets(&s_at_cmd_ctx, true, dump);
2823-
if (res != ERROR_OK) {
2824-
LOG_ERROR("Failed to connect to targets (%d)!", res);
28252842
esp_gcov_cmd_cleanup(&s_at_cmd_ctx);
2826-
return res;
2843+
return ERROR_FAIL;
28272844
}
28282845
memset(&run, 0, sizeof(run));
28292846
run.stack_size = 1024;
@@ -2833,7 +2850,8 @@ COMMAND_HANDLER(esp32_cmd_gcov)
28332850
run.on_board.min_stack_size = ESP_DBG_STUBS_STACK_MIN_SIZE;
28342851
run.on_board.code_buf_addr = dbg_stubs->desc.tramp_addr;
28352852
run.on_board.code_buf_size = ESP_DBG_STUBS_CODE_BUF_SIZE;
2836-
xtensa_run_onboard_func(target, &run, func_addr, 0);
2853+
/* this gunction works for SMP and non-SMP targets */
2854+
esp_xtensa_smp_run_onboard_func(run_target, &run, func_addr, 0);
28372855
LOG_DEBUG("FUNC RET = 0x%x", run.ret_code);
28382856
}
28392857
/* disconnect */

src/target/esp_xtensa_smp.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,47 @@ int esp_xtensa_smp_run_func_image(struct target *target,
508508
return ERROR_OK;
509509
}
510510

511+
int esp_xtensa_smp_run_onboard_func(struct target *target,
512+
struct xtensa_algo_run_data *run,
513+
uint32_t func_addr,
514+
uint32_t num_args,
515+
...)
516+
{
517+
struct target *run_target;
518+
struct target_list *head;
519+
va_list ap;
520+
uint32_t smp_break;
521+
int res;
522+
523+
if (target->smp) {
524+
/* find first HALTED and examined core */
525+
foreach_smp_target(head, target->head) {
526+
run_target = head->target;
527+
if (target_was_examined(run_target) && run_target->state == TARGET_HALTED)
528+
break;
529+
}
530+
if (head == NULL) {
531+
LOG_ERROR("Failed to find HALTED core!");
532+
return ERROR_FAIL;
533+
}
534+
res = esp_xtensa_smp_smpbreak_disable(run_target, &smp_break);
535+
if (res != ERROR_OK)
536+
return res;
537+
} else
538+
run_target = target;
539+
540+
va_start(ap, num_args);
541+
res = xtensa_run_onboard_func_va(run_target, run, func_addr, num_args, ap);
542+
va_end(ap);
543+
544+
if (target->smp) {
545+
res = esp_xtensa_smp_smpbreak_restore(run_target, smp_break);
546+
if (res != ERROR_OK)
547+
return res;
548+
}
549+
return ERROR_OK;
550+
}
551+
511552
int esp_xtensa_smp_init_arch_info(struct target *target,
512553
struct esp_xtensa_smp_common *esp_xtensa_smp,
513554
const struct xtensa_config *xtensa_cfg,

src/target/esp_xtensa_smp.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ int esp_xtensa_smp_run_func_image(struct target *target,
6868
struct xtensa_algo_image *image,
6969
uint32_t num_args,
7070
...);
71+
int esp_xtensa_smp_run_onboard_func(struct target *target,
72+
struct xtensa_algo_run_data *run,
73+
uint32_t func_addr,
74+
uint32_t num_args,
75+
...);
7176

7277
extern const struct command_registration esp_xtensa_smp_command_handlers[];
7378
extern const struct command_registration esp_xtensa_smp_xtensa_command_handlers[];

0 commit comments

Comments
 (0)