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

Last change on this file since 396 was 390, checked in by alain, 10 years ago

1) Introducing the new system call giet_get_xy() in stdio.h,

required for the free() funcyion in malloc.h

2) Fixing bugs in malloc.c

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