Files
sw_openocd/src/target/espressif/esp_semihosting.c
Erhan Kurubas faeae51d7f target/espressif: check common_magic instead of gdb_arch string
The value returned by target_get_gdb_arch() is something specific for GDB.
There could be several variants of the same CPU.
If we start implementing all the variants, checking the string value,
could become incorrect.
It's better to check for xtensa->common_magic == XTENSA_COMMON_MAGIC

Signed-off-by: Erhan Kurubas <erhan.kurubas@espressif.com>
Change-Id: I20f3fdced176c3b9ab00f889743161ecad7280f9
Reviewed-on: https://review.openocd.org/c/openocd/+/7536
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
2023-03-25 18:06:36 +00:00

126 lines
3.6 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/***************************************************************************
* Semihosting API for Espressif chips *
* Copyright (C) 2022 Espressif Systems Ltd. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <helper/log.h>
#include <target/target.h>
#include <target/semihosting_common.h>
#include "esp_semihosting.h"
#include "esp_xtensa.h"
static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target)
{
struct xtensa *xtensa = target->arch_info;
if (xtensa->common_magic == XTENSA_COMMON_MAGIC)
return &target_to_esp_xtensa(target)->semihost;
/* TODO: add riscv */
LOG_ERROR("Unknown target arch!");
return NULL;
}
static int esp_semihosting_sys_seek(struct target *target, uint64_t fd, uint32_t pos, size_t whence)
{
struct semihosting *semihosting = target->semihosting;
semihosting->result = lseek(fd, pos, whence);
semihosting->sys_errno = errno;
LOG_TARGET_DEBUG(target, "lseek(%" PRIx64 ", %" PRIu32 " %" PRId64 ")=%d", fd, pos, semihosting->result, errno);
return ERROR_OK;
}
int esp_semihosting_common(struct target *target)
{
struct semihosting *semihosting = target->semihosting;
if (!semihosting)
/* Silently ignore if the semihosting field was not set. */
return ERROR_OK;
int retval = ERROR_NOT_IMPLEMENTED;
/* Enough space to hold 4 long words. */
uint8_t fields[4 * 8];
/*
* By default return an error.
* The actual result must be set by each function
*/
semihosting->result = -1;
semihosting->sys_errno = EIO;
LOG_TARGET_DEBUG(target, "op=0x%x, param=0x%" PRIx64, semihosting->op, semihosting->param);
switch (semihosting->op) {
case ESP_SEMIHOSTING_SYS_DRV_INFO:
/* Return success to make esp-idf application happy */
retval = ERROR_OK;
semihosting->result = 0;
semihosting->sys_errno = 0;
break;
case ESP_SEMIHOSTING_SYS_SEEK:
retval = semihosting_read_fields(target, 3, fields);
if (retval == ERROR_OK) {
uint64_t fd = semihosting_get_field(target, 0, fields);
uint32_t pos = semihosting_get_field(target, 1, fields);
size_t whence = semihosting_get_field(target, 2, fields);
retval = esp_semihosting_sys_seek(target, fd, pos, whence);
}
break;
case ESP_SEMIHOSTING_SYS_APPTRACE_INIT:
case ESP_SEMIHOSTING_SYS_DEBUG_STUBS_INIT:
case ESP_SEMIHOSTING_SYS_BREAKPOINT_SET:
case ESP_SEMIHOSTING_SYS_WATCHPOINT_SET:
/* For the time being only riscv chips support these commands
* TODO: invoke riscv custom command handler */
break;
}
return retval;
}
int esp_semihosting_basedir_command(struct command_invocation *cmd)
{
struct target *target = get_current_target(CMD_CTX);
if (!target) {
LOG_ERROR("No target selected");
return ERROR_FAIL;
}
struct semihosting *semihosting = target->semihosting;
if (!semihosting) {
command_print(CMD, "semihosting not supported for current target");
return ERROR_FAIL;
}
if (!semihosting->is_active) {
if (semihosting->setup(target, true) != ERROR_OK) {
LOG_ERROR("Failed to Configure semihosting");
return ERROR_FAIL;
}
semihosting->is_active = true;
}
if (CMD_ARGC > 0) {
free(semihosting->basedir);
semihosting->basedir = strdup(CMD_ARGV[0]);
if (!semihosting->basedir) {
command_print(CMD, "semihosting failed to allocate memory for basedir!");
return ERROR_FAIL;
}
}
command_print(CMD, "DEPRECATED! semihosting base dir: %s",
semihosting->basedir ? semihosting->basedir : "");
return ERROR_OK;
}