From: openocd-gerrit <ope...@us...> - 2023-12-10 13:32:27
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 4003762177b1aec2ab27eaa6946b47f13c457bbc (commit) from d06d8ea3e4d0057dd13a6dac792b1ad7c246aebb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4003762177b1aec2ab27eaa6946b47f13c457bbc Author: Erhan Kurubas <erh...@es...> Date: Mon Jul 10 23:47:06 2023 +0200 target/espressif: add algorithm support to xtensa chips Also includes esp_xtensa flasher stub jumper binary. Signed-off-by: Erhan Kurubas <erh...@es...> Change-Id: I054ce31033ca6a87afe9b5325b545338a7d8fe8f Reviewed-on: https://review.openocd.org/c/openocd/+/7772 Tested-by: jenkins Reviewed-by: Ian Thompson <ia...@ca...> Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/contrib/loaders/trampoline/espressif/xtensa/Makefile b/contrib/loaders/trampoline/espressif/xtensa/Makefile new file mode 100644 index 000000000..bd1f63044 --- /dev/null +++ b/contrib/loaders/trampoline/espressif/xtensa/Makefile @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Espressif Xtensa Makefile to compile flasher stub wrapper +# Copyright (C) 2023 Espressif Systems Ltd. + +# Prefix for Espressif xtensa cross compilers (can include a directory path) +CROSS ?= xtensa-esp32-elf- + +APP_ARCH := xtensa +APP_CHIP_PATH := $(shell pwd) +SRCS := $(APP_CHIP_PATH)/esp_xtensa_stub_tramp_win.S + +BIN2C = ../../../../../src/helper/bin2char.sh +BUILD_DIR = build + +APP = esp_xtensa_stub_tramp_win +APP_OBJ = $(BUILD_DIR)/$(APP).o +APP_BIN = $(BUILD_DIR)/$(APP).bin +APP_CODE = $(APP).inc + +.PHONY: all clean + +all: $(BUILD_DIR) $(APP_OBJ) $(APP_CODE) + +$(BUILD_DIR): + $(Q) mkdir $@ + +$(APP_OBJ): $(SRCS) + @echo " CC $^ -> $@" + $(Q) $(CROSS)gcc -c $(CFLAGS) -o $@ $^ + +$(APP_CODE): $(APP_OBJ) + @echo " CC $^ -> $@" + $(Q) $(CROSS)objcopy -O binary -j.text $^ $(APP_BIN) + $(Q) $(BIN2C) < $(APP_BIN) > $@ + +clean: + $(Q) rm -rf $(BUILD_DIR) diff --git a/contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.S b/contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.S new file mode 100644 index 000000000..e0c827d9f --- /dev/null +++ b/contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.S @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Xtensa flasher stub wrapper * + * Copyright (C) 2017 Espressif Systems Ltd. * + ***************************************************************************/ + +/* + * Expects : + * a0 = zero + * a1 = stack_base + stack_size - 16, 16 bytes aligned + * a8 = address of the function to call + * Params : + * a2 = command arg0, result (out) + * a3 = command arg1 + * a4 = command arg2 + * a5 = command arg3 + * a6 = command arg4 + * Maximum 5 user args + */ + .text + + .align 4 +_stub_enter: + /* initialize initial stack frame for callx8 */ + addi a9, sp, 32 /* point 16 past extra save area */ + s32e a9, sp, -12 /* access to extra save area */ + /* prepare args */ + mov a10, a2 + mov a11, a3 + mov a12, a4 + mov a13, a5 + mov a14, a6 + /* call stub */ + callx8 a8 + /* prepare return value */ + mov a2, a10 + break 0,0 + +_idle_loop: + j _idle_loop diff --git a/contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.inc b/contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.inc new file mode 100644 index 000000000..1657223e1 --- /dev/null +++ b/contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.inc @@ -0,0 +1,3 @@ +/* Autogenerated with ../../../../../src/helper/bin2char.sh */ +0x92,0xc1,0x20,0x90,0xd1,0x49,0xad,0x02,0xbd,0x03,0xcd,0x04,0xdd,0x05,0x60,0xe6, +0x20,0xe0,0x08,0x00,0x2d,0x0a,0x00,0x40,0x00,0x06,0xff,0xff, diff --git a/src/target/espressif/Makefile.am b/src/target/espressif/Makefile.am index 1fbd926d9..cf82ee995 100644 --- a/src/target/espressif/Makefile.am +++ b/src/target/espressif/Makefile.am @@ -10,6 +10,8 @@ noinst_LTLIBRARIES += %D%/libespressif.la %D%/esp_xtensa_semihosting.h \ %D%/esp_xtensa_apptrace.c \ %D%/esp_xtensa_apptrace.h \ + %D%/esp_xtensa_algorithm.c \ + %D%/esp_xtensa_algorithm.h \ %D%/esp32_apptrace.c \ %D%/esp32_apptrace.h \ %D%/esp32.c \ diff --git a/src/target/espressif/esp.c b/src/target/espressif/esp.c index 9583d6493..600f6d7e9 100644 --- a/src/target/espressif/esp.c +++ b/src/target/espressif/esp.c @@ -14,6 +14,16 @@ #include "target/target.h" #include "esp.h" +int esp_common_init(struct esp_common *esp, const struct esp_algorithm_hw *algo_hw) +{ + if (!esp) + return ERROR_FAIL; + + esp->algo_hw = algo_hw; + + return ERROR_OK; +} + int esp_dbgstubs_table_read(struct target *target, struct esp_dbg_stubs *dbg_stubs) { uint32_t table_size, table_start_id, desc_entry_id, gcov_entry_id; diff --git a/src/target/espressif/esp.h b/src/target/espressif/esp.h index 3ba2b8bcf..6e0a2d2d3 100644 --- a/src/target/espressif/esp.h +++ b/src/target/espressif/esp.h @@ -77,9 +77,11 @@ struct esp_dbg_stubs { }; struct esp_common { + const struct esp_algorithm_hw *algo_hw; struct esp_dbg_stubs dbg_stubs; }; +int esp_common_init(struct esp_common *esp, const struct esp_algorithm_hw *algo_hw); int esp_dbgstubs_table_read(struct target *target, struct esp_dbg_stubs *dbg_stubs); #endif /* OPENOCD_TARGET_ESP_H */ diff --git a/src/target/espressif/esp32.c b/src/target/espressif/esp32.c index b510f287c..324aa3993 100644 --- a/src/target/espressif/esp32.c +++ b/src/target/espressif/esp32.c @@ -484,6 +484,10 @@ struct target_type esp32_target = { .get_gdb_arch = xtensa_get_gdb_arch, .get_gdb_reg_list = xtensa_get_gdb_reg_list, + .run_algorithm = xtensa_run_algorithm, + .start_algorithm = xtensa_start_algorithm, + .wait_algorithm = xtensa_wait_algorithm, + .add_breakpoint = esp_xtensa_breakpoint_add, .remove_breakpoint = esp_xtensa_breakpoint_remove, diff --git a/src/target/espressif/esp32s2.c b/src/target/espressif/esp32s2.c index dadc130c1..2abde479e 100644 --- a/src/target/espressif/esp32s2.c +++ b/src/target/espressif/esp32s2.c @@ -521,6 +521,10 @@ struct target_type esp32s2_target = { .get_gdb_arch = xtensa_get_gdb_arch, .get_gdb_reg_list = xtensa_get_gdb_reg_list, + .run_algorithm = xtensa_run_algorithm, + .start_algorithm = xtensa_start_algorithm, + .wait_algorithm = xtensa_wait_algorithm, + .add_breakpoint = esp_xtensa_breakpoint_add, .remove_breakpoint = esp_xtensa_breakpoint_remove, diff --git a/src/target/espressif/esp32s3.c b/src/target/espressif/esp32s3.c index 5036956ee..22e1630e1 100644 --- a/src/target/espressif/esp32s3.c +++ b/src/target/espressif/esp32s3.c @@ -405,6 +405,10 @@ struct target_type esp32s3_target = { .get_gdb_arch = xtensa_get_gdb_arch, .get_gdb_reg_list = xtensa_get_gdb_reg_list, + .run_algorithm = xtensa_run_algorithm, + .start_algorithm = xtensa_start_algorithm, + .wait_algorithm = xtensa_wait_algorithm, + .add_breakpoint = esp_xtensa_breakpoint_add, .remove_breakpoint = esp_xtensa_breakpoint_remove, diff --git a/src/target/espressif/esp_xtensa.c b/src/target/espressif/esp_xtensa.c index 0bd2cdd9d..11895d23b 100644 --- a/src/target/espressif/esp_xtensa.c +++ b/src/target/espressif/esp_xtensa.c @@ -12,10 +12,12 @@ #include <stdbool.h> #include <stdint.h> #include <target/smp.h> -#include "esp_xtensa_apptrace.h" #include <target/register.h> +#include "esp.h" #include "esp_xtensa.h" +#include "esp_xtensa_apptrace.h" #include "esp_semihosting.h" +#include "esp_xtensa_algorithm.h" #define ESP_XTENSA_DBGSTUBS_UPDATE_DATA_ENTRY(_e_) \ do { \ @@ -68,6 +70,10 @@ int esp_xtensa_init_arch_info(struct target *target, int ret = xtensa_init_arch_info(target, &esp_xtensa->xtensa, dm_cfg); if (ret != ERROR_OK) return ret; + ret = esp_common_init(&esp_xtensa->esp, &xtensa_algo_hw); + if (ret != ERROR_OK) + return ret; + esp_xtensa->semihost.ops = (struct esp_semihost_ops *)semihost_ops; esp_xtensa->apptrace.hw = &esp_xtensa_apptrace_hw; return ERROR_OK; diff --git a/src/target/espressif/esp_xtensa_algorithm.c b/src/target/espressif/esp_xtensa_algorithm.c new file mode 100644 index 000000000..68005cbf2 --- /dev/null +++ b/src/target/espressif/esp_xtensa_algorithm.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/*************************************************************************** + * Module to run arbitrary code on Xtensa using OpenOCD * + * Copyright (C) 2019 Espressif Systems Ltd. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <target/xtensa/xtensa.h> +#include "esp_xtensa_algorithm.h" + +static int esp_xtensa_algo_init(struct target *target, struct esp_algorithm_run_data *run, + uint32_t num_args, va_list ap); +static int esp_xtensa_algo_cleanup(struct target *target, struct esp_algorithm_run_data *run); +static const uint8_t *esp_xtensa_stub_tramp_get(struct target *target, size_t *size); + +const struct esp_algorithm_hw xtensa_algo_hw = { + .algo_init = esp_xtensa_algo_init, + .algo_cleanup = esp_xtensa_algo_cleanup, + .stub_tramp_get = esp_xtensa_stub_tramp_get, +}; + +/* Generated from contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.S */ +static const uint8_t esp_xtensa_stub_tramp_win[] = { +#include "../../../contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.inc" +}; + +static const uint8_t *esp_xtensa_stub_tramp_get(struct target *target, size_t *size) +{ + struct xtensa *xtensa = target_to_xtensa(target); + + if (!xtensa->core_config->windowed) { + LOG_ERROR("Running stubs is not supported for cores without windowed registers option!"); + return NULL; + } + *size = sizeof(esp_xtensa_stub_tramp_win); + return esp_xtensa_stub_tramp_win; +} + +static int esp_xtensa_algo_regs_init_start(struct target *target, struct esp_algorithm_run_data *run) +{ + uint32_t stack_addr = run->stub.stack_addr; + + LOG_TARGET_DEBUG(target, "Check stack addr 0x%x", stack_addr); + if (stack_addr & 0xFUL) { + stack_addr &= ~0xFUL; + LOG_TARGET_DEBUG(target, "Adjust stack addr to 0x%x", stack_addr); + } + stack_addr -= 16; + struct reg_param *params = run->reg_args.params; + init_reg_param(¶ms[0], "a0", 32, PARAM_OUT); /*TODO: move to tramp */ + init_reg_param(¶ms[1], "a1", 32, PARAM_OUT); + init_reg_param(¶ms[2], "a8", 32, PARAM_OUT); + init_reg_param(¶ms[3], "windowbase", 32, PARAM_OUT); /*TODO: move to tramp */ + init_reg_param(¶ms[4], "windowstart", 32, PARAM_OUT); /*TODO: move to tramp */ + init_reg_param(¶ms[5], "ps", 32, PARAM_OUT); + buf_set_u32(params[0].value, 0, 32, 0); /* a0 TODO: move to tramp */ + buf_set_u32(params[1].value, 0, 32, stack_addr); /* a1 */ + buf_set_u32(params[2].value, 0, 32, run->stub.entry); /* a8 */ + buf_set_u32(params[3].value, 0, 32, 0x0); /* initial window base TODO: move to tramp */ + buf_set_u32(params[4].value, 0, 32, 0x1); /* initial window start TODO: move to tramp */ + buf_set_u32(params[5].value, 0, 32, 0x60025); /* enable WOE, UM and debug interrupts level (6) */ + return ERROR_OK; +} + +static int esp_xtensa_algo_init(struct target *target, struct esp_algorithm_run_data *run, + uint32_t num_args, va_list ap) +{ + enum xtensa_mode core_mode = XT_MODE_ANY; + static const char *const arg_regs[] = { "a2", "a3", "a4", "a5", "a6" }; + + if (!run) + return ERROR_FAIL; + + if (num_args > ARRAY_SIZE(arg_regs)) { + LOG_ERROR("Too many algo user args %u! Max %zu args are supported.", num_args, ARRAY_SIZE(arg_regs)); + return ERROR_FAIL; + } + + struct xtensa_algorithm *ainfo = calloc(1, sizeof(struct xtensa_algorithm)); + if (!ainfo) { + LOG_ERROR("Unable to allocate memory"); + return ERROR_FAIL; + } + + if (run->arch_info) { + struct xtensa_algorithm *xtensa_algo = run->arch_info; + core_mode = xtensa_algo->core_mode; + } + + run->reg_args.first_user_param = ESP_XTENSA_STUB_ARGS_FUNC_START; + run->reg_args.count = run->reg_args.first_user_param + num_args; + if (num_args == 0) + run->reg_args.count++; /* a2 reg is used as the 1st arg and return code */ + LOG_DEBUG("reg params count %d (%d/%d).", + run->reg_args.count, + run->reg_args.first_user_param, + num_args); + run->reg_args.params = calloc(run->reg_args.count, sizeof(struct reg_param)); + if (!run->reg_args.params) { + free(ainfo); + LOG_ERROR("Unable to allocate memory"); + return ERROR_FAIL; + } + + esp_xtensa_algo_regs_init_start(target, run); + + init_reg_param(&run->reg_args.params[run->reg_args.first_user_param + 0], "a2", 32, PARAM_IN_OUT); + + if (num_args > 0) { + uint32_t arg = va_arg(ap, uint32_t); + esp_algorithm_user_arg_set_uint(run, 0, arg); + LOG_DEBUG("Set arg[0] = %d (%s)", arg, run->reg_args.params[run->reg_args.first_user_param + 0].reg_name); + } else { + esp_algorithm_user_arg_set_uint(run, 0, 0); + } + + for (unsigned int i = 1; i < num_args; i++) { + uint32_t arg = va_arg(ap, uint32_t); + init_reg_param(&run->reg_args.params[run->reg_args.first_user_param + i], (char *)arg_regs[i], 32, PARAM_OUT); + esp_algorithm_user_arg_set_uint(run, i, arg); + LOG_DEBUG("Set arg[%d] = %d (%s)", i, arg, run->reg_args.params[run->reg_args.first_user_param + i].reg_name); + } + + ainfo->core_mode = core_mode; + run->stub.ainfo = ainfo; + return ERROR_OK; +} + +static int esp_xtensa_algo_cleanup(struct target *target, struct esp_algorithm_run_data *run) +{ + free(run->stub.ainfo); + for (uint32_t i = 0; i < run->reg_args.count; i++) + destroy_reg_param(&run->reg_args.params[i]); + free(run->reg_args.params); + return ERROR_OK; +} diff --git a/src/target/espressif/esp_xtensa_algorithm.h b/src/target/espressif/esp_xtensa_algorithm.h new file mode 100644 index 000000000..36fa1a331 --- /dev/null +++ b/src/target/espressif/esp_xtensa_algorithm.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/*************************************************************************** + * Module to run arbitrary code on Xtensa using OpenOCD * + * Copyright (C) 2019 Espressif Systems Ltd. * + ***************************************************************************/ + +#ifndef OPENOCD_TARGET_ESP_XTENSA_ALGO_H +#define OPENOCD_TARGET_ESP_XTENSA_ALGO_H + +#include <target/xtensa/xtensa.h> +#include <target/espressif/esp_algorithm.h> + +/** Index of the first user-defined algo arg. @see algorithm_stub */ +#define ESP_XTENSA_STUB_ARGS_FUNC_START 6 + +extern const struct esp_algorithm_hw xtensa_algo_hw; + +#endif /* OPENOCD_TARGET_XTENSA_ALGO_H */ ----------------------------------------------------------------------- Summary of changes: .../espressif/xtensa/Makefile} | 26 ++-- .../espressif/xtensa/esp_xtensa_stub_tramp_win.S | 41 ++++++ .../espressif/xtensa/esp_xtensa_stub_tramp_win.inc | 3 + src/target/espressif/Makefile.am | 2 + src/target/espressif/esp.c | 10 ++ src/target/espressif/esp.h | 2 + src/target/espressif/esp32.c | 4 + src/target/espressif/esp32s2.c | 4 + src/target/espressif/esp32s3.c | 4 + src/target/espressif/esp_xtensa.c | 8 +- src/target/espressif/esp_xtensa_algorithm.c | 140 +++++++++++++++++++++ src/target/espressif/esp_xtensa_algorithm.h | 19 +++ 12 files changed, 248 insertions(+), 15 deletions(-) copy contrib/loaders/{reset/espressif/common.mk => trampoline/espressif/xtensa/Makefile} (53%) create mode 100644 contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.S create mode 100644 contrib/loaders/trampoline/espressif/xtensa/esp_xtensa_stub_tramp_win.inc create mode 100644 src/target/espressif/esp_xtensa_algorithm.c create mode 100644 src/target/espressif/esp_xtensa_algorithm.h hooks/post-receive -- Main OpenOCD repository |