target/xtensa: avoid IHI for writes to non-executable memory
[openocd.git] / 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 #include "xtensa_fileio.h"
19
20 int xtensa_chip_init_arch_info(struct target *target, void *arch_info,
21 struct xtensa_debug_module_config *dm_cfg)
22 {
23 struct xtensa_chip_common *xtensa_chip = (struct xtensa_chip_common *)arch_info;
24 int ret = xtensa_init_arch_info(target, &xtensa_chip->xtensa, dm_cfg);
25 if (ret != ERROR_OK)
26 return ret;
27 /* All xtensa target structures point back to original xtensa_chip */
28 xtensa_chip->xtensa.xtensa_chip = arch_info;
29 return ERROR_OK;
30 }
31
32 int xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target)
33 {
34 int ret = xtensa_target_init(cmd_ctx, target);
35 if (ret != ERROR_OK)
36 return ret;
37 return xtensa_fileio_init(target);
38 }
39
40 int xtensa_chip_arch_state(struct target *target)
41 {
42 return ERROR_OK;
43 }
44
45 static int xtensa_chip_poll(struct target *target)
46 {
47 enum target_state old_state = target->state;
48 int ret = xtensa_poll(target);
49
50 if (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {
51 /*Call any event callbacks that are applicable */
52 if (old_state == TARGET_DEBUG_RUNNING) {
53 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
54 } else {
55 xtensa_fileio_detect_proc(target);
56 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
57 }
58 }
59
60 return ret;
61 }
62
63 static int xtensa_chip_virt2phys(struct target *target,
64 target_addr_t virtual, target_addr_t *physical)
65 {
66 if (physical) {
67 *physical = virtual;
68 return ERROR_OK;
69 }
70 return ERROR_FAIL;
71 }
72
73 static const struct xtensa_debug_ops xtensa_chip_dm_dbg_ops = {
74 .queue_enable = xtensa_dm_queue_enable,
75 .queue_reg_read = xtensa_dm_queue_reg_read,
76 .queue_reg_write = xtensa_dm_queue_reg_write
77 };
78
79 static const struct xtensa_power_ops xtensa_chip_dm_pwr_ops = {
80 .queue_reg_read = xtensa_dm_queue_pwr_reg_read,
81 .queue_reg_write = xtensa_dm_queue_pwr_reg_write
82 };
83
84 static int xtensa_chip_target_create(struct target *target, Jim_Interp *interp)
85 {
86 struct xtensa_debug_module_config xtensa_chip_dm_cfg = {
87 .dbg_ops = &xtensa_chip_dm_dbg_ops,
88 .pwr_ops = &xtensa_chip_dm_pwr_ops,
89 .tap = NULL,
90 .queue_tdi_idle = NULL,
91 .queue_tdi_idle_arg = NULL,
92 .dap = NULL,
93 .debug_ap = NULL,
94 .debug_apsel = DP_APSEL_INVALID,
95 .ap_offset = 0,
96 };
97
98 struct adiv5_private_config *pc = target->private_config;
99 if (adiv5_verify_config(pc) == ERROR_OK) {
100 xtensa_chip_dm_cfg.dap = pc->dap;
101 xtensa_chip_dm_cfg.debug_apsel = pc->ap_num;
102 xtensa_chip_dm_cfg.ap_offset = target->dbgbase;
103 LOG_DEBUG("DAP: ap_num %" PRId64 " DAP %p\n", pc->ap_num, pc->dap);
104 } else {
105 xtensa_chip_dm_cfg.tap = target->tap;
106 LOG_DEBUG("JTAG: %s:%s pos %d", target->tap->chip, target->tap->tapname,
107 target->tap->abs_chain_position);
108 }
109
110 struct xtensa_chip_common *xtensa_chip = calloc(1, sizeof(struct xtensa_chip_common));
111 if (!xtensa_chip) {
112 LOG_ERROR("Failed to alloc chip-level memory!");
113 return ERROR_FAIL;
114 }
115
116 int ret = xtensa_chip_init_arch_info(target, xtensa_chip, &xtensa_chip_dm_cfg);
117 if (ret != ERROR_OK) {
118 LOG_ERROR("Failed to init arch info!");
119 free(xtensa_chip);
120 return ret;
121 }
122
123 /*Assume running target. If different, the first poll will fix this. */
124 target->state = TARGET_RUNNING;
125 target->debug_reason = DBG_REASON_NOTHALTED;
126 return ERROR_OK;
127 }
128
129 static void xtensa_chip_target_deinit(struct target *target)
130 {
131 struct xtensa *xtensa = target_to_xtensa(target);
132 xtensa_target_deinit(target);
133 free(xtensa->xtensa_chip);
134 }
135
136 static int xtensa_chip_examine(struct target *target)
137 {
138 struct xtensa *xtensa = target_to_xtensa(target);
139 int retval = xtensa_dm_examine(&xtensa->dbg_mod);
140 if (retval == ERROR_OK)
141 retval = xtensa_examine(target);
142 return retval;
143 }
144
145 static int xtensa_chip_jim_configure(struct target *target, struct jim_getopt_info *goi)
146 {
147 return adiv5_jim_configure_ext(target, goi, NULL, ADI_CONFIGURE_DAP_OPTIONAL);
148 }
149
150 /** Methods for generic example of Xtensa-based chip-level targets. */
151 struct target_type xtensa_chip_target = {
152 .name = "xtensa",
153
154 .poll = xtensa_chip_poll,
155 .arch_state = xtensa_chip_arch_state,
156
157 .halt = xtensa_halt,
158 .resume = xtensa_resume,
159 .step = xtensa_step,
160
161 .assert_reset = xtensa_assert_reset,
162 .deassert_reset = xtensa_deassert_reset,
163 .soft_reset_halt = xtensa_soft_reset_halt,
164
165 .virt2phys = xtensa_chip_virt2phys,
166 .mmu = xtensa_mmu_is_enabled,
167 .read_memory = xtensa_read_memory,
168 .write_memory = xtensa_write_memory,
169
170 .read_buffer = xtensa_read_buffer,
171 .write_buffer = xtensa_write_buffer,
172
173 .checksum_memory = xtensa_checksum_memory,
174
175 .get_gdb_reg_list = xtensa_get_gdb_reg_list,
176
177 .run_algorithm = xtensa_run_algorithm,
178 .start_algorithm = xtensa_start_algorithm,
179 .wait_algorithm = xtensa_wait_algorithm,
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
197 .get_gdb_fileio_info = xtensa_get_gdb_fileio_info,
198 .gdb_fileio_end = xtensa_gdb_fileio_end,
199 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)