1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright © 2023 Keith Packard
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above
14  *    copyright notice, this list of conditions and the following
15  *    disclaimer in the documentation and/or other materials provided
16  *    with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  *    contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef _ARC_SEMIHOST_H_
37 #define _ARC_SEMIHOST_H_
38 
39 #include <stdint.h>
40 #include <errno.h>
41 
42 #define SYS_SEMIHOST_exit	1
43 #define SYS_SEMIHOST_read	3
44 #define SYS_SEMIHOST_write	4
45 #define SYS_SEMIHOST_open	5
46 #define SYS_SEMIHOST_close	6
47 #define SYS_SEMIHOST_unlink	10
48 #define SYS_SEMIHOST_time	13
49 #define SYS_SEMIHOST_lseek	19
50 #define SYS_SEMIHOST_times	43
51 #define SYS_SEMIHOST_gettimeofday	78
52 #define SYS_SEMIHOST_stat	106 /* nsim stat's is corupted.  */
53 #define SYS_SEMIHOST_fstat	108
54 #define SYS_SEMIHOST_argc	1000
55 #define SYS_SEMIHOST_argv_sz	1001
56 #define SYS_SEMIHOST_argv	1002
57 #define SYS_SEMIHOST_memset	1004
58 #define SYS_SEMIHOST_errno      2000
59 
60 enum {
61     TARGET_ERRNO_EPERM = 1,			/* Not owner */
62     TARGET_ERRNO_ENOENT = 2,		/* No such file or directory */
63     TARGET_ERRNO_ESRCH = 3,			/* No such process */
64     TARGET_ERRNO_EINTR = 4,			/* Interrupted system call */
65     TARGET_ERRNO_EIO = 5,			/* I/O error */
66     TARGET_ERRNO_ENXIO = 6,			/* No such device or address */
67     TARGET_ERRNO_E2BIG = 7,			/* Arg list too long */
68     TARGET_ERRNO_ENOEXEC = 8,		/* Exec format error */
69     TARGET_ERRNO_EBADF = 9,			/* Bad file number */
70     TARGET_ERRNO_ECHILD = 10,		/* No children */
71     TARGET_ERRNO_EAGAIN = 11,		/* No more processes */
72     TARGET_ERRNO_ENOMEM = 12,		/* Not enough space */
73     TARGET_ERRNO_EACCES = 13,		/* Permission denied */
74     TARGET_ERRNO_EFAULT = 14,		/* Bad address */
75     TARGET_ERRNO_ENOTBLK = 15,	    /* Block device required */
76     TARGET_ERRNO_EBUSY = 16,		/* Device or resource busy */
77     TARGET_ERRNO_EEXIST = 17,		/* File exists */
78     TARGET_ERRNO_EXDEV = 18,		/* Cross-device link */
79     TARGET_ERRNO_ENODEV = 19,		/* No such device */
80     TARGET_ERRNO_ENOTDIR = 20,		/* Not a directory */
81     TARGET_ERRNO_EISDIR = 21,		/* Is a directory */
82     TARGET_ERRNO_EINVAL = 22,		/* Invalid argument */
83     TARGET_ERRNO_ENFILE = 23,		/* Too many open files in system */
84     TARGET_ERRNO_EMFILE = 24,		/* File descriptor value too large */
85     TARGET_ERRNO_ENOTTY = 25,		/* Not a character device */
86     TARGET_ERRNO_ETXTBSY = 26,		/* Text file busy */
87     TARGET_ERRNO_EFBIG = 27,		/* File too large */
88     TARGET_ERRNO_ENOSPC = 28,		/* No space left on device */
89     TARGET_ERRNO_ESPIPE = 29,		/* Illegal seek */
90     TARGET_ERRNO_EROFS = 30,		/* Read-only file system */
91     TARGET_ERRNO_EMLINK = 31,		/* Too many links */
92     TARGET_ERRNO_EPIPE = 32,		/* Broken pipe */
93     TARGET_ERRNO_EDOM = 33,			/* Mathematics argument out of domain of function */
94     TARGET_ERRNO_ERANGE = 34,		/* Result too large */
95     TARGET_ERRNO_ENOMSG = 35,		/* No message of desired type */
96     TARGET_ERRNO_EIDRM = 36,		/* Identifier removed */
97     TARGET_ERRNO_ECHRNG = 37,       /* Channel number out of range */
98     TARGET_ERRNO_EL2NSYNC = 38,     /* Level 2 not synchronized */
99     TARGET_ERRNO_EL3HLT = 39,	    /* Level 3 halted */
100     TARGET_ERRNO_EL3RST = 40,       /* Level 3 reset */
101     TARGET_ERRNO_ELNRNG = 41,	    /* Link number out of range */
102     TARGET_ERRNO_EUNATCH = 42,	    /* Protocol driver not attached */
103     TARGET_ERRNO_ENOCSI = 43,	    /* No CSI structure available */
104     TARGET_ERRNO_EL2HLT = 44,	    /* Level 2 halted */
105     TARGET_ERRNO_EDEADLK = 45,		/* Deadlock */
106     TARGET_ERRNO_ENOLCK = 46,		/* No lock */
107     TARGET_ERRNO_EBADE = 50,		/* Invalid exchange */
108     TARGET_ERRNO_EBADR = 51,		/* Invalid request descriptor */
109     TARGET_ERRNO_EXFULL = 52,		/* Exchange full */
110     TARGET_ERRNO_ENOANO = 53,		/* No anode */
111     TARGET_ERRNO_EBADRQC = 54,		/* Invalid request code */
112     TARGET_ERRNO_EBADSLT = 55,		/* Invalid slot */
113     TARGET_ERRNO_EDEADLOCK = 56,	/* File locking deadlock error */
114     TARGET_ERRNO_EBFONT = 57,		/* Bad font file fmt */
115     TARGET_ERRNO_ENOSTR = 60,		/* Not a stream */
116     TARGET_ERRNO_ENODATA = 61,		/* No data (for no delay io) */
117     TARGET_ERRNO_ETIME = 62,		/* Stream ioctl timeout */
118     TARGET_ERRNO_ENOSR = 63,		/* No stream resources */
119     TARGET_ERRNO_ENONET = 64,		/* Machine is not on the network */
120     TARGET_ERRNO_ENOPKG = 65,		/* Package not installed */
121     TARGET_ERRNO_EREMOTE = 66,		/* The object is remote */
122     TARGET_ERRNO_ENOLINK = 67,		/* Virtual circuit is gone */
123     TARGET_ERRNO_EADV = 68,			/* Advertise error */
124     TARGET_ERRNO_ESRMNT = 69,		/* Srmount error */
125     TARGET_ERRNO_ECOMM = 70,		/* Communication error on send */
126     TARGET_ERRNO_EPROTO = 71,		/* Protocol error */
127     TARGET_ERRNO_EMULTIHOP = 74,	/* Multihop attempted */
128     TARGET_ERRNO_ELBIN = 75,		/* Inode is remote (not really error) */
129     TARGET_ERRNO_EDOTDOT = 76,		/* Cross mount point (not really error) */
130     TARGET_ERRNO_EBADMSG = 77,		/* Bad message */
131     TARGET_ERRNO_EFTYPE = 79,		/* Inappropriate file type or format */
132     TARGET_ERRNO_ENOTUNIQ = 80,		/* Given log. name not unique */
133     TARGET_ERRNO_EBADFD = 81,		/* File descriptor in bad state */
134     TARGET_ERRNO_EREMCHG = 82,		/* Remote address changed */
135     TARGET_ERRNO_ELIBACC = 83,		/* Can't access a needed shared lib */
136     TARGET_ERRNO_ELIBBAD = 84,		/* Accessing a corrupted shared lib */
137     TARGET_ERRNO_ELIBSCN = 85,		/* .lib section in a.out corrupted */
138     TARGET_ERRNO_ELIBMAX = 86,		/* Attempting to link in too many libs */
139     TARGET_ERRNO_ELIBEXEC = 87,		/* Attempting to exec a shared library */
140     TARGET_ERRNO_ENOSYS = 88,		/* Function not implemented */
141     TARGET_ERRNO_ENMFILE = 89,      /* No more files */
142     TARGET_ERRNO_ENOTEMPTY = 90,	/* Directory not empty */
143     TARGET_ERRNO_ENAMETOOLONG = 91,	/* File or path name too long */
144     TARGET_ERRNO_ELOOP = 92,		/* Too many symbolic links */
145     TARGET_ERRNO_EOPNOTSUPP = 95,	/* Operation not supported on socket */
146     TARGET_ERRNO_EPFNOSUPPORT = 96, /* Protocol family not supported */
147     TARGET_ERRNO_ECONNRESET = 104,  /* Connection reset by peer */
148     TARGET_ERRNO_ENOBUFS = 105,		/* No buffer space available */
149     TARGET_ERRNO_EAFNOSUPPORT = 106,/* Address family not supported by protocol family */
150     TARGET_ERRNO_EPROTOTYPE = 107,	/* Protocol wrong type for socket */
151     TARGET_ERRNO_ENOTSOCK = 108,	/* Socket operation on non-socket */
152     TARGET_ERRNO_ENOPROTOOPT = 109,	/* Protocol not available */
153     TARGET_ERRNO_ESHUTDOWN = 110,	/* Can't send after socket shutdown */
154     TARGET_ERRNO_ECONNREFUSED = 111,/* Connection refused */
155     TARGET_ERRNO_EADDRINUSE = 112,	/* Address already in use */
156     TARGET_ERRNO_ECONNABORTED = 113,/* Software caused connection abort */
157     TARGET_ERRNO_ENETUNREACH = 114,	/* Network is unreachable */
158     TARGET_ERRNO_ENETDOWN = 115,	/* Network interface is not configured */
159     TARGET_ERRNO_ETIMEDOUT = 116,	/* Connection timed out */
160     TARGET_ERRNO_EHOSTDOWN = 117,	/* Host is down */
161     TARGET_ERRNO_EHOSTUNREACH = 118,/* Host is unreachable */
162     TARGET_ERRNO_EINPROGRESS = 119,	/* Connection already in progress */
163     TARGET_ERRNO_EALREADY = 120,	/* Socket already connected */
164     TARGET_ERRNO_EDESTADDRREQ = 121,/* Destination address required */
165     TARGET_ERRNO_EMSGSIZE = 122,	/* Message too long */
166     TARGET_ERRNO_EPROTONOSUPPORT = 123,	/* Unknown protocol */
167     TARGET_ERRNO_ESOCKTNOSUPPORT = 124,	/* Socket type not supported */
168     TARGET_ERRNO_EADDRNOTAVAIL = 125,	/* Address not available */
169     TARGET_ERRNO_ENETRESET = 126,   /* Connection aborted by network */
170     TARGET_ERRNO_EISCONN = 127,		/* Socket is already connected */
171     TARGET_ERRNO_ENOTCONN = 128,	/* Socket is not connected */
172     TARGET_ERRNO_ETOOMANYREFS = 129,/* Too many references: cannot splice */
173     TARGET_ERRNO_EPROCLIM = 130,    /* Too many processes */
174     TARGET_ERRNO_EUSERS = 131,      /* Too many users */
175     TARGET_ERRNO_EDQUOT = 132,      /* Reserved */
176     TARGET_ERRNO_ESTALE = 133,      /* Reserved */
177     TARGET_ERRNO_ENOTSUP = 134,     /* Not supported */
178     TARGET_ERRNO_ENOMEDIUM = 135,   /* No medium found */
179     TARGET_ERRNO_ENOSHARE = 136,    /* No such host or network path */
180     TARGET_ERRNO_ECASECLASH = 137,  /* Filename exists with different case */
181     TARGET_ERRNO_EILSEQ = 138,		/* Illegal byte sequence */
182     TARGET_ERRNO_EOVERFLOW = 139,	/* Value too large for defined data type */
183     TARGET_ERRNO_ECANCELED = 140,	/* Operation canceled */
184     TARGET_ERRNO_ENOTRECOVERABLE = 141,	/* State not recoverable */
185     TARGET_ERRNO_EOWNERDEAD = 142,	/* Previous owner died */
186     TARGET_ERRNO_ESTRPIPE = 143,	/* Streams pipe error */
187     TARGET_ERRNO_EHWPOISON = 144,   /* Memory page has hardware error */
188     TARGET_ERRNO_EISNAM = 145,      /* Is a named type file */
189     TARGET_ERRNO_EKEYEXPIRED = 146, /* Key has expired */
190     TARGET_ERRNO_EKEYREJECTED = 147,/* Key was rejected by service */
191     TARGET_ERRNO_EKEYREVOKED = 148, /* Key has been revoked */
192 };
193 
194 #ifdef __ARC700__
195 #define SWI     "trap0"
196 #else
197 #define SWI     "swi"
198 #endif
199 
200 static inline uintptr_t
arc_semihost0(uintptr_t op)201 arc_semihost0(uintptr_t op)
202 {
203     register uintptr_t r_op __asm__("r8") = op;
204     register uintptr_t r_r0 __asm__("r0");
205 
206     __asm__ volatile (SWI : "=r" (r_r0) : "r" (r_op));
207     return r_r0;
208 }
209 
210 static inline uintptr_t
arc_semihost1(uintptr_t op,uintptr_t r0)211 arc_semihost1(uintptr_t op, uintptr_t r0)
212 {
213     register uintptr_t r_op __asm__("r8") = op;
214     register uintptr_t r_r0 __asm__("r0") = r0;
215 
216     __asm__ volatile (SWI : "=r" (r_r0) : "r" (r_op), "r" (r_r0));
217     return r_r0;
218 }
219 
220 static inline uintptr_t
arc_semihost2(uintptr_t op,uintptr_t r0,uintptr_t r1)221 arc_semihost2(uintptr_t op, uintptr_t r0, uintptr_t r1)
222 {
223     register uintptr_t r_op __asm__("r8") = op;
224     register uintptr_t r_r0 __asm__("r0") = r0;
225     register uintptr_t r_r1 __asm__("r1") = r1;
226 
227     __asm__ volatile (SWI : "=r" (r_r0) : "r" (r_op), "r" (r_r0), "r" (r_r1));
228     return r_r0;
229 }
230 
231 static inline uintptr_t
arc_semihost3(uintptr_t op,uintptr_t r0,uintptr_t r1,uintptr_t r2)232 arc_semihost3(uintptr_t op, uintptr_t r0, uintptr_t r1, uintptr_t r2)
233 {
234     register uintptr_t r_op __asm__("r8") = op;
235     register uintptr_t r_r0 __asm__("r0") = r0;
236     register uintptr_t r_r1 __asm__("r1") = r1;
237     register uintptr_t r_r2 __asm__("r2") = r2;
238 
239     __asm__ volatile (SWI : "=r" (r_r0) : "r" (r_op), "r" (r_r0), "r" (r_r1), "r" (r_r2));
240     return r_r0;
241 }
242 
243 void arc_semihost_errno(int def);
244 
245 #endif /* _ARC_SEMIHOST_H_ */
246