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

Last change on this file since 402 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
RevLine 
[258]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>
[267]10#include <giet_config.h>
[258]11
12////////////////////////////////////////////////////////////////////////////////////
[390]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////////////////////////////////////////////////////////////////////////////////////
[295]46/////////////////////  TTY device related system calls /////////////////////////////
[258]47////////////////////////////////////////////////////////////////////////////////////
[295]48
[352]49///////////////////////////////////////////////////////////////////////
[345]50static int __printf( char* format, unsigned int channel, va_list* args) 
[258]51{
[345]52    int ret;                    // return value from the syscalls
[258]53
[295]54printf_text:
[258]55
[295]56    while (*format) 
[258]57    {
[295]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,
[258]66                           0);
67
[295]68            if (ret != i) goto return_error;
69
70            format += i;
[258]71        }
[295]72        if (*format == '%') 
[258]73        {
[295]74            format++;
75            goto printf_arguments;
[258]76        }
77    }
78
[345]79    return 0;
[295]80
81printf_arguments:
82
[258]83    {
[295]84        char buf[20];
85        char * pbuf;
86        unsigned int len = 0;
87        static const char HexaTab[] = "0123456789ABCDEF";
88        unsigned int i;
[258]89
[295]90        switch (*format++) 
[258]91        {
[295]92            case ('c'):             /* char conversion */
[258]93            {
[345]94                int val = va_arg( *args, int );
[295]95                len = 1;
96                buf[0] = val;
97                pbuf = &buf[0];
98                break;
[258]99            }
[295]100            case ('d'):             /* 32 bits decimal signed integer */
[258]101            {
[345]102                int val = va_arg( *args, int );
[295]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;
[258]121            }
[295]122            case ('u'):             /* 32 bits decimal unsigned integer */
123            {
[345]124                unsigned int val = va_arg( *args, unsigned int );
[295]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            {
[345]136                unsigned int val = va_arg( *args, unsigned int );
[295]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            {
[345]154                unsigned long long val = va_arg( *args, unsigned long long );
[295]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            {
[345]172                char* str = va_arg( *args, char* );
[295]173                while (str[len]) 
174                {
175                    len++;
176                }
177                pbuf = str;
178                break;
179            }
180            default:
181                goto return_error;
[258]182        }
183
[295]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;
[258]192    }
193
[295]194return_error:
[345]195    return 1;
196} // end __printf()
[295]197
[345]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);
[295]206    va_end( args );
[345]207
208    if (ret)
209    {
[382]210        giet_exit("ERROR in giet_tty_printf()");
[345]211    }
[295]212} // end giet_tty_printf()
213
214////////////////////////////////////////
215void giet_shr_printf( char* format, ...) 
[258]216{
[295]217    va_list args;
[345]218    const int channel = 0;
219    volatile unsigned int sr_save;
[258]220
[295]221    sys_call( SYSCALL_TTY_GET_LOCK,
222              channel,
223              (unsigned int)&sr_save,
224              0, 0 );
225
[345]226    va_start( args, format );
227    int ret = __printf(format, channel, &args);
228    va_end( args );
[258]229
[295]230    sys_call( SYSCALL_TTY_RELEASE_LOCK,
231              channel,
232              (unsigned int)&sr_save,
233              0, 0 );
[267]234
[345]235    if (ret)
[258]236    {
[345]237        giet_exit("error in giet_shr_printf()");
[258]238    }
[345]239} // end giet_shr_printf()
[267]240
[295]241/////////////////////////////////
242void giet_tty_getc( char * byte ) 
243{
244    int ret;
245
246    do
[267]247    {
[295]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()");
[267]254    }
[295]255    while (ret != 1); 
256}
[267]257
[295]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;
[258]294}
295
[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);
[258]325
[295]326        // analyse character
327        if ((string_byte > 0x2F) && (string_byte < 0x3A))  /* decimal character */
328        {
329            buf[length] = (unsigned char)string_byte;
330            length++;
[258]331
[295]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 );
[352]356                if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
[295]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 );
[352]395            if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
[295]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 );
[352]404        if ( ret < 0 ) giet_exit("error in giet_tty_getw()");
[295]405
406        // return 0 value
407        *val = 0;
408    }
409}
410
411
[258]412//////////////////////////////////////////////////////////////////////////////////
413/////////////////////  TIMER related system calls ////////////////////////////////
414//////////////////////////////////////////////////////////////////////////////////
415
[295]416///////////////////////
417void giet_timer_start() 
[258]418{
[295]419    if ( sys_call( SYSCALL_TIMER_START, 0, 0, 0, 0 ) ) 
420       giet_exit("error in giet_timer_start()");
[258]421}
[295]422
423//////////////////////
424void giet_timer_stop() 
[258]425{
[295]426    if ( sys_call( SYSCALL_TIMER_STOP, 0, 0, 0, 0 ) ) 
427        giet_exit("error in giet_timer_stop()");
[258]428}
429
430
431//////////////////////////////////////////////////////////////////////////////////
432///////////////  Frame buffer device related system calls  ///////////////////////
433//////////////////////////////////////////////////////////////////////////////////
434
[295]435////////////////////////////////////////////
436void giet_fb_sync_write( unsigned int offset, 
[258]437                        void *       buffer, 
438                        unsigned int length ) 
439{
[295]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()");
[258]445}
[295]446
447///////////////////////////////////////////
448void giet_fb_sync_read( unsigned int offset, 
449                        void *       buffer, 
450                        unsigned int length ) 
[258]451{
[295]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()");
[258]457}
[295]458
459/////////////////////////////////////////
460void giet_fb_cma_init( void *       buf0,
461                       void *       buf1,
462                       unsigned int length )
[258]463{
[295]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()");
[258]469}
[295]470
471///////////////////////////////////////////////
472void giet_fb_cma_write( unsigned int buffer_id )
[258]473{
[295]474    if ( sys_call( SYSCALL_FB_CMA_WRITE, 
475                   buffer_id, 
476                   0, 0, 0 ) )   giet_exit("error in giet_fb_cma_write()");
[258]477}
[295]478
479////////////////////////
480void giet_fb_cma_stop()
[258]481{
[295]482    if ( sys_call( SYSCALL_FB_CMA_STOP, 
483                   0, 0, 0, 0 ) )    giet_exit("error in giet_fb_cma_stop()");
[258]484}
485
486
487//////////////////////////////////////////////////////////////////////////////////
488/////////////////////// NIC related system calls /////////////////////////////////
489//////////////////////////////////////////////////////////////////////////////////
490
[295]491/////////////////////////
492void giet_nic_cma_start()
[258]493{
[295]494    if ( sys_call( SYSCALL_NIC_CMA_START, 0, 0, 0, 0 ) ) 
495       giet_exit("error in giet_nic_cma_start()");
[258]496}
[295]497
498/////////////////////////
499void giet_nic_cma_stop()
[258]500{
[295]501    if ( sys_call( SYSCALL_NIC_CMA_STOP, 0, 0, 0, 0 ) ) 
502        giet_exit("error in giet_nic_cma_stop()");
[258]503}
504
[295]505///////////////////////////////////////////////////////////////////////////////////
506///////////////////// FAT related system calls ////////////////////////////////////
507///////////////////////////////////////////////////////////////////////////////////
[258]508
[295]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}
[258]518
[295]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, 
[390]529                   offset ) != count ) giet_exit("ERROR in giet_fat_read()");
[295]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, 
[390]542                   offset ) != count ) giet_exit("ERROR in giet_fat_write()");
[295]543}
544
545/* variant implementing the UNIX spec
[258]546///////////////////////////////////////////////////////////////////////////////////
[295]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.
[258]551///////////////////////////////////////////////////////////////////////////////////
[295]552void giet_fat_write( unsigned int fd,
553                    void*        buffer,
554                    unsigned int count )  // number of bytes
[258]555{
[295]556    return sys_call( SYSCALL_FAT_WRITE,
557                     fd,
558                     (unsigned int)buffer,
559                     count, 0 );
[258]560}
[295]561*/
562
563/////////////////////////////////////
564void giet_fat_lseek( unsigned int fd, 
565                    unsigned int offset, 
566                    unsigned int whence )
[258]567{
[295]568    if ( sys_call( SYSCALL_FAT_LSEEK, 
569                   fd, 
570                   offset, 
571                   whence, 
[390]572                   0 ) ) giet_exit("ERROR in giet_fat_lseek()");
[258]573}
[295]574
575//////////////////////////////////////
576void giet_fat_fstat( unsigned int fd )
[258]577{
[295]578    if ( sys_call( SYSCALL_FAT_FSTAT,
579                   fd,
[390]580                   0, 0, 0 ) )  giet_exit("ERROR in giet_fat_lseek()");
[258]581}
[295]582
583/////////////////////////////////////
584void giet_fat_close( unsigned int fd )
[258]585{
[295]586    if ( sys_call( SYSCALL_FAT_CLOSE,
587                   fd,
[390]588                   0, 0, 0 ) )  giet_exit("ERROR in giet_fat_close()");
[258]589}
[295]590
591
[258]592//////////////////////////////////////////////////////////////////////////////////
[390]593///////////////////// Task context  system calls /////////////////////////////////
[258]594//////////////////////////////////////////////////////////////////////////////////
[295]595
596///////////////////////
[258]597int giet_proc_task_id() 
598{
599    return sys_call( SYSCALL_LOCAL_TASK_ID, 
600                     0, 0, 0, 0 );
601}
[295]602
603/////////////////////////
[258]604int giet_global_task_id() 
605{
606    return sys_call( SYSCALL_GLOBAL_TASK_ID, 
607                     0, 0, 0, 0 );
608}
609
[295]610////////////////////
[267]611int giet_thread_id() 
612{
613    return sys_call( SYSCALL_THREAD_ID, 
614                     0, 0, 0, 0 );
615}
616
[295]617
[390]618//////////////////////////////////////////////////////////////////////////////////
619///////////////////// Miscellaneous system calls /////////////////////////////////
620//////////////////////////////////////////////////////////////////////////////////
621
[295]622//////////////////////////////
623void giet_exit( char* string ) 
[258]624{
[295]625    sys_call( SYSCALL_EXIT,
626              (unsigned int)string,
627              0, 0, 0 );
[258]628}
[295]629
630/////////////////////////////////////////
631void giet_assert( unsigned int condition,
632                  char*        string )
[258]633{
[295]634    if ( condition == 0 ) giet_exit( string );
[258]635}
[295]636
[390]637//////////////////////////
638void giet_context_switch() 
639{
640    sys_call( SYSCALL_CTX_SWITCH,
641              0, 0, 0, 0 );
642}
643
[295]644////////////////////////////////////////////////////
645void giet_vobj_get_vbase( char*         vspace_name, 
646                          char*         vobj_name, 
647                          unsigned int* vobj_vaddr ) 
[258]648{
[295]649    if ( sys_call( SYSCALL_VOBJ_GET_VBASE, 
650                   (unsigned int) vspace_name,
651                   (unsigned int) vobj_name,
652                   (unsigned int) vobj_vaddr,
[390]653                   0 ) )  giet_exit("ERROR in giet_vobj_get_vbase()");
[258]654}
[260]655
[295]656///////////////////////////////////////////////
657void giet_proc_number( unsigned int  cluster_id, 
[368]658                       unsigned int* buffer ) 
[260]659{
[295]660    if ( sys_call( SYSCALL_PROC_NUMBER, 
661                   cluster_id, 
662                   (unsigned int) buffer, 
[390]663                   0, 0) )  giet_exit("ERROR in giet_proc_number()");
[260]664}
665
[295]666/////////////////////////////////////////
667void giet_heap_info( unsigned int* vaddr, 
[368]668                     unsigned int* length,
669                     unsigned int  x,
670                     unsigned int  y ) 
[258]671{
[295]672    if ( sys_call( SYSCALL_HEAP_INFO, 
673                   (unsigned int)vaddr, 
674                   (unsigned int)length, 
[368]675                   x,
[390]676                   y ) )  giet_exit("ERROR in giet_heap_info()");
[258]677}
678
[390]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
[258]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.