1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Semihosting API for Espressif chips *
5 * Copyright (C) 2022 Espressif Systems Ltd. *
6 ***************************************************************************/
12 #include <helper/log.h>
13 #include <target/target.h>
14 #include <target/semihosting_common.h>
15 #include "esp_semihosting.h"
16 #include "esp_xtensa.h"
18 static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target)
20 const char *arch = target_get_gdb_arch(target);
22 if (strncmp(arch, "xtensa", 6) == 0)
23 return &target_to_esp_xtensa(target)->semihost;
26 LOG_ERROR("Unknown target arch!");
30 static int esp_semihosting_sys_seek(struct target *target, uint64_t fd, uint32_t pos, size_t whence)
32 struct semihosting *semihosting = target->semihosting;
34 semihosting->result = lseek(fd, pos, whence);
35 semihosting->sys_errno = errno;
36 LOG_TARGET_DEBUG(target, "lseek(%" PRIx64 ", %" PRIu32 " %" PRId64 ")=%d", fd, pos, semihosting->result, errno);
40 int esp_semihosting_common(struct target *target)
42 struct semihosting *semihosting = target->semihosting;
44 /* Silently ignore if the semihosting field was not set. */
47 int retval = ERROR_NOT_IMPLEMENTED;
49 /* Enough space to hold 4 long words. */
50 uint8_t fields[4 * 8];
53 * By default return an error.
54 * The actual result must be set by each function
56 semihosting->result = -1;
57 semihosting->sys_errno = EIO;
59 LOG_TARGET_DEBUG(target, "op=0x%x, param=0x%" PRIx64, semihosting->op, semihosting->param);
61 switch (semihosting->op) {
62 case ESP_SEMIHOSTING_SYS_DRV_INFO:
63 /* Return success to make esp-idf application happy */
65 semihosting->result = 0;
66 semihosting->sys_errno = 0;
69 case ESP_SEMIHOSTING_SYS_SEEK:
70 retval = semihosting_read_fields(target, 3, fields);
71 if (retval == ERROR_OK) {
72 uint64_t fd = semihosting_get_field(target, 0, fields);
73 uint32_t pos = semihosting_get_field(target, 1, fields);
74 size_t whence = semihosting_get_field(target, 2, fields);
75 retval = esp_semihosting_sys_seek(target, fd, pos, whence);
79 case ESP_SEMIHOSTING_SYS_APPTRACE_INIT:
80 case ESP_SEMIHOSTING_SYS_DEBUG_STUBS_INIT:
81 case ESP_SEMIHOSTING_SYS_BREAKPOINT_SET:
82 case ESP_SEMIHOSTING_SYS_WATCHPOINT_SET:
83 /* For the time being only riscv chips support these commands
84 * TODO: invoke riscv custom command handler */
91 int esp_semihosting_basedir_command(struct command_invocation *cmd)
93 struct target *target = get_current_target(CMD_CTX);
96 LOG_ERROR("No target selected");
100 struct semihosting *semihosting = target->semihosting;
102 command_print(CMD, "semihosting not supported for current target");
106 if (!semihosting->is_active) {
107 if (semihosting->setup(target, true) != ERROR_OK) {
108 LOG_ERROR("Failed to Configure semihosting");
111 semihosting->is_active = true;
115 free(semihosting->basedir);
116 semihosting->basedir = strdup(CMD_ARGV[0]);
117 if (!semihosting->basedir) {
118 command_print(CMD, "semihosting failed to allocate memory for basedir!");
123 command_print(CMD, "DEPRECATED! semihosting base dir: %s",
124 semihosting->basedir ? semihosting->basedir : "");