1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
4 * Copyright 2014 Broadcom Corporation
9 #include <semihosting.h>
13 #define SYSWRITEC 0x03
14 #define SYSWRITE0 0x04
18 #define SYSISERROR 0x08
23 #if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)
24 static bool _semihosting_enabled = true;
25 static bool try_semihosting = true;
27 bool semihosting_enabled(void)
29 if (try_semihosting) {
30 smh_trap(SYSERRNO, NULL);
31 try_semihosting = false;
34 return _semihosting_enabled;
37 void disable_semihosting(void)
39 _semihosting_enabled = false;
44 * smh_errno() - Read the host's errno
46 * This gets the value of the host's errno and negates it. The host's errno may
47 * or may not be set, so only call this function if a previous semihosting call
50 * Return: a negative error value
52 static int smh_errno(void)
54 long ret = smh_trap(SYSERRNO, NULL);
56 if (ret > 0 && ret < INT_MAX)
61 long smh_open(const char *fname, enum smh_open_mode mode)
70 debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode);
73 open.len = strlen(fname);
76 /* Open the file on the host */
77 fd = smh_trap(SYSOPEN, &open);
84 * struct smg_rdwr_s - Arguments for read and write
85 * @fd: A file descriptor returned from smh_open()
86 * @memp: Pointer to a buffer of memory of at least @len bytes
87 * @len: The number of bytes to read or write
95 long smh_read(long fd, void *memp, size_t len)
98 struct smh_rdwr_s read;
100 debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len);
106 ret = smh_trap(SYSREAD, &read);
112 long smh_write(long fd, const void *memp, size_t len, ulong *written)
115 struct smh_rdwr_s write;
117 debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len);
120 write.memp = (void *)memp;
123 ret = smh_trap(SYSWRITE, &write);
124 *written = len - ret;
130 long smh_close(long fd)
134 debug("%s: fd %ld\n", __func__, fd);
136 ret = smh_trap(SYSCLOSE, &fd);
142 long smh_flen(long fd)
146 debug("%s: fd %ld\n", __func__, fd);
148 ret = smh_trap(SYSFLEN, &fd);
154 long smh_seek(long fd, long pos)
162 debug("%s: fd %ld pos %ld\n", __func__, fd, pos);
167 ret = smh_trap(SYSSEEK, &seek);
175 return smh_trap(SYSREADC, NULL);
178 void smh_putc(char ch)
180 smh_trap(SYSWRITEC, &ch);
183 void smh_puts(const char *s)
185 smh_trap(SYSWRITE0, (char *)s);