OpenOCD
esp_xtensa.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Espressif Xtensa target API for OpenOCD *
5  * Copyright (C) 2019 Espressif Systems Ltd. *
6  ***************************************************************************/
7 
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11 
12 #include <stdbool.h>
13 #include <stdint.h>
14 #include <target/smp.h>
15 #include <target/register.h>
16 #include "esp.h"
17 #include "esp_xtensa.h"
18 #include "esp_xtensa_apptrace.h"
19 #include "esp_semihosting.h"
20 #include "esp_xtensa_algorithm.h"
21 
22 #define ESP_XTENSA_DBGSTUBS_UPDATE_DATA_ENTRY(_e_) \
23  do { \
24  uint32_t __internal_val = (_e_); \
25  if (!xtensa_data_addr_valid(target, __internal_val)) { \
26  LOG_ERROR("No valid stub data entry found (0x%" PRIx32 ")!", __internal_val); \
27  return; \
28  } \
29  } while (0)
30 
31 #define ESP_XTENSA_DBGSTUBS_UPDATE_CODE_ENTRY(_e_) \
32  do { \
33  uint32_t __internal_val = (_e_); \
34  if (__internal_val == 0) { \
35  LOG_ERROR("No valid stub code entry found (0x%" PRIx32 ")!", __internal_val); \
36  return; \
37  } \
38  } while (0)
39 
40 static void esp_xtensa_dbgstubs_info_update(struct target *target);
41 static void esp_xtensa_dbgstubs_addr_check(struct target *target);
42 
44 {
45  struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);
46 
47  if (esp_xtensa->esp.dbg_stubs.base == 0)
48  return ERROR_OK;
49 
50  LOG_TARGET_INFO(target, "Restore debug stubs address %" PRIx32, esp_xtensa->esp.dbg_stubs.base);
52  if (res != ERROR_OK) {
53  LOG_ERROR("Failed to write trace status (%d)!", res);
54  return res;
55  }
56  return ERROR_OK;
57 }
59 {
60  /* debug stubs can be used in HALTED state only, so it is OK to get info about them here */
62  return ERROR_OK;
63 }
64 
66  struct esp_xtensa_common *esp_xtensa,
67  struct xtensa_debug_module_config *dm_cfg,
68  const struct esp_semihost_ops *semihost_ops)
69 {
70  int ret = xtensa_init_arch_info(target, &esp_xtensa->xtensa, dm_cfg);
71  if (ret != ERROR_OK)
72  return ret;
73  ret = esp_common_init(&esp_xtensa->esp, &xtensa_algo_hw);
74  if (ret != ERROR_OK)
75  return ret;
76 
77  esp_xtensa->semihost.ops = (struct esp_semihost_ops *)semihost_ops;
78  esp_xtensa->apptrace.hw = &esp_xtensa_apptrace_hw;
79  return ERROR_OK;
80 }
81 
82 int esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
83 {
84  return xtensa_target_init(cmd_ctx, target);
85 }
86 
88 {
89  LOG_DEBUG("start");
90 
93  if (ret != ERROR_OK)
94  return;
95  }
97  free(target_to_esp_xtensa(target)); /* same as free(xtensa) */
98 }
99 
101 {
102  return ERROR_OK;
103 }
104 
106 {
109 
110  int ret = xtensa_poll(target);
111 
113  LOG_TARGET_DEBUG(target, "Clear debug stubs info");
115  }
118  return ret;
119 }
120 
122 {
123  struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);
124  uint32_t vec_addr = 0;
125 
126  if (esp_xtensa->esp.dbg_stubs.base != 0)
127  return;
128 
129  int res = esp_xtensa_apptrace_status_reg_read(target, &vec_addr);
130  if (res != ERROR_OK) {
131  LOG_ERROR("Failed to read debug stubs address location (%d)!", res);
132  return;
133  }
134  if (xtensa_data_addr_valid(target, vec_addr)) {
135  LOG_TARGET_INFO(target, "Detected debug stubs @ %" PRIx32, vec_addr);
137  if (res != ERROR_OK)
138  LOG_ERROR("Failed to clear debug stubs address location (%d)!", res);
139  esp_xtensa->esp.dbg_stubs.base = vec_addr;
140  }
141 }
142 
144 {
145  struct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);
146 
147  if (esp_xtensa->esp.dbg_stubs.base == 0 || esp_xtensa->esp.dbg_stubs.entries_count != 0)
148  return;
149 
150  int res = esp_dbgstubs_table_read(target, &esp_xtensa->esp.dbg_stubs);
151  if (res != ERROR_OK)
152  return;
153  if (esp_xtensa->esp.dbg_stubs.entries_count == 0)
154  return;
155 
156  /* read debug stubs descriptor */
159  sizeof(struct esp_dbg_stubs_desc),
160  (uint8_t *)&esp_xtensa->esp.dbg_stubs.desc);
161  if (res != ERROR_OK) {
162  LOG_ERROR("Failed to read debug stubs descriptor (%d)!", res);
163  return;
164  }
169 }
170 
172 {
174  /* flash breakpoints will be handled in another patch */
175 }
176 
178 {
180  /* flash breakpoints will be handled in another patch */
181 }
int esp_dbgstubs_table_read(struct target *target, struct esp_dbg_stubs *dbg_stubs)
Definition: esp.c:27
int esp_common_init(struct esp_common *esp, const struct esp_algorithm_hw *algo_hw)
Definition: esp.c:17
@ ESP_DBG_STUB_DESC
Definition: esp.h:31
#define ESP_XTENSA_DBGSTUBS_UPDATE_CODE_ENTRY(_e_)
Definition: esp_xtensa.c:31
static void esp_xtensa_dbgstubs_info_update(struct target *target)
Definition: esp_xtensa.c:143
static void esp_xtensa_dbgstubs_addr_check(struct target *target)
Definition: esp_xtensa.c:121
int esp_xtensa_init_arch_info(struct target *target, struct esp_xtensa_common *esp_xtensa, struct xtensa_debug_module_config *dm_cfg, const struct esp_semihost_ops *semihost_ops)
Definition: esp_xtensa.c:65
int esp_xtensa_poll(struct target *target)
Definition: esp_xtensa.c:105
#define ESP_XTENSA_DBGSTUBS_UPDATE_DATA_ENTRY(_e_)
Definition: esp_xtensa.c:22
int esp_xtensa_arch_state(struct target *target)
Definition: esp_xtensa.c:100
void esp_xtensa_target_deinit(struct target *target)
Definition: esp_xtensa.c:87
int esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
Definition: esp_xtensa.c:82
int esp_xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint)
Definition: esp_xtensa.c:177
static int esp_xtensa_dbgstubs_restore(struct target *target)
Definition: esp_xtensa.c:43
int esp_xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint)
Definition: esp_xtensa.c:171
int esp_xtensa_on_halt(struct target *target)
Definition: esp_xtensa.c:58
static struct esp_xtensa_common * target_to_esp_xtensa(struct target *target)
Definition: esp_xtensa.h:24
const struct esp_algorithm_hw xtensa_algo_hw
int esp_xtensa_apptrace_status_reg_write(struct target *target, uint32_t stat)
int esp_xtensa_apptrace_status_reg_read(struct target *target, uint32_t *stat)
struct esp32_apptrace_hw esp_xtensa_apptrace_hw
#define LOG_TARGET_INFO(target, fmt_str,...)
Definition: log.h:152
#define LOG_TARGET_DEBUG(target, fmt_str,...)
Definition: log.h:149
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
struct esp_dbg_stubs dbg_stubs
Definition: esp.h:81
Debug stubs descriptor.
Definition: esp.h:47
uint32_t min_stack_addr
Pre-compiled target buffer's addr for stack.
Definition: esp.h:58
uint32_t data_free
Address of free-like function to free buffer allocated with data_alloc.
Definition: esp.h:62
uint32_t tramp_addr
Address of pre-compiled target buffer for stub trampoline.
Definition: esp.h:51
uint32_t data_alloc
Address of malloc-like function to allocate buffer on target.
Definition: esp.h:60
uint32_t entries[ESP_DBG_STUB_ENTRY_MAX]
Table contents.
Definition: esp.h:72
struct esp_dbg_stubs_desc desc
Debug stubs decsriptor.
Definition: esp.h:76
uint32_t entries_count
Number of table entries.
Definition: esp.h:74
uint32_t base
Address.
Definition: esp.h:70
struct esp_semihost_ops * ops
Semihost calls handling operations.
const struct esp32_apptrace_hw * hw
struct esp_semihost_data semihost
Definition: esp_xtensa.h:20
struct xtensa xtensa
Definition: esp_xtensa.h:18
struct esp_xtensa_apptrace_info apptrace
Definition: esp_xtensa.h:21
struct esp_common esp
Definition: esp_xtensa.h:19
Definition: target.h:116
enum target_state state
Definition: target.h:157
Represents a generic Xtensa core.
Definition: xtensa.h:241
struct xtensa_debug_module dbg_mod
Definition: xtensa.h:245
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
Definition: target.c:2407
static bool target_was_examined(const struct target *target)
Definition: target.h:436
@ TARGET_DEBUG_RUNNING
Definition: target.h:58
int xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint)
Definition: xtensa.c:2481
void xtensa_target_deinit(struct target *target)
Definition: xtensa.c:3412
int xtensa_poll(struct target *target)
Definition: xtensa.c:2233
int xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint)
Definition: xtensa.c:2525
int xtensa_target_init(struct command_context *cmd_ctx, struct target *target)
Definition: xtensa.c:3346
int xtensa_init_arch_info(struct target *target, struct xtensa *xtensa, const struct xtensa_debug_module_config *dm_cfg)
Definition: xtensa.c:3302
static struct xtensa * target_to_xtensa(struct target *target)
Definition: xtensa.h:290
static bool xtensa_data_addr_valid(struct target *target, uint32_t addr)
Definition: xtensa.h:314
static xtensa_pwrstat_t xtensa_dm_power_status_get(struct xtensa_debug_module *dm)
#define PWRSTAT_COREWASRESET(x)