]> rtime.felk.cvut.cz Git - arc.git/blob - common/newlib_port.c
Merge with 422b4aa0953939f40e73df879f3cbcbf8959a73b
[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 #ifdef USE_TTY_TCF_STREAMS\r
33 #include "streams.h"\r
34 #endif\r
35 \r
36 \r
37 #if defined(CFG_ARM)\r
38 #define open    _open\r
39 #define exit    _exit\r
40 #define fstat   _fstat\r
41 #define getpid  _getpid\r
42 #define kill    _kill\r
43 #define close   _close\r
44 #define isatty  _isatty\r
45 #define sbrk    _sbrk\r
46 #define read    _read\r
47 #define write   _write\r
48 #define lseek   _lseek\r
49 #endif\r
50 \r
51 // Operation on Winidea terminal buffer\r
52 \r
53 \r
54 #define TWBUFF_SIZE 0x100\r
55 #define TRBUFF_SIZE 0x100\r
56 \r
57 \r
58 #define TBUFF_PTR 2\r
59 \r
60 #define TWBUFF_LEN (TWBUFF_SIZE+TBUFF_PTR)\r
61 #define TRBUFF_LEN (TRBUFF_SIZE+TBUFF_PTR)\r
62 #define TWBUFF_TPTR (g_TWBuffer[TWBUFF_SIZE+0])\r
63 #define TWBUFF_CPTR (g_TWBuffer[TWBUFF_SIZE+1])\r
64 #define TWBUFF_INC(n) ((n + 1)&(TWBUFF_SIZE-1))\r
65 #define TWBUFF_FULL() (TWBUFF_TPTR==((TWBUFF_CPTR-1)&(TWBUFF_SIZE-1)))\r
66 \r
67 #ifdef USE_TTY_WINIDEA\r
68 \r
69 #if defined(MC912DG128A)\r
70 static volatile unsigned char g_TWBuffer[TWBUFF_LEN];\r
71 static volatile unsigned char g_TRBuffer[TRBUFF_LEN];\r
72 static volatile char g_TConn __attribute__ ((section (".winidea_port")));\r
73 \r
74 #else\r
75 static volatile unsigned char g_TWBuffer[TWBUFF_LEN] __attribute__ ((aligned (0x100))); // Transmit to WinIDEA terminal\r
76 static volatile unsigned char g_TRBuffer[TRBUFF_LEN] __attribute__ ((aligned (0x100)));\r
77 static volatile char g_TConn __attribute__ ((section (".winidea_port")));\r
78 \r
79 #endif\r
80 \r
81 #endif\r
82 \r
83 #define FILE_RAMLOG             3\r
84 \r
85 /* Location MUST match NoICE configuration */\r
86 #ifdef USE_TTY_NOICE\r
87 static volatile char VUART_TX __attribute__ ((section (".noice_port")));\r
88 static volatile char VUART_RX __attribute__ ((section (".noice_port")));\r
89 volatile unsigned char START_VUART = 0;\r
90 #endif\r
91 \r
92 /*\r
93  * T32 stuff\r
94  */\r
95 \r
96 // This must be in un-cached space....\r
97 #ifdef USE_TTY_T32\r
98 static volatile char t32_outport __attribute__ ((section (".t32_outport")));\r
99 \r
100 void t32_writebyte(char c)\r
101 {\r
102         /* T32 can hang here for several reasons;\r
103          * - term.view e:address.offset(v.address(t32_outport)) e:0\r
104          */\r
105 \r
106         while (t32_outport != 0 ) ; /* wait until port is free */\r
107         t32_outport = c; /* send character */\r
108 }\r
109 #endif\r
110 /*\r
111  * clib support\r
112  */\r
113 \r
114 /* Do nothing */\r
115 int close( int fd ) {\r
116         (void)fd;\r
117         return (-1);\r
118 }\r
119 \r
120 char *__env[1] = { 0 };\r
121 char **environ = __env;\r
122 \r
123 \r
124 #include <errno.h>\r
125 #undef errno\r
126 extern int errno;\r
127 \r
128 \r
129 int execve(const char *path, char * const argv[], char * const envp[] ) {\r
130 //int execve(char *name, char **argv, char **env){\r
131         (void)path;\r
132         (void)argv;\r
133         (void)envp;\r
134         errno=ENOMEM;\r
135         return -1;\r
136 }\r
137 \r
138 int fork() {\r
139   errno=EAGAIN;\r
140   return -1;\r
141 }\r
142 \r
143 #include <sys/stat.h>\r
144 int fstat(int file, struct stat *st) {\r
145         (void)file;\r
146         st->st_mode = S_IFCHR;\r
147         return 0;\r
148 }\r
149 \r
150 /* Returns 1 if connected to a terminal. T32 can be a terminal\r
151  */\r
152 \r
153 int isatty( int fd )\r
154 {\r
155         (void)fd;\r
156         return 1;\r
157 }\r
158 \r
159 /*\r
160 int fstat( int fd,  struct stat *buf )\r
161 {\r
162   buf->st_mode = S_IFCHR;\r
163   buf->st_blksize = 0;\r
164 \r
165   return (0);\r
166 }\r
167 */\r
168 \r
169 /* reposition read/write file offset\r
170  * We can't seek, return error.*/\r
171 off_t lseek( int fd, off_t offset,int whence)\r
172 {\r
173         (void)fd;\r
174         (void)offset;\r
175         (void)whence;\r
176 \r
177         errno = ESPIPE;\r
178         return ((off_t)-1);\r
179 }\r
180 \r
181 int open(const char *name, int flags, int mode){\r
182         (void)name;\r
183         (void)flags;\r
184         (void)mode;\r
185 \r
186 #if defined(USE_RAMLOG)\r
187         if( strcmp(name,"ramlog") == 0 ) {\r
188                 return FILE_RAMLOG;\r
189         }\r
190 #endif\r
191 \r
192     return -1;\r
193 }\r
194 \r
195 int read( int fd, void *buf, size_t nbytes )\r
196 {\r
197         (void)fd;\r
198         (void)buf;\r
199         (void)nbytes;\r
200 #ifdef USE_TTY_WINIDEA\r
201         (void)g_TRBuffer[0];\r
202 #endif\r
203 \r
204 #ifdef USE_TTY_NOICE\r
205         // Not tested at all\r
206     int retval;\r
207     while (VUART_RX != 0)\r
208     {\r
209     }\r
210 \r
211     retval = VUART_RX;\r
212     VUART_RX = 0;\r
213 #endif\r
214 \r
215         /* Only support write for now, return 0 read */\r
216         return 0;\r
217 }\r
218 \r
219 \r
220 int write(  int fd, const void *_buf, size_t nbytes)\r
221 {\r
222         //(void)fd;  // Normally 0- ?, 1-stdout, 2-stderr,\r
223                                 // Added 3-ramlog,\r
224 \r
225 \r
226         if( fd <= STDERR_FILENO ) {\r
227 #ifdef USE_TTY_NOICE\r
228         char *buf1 = (char *)_buf;\r
229         if (START_VUART)\r
230         {\r
231            for (int i = 0; i < nbytes; i++) {\r
232                    char c = buf1[i];\r
233                    if (c == '\n')\r
234                    {\r
235                            while (VUART_TX != 0)\r
236                            {\r
237                            }\r
238 \r
239                            VUART_TX = '\r';\r
240                    }\r
241 \r
242                    while (VUART_TX != 0)\r
243                    {\r
244                    }\r
245 \r
246                    VUART_TX = c;\r
247            }\r
248         }\r
249 #endif\r
250 \r
251 #ifdef USE_TTY_WINIDEA\r
252                 if (g_TConn)\r
253                 {\r
254           char *buf = (char *)_buf;\r
255                   unsigned char nCnt,nLen;\r
256                   for(nCnt=0; nCnt<nbytes; nCnt++)\r
257                         {\r
258                         while(TWBUFF_FULL());\r
259                         nLen=TWBUFF_TPTR;\r
260                         g_TWBuffer[nLen]=buf[nCnt];\r
261                         nLen=TWBUFF_INC(nLen);\r
262                         TWBUFF_TPTR=nLen;\r
263                         }\r
264                 }\r
265 #endif\r
266 \r
267 #ifdef USE_TTY_T32\r
268                 char *buf = (char *)_buf;\r
269                 for (int i = 0; i < nbytes; i++) {\r
270                         if (*(buf + i) == '\n') {\r
271                                 t32_writebyte ('\r');\r
272 //                      t32_writebyte ('\n');\r
273                         }\r
274                         t32_writebyte (*(buf + i));\r
275                 }\r
276 #endif\r
277 \r
278 #ifdef USE_TTY_ARM_ITM\r
279                 char *buf = (char *)_buf;\r
280                 for (int i = 0; i < nbytes; i++) {\r
281                         ITM_SendChar(*(buf + i));\r
282                 }\r
283 #endif\r
284 \r
285 #ifdef USE_TTY_TCF_STREAMS\r
286                 char *buf = (char *)_buf;\r
287                 for (int i = 0; i < nbytes; i++) {\r
288                         TCF_TTY_SendChar(*(buf + i));\r
289                 }\r
290 #endif\r
291 \r
292 #if defined(USE_RAMLOG)\r
293                 {\r
294                         char *buf = (char *)_buf;\r
295                         for (int i = 0; i < nbytes; i++) {\r
296                                 ramlog_chr (*(buf + i));\r
297                         }\r
298                 }\r
299 #endif\r
300 \r
301         }\r
302         else\r
303         {\r
304 #if defined(USE_RAMLOG)\r
305                 /* RAMLOG support */\r
306                 if(fd == FILE_RAMLOG) {\r
307                         char *buf = (char *)_buf;\r
308                         for (int i = 0; i < nbytes; i++) {\r
309                                 ramlog_chr (*(buf + i));\r
310                         }\r
311                 }\r
312 #endif\r
313         }\r
314 \r
315         return (nbytes);\r
316 }\r
317 \r
318 int arc_putchar(int fd, int c) {\r
319         char cc = c;\r
320         write( fd,&cc,1);\r
321 \r
322         return 0;\r
323 }\r
324 \r
325 /* If we use malloc and it runs out of memory it calls sbrk()\r
326  */\r
327 #if 1\r
328 \r
329 extern char _end[];\r
330 \r
331 //static char *curbrk = _end;\r
332 \r
333 #ifndef HEAPSIZE\r
334 #define HEAPSIZE 16000\r
335 #endif\r
336 \r
337 /*\r
338  * The heap sadly have alignment that depends on the pagesize that\r
339  * you compile malloc newlib with. From what I can tell from the\r
340  * code that is a pagesize of 4096.\r
341  */\r
342 \r
343 unsigned char _heap[HEAPSIZE] __attribute__((aligned (4)));\r
344 //__attribute__((section(".heap")));\r
345 \r
346 void * sbrk( ptrdiff_t incr )\r
347 {\r
348     static unsigned char *heap_end;\r
349     unsigned char *prev_heap_end;\r
350 \r
351 /* initialize */\r
352     if( heap_end == 0 )\r
353         heap_end = _heap;\r
354 \r
355         prev_heap_end = heap_end;\r
356 \r
357         if( heap_end + incr - _heap > HEAPSIZE ) {\r
358         /* heap overflow - announce on stderr */\r
359                 write( 2, "Heap overflow!\n", 15 );\r
360                 abort();\r
361         }\r
362 \r
363    heap_end += incr;\r
364 \r
365    return (caddr_t) prev_heap_end;\r
366 }\r
367 #else\r
368 void *sbrk(int inc )\r
369 {\r
370         /* We use our own malloc */\r
371         return (void *)(-1);\r
372 }\r
373 #endif\r
374 \r
375 int stat( const char *file, struct stat *st ) {\r
376 //int stat(char *file, struct stat *st) {\r
377         (void)file;\r
378         st->st_mode = S_IFCHR;\r
379         return 0;\r
380 }\r
381 \r
382 \r
383 int getpid() {\r
384   return 1;\r
385 }\r
386 \r
387 #include <errno.h>\r
388 #undef errno\r
389 extern int errno;\r
390 int kill(int pid, int sig){\r
391         (void)pid;\r
392         (void)sig;\r
393         errno=EINVAL;\r
394         return(-1);\r
395 }\r
396 \r
397 \r
398 /* Should not really be here, but .. */\r
399 \r
400 void _fini( void )\r
401 {\r
402 \r
403 }\r
404 \r
405 \r
406 void __init( void )\r
407 {\r
408 \r
409 }\r
410 #if defined(CFG_ARM)\r
411 void _exit( int status ) {\r
412         while(1);\r
413 }\r
414 #endif\r
415 \r