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

Last change on this file since 449 was 438, checked in by alain, 10 years ago

Inroducing support in the stdio for dynamic allocation of peripherals
in the stdio library.

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