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

Last change on this file since 321 was 295, checked in by alain, 11 years ago

Introducing a major release, to suppoort the tsar_generic_leti platform
and the various (external or internal) peripherals configurations.
The map.xml format has been modified, in order to support the new
vci_iopic componentand a new policy for peripherals initialisation.
The IRQs are nom described in the XICU and IOPIC components
(and not anymore in the processors).
To enforce this major change, the map.xml file signature changed:
The signature value must be: 0xDACE2014

This new release has been tested on the tsar_generic_leti platform
for the following mappings:

  • 4c_4p_sort_leti
  • 4c_4p_sort_leti_ext
  • 4c_4p_transpose_leti
  • 4c_4p_transpose_leti_ext
  • 4c_1p_four_leti_ext
  • Property svn:executable set to *
File size: 23.7 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;
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.