comparison packages/redboot/current/src/syscall.c @ 136:a9ac27ec7abc ecos-sw-2000-11-17

Merge from eCos master repository on 2000-11-17-18:24:25-GMT
author jlarmour
date Fri, 17 Nov 2000 23:16:43 +0000
parents
children 25e238959bae
comparison
equal deleted inserted replaced
135:3bc2abeae9ff 136:a9ac27ec7abc
1 /*==========================================================================
2 //
3 // syscall.c
4 //
5 // Redboot syscall handling for GNUPro bsp support
6 //
7 //==========================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Red Hat eCos Public License
12 // Version 1.1 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://www.redhat.com/
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Configurable Operating System,
22 // released September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Red Hat.
25 // Portions created by Red Hat are
26 // Copyright (C) 2000 Red Hat, Inc.
27 // All Rights Reserved.
28 // -------------------------------------------
29 //
30 //####COPYRIGHTEND####
31 //==========================================================================
32 //#####DESCRIPTIONBEGIN####
33 //
34 // Author(s): msalter
35 // Contributors: msalter
36 // Date: 1999-02-20
37 // Purpose: Temporary support for gnupro bsp
38 //
39 //####DESCRIPTIONEND####
40 //
41 //=========================================================================*/
42
43 #include <redboot.h>
44
45 #ifdef CYGSEM_REDBOOT_BSP_SYSCALLS
46
47 #define EIO 5 /* I/O error */
48
49 // These are required by the ANSI C part of newlib (excluding system() of
50 // course).
51 #define SYS_exit 1
52 #define SYS_open 2
53 #define SYS_close 3
54 #define SYS_read 4
55 #define SYS_write 5
56 #define SYS_lseek 6
57 #define SYS_unlink 7
58 #define SYS_getpid 8
59 #define SYS_kill 9
60 #define SYS_fstat 10
61 //#define SYS_sbrk 11 - not currently a system call, but reserved.
62
63 // ARGV support.
64 #define SYS_argvlen 12
65 #define SYS_argv 13
66
67 // These are extras added for one reason or another.
68 #define SYS_chdir 14
69 #define SYS_stat 15
70 #define SYS_chmod 16
71 #define SYS_utime 17
72 #define SYS_time 18
73
74 #define SYS_interrupt 1000
75
76 #define __GET_SHARED 0xbaad
77
78
79 /*
80 * Clients of this BSP will need to have access to BSP functions and
81 * data structures. Because, the client and the BSP may not be linked
82 * together, a structure of vectors is used to gain this access. A
83 * pointer to this structure can be gotten via a syscall. This syscall
84 * is made automatically from within the crt0.o file.
85 */
86 typedef struct {
87 int version; /* version number for future expansion */
88 const void **__ictrl_table;
89 void **__exc_table;
90 void *__dbg_vector;
91 void *__kill_vector;
92 void *__console_procs;
93 void *__debug_procs;
94 void (*__flush_dcache)(void *__p, int __nbytes);
95 void (*__flush_icache)(void *__p, int __nbytes);
96 void *__cpu_data;
97 void *__board_data;
98 void *__sysinfo;
99 int (*__set_debug_comm)(int __comm_id);
100 int (*__set_console_comm)(int __comm_id);
101 int (*__set_serial_baud)(int __comm_id, int baud);
102 void *__dbg_data;
103 void (*__reset)(void);
104 int __console_interrupt_flag;
105 } __shared_t;
106
107 static __shared_t __shared_data = { 2 };
108
109 static inline char __getc(void)
110 {
111 char c;
112 hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
113
114 if (__chan)
115 c = CYGACC_COMM_IF_GETC(*__chan);
116 else {
117 __chan = CYGACC_CALL_IF_DEBUG_PROCS();
118 c = CYGACC_COMM_IF_GETC(*__chan);
119 }
120 return c;
121 }
122
123 static inline void __putc(char c)
124 {
125 hal_virtual_comm_table_t* __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
126 if (__chan)
127 CYGACC_COMM_IF_PUTC(*__chan, c);
128 else {
129 __chan = CYGACC_CALL_IF_DEBUG_PROCS();
130 CYGACC_COMM_IF_PUTC(*__chan, c);
131 }
132 }
133
134
135 //
136 // read -- read bytes from the serial port. Ignore fd, since
137 // we only have stdin.
138 static int
139 sys_read(int fd, char *buf, int nbytes)
140 {
141 int i = 0;
142
143 for (i = 0; i < nbytes; i++) {
144 *(buf + i) = __getc();
145 if ((*(buf + i) == '\n') || (*(buf + i) == '\r')) {
146 (*(buf + i + 1)) = 0;
147 break;
148 }
149 }
150 return (i);
151 }
152
153
154 //
155 // write -- write bytes to the serial port. Ignore fd, since
156 // stdout and stderr are the same. Since we have no filesystem,
157 // open will only return an error.
158 //
159 static int
160 sys_write(int fd, char *buf, int nbytes)
161 {
162 #define WBUFSIZE 256
163 int tosend;
164
165 tosend = nbytes;
166
167 while (tosend > 0) {
168 if (*buf == '\n')
169 __putc('\r');
170 __putc(*buf++);
171 tosend--;
172 }
173
174 return (nbytes);
175 }
176
177
178 //
179 // open -- open a file descriptor. We don't have a filesystem, so
180 // we return an error.
181 //
182 static int
183 sys_open (const char *buf, int flags, int mode)
184 {
185 return (-EIO);
186 }
187
188
189 //
190 // close -- We don't need to do anything, but pretend we did.
191 //
192 static int
193 sys_close(int fd)
194 {
195 return (0);
196 }
197
198
199 //
200 // lseek -- Since a serial port is non-seekable, we return an error.
201 //
202 static int
203 sys_lseek(int fd, int offset, int whence)
204 {
205 return (-EIO);
206 }
207
208
209 static int
210 sys_utime(unsigned long *p)
211 {
212 #ifdef HAVE_SYS_CLOCK
213 extern unsigned long __clock;
214
215 /* target clock runs at CLOCKS_PER_SEC. Convert to HZ */
216 if (p)
217 *p = (__clock * HZ) / CLOCKS_PER_SEC;
218 #else
219 if (p)
220 *p = 0;
221 #endif
222 return 0;
223 }
224
225
226 //
227 // Generic syscall handler.
228 //
229 // Returns 0 if syscall number is not handled by this
230 // module, 1 otherwise. This allows applications to
231 // extend the syscall handler by using exception chaining.
232 //
233 int
234 __do_syscall(int func, // syscall function number
235 long arg1, long arg2, // up to four args.
236 long arg3, long arg4,
237 int *retval) // syscall return value
238 {
239 int err = 0;
240
241 switch (func) {
242
243 case SYS_read:
244 err = sys_read((int)arg1, (char *)arg2, (int)arg3);
245 break;
246
247 case SYS_write:
248 err = sys_write((int)arg1, (char *)arg2, (int)arg3);
249 break;
250
251 case SYS_open:
252 err = sys_open((const char *)arg1, (int)arg2, (int)arg3);
253 break;
254
255 case SYS_close:
256 err = sys_close((int)arg1);
257 break;
258
259 case SYS_lseek:
260 err = sys_lseek((int)arg1, (int)arg2, (int)arg3);
261 break;
262
263 case SYS_utime:
264 err = sys_utime((unsigned long *)arg1);
265 break;
266
267 case __GET_SHARED:
268 *(__shared_t **)arg1 = &__shared_data;
269 break;
270
271 default:
272 return 0;
273 }
274
275 *retval = err;
276 return 1;
277 }
278
279 #endif