1 // SPDX-License-Identifier: GPL-2.0+
4 * Copyright 2014 Broadcom Corporation
8 #include <semihosting.h>
9 #include <linux/errno.h>
10 #include <linux/string.h>
14 #define SYSWRITEC 0x03
15 #define SYSWRITE0 0x04
19 #define SYSISERROR 0x08
24 #if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)
25 static bool _semihosting_enabled = true;
26 static bool try_semihosting = true;
28 bool semihosting_enabled(void)
30 if (try_semihosting) {
31 smh_trap(SYSERRNO, NULL);
32 try_semihosting = false;
35 return _semihosting_enabled;
38 void disable_semihosting(void)
40 _semihosting_enabled = false;
45 * smh_errno() - Read the host's errno
47 * This gets the value of the host's errno and negates it. The host's errno may
48 * or may not be set, so only call this function if a previous semihosting call
51 * Return: a negative error value
53 static int smh_errno(void)
55 long ret = smh_trap(SYSERRNO, NULL);
57 if (ret > 0 && ret < INT_MAX)
62 long smh_open(const char *fname, enum smh_open_mode mode)
71 debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode);
74 open.len = strlen(fname);
77 /* Open the file on the host */
78 fd = smh_trap(SYSOPEN, &open);
85 * struct smg_rdwr_s - Arguments for read and write
86 * @fd: A file descriptor returned from smh_open()
87 * @memp: Pointer to a buffer of memory of at least @len bytes
88 * @len: The number of bytes to read or write
96 long smh_read(long fd, void *memp, size_t len)
99 struct smh_rdwr_s read;
101 debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len);
107 ret = smh_trap(SYSREAD, &read);
113 long smh_write(long fd, const void *memp, size_t len, ulong *written)
116 struct smh_rdwr_s write;
118 debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len);
121 write.memp = (void *)memp;
124 ret = smh_trap(SYSWRITE, &write);
125 *written = len - ret;
131 long smh_close(long fd)
135 debug("%s: fd %ld\n", __func__, fd);
137 ret = smh_trap(SYSCLOSE, &fd);
143 long smh_flen(long fd)
147 debug("%s: fd %ld\n", __func__, fd);
149 ret = smh_trap(SYSFLEN, &fd);
155 long smh_seek(long fd, long pos)
163 debug("%s: fd %ld pos %ld\n", __func__, fd, pos);
168 ret = smh_trap(SYSSEEK, &seek);
176 return smh_trap(SYSREADC, NULL);
179 void smh_putc(char ch)
181 smh_trap(SYSWRITEC, &ch);
184 void smh_puts(const char *s)
186 smh_trap(SYSWRITE0, (char *)s);