1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2018 by Liviu Ionescu *
7 * Copyright (C) 2018 by Marvell Technology Group Ltd. *
8 * Written by Nicolas Pitre <nico@marvell.com> *
10 * Copyright (C) 2010 by Spencer Oliver *
11 * spen@spen-soft.co.uk *
13 * Copyright (C) 2016 by Square, Inc. *
14 * Steven Stallion <stallion@squareup.com> *
15 ***************************************************************************/
19 * Common ARM semihosting support.
21 * Semihosting enables code running on a target to use some of the I/O
22 * facilities on the host computer. The target application must be linked
23 * against a library that forwards operation requests by using an
24 * instruction trapped by the debugger.
26 * Details can be found in
27 * "Semihosting for AArch32 and AArch64, Release 2.0"
28 * https://static.docs.arm.com/100863/0200/semihosting.pdf
37 #include "target_type.h"
38 #include "semihosting_common.h"
40 #include <helper/binarybuffer.h>
41 #include <helper/log.h>
42 #include <server/gdb_server.h>
46 * It is not possible to use O_... flags defined in sys/stat.h because they
47 * are not guaranteed to match the values defined by the GDB Remote Protocol.
48 * See https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags
51 TARGET_O_RDONLY
= 0x000,
52 TARGET_O_WRONLY
= 0x001,
53 TARGET_O_RDWR
= 0x002,
54 TARGET_O_APPEND
= 0x008,
55 TARGET_O_CREAT
= 0x200,
56 TARGET_O_TRUNC
= 0x400,
57 /* O_EXCL=0x800 is not required in this implementation. */
60 /* GDB remote protocol does not differentiate between text and binary open modes. */
61 static const int open_gdb_modeflags
[12] = {
66 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
67 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
68 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
69 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_TRUNC
,
70 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_APPEND
,
71 TARGET_O_WRONLY
| TARGET_O_CREAT
| TARGET_O_APPEND
,
72 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_APPEND
,
73 TARGET_O_RDWR
| TARGET_O_CREAT
| TARGET_O_APPEND
76 static const int open_host_modeflags
[12] = {
81 O_WRONLY
| O_CREAT
| O_TRUNC
,
82 O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
,
83 O_RDWR
| O_CREAT
| O_TRUNC
,
84 O_RDWR
| O_CREAT
| O_TRUNC
| O_BINARY
,
85 O_WRONLY
| O_CREAT
| O_APPEND
,
86 O_WRONLY
| O_CREAT
| O_APPEND
| O_BINARY
,
87 O_RDWR
| O_CREAT
| O_APPEND
,
88 O_RDWR
| O_CREAT
| O_APPEND
| O_BINARY
91 static int semihosting_common_fileio_info(struct target
*target
,
92 struct gdb_fileio_info
*fileio_info
);
93 static int semihosting_common_fileio_end(struct target
*target
, int result
,
94 int fileio_errno
, bool ctrl_c
);
97 * Initialize common semihosting support.
99 * @param target Pointer to the target to initialize.
102 * @return An error status if there is a problem during initialization.
104 int semihosting_common_init(struct target
*target
, void *setup
,
109 target
->fileio_info
= malloc(sizeof(*target
->fileio_info
));
110 if (!target
->fileio_info
) {
111 LOG_ERROR("out of memory");
114 memset(target
->fileio_info
, 0, sizeof(*target
->fileio_info
));
116 struct semihosting
*semihosting
;
117 semihosting
= malloc(sizeof(*target
->semihosting
));
119 LOG_ERROR("out of memory");
123 semihosting
->is_active
= false;
124 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
125 semihosting
->tcp_connection
= NULL
;
126 semihosting
->stdin_fd
= -1;
127 semihosting
->stdout_fd
= -1;
128 semihosting
->stderr_fd
= -1;
129 semihosting
->is_fileio
= false;
130 semihosting
->hit_fileio
= false;
131 semihosting
->is_resumable
= false;
132 semihosting
->has_resumable_exit
= false;
133 semihosting
->word_size_bytes
= 0;
134 semihosting
->op
= -1;
135 semihosting
->param
= 0;
136 semihosting
->result
= -1;
137 semihosting
->sys_errno
= -1;
138 semihosting
->cmdline
= NULL
;
139 semihosting
->basedir
= NULL
;
141 /* If possible, update it in setup(). */
142 semihosting
->setup_time
= clock();
144 semihosting
->setup
= setup
;
145 semihosting
->post_result
= post_result
;
146 semihosting
->user_command_extension
= NULL
;
148 target
->semihosting
= semihosting
;
150 target
->type
->get_gdb_fileio_info
= semihosting_common_fileio_info
;
151 target
->type
->gdb_fileio_end
= semihosting_common_fileio_end
;
156 struct semihosting_tcp_service
{
157 struct semihosting
*semihosting
;
162 static bool semihosting_is_redirected(struct semihosting
*semihosting
, int fd
)
164 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_NONE
)
167 bool is_read_op
= false;
169 switch (semihosting
->op
) {
170 /* check debug semihosting operations: READC, WRITEC and WRITE0 */
171 case SEMIHOSTING_SYS_READC
:
174 case SEMIHOSTING_SYS_WRITEC
:
175 case SEMIHOSTING_SYS_WRITE0
:
176 /* debug operations are redirected when CFG is either DEBUG or ALL */
177 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_STDIO
)
181 /* check stdio semihosting operations: READ and WRITE */
182 case SEMIHOSTING_SYS_READ
:
185 case SEMIHOSTING_SYS_WRITE
:
186 /* stdio operations are redirected when CFG is either STDIO or ALL */
187 if (semihosting
->redirect_cfg
== SEMIHOSTING_REDIRECT_CFG_DEBUG
)
196 return fd
== semihosting
->stdin_fd
;
198 /* write operation */
199 return fd
== semihosting
->stdout_fd
|| fd
== semihosting
->stderr_fd
;
202 static ssize_t
semihosting_redirect_write(struct semihosting
*semihosting
, void *buf
, int size
)
204 if (!semihosting
->tcp_connection
) {
205 LOG_ERROR("No connected TCP client for semihosting");
206 semihosting
->sys_errno
= EBADF
; /* Bad file number */
210 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
212 int retval
= connection_write(semihosting
->tcp_connection
, buf
, size
);
215 log_socket_error(service
->name
);
220 static ssize_t
semihosting_write(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
222 if (semihosting_is_redirected(semihosting
, fd
))
223 return semihosting_redirect_write(semihosting
, buf
, size
);
226 return write(fd
, buf
, size
);
229 static ssize_t
semihosting_redirect_read(struct semihosting
*semihosting
, void *buf
, int size
)
231 if (!semihosting
->tcp_connection
) {
232 LOG_ERROR("No connected TCP client for semihosting");
233 semihosting
->sys_errno
= EBADF
; /* Bad file number */
237 struct semihosting_tcp_service
*service
= semihosting
->tcp_connection
->service
->priv
;
239 service
->error
= ERROR_OK
;
240 semihosting
->tcp_connection
->input_pending
= true;
242 int retval
= connection_read(semihosting
->tcp_connection
, buf
, size
);
245 service
->error
= ERROR_SERVER_REMOTE_CLOSED
;
248 log_socket_error(service
->name
);
250 semihosting
->tcp_connection
->input_pending
= false;
255 static inline int semihosting_putchar(struct semihosting
*semihosting
, int fd
, int c
)
257 if (semihosting_is_redirected(semihosting
, fd
))
258 return semihosting_redirect_write(semihosting
, &c
, 1);
260 /* default putchar */
264 static inline ssize_t
semihosting_read(struct semihosting
*semihosting
, int fd
, void *buf
, int size
)
266 if (semihosting_is_redirected(semihosting
, fd
))
267 return semihosting_redirect_read(semihosting
, buf
, size
);
270 ssize_t result
= read(fd
, buf
, size
);
271 semihosting
->sys_errno
= errno
;
276 static inline int semihosting_getchar(struct semihosting
*semihosting
, int fd
)
278 if (semihosting_is_redirected(semihosting
, fd
)) {
281 if (semihosting_redirect_read(semihosting
, &c
, 1) > 0)
287 /* default getchar */
292 * User operation parameter string storage buffer. Contains valid data when the
293 * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.
295 static char *semihosting_user_op_params
;
297 const char *semihosting_opcode_to_str(const uint64_t opcode
)
300 case SEMIHOSTING_SYS_CLOSE
:
302 case SEMIHOSTING_SYS_CLOCK
:
304 case SEMIHOSTING_SYS_ELAPSED
:
306 case SEMIHOSTING_SYS_ERRNO
:
308 case SEMIHOSTING_SYS_EXIT
:
310 case SEMIHOSTING_SYS_EXIT_EXTENDED
:
311 return "EXIT_EXTENDED";
312 case SEMIHOSTING_SYS_FLEN
:
314 case SEMIHOSTING_SYS_GET_CMDLINE
:
315 return "GET_CMDLINE";
316 case SEMIHOSTING_SYS_HEAPINFO
:
318 case SEMIHOSTING_SYS_ISERROR
:
320 case SEMIHOSTING_SYS_ISTTY
:
322 case SEMIHOSTING_SYS_OPEN
:
324 case SEMIHOSTING_SYS_READ
:
326 case SEMIHOSTING_SYS_READC
:
328 case SEMIHOSTING_SYS_REMOVE
:
330 case SEMIHOSTING_SYS_RENAME
:
332 case SEMIHOSTING_SYS_SEEK
:
334 case SEMIHOSTING_SYS_SYSTEM
:
336 case SEMIHOSTING_SYS_TICKFREQ
:
338 case SEMIHOSTING_SYS_TIME
:
340 case SEMIHOSTING_SYS_TMPNAM
:
342 case SEMIHOSTING_SYS_WRITE
:
344 case SEMIHOSTING_SYS_WRITEC
:
346 case SEMIHOSTING_SYS_WRITE0
:
348 case SEMIHOSTING_USER_CMD_0X100
... SEMIHOSTING_USER_CMD_0X1FF
:
350 case SEMIHOSTING_ARM_RESERVED_START
... SEMIHOSTING_ARM_RESERVED_END
:
351 return "ARM_RESERVED_CMD";
358 * Portable implementation of ARM semihosting calls.
359 * Performs the currently pending semihosting operation
360 * encoded in target->semihosting.
362 int semihosting_common(struct target
*target
)
364 struct semihosting
*semihosting
= target
->semihosting
;
366 /* Silently ignore if the semihosting field was not set. */
370 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
373 * By default return an error.
374 * The actual result must be set by each function
376 semihosting
->result
= -1;
378 /* Most operations are resumable, except the two exit calls. */
379 semihosting
->is_resumable
= true;
383 /* Enough space to hold 4 long words. */
386 LOG_DEBUG("op=0x%x (%s), param=0x%" PRIx64
, semihosting
->op
,
387 semihosting_opcode_to_str(semihosting
->op
),
390 switch (semihosting
->op
) {
392 case SEMIHOSTING_SYS_CLOCK
: /* 0x10 */
394 * Returns the number of centiseconds (hundredths of a second)
395 * since the execution started.
397 * Values returned can be of limited use for some benchmarking
398 * purposes because of communication overhead or other
399 * agent-specific factors. For example, with a debug hardware
400 * unit the request is passed back to the host for execution.
401 * This can lead to unpredictable delays in transmission and
402 * process scheduling.
404 * Use this function to calculate time intervals, by calculating
405 * differences between intervals with and without the code
406 * sequence to be timed.
409 * The PARAMETER REGISTER must contain 0. There are no other
413 * On exit, the RETURN REGISTER contains:
414 * - The number of centiseconds since some arbitrary start
415 * point, if the call is successful.
416 * - –1 if the call is not successful. For example, because
417 * of a communications error.
420 clock_t delta
= clock() - semihosting
->setup_time
;
422 semihosting
->result
= delta
/ (CLOCKS_PER_SEC
/ 100);
426 case SEMIHOSTING_SYS_CLOSE
: /* 0x02 */
428 * Closes a file on the host system. The handle must reference
429 * a file that was opened with SYS_OPEN.
432 * On entry, the PARAMETER REGISTER contains a pointer to a
433 * one-field argument block:
434 * - field 1 Contains a handle for an open file.
437 * On exit, the RETURN REGISTER contains:
438 * - 0 if the call is successful
439 * - –1 if the call is not successful.
441 retval
= semihosting_read_fields(target
, 1, fields
);
442 if (retval
!= ERROR_OK
)
445 int fd
= semihosting_get_field(target
, 0, fields
);
446 /* Do not allow to close OpenOCD's own standard streams */
447 if (fd
== 0 || fd
== 1 || fd
== 2) {
448 LOG_DEBUG("ignoring semihosting attempt to close %s",
449 (fd
== 0) ? "stdin" :
450 (fd
== 1) ? "stdout" : "stderr");
451 /* Just pretend success */
452 if (semihosting
->is_fileio
) {
453 semihosting
->result
= 0;
455 semihosting
->result
= 0;
456 semihosting
->sys_errno
= 0;
460 /* Close the descriptor */
461 if (semihosting
->is_fileio
) {
462 semihosting
->hit_fileio
= true;
463 fileio_info
->identifier
= "close";
464 fileio_info
->param_1
= fd
;
466 semihosting
->result
= close(fd
);
467 semihosting
->sys_errno
= errno
;
468 LOG_DEBUG("close(%d)=%" PRId64
, fd
, semihosting
->result
);
473 case SEMIHOSTING_SYS_ERRNO
: /* 0x13 */
475 * Returns the value of the C library errno variable that is
476 * associated with the semihosting implementation. The errno
477 * variable can be set by a number of C library semihosted
478 * functions, including:
486 * Whether errno is set or not, and to what value, is entirely
487 * host-specific, except where the ISO C standard defines the
491 * There are no parameters. The PARAMETER REGISTER must be 0.
494 * On exit, the RETURN REGISTER contains the value of the C
495 * library errno variable.
497 semihosting
->result
= semihosting
->sys_errno
;
500 case SEMIHOSTING_SYS_EXIT
: /* 0x18 */
502 * Note: SYS_EXIT was called angel_SWIreason_ReportException in
503 * previous versions of the documentation.
505 * An application calls this operation to report an exception
506 * to the debugger directly. The most common use is to report
507 * that execution has completed, using ADP_Stopped_ApplicationExit.
509 * Note: This semihosting operation provides no means for 32-bit
510 * callers to indicate an application exit with a specified exit
511 * code. Semihosting callers may prefer to check for the presence
512 * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use
513 * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it
517 * On entry, the PARAMETER register is set to a reason code
518 * describing the cause of the trap. Not all semihosting client
519 * implementations will necessarily trap every corresponding
520 * event. Important reason codes are:
522 * - ADP_Stopped_ApplicationExit 0x20026
523 * - ADP_Stopped_RunTimeErrorUnknown 0x20023
526 * On entry, the PARAMETER REGISTER contains a pointer to a
527 * two-field argument block:
528 * - field 1 The exception type, which is one of the set of
529 * reason codes in the above tables.
530 * - field 2 A subcode, whose meaning depends on the reason
532 * In particular, if field 1 is ADP_Stopped_ApplicationExit
533 * then field 2 is an exit status code, as passed to the C
534 * standard library exit() function. A simulator receiving
535 * this request must notify a connected debugger, if present,
536 * and then exit with the specified status.
539 * No return is expected from these calls. However, it is
540 * possible for the debugger to request that the application
541 * continues by performing an RDI_Execute request or equivalent.
542 * In this case, execution continues with the registers as they
543 * were on entry to the operation, or as subsequently modified
546 if (semihosting
->word_size_bytes
== 8) {
547 retval
= semihosting_read_fields(target
, 2, fields
);
548 if (retval
!= ERROR_OK
)
551 int type
= semihosting_get_field(target
, 0, fields
);
552 int code
= semihosting_get_field(target
, 1, fields
);
554 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
555 if (!gdb_get_actual_connections())
559 "semihosting: *** application exited with %d ***\n",
564 "semihosting: application exception %#x\n",
569 if (semihosting
->param
== ADP_STOPPED_APPLICATION_EXIT
) {
570 if (!gdb_get_actual_connections())
574 "semihosting: *** application exited normally ***\n");
576 } else if (semihosting
->param
== ADP_STOPPED_RUN_TIME_ERROR
) {
577 /* Chosen more or less arbitrarily to have a nicer message,
578 * otherwise all other return the same exit code 1. */
579 if (!gdb_get_actual_connections())
583 "semihosting: *** application exited with error ***\n");
586 if (!gdb_get_actual_connections())
590 "semihosting: application exception %#x\n",
591 (unsigned) semihosting
->param
);
595 if (!semihosting
->has_resumable_exit
) {
596 semihosting
->is_resumable
= false;
597 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
601 case SEMIHOSTING_SYS_EXIT_EXTENDED
: /* 0x20 */
603 * This operation is only supported if the semihosting extension
604 * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is
605 * reported using feature byte 0, bit 0. If this extension is
606 * supported, then the implementation provides a means to
607 * report a normal exit with a nonzero exit status in both 32-bit
608 * and 64-bit semihosting APIs.
610 * The implementation must provide the semihosting call
611 * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.
613 * SYS_EXIT_EXTENDED is used by an application to report an
614 * exception or exit to the debugger directly. The most common
615 * use is to report that execution has completed, using
616 * ADP_Stopped_ApplicationExit.
619 * On entry, the PARAMETER REGISTER contains a pointer to a
620 * two-field argument block:
621 * - field 1 The exception type, which should be one of the set
622 * of reason codes that are documented for the SYS_EXIT
623 * (0x18) call. For example, ADP_Stopped_ApplicationExit.
624 * - field 2 A subcode, whose meaning depends on the reason
625 * code in field 1. In particular, if field 1 is
626 * ADP_Stopped_ApplicationExit then field 2 is an exit status
627 * code, as passed to the C standard library exit() function.
628 * A simulator receiving this request must notify a connected
629 * debugger, if present, and then exit with the specified status.
632 * No return is expected from these calls.
634 * For the A64 API, this call is identical to the behavior of
635 * the mandatory SYS_EXIT (0x18) call. If this extension is
636 * supported, then both calls must be implemented.
638 retval
= semihosting_read_fields(target
, 2, fields
);
639 if (retval
!= ERROR_OK
)
642 int type
= semihosting_get_field(target
, 0, fields
);
643 int code
= semihosting_get_field(target
, 1, fields
);
645 if (type
== ADP_STOPPED_APPLICATION_EXIT
) {
646 if (!gdb_get_actual_connections())
650 "semihosting: *** application exited with %d ***\n",
654 fprintf(stderr
, "semihosting: exception %#x\n",
658 if (!semihosting
->has_resumable_exit
) {
659 semihosting
->is_resumable
= false;
660 return target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
664 case SEMIHOSTING_SYS_FLEN
: /* 0x0C */
666 * Returns the length of a specified file.
669 * On entry, the PARAMETER REGISTER contains a pointer to a
670 * one-field argument block:
671 * - field 1 A handle for a previously opened, seekable file
675 * On exit, the RETURN REGISTER contains:
676 * - The current length of the file object, if the call is
678 * - –1 if an error occurs.
680 if (semihosting
->is_fileio
) {
681 semihosting
->result
= -1;
682 semihosting
->sys_errno
= EINVAL
;
684 retval
= semihosting_read_fields(target
, 1, fields
);
685 if (retval
!= ERROR_OK
)
688 int fd
= semihosting_get_field(target
, 0, fields
);
690 semihosting
->result
= fstat(fd
, &buf
);
691 if (semihosting
->result
== -1) {
692 semihosting
->sys_errno
= errno
;
693 LOG_DEBUG("fstat(%d)=%" PRId64
, fd
, semihosting
->result
);
696 LOG_DEBUG("fstat(%d)=%" PRId64
, fd
, semihosting
->result
);
697 semihosting
->result
= buf
.st_size
;
701 case SEMIHOSTING_SYS_GET_CMDLINE
: /* 0x15 */
703 * Returns the command line that is used for the call to the
704 * executable, that is, argc and argv.
707 * On entry, the PARAMETER REGISTER points to a two-field data
708 * block to be used for returning the command string and its length:
709 * - field 1 A pointer to a buffer of at least the size that is
710 * specified in field 2.
711 * - field 2 The length of the buffer in bytes.
715 * If the call is successful, then the RETURN REGISTER contains 0,
716 * the PARAMETER REGISTER is unchanged, and the data block is
717 * updated as follows:
718 * - field 1 A pointer to a null-terminated string of the command
720 * - field 2 The length of the string in bytes.
721 * If the call is not successful, then the RETURN REGISTER
724 * Note: The semihosting implementation might impose limits on
725 * the maximum length of the string that can be transferred.
726 * However, the implementation must be able to support a
727 * command-line length of at least 80 bytes.
729 retval
= semihosting_read_fields(target
, 2, fields
);
730 if (retval
!= ERROR_OK
)
733 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
734 size_t size
= semihosting_get_field(target
, 1, fields
);
736 char *arg
= semihosting
->cmdline
?
737 semihosting
->cmdline
: "";
738 uint32_t len
= strlen(arg
) + 1;
740 semihosting
->result
= -1;
742 semihosting_set_field(target
, len
, 1, fields
);
743 retval
= target_write_buffer(target
, addr
, len
,
745 if (retval
!= ERROR_OK
)
747 semihosting
->result
= 0;
749 retval
= semihosting_write_fields(target
, 2, fields
);
750 if (retval
!= ERROR_OK
)
753 LOG_DEBUG("SYS_GET_CMDLINE=[%s], %" PRId64
, arg
, semihosting
->result
);
757 case SEMIHOSTING_SYS_HEAPINFO
: /* 0x16 */
759 * Returns the system stack and heap parameters.
762 * On entry, the PARAMETER REGISTER contains the address of a
763 * pointer to a four-field data block. The contents of the data
764 * block are filled by the function. The following C-like
765 * pseudocode describes the layout of the block:
774 * On exit, the PARAMETER REGISTER is unchanged and the data
775 * block has been updated.
777 retval
= semihosting_read_fields(target
, 1, fields
);
778 if (retval
!= ERROR_OK
)
781 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
782 /* tell the remote we have no idea */
783 memset(fields
, 0, 4 * semihosting
->word_size_bytes
);
784 retval
= target_write_memory(target
, addr
, 4,
785 semihosting
->word_size_bytes
,
787 if (retval
!= ERROR_OK
)
789 semihosting
->result
= 0;
793 case SEMIHOSTING_SYS_ISERROR
: /* 0x08 */
795 * Determines whether the return code from another semihosting
796 * call is an error status or not.
798 * This call is passed a parameter block containing the error
802 * On entry, the PARAMETER REGISTER contains a pointer to a
803 * one-field data block:
804 * - field 1 The required status word to check.
807 * On exit, the RETURN REGISTER contains:
808 * - 0 if the status field is not an error indication
809 * - A nonzero value if the status field is an error indication.
811 retval
= semihosting_read_fields(target
, 1, fields
);
812 if (retval
!= ERROR_OK
)
815 uint64_t code
= semihosting_get_field(target
, 0, fields
);
816 semihosting
->result
= (code
!= 0);
819 case SEMIHOSTING_SYS_ISTTY
: /* 0x09 */
821 * Checks whether a file is connected to an interactive device.
824 * On entry, the PARAMETER REGISTER contains a pointer to a
825 * one-field argument block:
826 * field 1 A handle for a previously opened file object.
829 * On exit, the RETURN REGISTER contains:
830 * - 1 if the handle identifies an interactive device.
831 * - 0 if the handle identifies a file.
832 * - A value other than 1 or 0 if an error occurs.
834 if (semihosting
->is_fileio
) {
835 semihosting
->hit_fileio
= true;
836 fileio_info
->identifier
= "isatty";
837 fileio_info
->param_1
= semihosting
->param
;
839 retval
= semihosting_read_fields(target
, 1, fields
);
840 if (retval
!= ERROR_OK
)
842 int fd
= semihosting_get_field(target
, 0, fields
);
843 // isatty() on Windows may return any non-zero value if fd is a terminal
844 semihosting
->result
= isatty(fd
) ? 1 : 0;
845 semihosting
->sys_errno
= errno
;
846 LOG_DEBUG("isatty(%d)=%" PRId64
, fd
, semihosting
->result
);
850 case SEMIHOSTING_SYS_OPEN
: /* 0x01 */
852 * Opens a file on the host system.
854 * The file path is specified either as relative to the current
855 * directory of the host process, or absolute, using the path
856 * conventions of the host operating system.
858 * Semihosting implementations must support opening the special
859 * path name :semihosting-features as part of the semihosting
860 * extensions reporting mechanism.
862 * ARM targets interpret the special path name :tt as meaning
863 * the console input stream, for an open-read or the console
864 * output stream, for an open-write. Opening these streams is
865 * performed as part of the standard startup code for those
866 * applications that reference the C stdio streams. The
867 * semihosting extension SH_EXT_STDOUT_STDERR allows the
868 * semihosting caller to open separate output streams
869 * corresponding to stdout and stderr. This extension is
870 * reported using feature byte 0, bit 1. Use SYS_OPEN with
871 * the special path name :semihosting-features to access the
874 * If this extension is supported, the implementation must
875 * support the following additional semantics to SYS_OPEN:
876 * - If the special path name :tt is opened with an fopen
877 * mode requesting write access (w, wb, w+, or w+b), then
878 * this is a request to open stdout.
879 * - If the special path name :tt is opened with a mode
880 * requesting append access (a, ab, a+, or a+b), then this is
881 * a request to open stderr.
884 * On entry, the PARAMETER REGISTER contains a pointer to a
885 * three-field argument block:
886 * - field 1 A pointer to a null-terminated string containing
887 * a file or device name.
888 * - field 2 An integer that specifies the file opening mode.
889 * - field 3 An integer that gives the length of the string
890 * pointed to by field 1.
892 * The length does not include the terminating null character
893 * that must be present.
896 * On exit, the RETURN REGISTER contains:
897 * - A nonzero handle if the call is successful.
898 * - –1 if the call is not successful.
900 retval
= semihosting_read_fields(target
, 3, fields
);
901 if (retval
!= ERROR_OK
)
904 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
905 uint32_t mode
= semihosting_get_field(target
, 1, fields
);
906 size_t len
= semihosting_get_field(target
, 2, fields
);
909 semihosting
->result
= -1;
910 semihosting
->sys_errno
= EINVAL
;
913 size_t basedir_len
= semihosting
->basedir
? strlen(semihosting
->basedir
) : 0;
914 uint8_t *fn
= malloc(basedir_len
+ len
+ 2);
916 semihosting
->result
= -1;
917 semihosting
->sys_errno
= ENOMEM
;
919 if (basedir_len
> 0) {
920 strcpy((char *)fn
, semihosting
->basedir
);
921 if (fn
[basedir_len
- 1] != '/')
922 fn
[basedir_len
++] = '/';
924 retval
= target_read_memory(target
, addr
, 1, len
, fn
+ basedir_len
);
925 if (retval
!= ERROR_OK
) {
929 fn
[basedir_len
+ len
] = 0;
930 /* TODO: implement the :semihosting-features special file.
932 if (semihosting
->is_fileio
) {
933 if (strcmp((char *)fn
, ":semihosting-features") == 0) {
934 semihosting
->result
= -1;
935 semihosting
->sys_errno
= EINVAL
;
936 } else if (strcmp((char *)fn
, ":tt") == 0) {
938 semihosting
->result
= 0;
940 semihosting
->result
= 1;
942 semihosting
->result
= 2;
944 semihosting
->result
= -1;
946 semihosting
->hit_fileio
= true;
947 fileio_info
->identifier
= "open";
948 fileio_info
->param_1
= addr
;
949 fileio_info
->param_2
= len
;
950 fileio_info
->param_3
= open_gdb_modeflags
[mode
];
951 fileio_info
->param_4
= 0644;
954 if (strcmp((char *)fn
, ":tt") == 0) {
956 * - 0-3 ("r") for stdin,
957 * - 4-7 ("w") for stdout,
958 * - 8-11 ("a") for stderr */
960 int fd
= dup(STDIN_FILENO
);
961 semihosting
->result
= fd
;
962 semihosting
->stdin_fd
= fd
;
963 semihosting
->sys_errno
= errno
;
964 LOG_DEBUG("dup(STDIN)=%" PRId64
, semihosting
->result
);
965 } else if (mode
< 8) {
966 int fd
= dup(STDOUT_FILENO
);
967 semihosting
->result
= fd
;
968 semihosting
->stdout_fd
= fd
;
969 semihosting
->sys_errno
= errno
;
970 LOG_DEBUG("dup(STDOUT)=%" PRId64
, semihosting
->result
);
972 int fd
= dup(STDERR_FILENO
);
973 semihosting
->result
= fd
;
974 semihosting
->stderr_fd
= fd
;
975 semihosting
->sys_errno
= errno
;
976 LOG_DEBUG("dup(STDERR)=%" PRId64
, semihosting
->result
);
979 /* cygwin requires the permission setting
980 * otherwise it will fail to reopen a previously
982 semihosting
->result
= open((char *)fn
,
983 open_host_modeflags
[mode
],
985 semihosting
->sys_errno
= errno
;
986 LOG_DEBUG("open('%s')=%" PRId64
, fn
, semihosting
->result
);
994 case SEMIHOSTING_SYS_READ
: /* 0x06 */
996 * Reads the contents of a file into a buffer. The file position
997 * is specified either:
998 * - Explicitly by a SYS_SEEK.
999 * - Implicitly one byte beyond the previous SYS_READ or
1000 * SYS_WRITE request.
1002 * The file position is at the start of the file when it is
1003 * opened, and is lost when the file is closed. Perform the
1004 * file operation as a single action whenever possible. For
1005 * example, do not split a read of 16KB into four 4KB chunks
1006 * unless there is no alternative.
1009 * On entry, the PARAMETER REGISTER contains a pointer to a
1010 * three-field data block:
1011 * - field 1 Contains a handle for a file previously opened
1013 * - field 2 Points to a buffer.
1014 * - field 3 Contains the number of bytes to read to the buffer
1018 * On exit, the RETURN REGISTER contains the number of bytes not
1019 * filled in the buffer (buffer_length - bytes_read) as follows:
1020 * - If the RETURN REGISTER is 0, the entire buffer was
1021 * successfully filled.
1022 * - If the RETURN REGISTER is the same as field 3, no bytes
1023 * were read (EOF can be assumed).
1024 * - If the RETURN REGISTER contains a value smaller than
1025 * field 3, the read succeeded but the buffer was only partly
1026 * filled. For interactive devices, this is the most common
1029 retval
= semihosting_read_fields(target
, 3, fields
);
1030 if (retval
!= ERROR_OK
)
1033 int fd
= semihosting_get_field(target
, 0, fields
);
1034 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1035 size_t len
= semihosting_get_field(target
, 2, fields
);
1036 if (semihosting
->is_fileio
) {
1037 semihosting
->hit_fileio
= true;
1038 fileio_info
->identifier
= "read";
1039 fileio_info
->param_1
= fd
;
1040 fileio_info
->param_2
= addr
;
1041 fileio_info
->param_3
= len
;
1043 uint8_t *buf
= malloc(len
);
1045 semihosting
->result
= -1;
1046 semihosting
->sys_errno
= ENOMEM
;
1048 semihosting
->result
= semihosting_read(semihosting
, fd
, buf
, len
);
1049 LOG_DEBUG("read(%d, 0x%" PRIx64
", %zu)=%" PRId64
,
1053 semihosting
->result
);
1054 if (semihosting
->result
>= 0) {
1055 retval
= target_write_buffer(target
, addr
,
1056 semihosting
->result
,
1058 if (retval
!= ERROR_OK
) {
1062 /* the number of bytes NOT filled in */
1063 semihosting
->result
= len
-
1064 semihosting
->result
;
1072 case SEMIHOSTING_SYS_READC
: /* 0x07 */
1074 * Reads a byte from the console.
1077 * The PARAMETER REGISTER must contain 0. There are no other
1078 * parameters or values possible.
1081 * On exit, the RETURN REGISTER contains the byte read from
1084 if (semihosting
->is_fileio
) {
1085 LOG_ERROR("SYS_READC not supported by semihosting fileio");
1088 semihosting
->result
= semihosting_getchar(semihosting
, semihosting
->stdin_fd
);
1089 LOG_DEBUG("getchar()=%" PRId64
, semihosting
->result
);
1092 case SEMIHOSTING_SYS_REMOVE
: /* 0x0E */
1094 * Deletes a specified file on the host filing system.
1097 * On entry, the PARAMETER REGISTER contains a pointer to a
1098 * two-field argument block:
1099 * - field 1 Points to a null-terminated string that gives the
1100 * path name of the file to be deleted.
1101 * - field 2 The length of the string.
1104 * On exit, the RETURN REGISTER contains:
1105 * - 0 if the delete is successful
1106 * - A nonzero, host-specific error code if the delete fails.
1108 retval
= semihosting_read_fields(target
, 2, fields
);
1109 if (retval
!= ERROR_OK
)
1112 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1113 size_t len
= semihosting_get_field(target
, 1, fields
);
1114 if (semihosting
->is_fileio
) {
1115 semihosting
->hit_fileio
= true;
1116 fileio_info
->identifier
= "unlink";
1117 fileio_info
->param_1
= addr
;
1118 fileio_info
->param_2
= len
;
1120 uint8_t *fn
= malloc(len
+1);
1122 semihosting
->result
= -1;
1123 semihosting
->sys_errno
= ENOMEM
;
1126 target_read_memory(target
, addr
, 1, len
,
1128 if (retval
!= ERROR_OK
) {
1133 semihosting
->result
= remove((char *)fn
);
1134 semihosting
->sys_errno
= errno
;
1135 LOG_DEBUG("remove('%s')=%" PRId64
, fn
, semihosting
->result
);
1143 case SEMIHOSTING_SYS_RENAME
: /* 0x0F */
1145 * Renames a specified file.
1148 * On entry, the PARAMETER REGISTER contains a pointer to a
1149 * four-field data block:
1150 * - field 1 A pointer to the name of the old file.
1151 * - field 2 The length of the old filename.
1152 * - field 3 A pointer to the new filename.
1153 * - field 4 The length of the new filename. Both strings are
1157 * On exit, the RETURN REGISTER contains:
1158 * - 0 if the rename is successful.
1159 * - A nonzero, host-specific error code if the rename fails.
1161 retval
= semihosting_read_fields(target
, 4, fields
);
1162 if (retval
!= ERROR_OK
)
1165 uint64_t addr1
= semihosting_get_field(target
, 0, fields
);
1166 size_t len1
= semihosting_get_field(target
, 1, fields
);
1167 uint64_t addr2
= semihosting_get_field(target
, 2, fields
);
1168 size_t len2
= semihosting_get_field(target
, 3, fields
);
1169 if (semihosting
->is_fileio
) {
1170 semihosting
->hit_fileio
= true;
1171 fileio_info
->identifier
= "rename";
1172 fileio_info
->param_1
= addr1
;
1173 fileio_info
->param_2
= len1
;
1174 fileio_info
->param_3
= addr2
;
1175 fileio_info
->param_4
= len2
;
1177 uint8_t *fn1
= malloc(len1
+1);
1178 uint8_t *fn2
= malloc(len2
+1);
1182 semihosting
->result
= -1;
1183 semihosting
->sys_errno
= ENOMEM
;
1185 retval
= target_read_memory(target
, addr1
, 1, len1
,
1187 if (retval
!= ERROR_OK
) {
1192 retval
= target_read_memory(target
, addr2
, 1, len2
,
1194 if (retval
!= ERROR_OK
) {
1201 semihosting
->result
= rename((char *)fn1
,
1203 semihosting
->sys_errno
= errno
;
1204 LOG_DEBUG("rename('%s', '%s')=%" PRId64
" %d", fn1
, fn2
, semihosting
->result
, errno
);
1212 case SEMIHOSTING_SYS_SEEK
: /* 0x0A */
1214 * Seeks to a specified position in a file using an offset
1215 * specified from the start of the file. The file is assumed
1216 * to be a byte array and the offset is given in bytes.
1219 * On entry, the PARAMETER REGISTER contains a pointer to a
1220 * two-field data block:
1221 * - field 1 A handle for a seekable file object.
1222 * - field 2 The absolute byte position to seek to.
1225 * On exit, the RETURN REGISTER contains:
1226 * - 0 if the request is successful.
1227 * - A negative value if the request is not successful.
1228 * Use SYS_ERRNO to read the value of the host errno variable
1229 * describing the error.
1231 * Note: The effect of seeking outside the current extent of
1232 * the file object is undefined.
1234 retval
= semihosting_read_fields(target
, 2, fields
);
1235 if (retval
!= ERROR_OK
)
1238 int fd
= semihosting_get_field(target
, 0, fields
);
1239 off_t pos
= semihosting_get_field(target
, 1, fields
);
1240 if (semihosting
->is_fileio
) {
1241 semihosting
->hit_fileio
= true;
1242 fileio_info
->identifier
= "lseek";
1243 fileio_info
->param_1
= fd
;
1244 fileio_info
->param_2
= pos
;
1245 fileio_info
->param_3
= SEEK_SET
;
1247 semihosting
->result
= lseek(fd
, pos
, SEEK_SET
);
1248 semihosting
->sys_errno
= errno
;
1249 LOG_DEBUG("lseek(%d, %d)=%" PRId64
, fd
, (int)pos
, semihosting
->result
);
1250 if (semihosting
->result
== pos
)
1251 semihosting
->result
= 0;
1256 case SEMIHOSTING_SYS_SYSTEM
: /* 0x12 */
1258 * Passes a command to the host command-line interpreter.
1259 * This enables you to execute a system command such as dir,
1260 * ls, or pwd. The terminal I/O is on the host, and is not
1261 * visible to the target.
1264 * On entry, the PARAMETER REGISTER contains a pointer to a
1265 * two-field argument block:
1266 * - field 1 Points to a string to be passed to the host
1267 * command-line interpreter.
1268 * - field 2 The length of the string.
1271 * On exit, the RETURN REGISTER contains the return status.
1274 /* Provide SYS_SYSTEM functionality. Uses the
1275 * libc system command, there may be a reason *NOT*
1276 * to use this, but as I can't think of one, I
1277 * implemented it this way.
1279 retval
= semihosting_read_fields(target
, 2, fields
);
1280 if (retval
!= ERROR_OK
)
1283 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1284 size_t len
= semihosting_get_field(target
, 1, fields
);
1285 if (semihosting
->is_fileio
) {
1286 semihosting
->hit_fileio
= true;
1287 fileio_info
->identifier
= "system";
1288 fileio_info
->param_1
= addr
;
1289 fileio_info
->param_2
= len
;
1291 uint8_t *cmd
= malloc(len
+1);
1293 semihosting
->result
= -1;
1294 semihosting
->sys_errno
= ENOMEM
;
1296 retval
= target_read_memory(target
,
1301 if (retval
!= ERROR_OK
) {
1306 semihosting
->result
= system(
1308 LOG_DEBUG("system('%s')=%" PRId64
, cmd
, semihosting
->result
);
1317 case SEMIHOSTING_SYS_TIME
: /* 0x11 */
1319 * Returns the number of seconds since 00:00 January 1, 1970.
1320 * This value is real-world time, regardless of any debug agent
1324 * There are no parameters.
1327 * On exit, the RETURN REGISTER contains the number of seconds.
1329 semihosting
->result
= time(NULL
);
1332 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1334 * Writes the contents of a buffer to a specified file at the
1335 * current file position. The file position is specified either:
1336 * - Explicitly, by a SYS_SEEK.
1337 * - Implicitly as one byte beyond the previous SYS_READ or
1338 * SYS_WRITE request.
1340 * The file position is at the start of the file when the file
1341 * is opened, and is lost when the file is closed.
1343 * Perform the file operation as a single action whenever
1344 * possible. For example, do not split a write of 16KB into
1345 * four 4KB chunks unless there is no alternative.
1348 * On entry, the PARAMETER REGISTER contains a pointer to a
1349 * three-field data block:
1350 * - field 1 Contains a handle for a file previously opened
1352 * - field 2 Points to the memory containing the data to be written.
1353 * - field 3 Contains the number of bytes to be written from
1354 * the buffer to the file.
1357 * On exit, the RETURN REGISTER contains:
1358 * - 0 if the call is successful.
1359 * - The number of bytes that are not written, if there is an error.
1361 retval
= semihosting_read_fields(target
, 3, fields
);
1362 if (retval
!= ERROR_OK
)
1365 int fd
= semihosting_get_field(target
, 0, fields
);
1366 uint64_t addr
= semihosting_get_field(target
, 1, fields
);
1367 size_t len
= semihosting_get_field(target
, 2, fields
);
1368 if (semihosting
->is_fileio
) {
1369 semihosting
->hit_fileio
= true;
1370 fileio_info
->identifier
= "write";
1371 fileio_info
->param_1
= fd
;
1372 fileio_info
->param_2
= addr
;
1373 fileio_info
->param_3
= len
;
1375 uint8_t *buf
= malloc(len
);
1377 semihosting
->result
= -1;
1378 semihosting
->sys_errno
= ENOMEM
;
1380 retval
= target_read_buffer(target
, addr
, len
, buf
);
1381 if (retval
!= ERROR_OK
) {
1385 semihosting
->result
= semihosting_write(semihosting
, fd
, buf
, len
);
1386 semihosting
->sys_errno
= errno
;
1387 LOG_DEBUG("write(%d, 0x%" PRIx64
", %zu)=%" PRId64
,
1391 semihosting
->result
);
1392 if (semihosting
->result
>= 0) {
1393 /* The number of bytes that are NOT written.
1395 semihosting
->result
= len
-
1396 semihosting
->result
;
1405 case SEMIHOSTING_SYS_WRITEC
: /* 0x03 */
1407 * Writes a character byte, pointed to by the PARAMETER REGISTER,
1408 * to the debug channel. When executed under a semihosting
1409 * debugger, the character appears on the host debugger console.
1412 * On entry, the PARAMETER REGISTER contains a pointer to the
1416 * None. The RETURN REGISTER is corrupted.
1418 if (semihosting
->is_fileio
) {
1419 semihosting
->hit_fileio
= true;
1420 fileio_info
->identifier
= "write";
1421 fileio_info
->param_1
= 1;
1422 fileio_info
->param_2
= semihosting
->param
;
1423 fileio_info
->param_3
= 1;
1425 uint64_t addr
= semihosting
->param
;
1427 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1428 if (retval
!= ERROR_OK
)
1430 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1431 semihosting
->result
= 0;
1435 case SEMIHOSTING_SYS_WRITE0
: /* 0x04 */
1437 * Writes a null-terminated string to the debug channel.
1438 * When executed under a semihosting debugger, the characters
1439 * appear on the host debugger console.
1442 * On entry, the PARAMETER REGISTER contains a pointer to the
1443 * first byte of the string.
1446 * None. The RETURN REGISTER is corrupted.
1448 if (semihosting
->is_fileio
) {
1450 uint64_t addr
= semihosting
->param
;
1453 retval
= target_read_memory(target
, addr
, 1, 1, &c
);
1454 if (retval
!= ERROR_OK
)
1460 semihosting
->hit_fileio
= true;
1461 fileio_info
->identifier
= "write";
1462 fileio_info
->param_1
= 1;
1463 fileio_info
->param_2
= semihosting
->param
;
1464 fileio_info
->param_3
= count
;
1466 uint64_t addr
= semihosting
->param
;
1469 retval
= target_read_memory(target
, addr
++, 1, 1, &c
);
1470 if (retval
!= ERROR_OK
)
1474 semihosting_putchar(semihosting
, semihosting
->stdout_fd
, c
);
1476 semihosting
->result
= 0;
1480 case SEMIHOSTING_USER_CMD_0X100
... SEMIHOSTING_USER_CMD_0X107
:
1482 * This is a user defined operation (while user cmds 0x100-0x1ff
1483 * are possible, only 0x100-0x107 are currently implemented).
1485 * Reads the user operation parameters from target, then fires the
1486 * corresponding target event. When the target callbacks returned,
1487 * cleans up the command parameter buffer.
1490 * On entry, the PARAMETER REGISTER contains a pointer to a
1491 * two-field data block:
1492 * - field 1 Contains a pointer to the bound command parameter
1494 * - field 2 Contains the command parameter string length
1497 * On exit, the RETURN REGISTER contains the return status.
1499 if (semihosting
->user_command_extension
) {
1500 retval
= semihosting
->user_command_extension(target
);
1501 if (retval
!= ERROR_NOT_IMPLEMENTED
)
1503 /* If custom user command not handled, we are looking for the TCL handler */
1506 assert(!semihosting_user_op_params
);
1507 retval
= semihosting_read_fields(target
, 2, fields
);
1508 if (retval
!= ERROR_OK
) {
1509 LOG_ERROR("Failed to read fields for user defined command"
1510 " op=0x%x", semihosting
->op
);
1514 uint64_t addr
= semihosting_get_field(target
, 0, fields
);
1516 size_t len
= semihosting_get_field(target
, 1, fields
);
1517 if (len
> SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
) {
1518 LOG_ERROR("The maximum length for user defined command "
1519 "parameter is %u, received length is %zu (op=0x%x)",
1520 SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH
,
1526 semihosting_user_op_params
= malloc(len
+ 1);
1527 if (!semihosting_user_op_params
)
1529 semihosting_user_op_params
[len
] = 0;
1531 retval
= target_read_buffer(target
, addr
, len
,
1532 (uint8_t *)(semihosting_user_op_params
));
1533 if (retval
!= ERROR_OK
) {
1534 LOG_ERROR("Failed to read from target, semihosting op=0x%x (%s)",
1536 semihosting_opcode_to_str(semihosting
->op
));
1537 free(semihosting_user_op_params
);
1538 semihosting_user_op_params
= NULL
;
1542 target_handle_event(target
, semihosting
->op
);
1543 free(semihosting_user_op_params
);
1544 semihosting_user_op_params
= NULL
;
1545 semihosting
->result
= 0;
1548 case SEMIHOSTING_SYS_ELAPSED
: /* 0x30 */
1550 * Returns the number of elapsed target ticks since execution
1552 * Use SYS_TICKFREQ to determine the tick frequency.
1555 * On entry, the PARAMETER REGISTER points to a two-field data
1556 * block to be used for returning the number of elapsed ticks:
1557 * - field 1 The least significant field and is at the low address.
1558 * - field 2 The most significant field and is at the high address.
1561 * On entry the PARAMETER REGISTER points to a one-field data
1562 * block to be used for returning the number of elapsed ticks:
1563 * - field 1 The number of elapsed ticks as a 64-bit value.
1567 * - On success, the RETURN REGISTER contains 0, the PARAMETER
1568 * REGISTER is unchanged, and the data block pointed to by the
1569 * PARAMETER REGISTER is filled in with the number of elapsed
1571 * - On failure, the RETURN REGISTER contains -1, and the
1572 * PARAMETER REGISTER contains -1.
1574 * Note: Some semihosting implementations might not support this
1575 * semihosting operation, and they always return -1 in the
1579 case SEMIHOSTING_SYS_TICKFREQ
: /* 0x31 */
1581 * Returns the tick frequency.
1584 * The PARAMETER REGISTER must contain 0 on entry to this routine.
1587 * On exit, the RETURN REGISTER contains either:
1588 * - The number of ticks per second.
1589 * - –1 if the target does not know the value of one tick.
1591 * Note: Some semihosting implementations might not support
1592 * this semihosting operation, and they always return -1 in the
1596 case SEMIHOSTING_SYS_TMPNAM
: /* 0x0D */
1598 * Returns a temporary name for a file identified by a system
1602 * On entry, the PARAMETER REGISTER contains a pointer to a
1603 * three-word argument block:
1604 * - field 1 A pointer to a buffer.
1605 * - field 2 A target identifier for this filename. Its value
1606 * must be an integer in the range 0-255.
1607 * - field 3 Contains the length of the buffer. The length must
1608 * be at least the value of L_tmpnam on the host system.
1611 * On exit, the RETURN REGISTER contains:
1612 * - 0 if the call is successful.
1613 * - –1 if an error occurs.
1615 * The buffer pointed to by the PARAMETER REGISTER contains
1616 * the filename, prefixed with a suitable directory name.
1617 * If you use the same target identifier again, the same
1618 * filename is returned.
1620 * Note: The returned string must be null-terminated.
1624 fprintf(stderr
, "semihosting: unsupported call %#x\n",
1625 (unsigned) semihosting
->op
);
1626 semihosting
->result
= -1;
1627 semihosting
->sys_errno
= ENOTSUP
;
1630 if (!semihosting
->hit_fileio
) {
1631 retval
= semihosting
->post_result(target
);
1632 if (retval
!= ERROR_OK
) {
1633 LOG_ERROR("Failed to post semihosting result");
1641 /* -------------------------------------------------------------------------
1642 * Local functions. */
1644 static int semihosting_common_fileio_info(struct target
*target
,
1645 struct gdb_fileio_info
*fileio_info
)
1647 struct semihosting
*semihosting
= target
->semihosting
;
1652 * To avoid unnecessary duplication, semihosting prepares the
1653 * fileio_info structure out-of-band when the target halts. See
1654 * do_semihosting for more detail.
1656 if (!semihosting
->is_fileio
|| !semihosting
->hit_fileio
)
1662 static int semihosting_common_fileio_end(struct target
*target
, int result
,
1663 int fileio_errno
, bool ctrl_c
)
1665 struct gdb_fileio_info
*fileio_info
= target
->fileio_info
;
1666 struct semihosting
*semihosting
= target
->semihosting
;
1670 /* clear pending status */
1671 semihosting
->hit_fileio
= false;
1673 semihosting
->result
= result
;
1674 semihosting
->sys_errno
= fileio_errno
;
1677 * Some fileio results do not match up with what the semihosting
1678 * operation expects; for these operations, we munge the results
1681 switch (semihosting
->op
) {
1682 case SEMIHOSTING_SYS_WRITE
: /* 0x05 */
1683 case SEMIHOSTING_SYS_READ
: /* 0x06 */
1685 semihosting
->result
= fileio_info
->param_3
; /* Zero bytes read/written. */
1687 semihosting
->result
= (int64_t)fileio_info
->param_3
- result
;
1690 case SEMIHOSTING_SYS_SEEK
: /* 0x0a */
1692 semihosting
->result
= 0;
1696 return semihosting
->post_result(target
);
1699 /* -------------------------------------------------------------------------
1700 * Utility functions. */
1703 * Read all fields of a command from target to buffer.
1705 int semihosting_read_fields(struct target
*target
, size_t number
,
1708 struct semihosting
*semihosting
= target
->semihosting
;
1709 /* Use 4-byte multiples to trigger fast memory access. */
1710 return target_read_memory(target
, semihosting
->param
, 4,
1711 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1715 * Write all fields of a command from buffer to target.
1717 int semihosting_write_fields(struct target
*target
, size_t number
,
1720 struct semihosting
*semihosting
= target
->semihosting
;
1721 /* Use 4-byte multiples to trigger fast memory access. */
1722 return target_write_memory(target
, semihosting
->param
, 4,
1723 number
* (semihosting
->word_size_bytes
/ 4), fields
);
1727 * Extract a field from the buffer, considering register size and endianness.
1729 uint64_t semihosting_get_field(struct target
*target
, size_t index
,
1732 struct semihosting
*semihosting
= target
->semihosting
;
1733 if (semihosting
->word_size_bytes
== 8)
1734 return target_buffer_get_u64(target
, fields
+ (index
* 8));
1736 return target_buffer_get_u32(target
, fields
+ (index
* 4));
1740 * Store a field in the buffer, considering register size and endianness.
1742 void semihosting_set_field(struct target
*target
, uint64_t value
,
1746 struct semihosting
*semihosting
= target
->semihosting
;
1747 if (semihosting
->word_size_bytes
== 8)
1748 target_buffer_set_u64(target
, fields
+ (index
* 8), value
);
1750 target_buffer_set_u32(target
, fields
+ (index
* 4), value
);
1753 /* -------------------------------------------------------------------------
1754 * Semihosting redirect over TCP structs and functions */
1756 static int semihosting_service_new_connection_handler(struct connection
*connection
)
1758 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1759 service
->semihosting
->tcp_connection
= connection
;
1764 static int semihosting_service_input_handler(struct connection
*connection
)
1766 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1768 if (!connection
->input_pending
) {
1769 /* consume received data, not for semihosting IO */
1770 const int buf_len
= 100;
1772 int bytes_read
= connection_read(connection
, buf
, buf_len
);
1774 if (bytes_read
== 0) {
1775 return ERROR_SERVER_REMOTE_CLOSED
;
1776 } else if (bytes_read
== -1) {
1777 LOG_ERROR("error during read: %s", strerror(errno
));
1778 return ERROR_SERVER_REMOTE_CLOSED
;
1780 } else if (service
->error
!= ERROR_OK
) {
1781 return ERROR_SERVER_REMOTE_CLOSED
;
1787 static int semihosting_service_connection_closed_handler(struct connection
*connection
)
1789 struct semihosting_tcp_service
*service
= connection
->service
->priv
;
1791 free(service
->name
);
1798 static void semihosting_tcp_close_cnx(struct semihosting
*semihosting
)
1800 if (!semihosting
->tcp_connection
)
1803 struct service
*service
= semihosting
->tcp_connection
->service
;
1804 remove_service(service
->name
, service
->port
);
1805 semihosting
->tcp_connection
= NULL
;
1809 static const struct service_driver semihosting_service_driver
= {
1810 .name
= "semihosting",
1811 .new_connection_during_keep_alive_handler
= NULL
,
1812 .new_connection_handler
= semihosting_service_new_connection_handler
,
1813 .input_handler
= semihosting_service_input_handler
,
1814 .connection_closed_handler
= semihosting_service_connection_closed_handler
,
1815 .keep_client_alive_handler
= NULL
,
1818 /* -------------------------------------------------------------------------
1819 * Common semihosting commands handlers. */
1821 COMMAND_HANDLER(handle_common_semihosting_command
)
1823 struct target
*target
= get_current_target(CMD_CTX
);
1826 LOG_ERROR("No target selected");
1830 struct semihosting
*semihosting
= target
->semihosting
;
1832 command_print(CMD
, "semihosting not supported for current target");
1839 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], is_active
);
1841 if (!target_was_examined(target
)) {
1842 LOG_ERROR("Target not examined yet");
1846 if (semihosting
&& semihosting
->setup(target
, is_active
) != ERROR_OK
) {
1847 LOG_ERROR("Failed to Configure semihosting");
1851 /* FIXME never let that "catch" be dropped! (???) */
1852 semihosting
->is_active
= is_active
;
1855 command_print(CMD
, "semihosting is %s",
1856 semihosting
->is_active
1857 ? "enabled" : "disabled");
1862 COMMAND_HANDLER(handle_common_semihosting_redirect_command
)
1864 struct target
*target
= get_current_target(CMD_CTX
);
1867 LOG_ERROR("No target selected");
1871 struct semihosting
*semihosting
= target
->semihosting
;
1873 command_print(CMD
, "semihosting not supported for current target");
1877 if (!semihosting
->is_active
) {
1878 command_print(CMD
, "semihosting not yet enabled for current target");
1882 enum semihosting_redirect_config cfg
;
1886 return ERROR_COMMAND_SYNTAX_ERROR
;
1888 if (strcmp(CMD_ARGV
[0], "disable") == 0) {
1889 cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1891 return ERROR_COMMAND_SYNTAX_ERROR
;
1892 } else if (strcmp(CMD_ARGV
[0], "tcp") == 0) {
1893 if (CMD_ARGC
< 2 || CMD_ARGC
> 3)
1894 return ERROR_COMMAND_SYNTAX_ERROR
;
1898 cfg
= SEMIHOSTING_REDIRECT_CFG_ALL
;
1899 if (CMD_ARGC
== 3) {
1900 if (strcmp(CMD_ARGV
[2], "debug") == 0)
1901 cfg
= SEMIHOSTING_REDIRECT_CFG_DEBUG
;
1902 else if (strcmp(CMD_ARGV
[2], "stdio") == 0)
1903 cfg
= SEMIHOSTING_REDIRECT_CFG_STDIO
;
1904 else if (strcmp(CMD_ARGV
[2], "all") != 0)
1905 return ERROR_COMMAND_SYNTAX_ERROR
;
1908 return ERROR_COMMAND_SYNTAX_ERROR
;
1911 semihosting_tcp_close_cnx(semihosting
);
1912 semihosting
->redirect_cfg
= SEMIHOSTING_REDIRECT_CFG_NONE
;
1914 if (cfg
!= SEMIHOSTING_REDIRECT_CFG_NONE
) {
1915 struct semihosting_tcp_service
*service
=
1916 calloc(1, sizeof(struct semihosting_tcp_service
));
1918 LOG_ERROR("Failed to allocate semihosting TCP service.");
1922 service
->semihosting
= semihosting
;
1924 service
->name
= alloc_printf("%s semihosting service", target_name(target
));
1925 if (!service
->name
) {
1926 LOG_ERROR("Out of memory");
1931 int ret
= add_service(&semihosting_service_driver
,
1934 if (ret
!= ERROR_OK
) {
1935 LOG_ERROR("failed to initialize %s", service
->name
);
1936 free(service
->name
);
1942 semihosting
->redirect_cfg
= cfg
;
1947 COMMAND_HANDLER(handle_common_semihosting_fileio_command
)
1949 struct target
*target
= get_current_target(CMD_CTX
);
1952 LOG_ERROR("No target selected");
1956 struct semihosting
*semihosting
= target
->semihosting
;
1958 command_print(CMD
, "semihosting not supported for current target");
1962 if (!semihosting
->is_active
) {
1963 command_print(CMD
, "semihosting not yet enabled for current target");
1968 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->is_fileio
);
1970 command_print(CMD
, "semihosting fileio is %s",
1971 semihosting
->is_fileio
1972 ? "enabled" : "disabled");
1977 COMMAND_HANDLER(handle_common_semihosting_cmdline
)
1979 struct target
*target
= get_current_target(CMD_CTX
);
1983 LOG_ERROR("No target selected");
1987 struct semihosting
*semihosting
= target
->semihosting
;
1989 command_print(CMD
, "semihosting not supported for current target");
1993 free(semihosting
->cmdline
);
1994 semihosting
->cmdline
= CMD_ARGC
> 0 ? strdup(CMD_ARGV
[0]) : NULL
;
1996 for (i
= 1; i
< CMD_ARGC
; i
++) {
1997 char *cmdline
= alloc_printf("%s %s", semihosting
->cmdline
, CMD_ARGV
[i
]);
2000 free(semihosting
->cmdline
);
2001 semihosting
->cmdline
= cmdline
;
2004 command_print(CMD
, "semihosting command line is [%s]",
2005 semihosting
->cmdline
);
2010 COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command
)
2012 struct target
*target
= get_current_target(CMD_CTX
);
2015 LOG_ERROR("No target selected");
2019 struct semihosting
*semihosting
= target
->semihosting
;
2021 command_print(CMD
, "semihosting not supported for current target");
2025 if (!semihosting
->is_active
) {
2026 command_print(CMD
, "semihosting not yet enabled for current target");
2031 COMMAND_PARSE_ENABLE(CMD_ARGV
[0], semihosting
->has_resumable_exit
);
2033 command_print(CMD
, "semihosting resumable exit is %s",
2034 semihosting
->has_resumable_exit
2035 ? "enabled" : "disabled");
2040 COMMAND_HANDLER(handle_common_semihosting_read_user_param_command
)
2042 struct target
*target
= get_current_target(CMD_CTX
);
2043 struct semihosting
*semihosting
= target
->semihosting
;
2046 return ERROR_COMMAND_SYNTAX_ERROR
;
2048 if (!semihosting
->is_active
) {
2049 LOG_ERROR("semihosting not yet enabled for current target");
2053 if (!semihosting_user_op_params
) {
2054 LOG_ERROR("This command is usable only from a registered user "
2055 "semihosting event callback.");
2059 command_print_sameline(CMD
, "%s", semihosting_user_op_params
);
2064 COMMAND_HANDLER(handle_common_semihosting_basedir_command
)
2066 struct target
*target
= get_current_target(CMD_CTX
);
2069 return ERROR_COMMAND_SYNTAX_ERROR
;
2072 LOG_ERROR("No target selected");
2076 struct semihosting
*semihosting
= target
->semihosting
;
2078 command_print(CMD
, "semihosting not supported for current target");
2082 if (!semihosting
->is_active
) {
2083 command_print(CMD
, "semihosting not yet enabled for current target");
2088 free(semihosting
->basedir
);
2089 semihosting
->basedir
= strdup(CMD_ARGV
[0]);
2090 if (!semihosting
->basedir
) {
2091 command_print(CMD
, "semihosting failed to allocate memory for basedir!");
2096 command_print(CMD
, "semihosting base dir: %s",
2097 semihosting
->basedir
? semihosting
->basedir
: "");
2102 const struct command_registration semihosting_common_handlers
[] = {
2104 .name
= "semihosting",
2105 .handler
= handle_common_semihosting_command
,
2106 .mode
= COMMAND_EXEC
,
2107 .usage
= "['enable'|'disable']",
2108 .help
= "activate support for semihosting operations",
2111 .name
= "semihosting_redirect",
2112 .handler
= handle_common_semihosting_redirect_command
,
2113 .mode
= COMMAND_EXEC
,
2114 .usage
= "(disable | tcp <port> ['debug'|'stdio'|'all'])",
2115 .help
= "redirect semihosting IO",
2118 .name
= "semihosting_cmdline",
2119 .handler
= handle_common_semihosting_cmdline
,
2120 .mode
= COMMAND_EXEC
,
2121 .usage
= "arguments",
2122 .help
= "command line arguments to be passed to program",
2125 .name
= "semihosting_fileio",
2126 .handler
= handle_common_semihosting_fileio_command
,
2127 .mode
= COMMAND_EXEC
,
2128 .usage
= "['enable'|'disable']",
2129 .help
= "activate support for semihosting fileio operations",
2132 .name
= "semihosting_resexit",
2133 .handler
= handle_common_semihosting_resumable_exit_command
,
2134 .mode
= COMMAND_EXEC
,
2135 .usage
= "['enable'|'disable']",
2136 .help
= "activate support for semihosting resumable exit",
2139 .name
= "semihosting_read_user_param",
2140 .handler
= handle_common_semihosting_read_user_param_command
,
2141 .mode
= COMMAND_EXEC
,
2143 .help
= "read parameters in semihosting-user-cmd-0x10X callbacks",
2146 .name
= "semihosting_basedir",
2147 .handler
= handle_common_semihosting_basedir_command
,
2148 .mode
= COMMAND_EXEC
,
2150 .help
= "set the base directory for semihosting I/O operations",
2152 COMMAND_REGISTRATION_DONE