target/xtensa: enable DAP/SWD for generic xtensa
[fw/openocd] / src / target / xtensa / xtensa_chip.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Xtensa Chip-level Target Support for OpenOCD                          *
5  *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *
6  ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "assert.h"
13 #include <target/target.h>
14 #include <target/target_type.h>
15 #include <target/arm_adi_v5.h>
16 #include <rtos/rtos.h>
17 #include "xtensa_chip.h"
18
19 int xtensa_chip_init_arch_info(struct target *target, void *arch_info,
20         struct xtensa_debug_module_config *dm_cfg)
21 {
22         struct xtensa_chip_common *xtensa_chip = (struct xtensa_chip_common *)arch_info;
23         int ret = xtensa_init_arch_info(target, &xtensa_chip->xtensa, dm_cfg);
24         if (ret != ERROR_OK)
25                 return ret;
26         /* All xtensa target structures point back to original xtensa_chip */
27         xtensa_chip->xtensa.xtensa_chip = arch_info;
28         return ERROR_OK;
29 }
30
31 int xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target)
32 {
33         return xtensa_target_init(cmd_ctx, target);
34 }
35
36 int xtensa_chip_arch_state(struct target *target)
37 {
38         return ERROR_OK;
39 }
40
41 static int xtensa_chip_poll(struct target *target)
42 {
43         enum target_state old_state = target->state;
44         int ret = xtensa_poll(target);
45
46         if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
47                 /*Call any event callbacks that are applicable */
48                 if (old_state == TARGET_DEBUG_RUNNING)
49                         target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
50                 else
51                         target_call_event_callbacks(target, TARGET_EVENT_HALTED);
52         }
53
54         return ret;
55 }
56
57 static int xtensa_chip_virt2phys(struct target *target,
58         target_addr_t virtual, target_addr_t *physical)
59 {
60         if (physical) {
61                 *physical = virtual;
62                 return ERROR_OK;
63         }
64         return ERROR_FAIL;
65 }
66
67 static const struct xtensa_debug_ops xtensa_chip_dm_dbg_ops = {
68         .queue_enable = xtensa_dm_queue_enable,
69         .queue_reg_read = xtensa_dm_queue_reg_read,
70         .queue_reg_write = xtensa_dm_queue_reg_write
71 };
72
73 static const struct xtensa_power_ops xtensa_chip_dm_pwr_ops = {
74         .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
75         .queue_reg_write = xtensa_dm_queue_pwr_reg_write
76 };
77
78 static int xtensa_chip_target_create(struct target *target, Jim_Interp *interp)
79 {
80         struct xtensa_debug_module_config xtensa_chip_dm_cfg = {
81                 .dbg_ops = &xtensa_chip_dm_dbg_ops,
82                 .pwr_ops = &xtensa_chip_dm_pwr_ops,
83                 .tap = NULL,
84                 .queue_tdi_idle = NULL,
85                 .queue_tdi_idle_arg = NULL,
86                 .dap = NULL,
87                 .debug_ap = NULL,
88                 .debug_apsel = DP_APSEL_INVALID,
89                 .ap_offset = 0,
90         };
91
92         struct adiv5_private_config *pc = target->private_config;
93         if (adiv5_verify_config(pc) == ERROR_OK) {
94                 xtensa_chip_dm_cfg.dap = pc->dap;
95                 xtensa_chip_dm_cfg.debug_apsel = pc->ap_num;
96                 xtensa_chip_dm_cfg.ap_offset = target->dbgbase;
97                 LOG_DEBUG("DAP: ap_num %" PRId64 " DAP %p\n", pc->ap_num, pc->dap);
98         } else {
99                 xtensa_chip_dm_cfg.tap = target->tap;
100                 LOG_DEBUG("JTAG: %s:%s pos %d", target->tap->chip, target->tap->tapname,
101                         target->tap->abs_chain_position);
102         }
103
104         struct xtensa_chip_common *xtensa_chip = calloc(1, sizeof(struct xtensa_chip_common));
105         if (!xtensa_chip) {
106                 LOG_ERROR("Failed to alloc chip-level memory!");
107                 return ERROR_FAIL;
108         }
109
110         int ret = xtensa_chip_init_arch_info(target, xtensa_chip, &xtensa_chip_dm_cfg);
111         if (ret != ERROR_OK) {
112                 LOG_ERROR("Failed to init arch info!");
113                 free(xtensa_chip);
114                 return ret;
115         }
116
117         /*Assume running target. If different, the first poll will fix this. */
118         target->state = TARGET_RUNNING;
119         target->debug_reason = DBG_REASON_NOTHALTED;
120         return ERROR_OK;
121 }
122
123 void xtensa_chip_target_deinit(struct target *target)
124 {
125         struct xtensa *xtensa = target_to_xtensa(target);
126         xtensa_target_deinit(target);
127         free(xtensa->xtensa_chip);
128 }
129
130 static int xtensa_chip_examine(struct target *target)
131 {
132         struct xtensa *xtensa = target_to_xtensa(target);
133         int retval = xtensa_dm_examine(&xtensa->dbg_mod);
134         if (retval == ERROR_OK)
135                 retval = xtensa_examine(target);
136         return retval;
137 }
138
139 int xtensa_chip_jim_configure(struct target *target, struct jim_getopt_info *goi)
140 {
141         static bool dap_configured;
142         int ret = adiv5_jim_configure(target, goi);
143         if (ret == JIM_OK) {
144                 LOG_DEBUG("xtensa '-dap' target option found");
145                 dap_configured = true;
146         }
147         if (!dap_configured) {
148                 LOG_DEBUG("xtensa '-dap' target option not yet found, assuming JTAG...");
149                 target->has_dap = false;
150         }
151         return ret;
152 }
153
154 /** Methods for generic example of Xtensa-based chip-level targets. */
155 struct target_type xtensa_chip_target = {
156         .name = "xtensa",
157
158         .poll = xtensa_chip_poll,
159         .arch_state = xtensa_chip_arch_state,
160
161         .halt = xtensa_halt,
162         .resume = xtensa_resume,
163         .step = xtensa_step,
164
165         .assert_reset = xtensa_assert_reset,
166         .deassert_reset = xtensa_deassert_reset,
167         .soft_reset_halt = xtensa_soft_reset_halt,
168
169         .virt2phys = xtensa_chip_virt2phys,
170         .mmu = xtensa_mmu_is_enabled,
171         .read_memory = xtensa_read_memory,
172         .write_memory = xtensa_write_memory,
173
174         .read_buffer = xtensa_read_buffer,
175         .write_buffer = xtensa_write_buffer,
176
177         .checksum_memory = xtensa_checksum_memory,
178
179         .get_gdb_reg_list = xtensa_get_gdb_reg_list,
180
181         .add_breakpoint = xtensa_breakpoint_add,
182         .remove_breakpoint = xtensa_breakpoint_remove,
183
184         .add_watchpoint = xtensa_watchpoint_add,
185         .remove_watchpoint = xtensa_watchpoint_remove,
186
187         .target_create = xtensa_chip_target_create,
188         .target_jim_configure = xtensa_chip_jim_configure,
189         .init_target = xtensa_chip_target_init,
190         .examine = xtensa_chip_examine,
191         .deinit_target = xtensa_chip_target_deinit,
192
193         .gdb_query_custom = xtensa_gdb_query_custom,
194
195         .commands = xtensa_command_handlers,
196 };