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