]> rtime.felk.cvut.cz Git - arc.git/blob - common/newlib_port.c
Fee, changed type on for flag used to force garbage collection. Aborting job if memif...
[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 <stddef.h>\r
25 #include "Std_Types.h"\r
26 #include "Ramlog.h"\r
27 \r
28 #if defined(CFG_ARM_CM3)\r
29 #include "irq_types.h"\r
30 #include "stm32f10x.h"\r
31 #endif\r
32 \r
33 #ifdef USE_TTY_TCF_STREAMS\r
34 #include "streams.h"\r
35 #endif\r
36 \r
37 \r
38 #if defined(CFG_ARM)\r
39 #define open    _open\r
40 #define exit    _exit\r
41 #define fstat   _fstat\r
42 #define getpid  _getpid\r
43 #define kill    _kill\r
44 #define close   _close\r
45 #define isatty  _isatty\r
46 #define sbrk    _sbrk\r
47 #define read    _read\r
48 #define write   _write\r
49 #define lseek   _lseek\r
50 #endif\r
51 \r
52 // Operation on Winidea terminal buffer\r
53 \r
54 \r
55 #define TWBUFF_SIZE 0x100\r
56 #define TRBUFF_SIZE 0x100\r
57 \r
58 \r
59 #define TBUFF_PTR 2\r
60 \r
61 #define TWBUFF_LEN (TWBUFF_SIZE+TBUFF_PTR)\r
62 #define TRBUFF_LEN (TRBUFF_SIZE+TBUFF_PTR)\r
63 #define TWBUFF_TPTR (g_TWBuffer[TWBUFF_SIZE+0])\r
64 #define TWBUFF_CPTR (g_TWBuffer[TWBUFF_SIZE+1])\r
65 #define TWBUFF_INC(n) ((n + 1)&(TWBUFF_SIZE-1))\r
66 #define TWBUFF_FULL() (TWBUFF_TPTR==((TWBUFF_CPTR-1)&(TWBUFF_SIZE-1)))\r
67 \r
68 #ifdef USE_TTY_WINIDEA\r
69 \r
70 #if defined(MC912DG128A)\r
71 static volatile unsigned char g_TWBuffer[TWBUFF_LEN];\r
72 static volatile unsigned char g_TRBuffer[TRBUFF_LEN];\r
73 volatile char g_TConn __attribute__ ((section (".winidea_port")));\r
74 \r
75 #else\r
76 static volatile unsigned char g_TWBuffer[TWBUFF_LEN] __attribute__ ((aligned (0x100))); // Transmit to WinIDEA terminal\r
77 static volatile unsigned char g_TRBuffer[TRBUFF_LEN] __attribute__ ((aligned (0x100)));\r
78 volatile char g_TConn __attribute__ ((section (".winidea_port")));\r
79 \r
80 #endif\r
81 \r
82 #endif\r
83 \r
84 #ifdef USE_TTY_CODE_COMPOSER\r
85 \r
86 #define _DTOPEN    (0xF0)\r
87 #define _DTCLOSE   (0xF1)\r
88 #define _DTREAD    (0xF2)\r
89 #define _DTWRITE   (0xF3)\r
90 #define _DTLSEEK   (0xF4)\r
91 #define _DTUNLINK  (0xF5)\r
92 #define _DTGETENV  (0xF6)\r
93 #define _DTRENAME  (0xF7)\r
94 #define _DTGETTIME (0xF8)\r
95 #define _DTGETCLK  (0xF9)\r
96 #define _DTSYNC    (0xFF)\r
97 \r
98 #define LOADSHORT(x,y,z)  { x[(z)]   = (unsigned short) (y); \\r
99                             x[(z)+1] = (unsigned short) (y) >> 8;  }\r
100 \r
101 #define UNLOADSHORT(x,z) ((short) ( (short) x[(z)] +             \\r
102                                    ((short) x[(z)+1] << 8)))\r
103 \r
104 #define PACKCHAR(val, base, byte) ( (base)[(byte)] = (val) )\r
105 \r
106 #define UNPACKCHAR(base, byte)    ( (base)[byte] )\r
107 \r
108 \r
109 static unsigned char parmbuf[8];\r
110 #define BUFSIZ 512\r
111 #define CC_BUFFER_SIZE ((BUFSIZ)+32)\r
112 volatile unsigned int _CIOBUF_[CC_BUFFER_SIZE] __attribute__ ((section (".cio")));\r
113 \r
114 /***************************************************************************/\r
115 /*                                                                         */\r
116 /*  WRITEMSG()  -  Sends the passed data and parameters on to the host.    */\r
117 /*                                                                         */\r
118 /***************************************************************************/\r
119 void writemsg(unsigned char  command,\r
120               register const unsigned char *parm,\r
121               register const          char *data,\r
122               unsigned int            length)\r
123 {\r
124    volatile unsigned char *p = (volatile unsigned char *)(_CIOBUF_+1);\r
125    unsigned int i;\r
126 \r
127    /***********************************************************************/\r
128    /* THE LENGTH IS WRITTEN AS A TARGET INT                               */\r
129    /***********************************************************************/\r
130    _CIOBUF_[0] = length;\r
131 \r
132    /***********************************************************************/\r
133    /* THE COMMAND IS WRITTEN AS A TARGET BYTE                             */\r
134    /***********************************************************************/\r
135    *p++ = command;\r
136 \r
137    /***********************************************************************/\r
138    /* PACK THE PARAMETERS AND DATA SO THE HOST READS IT AS BYTE STREAM    */\r
139    /***********************************************************************/\r
140    for (i = 0; i < 8; i++)      PACKCHAR(*parm++, p, i);\r
141    for (i = 0; i < length; i++) PACKCHAR(*data++, p, i+8);\r
142 \r
143    /***********************************************************************/\r
144    /* THE BREAKPOINT THAT SIGNALS THE HOST TO DO DATA TRANSFER            */\r
145    /***********************************************************************/\r
146    __asm("       .global C$$IO$$");\r
147    __asm("C$$IO$$: nop");\r
148 }\r
149 \r
150 /***************************************************************************/\r
151 /*                                                                         */\r
152 /*  READMSG()   -  Reads the data and parameters passed from the host.     */\r
153 /*                                                                         */\r
154 /***************************************************************************/\r
155 void readmsg(register unsigned char *parm,\r
156              register char          *data)\r
157 {\r
158    volatile unsigned char *p = (volatile unsigned char *)(_CIOBUF_+1);\r
159    unsigned int   i;\r
160    unsigned int   length;\r
161 \r
162    /***********************************************************************/\r
163    /* THE LENGTH IS READ AS A TARGET INT                                  */\r
164    /***********************************************************************/\r
165    length = _CIOBUF_[0];\r
166 \r
167    /***********************************************************************/\r
168    /* UNPACK THE PARAMETERS AND DATA                                      */\r
169    /***********************************************************************/\r
170    for (i = 0; i < 8; i++) *parm++ = UNPACKCHAR(p, i);\r
171    if (data != NULL)\r
172       for (i = 0; i < length; i++) *data++ = UNPACKCHAR(p, i+8);\r
173 }\r
174 \r
175 /****************************************************************************/\r
176 /* HOSTWRITE()  -  Pass the write command and its arguments to the host.    */\r
177 /****************************************************************************/\r
178 int HOSTwrite(int dev_fd, const char *buf, unsigned count)\r
179 {\r
180    int result;\r
181 \r
182    if (count > BUFSIZ) count = BUFSIZ;\r
183 \r
184    LOADSHORT(parmbuf,dev_fd,0);\r
185    LOADSHORT(parmbuf,count,2);\r
186    writemsg(_DTWRITE,parmbuf,(char *)buf,count);\r
187    readmsg(parmbuf,NULL);\r
188 \r
189    result = UNLOADSHORT(parmbuf,0);\r
190 \r
191    return result;\r
192 }\r
193 \r
194 #endif\r
195 \r
196 #ifdef USE_TTY_TMS570_KEIL\r
197 #include "GLCD.h"\r
198 #endif\r
199 \r
200 #define FILE_RAMLOG             3\r
201 \r
202 /* Location MUST match NoICE configuration */\r
203 #ifdef USE_TTY_NOICE\r
204 static volatile char VUART_TX __attribute__ ((section (".noice_port")));\r
205 static volatile char VUART_RX __attribute__ ((section (".noice_port")));\r
206 volatile unsigned char START_VUART = 0;\r
207 #endif\r
208 \r
209 /*\r
210  * T32 stuff\r
211  */\r
212 \r
213 // This must be in un-cached space....\r
214 #ifdef USE_TTY_T32\r
215 static volatile char t32_outport __attribute__ ((section (".t32_outport")));\r
216 \r
217 void t32_writebyte(char c)\r
218 {\r
219         /* T32 can hang here for several reasons;\r
220          * - term.view e:address.offset(v.address(t32_outport)) e:0\r
221          */\r
222 \r
223         while (t32_outport != 0 ) ; /* wait until port is free */\r
224         t32_outport = c; /* send character */\r
225 }\r
226 #endif\r
227 /*\r
228  * clib support\r
229  */\r
230 \r
231 /* Do nothing */\r
232 int close( int fd ) {\r
233         (void)fd;\r
234         return (-1);\r
235 }\r
236 \r
237 char *__env[1] = { 0 };\r
238 char **environ = __env;\r
239 \r
240 \r
241 #include <errno.h>\r
242 #undef errno\r
243 extern int errno;\r
244 \r
245 \r
246 int execve(const char *path, char * const argv[], char * const envp[] ) {\r
247 //int execve(char *name, char **argv, char **env){\r
248         (void)path;\r
249         (void)argv;\r
250         (void)envp;\r
251         errno=ENOMEM;\r
252         return -1;\r
253 }\r
254 \r
255 pid_t fork() {\r
256   errno=EAGAIN;\r
257   return -1;\r
258 }\r
259 \r
260 #include <sys/stat.h>\r
261 int fstat(int file, struct stat *st) {\r
262         (void)file;\r
263         st->st_mode = S_IFCHR;\r
264         return 0;\r
265 }\r
266 \r
267 /* Returns 1 if connected to a terminal. T32 can be a terminal\r
268  */\r
269 \r
270 int isatty( int fd )\r
271 {\r
272         (void)fd;\r
273         return 1;\r
274 }\r
275 \r
276 /*\r
277 int fstat( int fd,  struct stat *buf )\r
278 {\r
279   buf->st_mode = S_IFCHR;\r
280   buf->st_blksize = 0;\r
281 \r
282   return (0);\r
283 }\r
284 */\r
285 \r
286 /* reposition read/write file offset\r
287  * We can't seek, return error.*/\r
288 off_t lseek( int fd, off_t offset,int whence)\r
289 {\r
290         (void)fd;\r
291         (void)offset;\r
292         (void)whence;\r
293 \r
294         errno = ESPIPE;\r
295         return ((off_t)-1);\r
296 }\r
297 \r
298 int open(const char *name, int flags, int mode){\r
299         (void)name;\r
300         (void)flags;\r
301         (void)mode;\r
302 \r
303 #if defined(USE_RAMLOG)\r
304         if( strcmp(name,"ramlog") == 0 ) {\r
305                 return FILE_RAMLOG;\r
306         }\r
307 #endif\r
308 \r
309     return -1;\r
310 }\r
311 \r
312 int read( int fd, void *buf, size_t nbytes )\r
313 {\r
314         (void)fd;\r
315         (void)buf;\r
316         (void)nbytes;\r
317 #ifdef USE_TTY_WINIDEA\r
318         (void)g_TRBuffer[0];\r
319 #endif\r
320 \r
321 #ifdef USE_TTY_NOICE\r
322         // Not tested at all\r
323     int retval;\r
324     while (VUART_RX != 0)\r
325     {\r
326     }\r
327 \r
328     retval = VUART_RX;\r
329     VUART_RX = 0;\r
330 #endif\r
331 \r
332         /* Only support write for now, return 0 read */\r
333         return 0;\r
334 }\r
335 \r
336 \r
337 int write(  int fd, const void *_buf, size_t nbytes)\r
338 {\r
339         //(void)fd;  // Normally 0- ?, 1-stdout, 2-stderr,\r
340                                 // Added 3-ramlog,\r
341 \r
342 \r
343         if( fd <= STDERR_FILENO ) {\r
344 #ifdef USE_TTY_NOICE\r
345         char *buf1 = (char *)_buf;\r
346         if (START_VUART)\r
347         {\r
348            for (int i = 0; i < nbytes; i++) {\r
349                    char c = buf1[i];\r
350                    if (c == '\n')\r
351                    {\r
352                            while (VUART_TX != 0)\r
353                            {\r
354                            }\r
355 \r
356                            VUART_TX = '\r';\r
357                    }\r
358 \r
359                    while (VUART_TX != 0)\r
360                    {\r
361                    }\r
362 \r
363                    VUART_TX = c;\r
364            }\r
365         }\r
366 #endif\r
367 \r
368 #ifdef USE_TTY_WINIDEA\r
369                 if (g_TConn)\r
370                 {\r
371           char *buf = (char *)_buf;\r
372                   unsigned char nCnt,nLen;\r
373                   for(nCnt=0; nCnt<nbytes; nCnt++)\r
374                         {\r
375                         while(TWBUFF_FULL()) ;\r
376                         nLen=TWBUFF_TPTR;\r
377                         g_TWBuffer[nLen]=buf[nCnt];\r
378                         nLen=TWBUFF_INC(nLen);\r
379                         TWBUFF_TPTR=nLen;\r
380                         }\r
381                 }\r
382 #endif\r
383 \r
384 #ifdef USE_TTY_T32\r
385                 char *buf = (char *)_buf;\r
386                 for (int i = 0; i < nbytes; i++) {\r
387                         if (*(buf + i) == '\n') {\r
388                                 t32_writebyte ('\r');\r
389 //                      t32_writebyte ('\n');\r
390                         }\r
391                         t32_writebyte (*(buf + i));\r
392                 }\r
393 #endif\r
394 \r
395 #ifdef USE_TTY_ARM_ITM\r
396                 char *buf = (char *)_buf;\r
397                 for (int i = 0; i < nbytes; i++) {\r
398                         ITM_SendChar(*(buf + i));\r
399                 }\r
400 #endif\r
401 \r
402 #ifdef USE_TTY_TCF_STREAMS\r
403                 char *buf = (char *)_buf;\r
404                 for (int i = 0; i < nbytes; i++) {\r
405                         TCF_TTY_SendChar(*(buf + i));\r
406                 }\r
407 #endif\r
408 \r
409 #ifdef USE_TTY_CODE_COMPOSER\r
410         HOSTwrite(fd, _buf, nbytes);\r
411 #endif\r
412 \r
413 #ifdef USE_TTY_TMS570_KEIL\r
414         for (int i = 0; i < nbytes; i++) {\r
415                 GLCD_PrintChar((char *)(_buf + i));\r
416         }\r
417 #endif\r
418 \r
419 #if defined(USE_RAMLOG)\r
420                 {\r
421                         char *buf = (char *)_buf;\r
422                         for (int i = 0; i < nbytes; i++) {\r
423                                 ramlog_chr (*(buf + i));\r
424                         }\r
425                 }\r
426 #endif\r
427 \r
428         }\r
429         else\r
430         {\r
431 #if defined(USE_RAMLOG)\r
432                 /* RAMLOG support */\r
433                 if(fd == FILE_RAMLOG) {\r
434                         char *buf = (char *)_buf;\r
435                         for (int i = 0; i < nbytes; i++) {\r
436                                 ramlog_chr (*(buf + i));\r
437                         }\r
438                 }\r
439 #endif\r
440         }\r
441 \r
442         return (nbytes);\r
443 }\r
444 \r
445 int arc_putchar(int fd, int c) {\r
446         char cc = c;\r
447         write( fd,&cc,1);\r
448 \r
449         return 0;\r
450 }\r
451 \r
452 /* If we use malloc and it runs out of memory it calls sbrk()\r
453  */\r
454 \r
455 #if defined(CFG_PPC)\r
456 \r
457 /* linker symbols */\r
458 extern char _heap_start[];  // incomplete array to ensure not placed in small-data\r
459 extern char _heap_end[];\r
460 \r
461 void * sbrk( ptrdiff_t incr )\r
462 {\r
463     char *prevEnd;\r
464     static char *nextAvailMemPtr = _heap_start;\r
465 \r
466     if( nextAvailMemPtr + incr >  _heap_end) {\r
467                 write( 2, "Heap overflow!\n", 15 );\r
468                 abort();\r
469         }\r
470     prevEnd = nextAvailMemPtr;\r
471     nextAvailMemPtr += incr;\r
472     return prevEnd;\r
473 }\r
474 #else\r
475 extern char _end[];\r
476 \r
477 //static char *curbrk = _end;\r
478 \r
479 #ifndef HEAPSIZE\r
480 #define HEAPSIZE 16000\r
481 #endif\r
482 \r
483 /*\r
484  * The heap sadly have alignment that depends on the pagesize that\r
485  * you compile malloc newlib with. From what I can tell from the\r
486  * code that is a pagesize of 4096.\r
487  */\r
488 \r
489 unsigned char _heap[HEAPSIZE] __attribute__((aligned (4)));\r
490 //__attribute__((section(".heap")));\r
491 \r
492 void * sbrk( ptrdiff_t incr )\r
493 {\r
494     static unsigned char *heap_end;\r
495     unsigned char *prev_heap_end;\r
496 \r
497 /* initialize */\r
498     if( heap_end == 0 ){\r
499         heap_end = _heap;\r
500     }\r
501     prev_heap_end = heap_end;\r
502 \r
503         if( heap_end + incr - _heap > HEAPSIZE ) {\r
504         /* heap overflow - announce on stderr */\r
505                 write( 2, "Heap overflow!\n", 15 );\r
506                 abort();\r
507         }\r
508 \r
509    heap_end += incr;\r
510 \r
511    return (caddr_t) prev_heap_end;\r
512 }\r
513 #endif\r
514 \r
515 int stat( const char *file, struct stat *st ) {\r
516 //int stat(char *file, struct stat *st) {\r
517         (void)file;\r
518         st->st_mode = S_IFCHR;\r
519         return 0;\r
520 }\r
521 \r
522 \r
523 pid_t getpid() {\r
524   return 1;\r
525 }\r
526 \r
527 #include <errno.h>\r
528 #undef errno\r
529 extern int errno;\r
530 int kill(int pid, int sig){\r
531         (void)pid;\r
532         (void)sig;\r
533         errno=EINVAL;\r
534         return(-1);\r
535 }\r
536 \r
537 \r
538 /* Should not really be here, but .. */\r
539 \r
540 void _fini( void )\r
541 {\r
542 \r
543 }\r
544 \r
545 \r
546 #if defined(__GNUC__)\r
547 void __init( void )\r
548 {\r
549 }\r
550 #endif\r
551 \r
552 #if defined(CFG_ARM)\r
553 void _exit( int status ) {\r
554 #ifdef USE_TTY_CODE_COMPOSER\r
555         __asm("        .global C$$EXIT");\r
556         __asm("C$$EXIT: nop");\r
557 #endif\r
558         while(1) ;\r
559 }\r
560 #endif\r
561 \r