source: soft/giet_vm/giet_libs/stdio.c @ 436

Last change on this file since 436 was 431, checked in by alain, 10 years ago

Introducing fixed format (X_WIDTH / Y_WIDTH / P_WIDTH) for processor index.

  • Property svn:executable set to *
File size: 20.4 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
2// File     : stdio.c         
3// Date     : 01/04/2010
4// Author   : alain greiner & Joel Porquet
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include <stdarg.h>
9#include <stdio.h>
10#include <giet_config.h>
11
12////////////////////////////////////////////////////////////////////////////////////
13/////////////////////  MIPS32     related system calls /////////////////////////////
14////////////////////////////////////////////////////////////////////////////////////
15
16/////////////////
17void giet_proc_xyp( unsigned int* cluster_x,
18                    unsigned int* cluster_y,
19                    unsigned int* lpid )
20{
21    sys_call( SYSCALL_PROCID,
22              (unsigned int)cluster_x,
23              (unsigned int)cluster_y,
24              (unsigned int)lpid,
25               0 );
26}
27
28////////////////////
29int giet_proctime() 
30{
31    return sys_call( SYSCALL_PROCTIME, 
32                     0, 0, 0, 0 );
33}
34
35///////////////
36int giet_rand() 
37{
38    unsigned int x = sys_call(SYSCALL_PROCTIME,
39                              0, 0, 0, 0);
40    if ((x & 0xF) > 7) 
41    {
42        return (x*x & 0xFFFF);
43    }
44    else 
45    {
46        return (x*x*x & 0xFFFF);
47    }
48}
49
50////////////////////////////////////////////////////////////////////////////////////
51/////////////////////  TTY device related system calls /////////////////////////////
52////////////////////////////////////////////////////////////////////////////////////
53
54///////////////////////////////////////////////////////////////////////
55static int __printf( char* format, unsigned int channel, va_list* args) 
56{
57    int ret;                    // return value from the syscalls
58
59printf_text:
60
61    while (*format) 
62    {
63        unsigned int i;
64        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
65        if (i) 
66        {
67            ret = sys_call(SYSCALL_TTY_WRITE, 
68                           (unsigned int)format,
69                           i, 
70                           channel,
71                           0);
72
73            if (ret != i) goto return_error;
74
75            format += i;
76        }
77        if (*format == '%') 
78        {
79            format++;
80            goto printf_arguments;
81        }
82    }
83
84    return 0;
85
86printf_arguments:
87
88    {
89        char buf[20];
90        char * pbuf;
91        unsigned int len = 0;
92        static const char HexaTab[] = "0123456789ABCDEF";
93        unsigned int i;
94
95        switch (*format++) 
96        {
97            case ('c'):             /* char conversion */
98            {
99                int val = va_arg( *args, int );
100                len = 1;
101                buf[0] = val;
102                pbuf = &buf[0];
103                break;
104            }
105            case ('d'):             /* 32 bits decimal signed integer */
106            {
107                int val = va_arg( *args, int );
108                if (val < 0) 
109                {
110                    val = -val;
111                    ret = sys_call(SYSCALL_TTY_WRITE, 
112                                   (unsigned int)"-",
113                                   1,
114                                   channel,
115                                   0);
116                    if (ret != 1) goto return_error;
117                }
118                for(i = 0; i < 10; i++) 
119                {
120                    buf[9 - i] = HexaTab[val % 10];
121                    if (!(val /= 10)) break;
122                }
123                len =  i + 1;
124                pbuf = &buf[9 - i];
125                break;
126            }
127            case ('u'):             /* 32 bits decimal unsigned integer */
128            {
129                unsigned int val = va_arg( *args, unsigned int );
130                for(i = 0; i < 10; i++) 
131                {
132                    buf[9 - i] = HexaTab[val % 10];
133                    if (!(val /= 10)) break;
134                }
135                len =  i + 1;
136                pbuf = &buf[9 - i];
137                break;
138            }
139            case ('x'):             /* 32 bits hexadecimal integer */
140            {
141                unsigned int val = va_arg( *args, unsigned int );
142                ret = sys_call(SYSCALL_TTY_WRITE,
143                               (unsigned int)"0x",
144                               2,
145                               channel,
146                               0);
147                if (ret != 2) goto return_error;       
148                for(i = 0; i < 8; i++) 
149                {
150                    buf[7 - i] = HexaTab[val % 16];
151                    if (!(val /= 16))  break;
152                }
153                len =  i + 1;
154                pbuf = &buf[7 - i];
155                break;
156            }
157            case ('l'):            /* 64 bits hexadecimal unsigned */
158            {
159                unsigned long long val = va_arg( *args, unsigned long long );
160                ret = sys_call(SYSCALL_TTY_WRITE,
161                               (unsigned int)"0x",
162                               2,
163                               channel,
164                               0);
165                if (ret != 2) goto return_error;
166                for(i = 0; i < 16; i++) 
167                {
168                    buf[15 - i] = HexaTab[val % 16];
169                    if (!(val /= 16))  break;
170                }
171                len =  i + 1;
172                pbuf = &buf[15 - i];
173                break;
174            }
175            case ('s'):             /* string */
176            {
177                char* str = va_arg( *args, char* );
178                while (str[len]) 
179                {
180                    len++;
181                }
182                pbuf = str;
183                break;
184            }
185            default:
186                goto return_error;
187        }
188
189        ret = sys_call(SYSCALL_TTY_WRITE, 
190                       (unsigned int)pbuf,
191                       len,
192                       channel, 
193                       0);
194        if (ret != len)  goto return_error;
195       
196        goto printf_text;
197    }
198
199return_error:
200    return 1;
201} // end __printf()
202
203
204////////////////////////////////////////
205void giet_tty_printf( char* format, ...) 
206{
207    va_list args;
208
209    va_start( args, format );
210    int ret = __printf(format, 0xFFFFFFFF, &args);
211    va_end( args );
212
213    if (ret)
214    {
215        giet_exit("ERROR in giet_tty_printf()");
216    }
217} // end giet_tty_printf()
218
219////////////////////////////////////////
220void giet_shr_printf( char* format, ...) 
221{
222    va_list args;
223    const int channel = 0;
224    volatile unsigned int sr_save;
225
226    sys_call( SYSCALL_TTY_GET_LOCK,
227              channel,
228              (unsigned int)&sr_save,
229              0, 0 );
230
231    va_start( args, format );
232    int ret = __printf(format, channel, &args);
233    va_end( args );
234
235    sys_call( SYSCALL_TTY_RELEASE_LOCK,
236              channel,
237              (unsigned int)&sr_save,
238              0, 0 );
239
240    if (ret)
241    {
242        giet_exit("error in giet_shr_printf()");
243    }
244} // end giet_shr_printf()
245
246/////////////////////////////////
247void giet_tty_getc( char * byte ) 
248{
249    int ret;
250
251    do
252    {
253        ret = sys_call(SYSCALL_TTY_READ, 
254                      (unsigned int)byte,  // buffer address
255                      1,                   // number of characters
256                      0xFFFFFFFF,          // channel index from task context
257                      0);
258        if ( ret < 0 ) giet_exit("error in giet_tty_getc()");
259    }
260    while (ret != 1); 
261}
262
263/////////////////////////////////////
264void giet_tty_gets( char*        buf, 
265                    unsigned int bufsize ) 
266{
267    int           ret;
268    unsigned char byte;
269    unsigned int  index = 0;
270 
271    while (index < (bufsize - 1)) 
272    {
273        do 
274        { 
275            ret = sys_call(SYSCALL_TTY_READ, 
276                           (unsigned int)(&byte),
277                           1,
278                           0xFFFFFFFF,
279                           0);
280            if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
281        } 
282        while (ret != 1);
283
284        if (byte == 0x0A)  /* LF */
285        {
286            break; 
287        }
288        else if ((byte == 0x7F) && (index > 0))  /* DEL */
289        {
290            index--; 
291        }
292        else 
293        {
294            buf[index] = byte;
295            index++;
296        }
297    }
298    buf[index] = 0;
299}
300
301///////////////////////////////////////
302void giet_tty_getw( unsigned int* val ) 
303{
304    unsigned char buf[32];
305    unsigned int  string_byte   = 0x00000000;    // string containing one single byte
306    unsigned int  string_cancel = 0x00082008;    // string containing BS/SPACE/BS
307    unsigned int  save = 0;
308    unsigned int  dec = 0;
309    unsigned int  done = 0;
310    unsigned int  overflow = 0;
311    unsigned int  length = 0;
312    unsigned int  i;
313    unsigned int  channel = 0xFFFFFFFF;
314    int           ret;      // return value from syscalls
315 
316    // get characters
317    while (done == 0) 
318    {
319        // read one character
320        do 
321        { 
322            ret = sys_call( SYSCALL_TTY_READ,
323                            (unsigned int)(&string_byte),
324                            1,
325                            channel, 
326                            0); 
327            if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
328        } 
329        while (ret != 1);
330
331        // analyse character
332        if ((string_byte > 0x2F) && (string_byte < 0x3A))  /* decimal character */
333        {
334            buf[length] = (unsigned char)string_byte;
335            length++;
336
337            // echo
338            ret = sys_call( SYSCALL_TTY_WRITE, 
339                            (unsigned int)(&string_byte),
340                            1, 
341                            channel, 
342                            0 );
343            if ( ret < 0 ) giet_exit("error in giet_tty_gets()");
344        }
345        else if (string_byte == 0x0A)                     /* LF character */
346        {
347            done = 1;
348        }
349        else if ( (string_byte == 0x7F) ||                /* DEL character */
350                  (string_byte == 0x08) )                 /* BS  character */
351        {
352            if ( length > 0 ) 
353            {
354                length--;    // cancel the character
355
356                ret = sys_call( SYSCALL_TTY_WRITE, 
357                                (unsigned int)(&string_cancel),
358                                3, 
359                                channel, 
360                                0 );
361                if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
362            }
363        }
364
365        // test buffer overflow
366        if ( length >= 32 ) 
367        {
368            overflow = 1;
369            done     = 1;
370        }
371    }  // end while characters
372
373    // string to int conversion with overflow detection
374    if ( overflow == 0 )
375    {
376        for (i = 0; (i < length) && (overflow == 0) ; i++) 
377        {
378            dec = dec * 10 + (buf[i] - 0x30);
379            if (dec < save)  overflow = 1; 
380            save = dec;
381        }
382    } 
383
384    // final evaluation
385    if ( overflow == 0 )
386    {
387        // return value
388        *val = dec;
389    }
390    else
391    {
392        // cancel all echo characters
393        for (i = 0; i < length ; i++) 
394        {
395            ret = sys_call( SYSCALL_TTY_WRITE, 
396                            (unsigned int)(&string_cancel),
397                            3, 
398                            channel, 
399                            0 );
400            if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
401        }
402        // echo character '0'
403        string_byte = 0x30;
404        ret = sys_call( SYSCALL_TTY_WRITE, 
405                        (unsigned int)(&string_byte),
406                        1, 
407                        channel, 
408                        0 );
409        if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
410
411        // return 0 value
412        *val = 0;
413    }
414}
415
416
417//////////////////////////////////////////////////////////////////////////////////
418/////////////////////  TIMER related system calls ////////////////////////////////
419//////////////////////////////////////////////////////////////////////////////////
420
421///////////////////////
422void giet_timer_start() 
423{
424    if ( sys_call( SYSCALL_TIMER_START, 0, 0, 0, 0 ) ) 
425       giet_exit("error in giet_timer_start()");
426}
427
428//////////////////////
429void giet_timer_stop() 
430{
431    if ( sys_call( SYSCALL_TIMER_STOP, 0, 0, 0, 0 ) ) 
432        giet_exit("error in giet_timer_stop()");
433}
434
435
436//////////////////////////////////////////////////////////////////////////////////
437///////////////  Frame buffer device related system calls  ///////////////////////
438//////////////////////////////////////////////////////////////////////////////////
439
440////////////////////////////////////////////
441void giet_fb_sync_write( unsigned int offset, 
442                        void *       buffer, 
443                        unsigned int length ) 
444{
445    if ( sys_call( SYSCALL_FB_SYNC_WRITE, 
446                   offset, 
447                   (unsigned int)buffer, 
448                   length, 
449                   0 ) )  giet_exit("error in giet_fb_sync_write()");
450}
451
452///////////////////////////////////////////
453void giet_fb_sync_read( unsigned int offset, 
454                        void *       buffer, 
455                        unsigned int length ) 
456{
457    if ( sys_call( SYSCALL_FB_SYNC_READ, 
458                   offset, 
459                   (unsigned int)buffer, 
460                   length, 
461                   0 ) )   giet_exit("error in giet_fb_sync_read()");
462}
463
464/////////////////////////////////////////
465void giet_fb_cma_init( void *       buf0,
466                       void *       buf1,
467                       unsigned int length )
468{
469    if ( sys_call( SYSCALL_FB_CMA_INIT, 
470                   (unsigned int)buf0, 
471                   (unsigned int)buf1, 
472                   length, 
473                   0 ) )   giet_exit("error in giet_fb_cma_init()");
474}
475
476///////////////////////////////////////////////
477void giet_fb_cma_write( unsigned int buffer_id )
478{
479    if ( sys_call( SYSCALL_FB_CMA_WRITE, 
480                   buffer_id, 
481                   0, 0, 0 ) )   giet_exit("error in giet_fb_cma_write()");
482}
483
484////////////////////////
485void giet_fb_cma_stop()
486{
487    if ( sys_call( SYSCALL_FB_CMA_STOP, 
488                   0, 0, 0, 0 ) )    giet_exit("error in giet_fb_cma_stop()");
489}
490
491
492//////////////////////////////////////////////////////////////////////////////////
493/////////////////////// NIC related system calls /////////////////////////////////
494//////////////////////////////////////////////////////////////////////////////////
495
496/////////////////////////
497void giet_nic_cma_start()
498{
499    if ( sys_call( SYSCALL_NIC_CMA_START, 0, 0, 0, 0 ) ) 
500       giet_exit("error in giet_nic_cma_start()");
501}
502
503/////////////////////////
504void giet_nic_cma_stop()
505{
506    if ( sys_call( SYSCALL_NIC_CMA_STOP, 0, 0, 0, 0 ) ) 
507        giet_exit("error in giet_nic_cma_stop()");
508}
509
510///////////////////////////////////////////////////////////////////////////////////
511///////////////////// FAT related system calls ////////////////////////////////////
512///////////////////////////////////////////////////////////////////////////////////
513
514///////////////////////////////////////////
515int giet_fat_open( const char*   pathname, 
516                   unsigned int  flags )
517{
518    return sys_call( SYSCALL_FAT_OPEN, 
519                     (unsigned int)pathname, 
520                     flags,
521                     0, 0 );
522}
523
524////////////////////////////////////
525void giet_fat_read( unsigned int fd,     
526                    void*        buffer, 
527                    unsigned int count, 
528                    unsigned int offset ) 
529{
530    if ( sys_call( SYSCALL_FAT_READ,
531                   fd, 
532                   (unsigned int)buffer,
533                   count, 
534                   offset ) != count ) giet_exit("ERROR in giet_fat_read()");
535}
536
537/////////////////////////////////////
538void giet_fat_write( unsigned int fd,
539                     void*        buffer, 
540                     unsigned int count,
541                     unsigned int offset )
542{
543    if ( sys_call( SYSCALL_FAT_WRITE, 
544                   fd, 
545                   (unsigned int)buffer,
546                   count, 
547                   offset ) != count ) giet_exit("ERROR in giet_fat_write()");
548}
549
550/* variant implementing the UNIX spec
551///////////////////////////////////////////////////////////////////////////////////
552// This system call writes to a file identified by the "fd" file descriptor.
553// - "buffer" is the source buffer virtual address (must be word aligned).
554// - "count" is a number of bytes (must be multiple of 4).
555// It uses the implicit "lseek" pointer in file descriptor.
556///////////////////////////////////////////////////////////////////////////////////
557void giet_fat_write( unsigned int fd,
558                    void*        buffer,
559                    unsigned int count )  // number of bytes
560{
561    return sys_call( SYSCALL_FAT_WRITE,
562                     fd,
563                     (unsigned int)buffer,
564                     count, 0 );
565}
566*/
567
568/////////////////////////////////////
569void giet_fat_lseek( unsigned int fd, 
570                    unsigned int offset, 
571                    unsigned int whence )
572{
573    if ( sys_call( SYSCALL_FAT_LSEEK, 
574                   fd, 
575                   offset, 
576                   whence, 
577                   0 ) ) giet_exit("ERROR in giet_fat_lseek()");
578}
579
580//////////////////////////////////////
581void giet_fat_fstat( unsigned int fd )
582{
583    if ( sys_call( SYSCALL_FAT_FSTAT,
584                   fd,
585                   0, 0, 0 ) )  giet_exit("ERROR in giet_fat_lseek()");
586}
587
588/////////////////////////////////////
589void giet_fat_close( unsigned int fd )
590{
591    if ( sys_call( SYSCALL_FAT_CLOSE,
592                   fd,
593                   0, 0, 0 ) )  giet_exit("ERROR in giet_fat_close()");
594}
595
596
597//////////////////////////////////////////////////////////////////////////////////
598///////////////////// Task context  system calls /////////////////////////////////
599//////////////////////////////////////////////////////////////////////////////////
600
601///////////////////////
602int giet_proc_task_id() 
603{
604    return sys_call( SYSCALL_LOCAL_TASK_ID, 
605                     0, 0, 0, 0 );
606}
607
608/////////////////////////
609int giet_global_task_id() 
610{
611    return sys_call( SYSCALL_GLOBAL_TASK_ID, 
612                     0, 0, 0, 0 );
613}
614
615////////////////////
616int giet_thread_id() 
617{
618    return sys_call( SYSCALL_THREAD_ID, 
619                     0, 0, 0, 0 );
620}
621
622
623//////////////////////////////////////////////////////////////////////////////////
624///////////////////// Miscellaneous system calls /////////////////////////////////
625//////////////////////////////////////////////////////////////////////////////////
626
627//////////////////////////////
628void giet_exit( char* string ) 
629{
630    sys_call( SYSCALL_EXIT,
631              (unsigned int)string,
632              0, 0, 0 );
633}
634
635/////////////////////////////////////////
636void giet_assert( unsigned int condition,
637                  char*        string )
638{
639    if ( condition == 0 ) giet_exit( string );
640}
641
642//////////////////////////
643void giet_context_switch() 
644{
645    sys_call( SYSCALL_CTX_SWITCH,
646              0, 0, 0, 0 );
647}
648
649////////////////////////////////////////////////////
650void giet_vobj_get_vbase( char*         vspace_name, 
651                          char*         vobj_name, 
652                          unsigned int* vobj_vaddr ) 
653{
654    if ( sys_call( SYSCALL_VOBJ_GET_VBASE, 
655                   (unsigned int) vspace_name,
656                   (unsigned int) vobj_name,
657                   (unsigned int) vobj_vaddr,
658                   0 ) )  giet_exit("ERROR in giet_vobj_get_vbase()");
659}
660
661///////////////////////////////////////////////
662void giet_proc_number( unsigned int  cluster_id, 
663                       unsigned int* buffer ) 
664{
665    if ( sys_call( SYSCALL_PROC_NUMBER, 
666                   cluster_id, 
667                   (unsigned int) buffer, 
668                   0, 0) )  giet_exit("ERROR in giet_proc_number()");
669}
670
671/////////////////////////////////////////
672void giet_heap_info( unsigned int* vaddr, 
673                     unsigned int* length,
674                     unsigned int  x,
675                     unsigned int  y ) 
676{
677    if ( sys_call( SYSCALL_HEAP_INFO, 
678                   (unsigned int)vaddr, 
679                   (unsigned int)length, 
680                   x,
681                   y ) )  giet_exit("ERROR in giet_heap_info()");
682}
683
684/////////////////////////////////////////
685void giet_get_xy( void*         ptr,
686                  unsigned int* px,
687                  unsigned int* py )
688{
689    if ( sys_call( SYSCALL_GET_XY,
690                   (unsigned int)ptr,
691                   (unsigned int)px,
692                   (unsigned int)py,
693                   0 ) )  giet_exit("ERROR in giet_get_xy()");
694}
695
696// Local Variables:
697// tab-width: 4
698// c-basic-offset: 4
699// c-file-offsets:((innamespace . 0)(inline-open . 0))
700// indent-tabs-mode: nil
701// End:
702// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
703
Note: See TracBrowser for help on using the repository browser.