]> rtime.felk.cvut.cz Git - arc.git/blob - common/newlib_port.c
Fixes to mahi-1 merge
[arc.git] / common / newlib_port.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 #include <unistd.h>\r
18 #include <sys/stat.h>\r
19 #include <sys/types.h>\r
20 #include <errno.h>\r
21 #include <stdlib.h>\r
22 #include <string.h>\r
23 #include <stdio.h>\r
24 #include "Std_Types.h"\r
25 #include "Ramlog.h"\r
26 \r
27 #if defined(CFG_ARM_CM3)\r
28 #include "irq_types.h"\r
29 #include "core_cm3.h"\r
30 #endif\r
31 \r
32 \r
33 #if defined(CFG_ARM)\r
34 #define open    _open\r
35 #define exit    _exit\r
36 #define fstat   _fstat\r
37 #define getpid  _getpid\r
38 #define kill    _kill\r
39 #define close   _close\r
40 #define isatty  _isatty\r
41 #define sbrk    _sbrk\r
42 #define read    _read\r
43 #define write   _write\r
44 #define lseek   _lseek\r
45 #endif\r
46 \r
47 // Operation on Winidea terminal buffer\r
48 \r
49 \r
50 #define TWBUFF_SIZE 0x100\r
51 #define TRBUFF_SIZE 0x100\r
52 \r
53 \r
54 #define TBUFF_PTR 2\r
55 \r
56 #define TWBUFF_LEN (TWBUFF_SIZE+TBUFF_PTR)\r
57 #define TRBUFF_LEN (TRBUFF_SIZE+TBUFF_PTR)\r
58 #define TWBUFF_TPTR (g_TWBuffer[TWBUFF_SIZE+0])\r
59 #define TWBUFF_CPTR (g_TWBuffer[TWBUFF_SIZE+1])\r
60 #define TWBUFF_INC(n) ((n + 1)&(TWBUFF_SIZE-1))\r
61 #define TWBUFF_FULL() (TWBUFF_TPTR==((TWBUFF_CPTR-1)&(TWBUFF_SIZE-1)))\r
62 \r
63 #ifdef USE_TTY_WINIDEA\r
64 \r
65 #if defined(MC912DG128A)\r
66 static volatile unsigned char g_TWBuffer[TWBUFF_LEN];\r
67 static volatile unsigned char g_TRBuffer[TRBUFF_LEN];\r
68 static volatile char g_TConn __attribute__ ((section (".winidea_port")));\r
69 \r
70 #else\r
71 static volatile unsigned char g_TWBuffer[TWBUFF_LEN] __attribute__ ((aligned (0x100))); // Transmit to WinIDEA terminal\r
72 static volatile unsigned char g_TRBuffer[TRBUFF_LEN] __attribute__ ((aligned (0x100)));\r
73 static volatile char g_TConn __attribute__ ((section (".winidea_port")));\r
74 \r
75 #endif\r
76 \r
77 #endif\r
78 \r
79 #define FILE_RAMLOG             3\r
80 \r
81 /*\r
82  * T32 stuff\r
83  */\r
84 \r
85 // This must be in un-cached space....\r
86 #ifdef USE_TTY_T32\r
87 static volatile char t32_outport __attribute__ ((section (".t32_outport")));\r
88 \r
89 void t32_writebyte(char c)\r
90 {\r
91         /* T32 can hang here for several reasons;\r
92          * - term.view e:address.offset(v.address(t32_outport)) e:0\r
93          */\r
94 \r
95         while (t32_outport != 0 ) ; /* wait until port is free */\r
96         t32_outport = c; /* send character */\r
97 }\r
98 #endif\r
99 /*\r
100  * clib support\r
101  */\r
102 \r
103 /* Do nothing */\r
104 int close( int fd ) {\r
105         (void)fd;\r
106         return (-1);\r
107 }\r
108 \r
109 char *__env[1] = { 0 };\r
110 char **environ = __env;\r
111 \r
112 \r
113 #include <errno.h>\r
114 #undef errno\r
115 extern int errno;\r
116 \r
117 \r
118 int execve(const char *path, char * const argv[], char * const envp[] ) {\r
119 //int execve(char *name, char **argv, char **env){\r
120         (void)path;\r
121         (void)argv;\r
122         (void)envp;\r
123         errno=ENOMEM;\r
124         return -1;\r
125 }\r
126 \r
127 int fork() {\r
128   errno=EAGAIN;\r
129   return -1;\r
130 }\r
131 \r
132 #include <sys/stat.h>\r
133 int fstat(int file, struct stat *st) {\r
134         (void)file;\r
135         st->st_mode = S_IFCHR;\r
136         return 0;\r
137 }\r
138 \r
139 /* Returns 1 if connected to a terminal. T32 can be a terminal\r
140  */\r
141 \r
142 int isatty( int fd )\r
143 {\r
144         (void)fd;\r
145         return 1;\r
146 }\r
147 \r
148 /*\r
149 int fstat( int fd,  struct stat *buf )\r
150 {\r
151   buf->st_mode = S_IFCHR;\r
152   buf->st_blksize = 0;\r
153 \r
154   return (0);\r
155 }\r
156 */\r
157 \r
158 /* reposition read/write file offset\r
159  * We can't seek, return error.*/\r
160 off_t lseek( int fd, off_t offset,int whence)\r
161 {\r
162         (void)fd;\r
163         (void)offset;\r
164         (void)whence;\r
165 \r
166         errno = ESPIPE;\r
167         return ((off_t)-1);\r
168 }\r
169 \r
170 int open(const char *name, int flags, int mode){\r
171         (void)name;\r
172         (void)flags;\r
173         (void)mode;\r
174 \r
175 #if defined(USE_RAMLOG)\r
176         if( strcmp(name,"ramlog") == 0 ) {\r
177                 return FILE_RAMLOG;\r
178         }\r
179 #endif\r
180 \r
181     return -1;\r
182 }\r
183 \r
184 int read( int fd, void *buf, size_t nbytes )\r
185 {\r
186         (void)fd;\r
187         (void)buf;\r
188         (void)nbytes;\r
189 #ifdef USE_TTY_WINIDEA\r
190         (void)g_TRBuffer[0];\r
191 #endif\r
192 \r
193         /* Only support write for now, return 0 read */\r
194         return 0;\r
195 }\r
196 \r
197 \r
198 int write(  int fd, const void *_buf, size_t nbytes)\r
199 {\r
200         //(void)fd;  // Normally 0- ?, 1-stdout, 2-stderr,\r
201                                 // Added 3-ramlog,\r
202 \r
203 \r
204         if( fd <= STDERR_FILENO ) {\r
205 #ifdef USE_TTY_WINIDEA\r
206                 if (g_TConn)\r
207                 {\r
208           char *buf = (char *)_buf;\r
209                   unsigned char nCnt,nLen;\r
210                   for(nCnt=0; nCnt<nbytes; nCnt++)\r
211                         {\r
212                         while(TWBUFF_FULL());\r
213                         nLen=TWBUFF_TPTR;\r
214                         g_TWBuffer[nLen]=buf[nCnt];\r
215                         nLen=TWBUFF_INC(nLen);\r
216                         TWBUFF_TPTR=nLen;\r
217                         }\r
218                 }\r
219 #endif\r
220 \r
221 #ifdef USE_TTY_T32\r
222                 char *buf = (char *)_buf;\r
223                 for (int i = 0; i < nbytes; i++) {\r
224                         if (*(buf + i) == '\n') {\r
225                                 t32_writebyte ('\r');\r
226 //                      t32_writebyte ('\n');\r
227                         }\r
228                         t32_writebyte (*(buf + i));\r
229                 }\r
230 #endif\r
231 \r
232 #ifdef USE_TTY_ARM_ITM\r
233                 char *buf = (char *)_buf;\r
234                 for (int i = 0; i < nbytes; i++) {\r
235                         ITM_SendChar(*(buf + i));\r
236                 }\r
237 #endif\r
238 \r
239 #if defined(USE_RAMLOG)\r
240                 {\r
241                         char *buf = (char *)_buf;\r
242                         for (int i = 0; i < nbytes; i++) {\r
243                                 ramlog_chr (*(buf + i));\r
244                         }\r
245                 }\r
246 #endif\r
247 \r
248         }\r
249         else\r
250         {\r
251 #if defined(USE_RAMLOG)\r
252                 /* RAMLOG support */\r
253                 if(fd == FILE_RAMLOG) {\r
254                         char *buf = (char *)_buf;\r
255                         for (int i = 0; i < nbytes; i++) {\r
256                                 ramlog_chr (*(buf + i));\r
257                         }\r
258                 }\r
259 #endif\r
260         }\r
261 \r
262         return (nbytes);\r
263 }\r
264 \r
265 int arc_putchar(int fd, int c) {\r
266         char cc = c;\r
267         write( fd,&cc,1);\r
268 \r
269         return 0;\r
270 }\r
271 \r
272 /* If we use malloc and it runs out of memory it calls sbrk()\r
273  */\r
274 #if 1\r
275 \r
276 extern char _end[];\r
277 \r
278 //static char *curbrk = _end;\r
279 \r
280 #ifndef HEAPSIZE\r
281 #define HEAPSIZE 16000\r
282 #endif\r
283 \r
284 /*\r
285  * The heap sadly have alignment that depends on the pagesize that\r
286  * you compile malloc newlib with. From what I can tell from the\r
287  * code that is a pagesize of 4096.\r
288  */\r
289 \r
290 unsigned char _heap[HEAPSIZE] __attribute__((aligned (4)));\r
291 //__attribute__((section(".heap")));\r
292 \r
293 void * sbrk( ptrdiff_t incr )\r
294 {\r
295     static unsigned char *heap_end;\r
296     unsigned char *prev_heap_end;\r
297 \r
298 /* initialize */\r
299     if( heap_end == 0 )\r
300         heap_end = _heap;\r
301 \r
302         prev_heap_end = heap_end;\r
303 \r
304         if( heap_end + incr - _heap > HEAPSIZE ) {\r
305         /* heap overflow - announce on stderr */\r
306                 write( 2, "Heap overflow!\n", 15 );\r
307                 abort();\r
308         }\r
309 \r
310    heap_end += incr;\r
311 \r
312    return (caddr_t) prev_heap_end;\r
313 }\r
314 #else\r
315 void *sbrk(int inc )\r
316 {\r
317         /* We use our own malloc */\r
318         return (void *)(-1);\r
319 }\r
320 #endif\r
321 \r
322 int stat( const char *file, struct stat *st ) {\r
323 //int stat(char *file, struct stat *st) {\r
324         (void)file;\r
325         st->st_mode = S_IFCHR;\r
326         return 0;\r
327 }\r
328 \r
329 \r
330 int getpid() {\r
331   return 1;\r
332 }\r
333 \r
334 #include <errno.h>\r
335 #undef errno\r
336 extern int errno;\r
337 int kill(int pid, int sig){\r
338         (void)pid;\r
339         (void)sig;\r
340         errno=EINVAL;\r
341         return(-1);\r
342 }\r
343 \r
344 \r
345 /* Should not really be here, but .. */\r
346 \r
347 void _fini( void )\r
348 {\r
349 \r
350 }\r
351 \r
352 \r
353 void __init( void )\r
354 {\r
355 \r
356 }\r
357 #if defined(CFG_ARM)\r
358 void _exit( int status ) {\r
359         while(1);\r
360 }\r
361 #endif\r
362 \r