target/cortex_m: prevent asserting reset if examine is deferred
[openocd.git] / src / target / espressif / esp_xtensa_algorithm.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Module to run arbitrary code on Xtensa using OpenOCD *
5 * Copyright (C) 2019 Espressif Systems Ltd. *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <target/xtensa/xtensa.h>
13 #include "esp_xtensa_algorithm.h"
14
15 static int esp_xtensa_algo_init(struct target *target, struct esp_algorithm_run_data *run,
16 uint32_t num_args, va_list ap);
17 static int esp_xtensa_algo_cleanup(struct target *target, struct esp_algorithm_run_data *run);
18 static const uint8_t *esp_xtensa_stub_tramp_get(struct target *target, size_t *size);
19
20 const struct esp_algorithm_hw xtensa_algo_hw = {
21 .algo_init = esp_xtensa_algo_init,
22 .algo_cleanup = esp_xtensa_algo_cleanup,
23 .stub_tramp_get = esp_xtensa_stub_tramp_get,
24 };
25
26 /* Generated from contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.S */
27 static const uint8_t esp_xtensa_stub_tramp_win[] = {
28 #include "../../../contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.inc"
29 };
30
31 static const uint8_t *esp_xtensa_stub_tramp_get(struct target *target, size_t *size)
32 {
33 struct xtensa *xtensa = target_to_xtensa(target);
34
35 if (!xtensa->core_config->windowed) {
36 LOG_ERROR("Running stubs is not supported for cores without windowed registers option!");
37 return NULL;
38 }
39 *size = sizeof(esp_xtensa_stub_tramp_win);
40 return esp_xtensa_stub_tramp_win;
41 }
42
43 static int esp_xtensa_algo_regs_init_start(struct target *target, struct esp_algorithm_run_data *run)
44 {
45 uint32_t stack_addr = run->stub.stack_addr;
46
47 LOG_TARGET_DEBUG(target, "Check stack addr 0x%x", stack_addr);
48 if (stack_addr & 0xFUL) {
49 stack_addr &= ~0xFUL;
50 LOG_TARGET_DEBUG(target, "Adjust stack addr to 0x%x", stack_addr);
51 }
52 stack_addr -= 16;
53 struct reg_param *params = run->reg_args.params;
54 init_reg_param(&params[0], "a0", 32, PARAM_OUT); /*TODO: move to tramp */
55 init_reg_param(&params[1], "a1", 32, PARAM_OUT);
56 init_reg_param(&params[2], "a8", 32, PARAM_OUT);
57 init_reg_param(&params[3], "windowbase", 32, PARAM_OUT); /*TODO: move to tramp */
58 init_reg_param(&params[4], "windowstart", 32, PARAM_OUT); /*TODO: move to tramp */
59 init_reg_param(&params[5], "ps", 32, PARAM_OUT);
60 buf_set_u32(params[0].value, 0, 32, 0); /* a0 TODO: move to tramp */
61 buf_set_u32(params[1].value, 0, 32, stack_addr); /* a1 */
62 buf_set_u32(params[2].value, 0, 32, run->stub.entry); /* a8 */
63 buf_set_u32(params[3].value, 0, 32, 0x0); /* initial window base TODO: move to tramp */
64 buf_set_u32(params[4].value, 0, 32, 0x1); /* initial window start TODO: move to tramp */
65 buf_set_u32(params[5].value, 0, 32, 0x60025); /* enable WOE, UM and debug interrupts level (6) */
66 return ERROR_OK;
67 }
68
69 static int esp_xtensa_algo_init(struct target *target, struct esp_algorithm_run_data *run,
70 uint32_t num_args, va_list ap)
71 {
72 enum xtensa_mode core_mode = XT_MODE_ANY;
73 static const char *const arg_regs[] = { "a2", "a3", "a4", "a5", "a6" };
74
75 if (!run)
76 return ERROR_FAIL;
77
78 if (num_args > ARRAY_SIZE(arg_regs)) {
79 LOG_ERROR("Too many algo user args %u! Max %zu args are supported.", num_args, ARRAY_SIZE(arg_regs));
80 return ERROR_FAIL;
81 }
82
83 struct xtensa_algorithm *ainfo = calloc(1, sizeof(struct xtensa_algorithm));
84 if (!ainfo) {
85 LOG_ERROR("Unable to allocate memory");
86 return ERROR_FAIL;
87 }
88
89 if (run->arch_info) {
90 struct xtensa_algorithm *xtensa_algo = run->arch_info;
91 core_mode = xtensa_algo->core_mode;
92 }
93
94 run->reg_args.first_user_param = ESP_XTENSA_STUB_ARGS_FUNC_START;
95 run->reg_args.count = run->reg_args.first_user_param + num_args;
96 if (num_args == 0)
97 run->reg_args.count++; /* a2 reg is used as the 1st arg and return code */
98 LOG_DEBUG("reg params count %d (%d/%d).",
99 run->reg_args.count,
100 run->reg_args.first_user_param,
101 num_args);
102 run->reg_args.params = calloc(run->reg_args.count, sizeof(struct reg_param));
103 if (!run->reg_args.params) {
104 free(ainfo);
105 LOG_ERROR("Unable to allocate memory");
106 return ERROR_FAIL;
107 }
108
109 esp_xtensa_algo_regs_init_start(target, run);
110
111 init_reg_param(&run->reg_args.params[run->reg_args.first_user_param + 0], "a2", 32, PARAM_IN_OUT);
112
113 if (num_args > 0) {
114 uint32_t arg = va_arg(ap, uint32_t);
115 esp_algorithm_user_arg_set_uint(run, 0, arg);
116 LOG_DEBUG("Set arg[0] = %d (%s)", arg, run->reg_args.params[run->reg_args.first_user_param + 0].reg_name);
117 } else {
118 esp_algorithm_user_arg_set_uint(run, 0, 0);
119 }
120
121 for (unsigned int i = 1; i < num_args; i++) {
122 uint32_t arg = va_arg(ap, uint32_t);
123 init_reg_param(&run->reg_args.params[run->reg_args.first_user_param + i], (char *)arg_regs[i], 32, PARAM_OUT);
124 esp_algorithm_user_arg_set_uint(run, i, arg);
125 LOG_DEBUG("Set arg[%d] = %d (%s)", i, arg, run->reg_args.params[run->reg_args.first_user_param + i].reg_name);
126 }
127
128 ainfo->core_mode = core_mode;
129 run->stub.ainfo = ainfo;
130 return ERROR_OK;
131 }
132
133 static int esp_xtensa_algo_cleanup(struct target *target, struct esp_algorithm_run_data *run)
134 {
135 free(run->stub.ainfo);
136 for (uint32_t i = 0; i < run->reg_args.count; i++)
137 destroy_reg_param(&run->reg_args.params[i]);
138 free(run->reg_args.params);
139 return ERROR_OK;
140 }

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)