xtensa: make local symbols static
[fw/openocd] / src / target / espressif / esp_semihosting.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Semihosting API for Espressif chips                                   *
5  *   Copyright (C) 2022 Espressif Systems Ltd.                             *
6  ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
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"
17
18 static struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target)
19 {
20         const char *arch = target_get_gdb_arch(target);
21         if (arch) {
22                 if (strncmp(arch, "xtensa", 6) == 0)
23                         return &target_to_esp_xtensa(target)->semihost;
24                 /* TODO: add riscv */
25         }
26         LOG_ERROR("Unknown target arch!");
27         return NULL;
28 }
29
30 static int esp_semihosting_sys_seek(struct target *target, uint64_t fd, uint32_t pos, size_t whence)
31 {
32         struct semihosting *semihosting = target->semihosting;
33
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);
37         return ERROR_OK;
38 }
39
40 int esp_semihosting_common(struct target *target)
41 {
42         struct semihosting *semihosting = target->semihosting;
43         if (!semihosting)
44                 /* Silently ignore if the semihosting field was not set. */
45                 return ERROR_OK;
46
47         int retval = ERROR_NOT_IMPLEMENTED;
48
49         /* Enough space to hold 4 long words. */
50         uint8_t fields[4 * 8];
51
52         /*
53          * By default return an error.
54          * The actual result must be set by each function
55          */
56         semihosting->result = -1;
57         semihosting->sys_errno = EIO;
58
59         LOG_TARGET_DEBUG(target, "op=0x%x, param=0x%" PRIx64, semihosting->op, semihosting->param);
60
61         switch (semihosting->op) {
62         case ESP_SEMIHOSTING_SYS_DRV_INFO:
63                 /* Return success to make esp-idf application happy */
64                 retval = ERROR_OK;
65                 semihosting->result = 0;
66                 semihosting->sys_errno = 0;
67                 break;
68
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);
76                 }
77                 break;
78
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 */
85                 break;
86         }
87
88         return retval;
89 }
90
91 int esp_semihosting_basedir_command(struct command_invocation *cmd)
92 {
93         struct target *target = get_current_target(CMD_CTX);
94
95         if (!target) {
96                 LOG_ERROR("No target selected");
97                 return ERROR_FAIL;
98         }
99
100         struct semihosting *semihosting = target->semihosting;
101         if (!semihosting) {
102                 command_print(CMD, "semihosting not supported for current target");
103                 return ERROR_FAIL;
104         }
105
106         if (!semihosting->is_active) {
107                 if (semihosting->setup(target, true) != ERROR_OK) {
108                         LOG_ERROR("Failed to Configure semihosting");
109                         return ERROR_FAIL;
110                 }
111                 semihosting->is_active = true;
112         }
113
114         if (CMD_ARGC > 0) {
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!");
119                         return ERROR_FAIL;
120                 }
121         }
122
123         command_print(CMD, "DEPRECATED! semihosting base dir: %s",
124                 semihosting->basedir ? semihosting->basedir : "");
125
126         return ERROR_OK;
127 }