1 /*
2 Language Independent Library
3
4 Copyright 1983-2009 Green Hills Software,Inc.
5
6 * This program is the property of Green Hills Software, Inc,
7 * its contents are proprietary information and no part of it
8 * is to be disclosed to anyone except employees of Green Hills
9 * Software, Inc., or as agreed in writing signed by the President
10 * of Green Hills Software, Inc.
11 */
12 /* ind_io.c: core set of low-level I/O functions. Machine Independent. */
13
14 /*
15 * This module, and ind_exit.c, contain the lowest level I/O functions in the
16 * Green Hills C library. These functions provide a very simple UNIX-like
17 * system call interface.
18 *
19 * The default implementations provided here all call down to __ghs_syscall()
20 * in the ind_call.* assembly file. This expects the environment to trap calls
21 * to __dotsyscall in the ".syscall" section, which contains a NOP that may be
22 * patched by software debuggers or triggered by hardware debuggers. If nothing
23 * happens, __ghs_syscall() returns a generic -1 and sets the C "errno" to 0.
24 *
25 * Please see the Green Hills C Library Documentation for complete directions
26 * as to how to customize this module for your system. The most essential
27 * group of functions appears in ind_exit.c (for size reasons), with more
28 * optional groups of functions appearing later in this file.
29 *
30 * All functions have been have are weak symbols. This is done so that any
31 * or all of the functions can be redefined by the user from a separate
32 * object file, and not result in multiply-defined symbol problems from the
33 * linker.
34 *
35 * MEMORY ALLOCATION: low-level memory allocation is now done in ind_heap.c
36 */
37
38 #if defined(EMBEDDED)
39
40 #if 1 // CAFE MOD
41 #include <cafe/os.h>
42 #endif // CAFE MOD
43
44 #include "indos.h"
45 #include "ind_io.h"
46
47 #if (__CHAR_BIT > 8) || 1
48 # define DO_OPEN_CREAT_MODE
49 #endif
50
51 #if defined(DO_OPEN_CREAT_MODE)
52 #include <stdarg.h>
53 #endif
54
55 /*============================================================================*/
56 /* FUNCTIONS NEEDED TO PRINT OUT HELLO WORLD AND ENTER SIMPLE INPUT */
57 /*============================================================================*/
58 /* write() output an array of characters to a file descriptor */
59 /* read() input an array of characters from a file descriptor */
60 /*============================================================================*/
61
62 /******************************************************************************/
63 /* int write (int fno, const void *buf, int size); */
64 /* Write at most size bytes into the file connected to fno (where fno is */
65 /* one of the file numbers returned by open() or creat()) into buf. */
66 /* Return the number of bytes written, or -1 to indicate an error and */
67 /* set errno appropriately. */
68 /* */
69 /* Note that line breaks have not received any special processing. If you */
70 /* are reimplementing this to talk to a serial port and a terminal, you will */
71 /* need to output a "\r\n" sequence for each '\n' in the character array. */
72 /* The typical symptom that this is necessary is "barber pole" text output. */
73 /******************************************************************************/
74 #pragma weak write=__ghs_hostio_write
75
76 #if 1 // CAFE MOD
__ghs_hostio_write(int fno,const void * buf,int size)77 int __ghs_hostio_write (int fno, const void *buf, int size)
78 {
79 if (fno == 1 || fno == 2) {
80 OSConsoleWrite(buf, size);
81 return size;
82 } else {
83 #pragma ghs nowarning 1547 /* Syscall prototype problems */
84 return __ghs_syscall(SYSCALL_WRITE, fno, buf, size);
85 #pragma ghs endnowarning 1547
86 }
87 }
88 #endif // CAFE MOD
89
90 #if 0 // CAFE GHS ORIG
91 int __ghs_hostio_write (int fno, const void *buf, int size)
92 {
93 #pragma ghs nowarning 1547 /* Syscall prototype problems */
94 return __ghs_syscall(SYSCALL_WRITE, fno, buf, size);
95 #pragma ghs endnowarning 1547
96 }
97 #endif // CAFE GHS ORIG
98
99 /******************************************************************************/
100 /* int read (int fno, void *buf, int size); */
101 /* Read at most size bytes into buf from the file connected to fno (where */
102 /* fno is one of the file numbers returned by open() or creat()). */
103 /* Return the number of bytes read. Return 0 at end of file. Return -1 on */
104 /* error and set errno appropriately. */
105 /* */
106 /* The stdio libraries assume that (as on unix) line breaks are converted to */
107 /* single '\n' characters by the time read() returns success. If you are */
108 /* taking characters from a terminal, replace any '\r' you see with a '\n'. */
109 /******************************************************************************/
110 #pragma weak read=__ghs_hostio_read
__ghs_hostio_read(int fno,void * buf,int size)111 int __ghs_hostio_read (int fno, void *buf, int size)
112 {
113 #pragma ghs nowarning 1547 /* Syscall prototype problems */
114 return __ghs_syscall(SYSCALL_READ, fno, buf, size);
115 #pragma ghs endnowarning 1547
116 }
117
118 /*============================================================================*/
119 /* FUNCTIONS NEEDED TO USE THE HOST FILESYSTEM FROM YOUR TARGET */
120 /*============================================================================*/
121 /* open() start using a file */
122 /* creat() create a new file and start using it */
123 /* close() stop using a file */
124 /* lseek() move around in a file */
125 /* unlink() delete a file on the host (!!) (be careful!) */
126 /* fcntl() do evil things to the file descriptor (avoid this) */
127 /*============================================================================*/
128
129 /******************************************************************************/
130 /* int open (const char *filename, int mode, ...); */
131 /* Open the file named filename with the indicated mode. */
132 /* filename is a null terminated string and mode is one of the following */
133 /* */
134 /* 0 => open for reading */
135 /* 1 => open for writing */
136 /* 2 => open for reading & writing */
137 /* */
138 /* If the open is successful return a small non-negative integer file number.*/
139 /* On failure return -1, and set errno in accordance with the error. */
140 /******************************************************************************/
141 #pragma ghs nowarning 236 /* va_arg() "controlling expression is constant" */
142 #pragma weak open=__ghs_hostio_open
__ghs_hostio_open(const char * filename,int flags,...)143 int __ghs_hostio_open (const char *filename, int flags, ...)
144 {
145 if(flags & O_CREAT) {
146 int mode;
147 #if defined(DO_OPEN_CREAT_MODE)
148 va_list va;
149
150 va_start(va, flags);
151
152 mode = va_arg(va, int);
153
154 va_end(va);
155 #else
156 mode = 066;
157 #endif
158 #pragma ghs nowarning 1547 /* Syscall prototype problems */
159 return __ghs_syscall(SYSCALL_OPEN2, filename, flags, mode);
160 #pragma ghs endnowarning 1547
161 } else {
162 #pragma ghs nowarning 1547 /* Syscall prototype problems */
163 return __ghs_syscall(SYSCALL_OPEN, filename, flags);
164 #pragma ghs endnowarning 1547
165 }
166 }
167
168 /******************************************************************************/
169 /* int creat (const char *filename, int prot); */
170 /* Create and open for writing a file named filename with protection */
171 /* as specified by prot. filename is a null terminated string. */
172 /* prot is expressed in unix format, it is the logical or of: */
173 /* */
174 /* 0400: owner read */
175 /* 0200: owner write */
176 /* 0100: owner execute/search directory */
177 /* 0040: group read */
178 /* 0020: group write */
179 /* 0010: group execute/search directory */
180 /* 0004: other (world) read */
181 /* 0002: other (world) write */
182 /* 0001: other (world) execute/search directory */
183 /* */
184 /* For things like terminals that cannot be created it should just open the */
185 /* device. If successful, return a small integer file number. On failure */
186 /* return -1 and set errno appropriately. */
187 /******************************************************************************/
188 #pragma weak creat=__ghs_hostio_creat
__ghs_hostio_creat(const char * filename,int prot)189 int __ghs_hostio_creat (const char *filename, int prot)
190 {
191 #pragma ghs nowarning 1547 /* Syscall prototype problems */
192 return __ghs_syscall(SYSCALL_CREAT, filename, prot);
193 #pragma ghs endnowarning 1547
194 }
195
196 /******************************************************************************/
197 /* int close (int fno); */
198 /* Close the file associated with the file number fno (returned by open() */
199 /* or creat()). Return 0 if all goes well. Return -1 if something went */
200 /* wrong and set errno appropriately. */
201 /******************************************************************************/
202 #pragma weak close=__ghs_hostio_close
__ghs_hostio_close(int fno)203 int __ghs_hostio_close (int fno)
204 {
205 #pragma ghs nowarning 1547 /* Syscall prototype problems */
206 return __ghs_syscall(SYSCALL_CLOSE, fno);
207 #pragma ghs endnowarning 1547
208 }
209
210 /******************************************************************************/
211 /* long lseek (int fno, long offset, int end); */
212 /* Seek to a new position within the file connected to the file number fno */
213 /* (returned by open() or creat()). If end is 0, seek to offset bytes from */
214 /* the beginning of the file. If end is 1, seek to offset bytes from the */
215 /* current position in the file. If end is 2 seek to offset bytes from */
216 /* the end of the file. lseek does no I/O. The next I/O operation to */
217 /* file number fno will begin at the new position in the file. */
218 /* */
219 /* Return the offset from the beginning of the file after the seek takes */
220 /* place. If an error occurs return -1 and set errno appropriately. */
221 /* If an error occurs the file position is not changed. */
222 /******************************************************************************/
223 #pragma weak lseek=__ghs_hostio_lseek
__ghs_hostio_lseek(int fno,off_t offset,int end)224 off_t __ghs_hostio_lseek (int fno, off_t offset, int end)
225 {
226 #pragma ghs nowarning 1547 /* Syscall prototype problems */
227 return __ghs_syscall(SYSCALL_LSEEK, fno, (long)offset, end);
228 #pragma ghs endnowarning 1547
229 }
230
231 /******************************************************************************/
232 /* int unlink (const char *name); */
233 /* */
234 /* name is the name of a file. The named file is deleted. */
235 /* Return 0 if the named file is deleted. Return -1 if there is no such */
236 /* file or if the file cannot be deleted, and set errno appropriately. */
237 /******************************************************************************/
238 #pragma weak unlink=__ghs_hostio_unlink
__ghs_hostio_unlink(const char * name)239 int __ghs_hostio_unlink (const char *name)
240 {
241 #pragma ghs nowarning 1547 /* Syscall prototype problems */
242 return __ghs_syscall(SYSCALL_UNLINK, name);
243 #pragma ghs endnowarning 1547
244 }
245
246 /******************************************************************************/
247 /* int fcntl (int fno, int cmd, int arg); */
248 /* When running under a Green Hills debugger, calls the host fcntl() function */
249 /* with the specified arguments. NO VALIDATION OR TRANSLATION IS PERFORMED. */
250 /* This call was added for use by C++ libraries only and should be avoided */
251 /* because the argument values may vary from host to host. */
252 /* */
253 /* Return the value which was returned by the host fcntl() call. */
254 /* If an error occurs return -1 and set errno appropriately. */
255 /******************************************************************************/
256 #pragma weak fcntl=__ghs_hostio_fcntl
__ghs_hostio_fcntl(int fno,int cmd,int arg)257 int __ghs_hostio_fcntl (int fno, int cmd, int arg)
258 {
259 #pragma ghs nowarning 1547 /* Syscall prototype problems */
260 return __ghs_syscall(SYSCALL_FCNTL, fno, cmd, arg);
261 #pragma ghs endnowarning 1547
262 }
263 #endif /* EMBEDDED */
264