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

Last change on this file since 337 was 331, checked in by alain, 11 years ago

Cosmetic.

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