1 /* 2 * Copyright (c) 2022, Commonwealth Scientific and Industrial Research 3 * Organisation (CSIRO) ABN 41 687 119 230. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 * 7 * Based on the ARM semihosting API from: 8 * https://github.com/ARM-software/abi-aa/blob/main/semihosting/semihosting.rst 9 * 10 * RISC-V semihosting also follows these conventions: 11 * https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc 12 */ 13 14 /** 15 * @file 16 * 17 * @brief public Semihosting APIs based on ARM definitions. 18 * @defgroup semihost Semihosting APIs 19 * @ingroup os_services 20 * @{ 21 */ 22 23 #ifndef ZEPHYR_INCLUDE_ARCH_COMMON_SEMIHOST_H_ 24 #define ZEPHYR_INCLUDE_ARCH_COMMON_SEMIHOST_H_ 25 26 /** @brief Semihosting instructions */ 27 enum semihost_instr { 28 /* 29 * File I/O operations 30 */ 31 32 /** Open a file or stream on the host system. */ 33 SEMIHOST_OPEN = 0x01, 34 /** Check whether a file is associated with a stream/terminal */ 35 SEMIHOST_ISTTY = 0x09, 36 /** Write to a file or stream. */ 37 SEMIHOST_WRITE = 0x05, 38 /** Read from a file at the current cursor position. */ 39 SEMIHOST_READ = 0x06, 40 /** Closes a file on the host which has been opened by SEMIHOST_OPEN. */ 41 SEMIHOST_CLOSE = 0x02, 42 /** Get the length of a file. */ 43 SEMIHOST_FLEN = 0x0C, 44 /** Set the file cursor to a given position in a file. */ 45 SEMIHOST_SEEK = 0x0A, 46 /** Get a temporary absolute file path to create a temporary file. */ 47 SEMIHOST_TMPNAM = 0x0D, 48 /** Remove a file on the host system. Possibly insecure! */ 49 SEMIHOST_REMOVE = 0x0E, 50 /** Rename a file on the host system. Possibly insecure! */ 51 SEMIHOST_RENAME = 0x0F, 52 53 /* 54 * Terminal I/O operations 55 */ 56 57 /** Write one character to the debug terminal. */ 58 SEMIHOST_WRITEC = 0x03, 59 /** Write a NULL terminated string to the debug terminal. */ 60 SEMIHOST_WRITE0 = 0x04, 61 /** Read one character from the debug terminal. */ 62 SEMIHOST_READC = 0x07, 63 64 /* 65 * Time operations 66 */ 67 SEMIHOST_CLOCK = 0x10, 68 SEMIHOST_ELAPSED = 0x30, 69 SEMIHOST_TICKFREQ = 0x31, 70 SEMIHOST_TIME = 0x11, 71 72 /* 73 * System/Misc. operations 74 */ 75 76 /** Retrieve the errno variable from semihosting operations. */ 77 SEMIHOST_ERRNO = 0x13, 78 /** Get commandline parameters for the application to run with */ 79 SEMIHOST_GET_CMDLINE = 0x15, 80 SEMIHOST_HEAPINFO = 0x16, 81 SEMIHOST_ISERROR = 0x08, 82 SEMIHOST_SYSTEM = 0x12 83 }; 84 85 /** 86 * @brief Modes to open a file with 87 * 88 * Behaviour corresponds to equivalent fopen strings. 89 * i.e. SEMIHOST_OPEN_RB_PLUS == "rb+" 90 */ 91 enum semihost_open_mode { 92 SEMIHOST_OPEN_R = 0, 93 SEMIHOST_OPEN_RB = 1, 94 SEMIHOST_OPEN_R_PLUS = 2, 95 SEMIHOST_OPEN_RB_PLUS = 3, 96 SEMIHOST_OPEN_W = 4, 97 SEMIHOST_OPEN_WB = 5, 98 SEMIHOST_OPEN_W_PLUS = 6, 99 SEMIHOST_OPEN_WB_PLUS = 7, 100 SEMIHOST_OPEN_A = 8, 101 SEMIHOST_OPEN_AB = 9, 102 SEMIHOST_OPEN_A_PLUS = 10, 103 SEMIHOST_OPEN_AB_PLUS = 11, 104 }; 105 106 /** 107 * @brief Manually execute a semihosting instruction 108 * 109 * @param instr instruction code to run 110 * @param args instruction specific arguments 111 * 112 * @return integer return code of instruction 113 */ 114 long semihost_exec(enum semihost_instr instr, void *args); 115 116 /** 117 * @brief Read a byte from the console 118 * 119 * @return char byte read from the console. 120 */ 121 char semihost_poll_in(void); 122 123 /** 124 * @brief Write a byte to the console 125 * 126 * @param c byte to write to console 127 */ 128 void semihost_poll_out(char c); 129 130 /** 131 * @brief Open a file on the host system 132 * 133 * @param path file path to open. Can be absolute or relative to current 134 * directory of the running process. 135 * @param mode value from @ref semihost_open_mode. 136 * 137 * @retval handle positive handle on success. 138 * @retval -1 on failure. 139 */ 140 long semihost_open(const char *path, long mode); 141 142 /** 143 * @brief Close a file 144 * 145 * @param fd handle returned by @ref semihost_open. 146 * 147 * @retval 0 on success. 148 * @retval -1 on failure. 149 */ 150 long semihost_close(long fd); 151 152 /** 153 * @brief Query the size of a file 154 * 155 * @param fd handle returned by @ref semihost_open. 156 * 157 * @retval positive file size on success. 158 * @retval -1 on failure. 159 */ 160 long semihost_flen(long fd); 161 162 /** 163 * @brief Seeks to an absolute position in a file. 164 * 165 * @param fd handle returned by @ref semihost_open. 166 * @param offset offset from the start of the file in bytes. 167 * 168 * @retval 0 on success. 169 * @retval -errno negative error code on failure. 170 */ 171 long semihost_seek(long fd, long offset); 172 173 /** 174 * @brief Read the contents of a file into a buffer. 175 * 176 * @param fd handle returned by @ref semihost_open. 177 * @param buf buffer to read data into. 178 * @param len number of bytes to read. 179 * 180 * @retval read number of bytes read on success. 181 * @retval -errno negative error code on failure. 182 */ 183 long semihost_read(long fd, void *buf, long len); 184 185 /** 186 * @brief Write the contents of a buffer into a file. 187 * 188 * @param fd handle returned by @ref semihost_open. 189 * @param buf buffer to write data from. 190 * @param len number of bytes to write. 191 * 192 * @retval 0 on success. 193 * @retval -errno negative error code on failure. 194 */ 195 long semihost_write(long fd, const void *buf, long len); 196 197 /** 198 * @} 199 */ 200 201 #endif /* ZEPHYR_INCLUDE_ARCH_COMMON_SEMIHOST_H_ */ 202