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

Last change on this file since 268 was 267, checked in by cfuguet, 11 years ago
  • Adding new task context information: THREAD INDEX.

This value can be accessed by USER applications to get the
thread index of the current task. This thread index
corresponds to the index in a vspace.

The value of this index can be forced in the vspace part
of the XML description file using the trdid field in the
task description. When this value is missing, for each
task, a value from 0 to N-1 will be assigned, where N is
the number of task in the vspace.

The user application access this value through the
giet_thread_id() function defined in the stdio library
which uses the SYSCALL_THREAD_ID to access the task
context information.

  • Supporting mono TTY platforms

When the GIET_MONO_TTY constant defined in the giet_config
file, contains a value different than 0, all tasks will
share the TTY[0]. If this is the case, in the stdio
library, the giet_tty_printf() function will take the TTY
hardware lock before writing

  • Property svn:executable set to *
File size: 32.9 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////////////////////////////////////////////////////////////////////////////////////
18//////////////////////  MIPS32 related system calls  ///////////////////////////////
19////////////////////////////////////////////////////////////////////////////////////
20
21////////////////////////////////////////////////////////////////////////////////////
22// giet_procid()
23////////////////////////////////////////////////////////////////////////////////////
24// This function returns the processor identifier.
25////////////////////////////////////////////////////////////////////////////////////
26int giet_procid() 
27{
28    return sys_call( SYSCALL_PROCID,
29                     0, 0, 0, 0 );
30}
31////////////////////////////////////////////////////////////////////////////////////
32// giet_proctime()
33////////////////////////////////////////////////////////////////////////////////////
34// This function returns the local processor time (clock cycles since boot)
35////////////////////////////////////////////////////////////////////////////////////
36int giet_proctime() 
37{
38    return sys_call( SYSCALL_PROCTIME, 
39                     0, 0, 0, 0 );
40}
41
42
43////////////////////////////////////////////////////////////////////////////////////
44/////////////////////  TTY device related system calls /////////////////////////////
45////////////////////////////////////////////////////////////////////////////////////
46
47////////////////////////////////////////////////////////////////////////////////////
48// giet_tty_putc()
49////////////////////////////////////////////////////////////////////////////////////
50// This function displays a single ascii character on a terminal.
51// The terminal index must be defined in the task context in the boot phase.
52// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
53// - Returns 1 if the character has been written, 0 otherwise.
54////////////////////////////////////////////////////////////////////////////////////
55int giet_tty_putc(char byte) 
56{
57    return sys_call(SYSCALL_TTY_WRITE, 
58                    (unsigned int)(&byte),
59                    1, 
60                    0xFFFFFFFF, 
61                    0);
62}
63////////////////////////////////////////////////////////////////////////////////////
64// giet_tty_puts()
65////////////////////////////////////////////////////////////////////////////////////
66// This function displays a string on a terminal.
67// The terminal index must be defined in the task context in the boot phase.
68// The string must be terminated by a NUL character.
69// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
70// - Returns the number of written characters.
71////////////////////////////////////////////////////////////////////////////////////
72int giet_tty_puts(char * buf) 
73{
74    unsigned int length = 0;
75    while (buf[length] != 0) { length++; }
76    return sys_call(SYSCALL_TTY_WRITE, 
77                   (unsigned int)buf, 
78                   length, 
79                   0xFFFFFFFF, 
80                   0);
81}
82////////////////////////////////////////////////////////////////////////////////////
83// giet_tty_putw()
84////////////////////////////////////////////////////////////////////////////////////
85// This function displays the value of a 32-bit word with decimal characters.
86// The terminal index must be defined in the task context in the boot phase.
87// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
88// Returns the number of written characters (should be equal to ten).
89////////////////////////////////////////////////////////////////////////////////////
90int giet_tty_putw(unsigned int val) 
91{
92    char buf[10];
93    unsigned int i;
94    for (i = 0; i < 10; i++) 
95    {
96        buf[9 - i] = (val % 10) + 0x30;
97        val = val / 10;
98    }
99    return sys_call(SYSCALL_TTY_WRITE, 
100                   (unsigned int)buf,
101                   10,
102                   0xFFFFFFFF,
103                   0);
104}
105////////////////////////////////////////////////////////////////////////////////////
106// giet_tty_getc()
107////////////////////////////////////////////////////////////////////////////////////
108// This blocking function fetches a single ascii character from a terminal.
109// The terminal index must be defined in the task context in the boot phase.
110// It uses the IRQ_GET interrupt, and the associated kernel buffer.
111// - Returns 0 when completed.
112////////////////////////////////////////////////////////////////////////////////////
113int giet_tty_getc(char * byte) 
114{
115    unsigned int ret = 0;
116    while (ret == 0) 
117    {
118        ret = sys_call(SYSCALL_TTY_READ, 
119                      (unsigned int)byte,  // buffer address
120                      1,                   // number of characters
121                      0xFFFFFFFF,          // channel index from task context
122                      0);
123    }
124    return 0;
125}
126////////////////////////////////////////////////////////////////////////////////////
127// giet_tty_gets()
128////////////////////////////////////////////////////////////////////////////////////
129// This blocking function fetches a string from a terminal to a fixed length buffer.
130// The terminal index must be defined in the task context in the boot phase.
131// It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
132// - Returns 0 when completed.
133// - Up to (bufsize - 1) characters (including the non printable characters)
134//   will be copied into buffer, and the string is always completed by a NUL
135//   character.
136// - The <LF> character is interpreted, and the function close the string with a
137//   NUL character if <LF> is read.
138// - The <DEL> character is interpreted, and the corresponding character(s) are
139//   removed from the target buffer.
140////////////////////////////////////////////////////////////////////////////////////
141int giet_tty_gets( char*        buf, 
142                   unsigned int bufsize) 
143{
144    unsigned int ret;
145    unsigned char byte;
146    unsigned int index = 0;
147
148    while (index < (bufsize - 1)) 
149    {
150        do 
151        { 
152            ret = sys_call(SYSCALL_TTY_READ, 
153                           (unsigned int)(&byte),
154                           1,
155                           0xFFFFFFFF,
156                           0);
157        } 
158        while (ret != 1);
159
160        if (byte == 0x0A)  /* LF */
161        {
162            break; 
163        }
164        else if ((byte == 0x7F) && (index > 0))  /* DEL */
165        {
166            index--; 
167        }
168        else 
169        {
170            buf[index] = byte;
171            index++;
172        }
173    }
174    buf[index] = 0;
175    return 0;
176}
177////////////////////////////////////////////////////////////////////////////////////
178// giet_tty_getw()
179////////////////////////////////////////////////////////////////////////////////////
180// This blocking function fetches a string of decimal characters (most
181// significant digit first) to build a 32-bit unsigned integer.
182// The terminal index must be defined in the task context in the boot phase.
183// It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
184// - Returns necessarily 0 when completed.
185//
186// - The non-blocking system function _tty_read_irq is called several times,
187//   and the decimal characters are written in a 32 characters buffer until a
188//   <LF> character is read.
189// - The <DEL> character is interpreted, and previous characters can be
190//   cancelled. All others characters are ignored.
191// - When the <LF> character is received, the string is converted to an
192//   unsigned int value. If the number of decimal digit is too large for the 32
193//   bits range, the zero value is returned.
194////////////////////////////////////////////////////////////////////////////////////
195int giet_tty_getw(unsigned int * val) 
196{
197    unsigned char buf[32];
198    unsigned char byte;
199    unsigned int save = 0;
200    unsigned int dec = 0;
201    unsigned int done = 0;
202    unsigned int overflow = 0;
203    unsigned int max = 0;
204    unsigned int i;
205    unsigned int ret;
206
207    while (done == 0) 
208    {
209        do 
210        { 
211            ret = sys_call(SYSCALL_TTY_READ,
212                           (unsigned int)(&byte),
213                           1,
214                           0xFFFFFFFF,
215                           0); 
216        } 
217        while (ret != 1);
218
219        if ((byte > 0x2F) && (byte < 0x3A))  /* decimal character */
220        {
221            buf[max] = byte;
222            max++;
223            giet_tty_putc(byte);
224        }
225        else if ((byte == 0x0A))   /* LF */
226        {
227            done = 1;
228        }
229        else if (byte == 0x7F)   /* DEL */
230        {
231            if (max > 0) 
232            {
233                max--;      /* cancel the character */
234                giet_tty_putc(0x08);
235                giet_tty_putc(0x20);
236                giet_tty_putc(0x08);
237            }
238        }
239        if (max == 32)  /* decimal string overflow */
240        {
241            for (i = 0; i < max; i++) 
242            {
243                /* cancel the string */
244                giet_tty_putc(0x08);
245                giet_tty_putc(0x20);
246                giet_tty_putc(0x08);
247            }
248            giet_tty_putc(0x30);
249            *val = 0;      /* return 0 value */
250            return 0;
251        }
252    }
253
254    /* string conversion */
255    for (i = 0; i < max; i++) 
256    {
257        dec = dec * 10 + (buf[i] - 0x30);
258        if (dec < save)  overflow = 1; 
259        save = dec;
260    }
261
262    /* check overflow */
263    if (overflow == 0) 
264    {
265        *val = dec; /* return decimal value */
266    }
267    else 
268    {
269        for (i = 0; i < max; i++) 
270        {
271            /* cancel the string */
272            giet_tty_putc(0x08);
273            giet_tty_putc(0x20);
274            giet_tty_putc(0x08);
275        }
276        giet_tty_putc(0x30);
277        *val = 0;         /* return 0 value */
278    }
279    return 0;
280}
281////////////////////////////////////////////////////////////////////////////////////
282// giet_tty_printf()
283////////////////////////////////////////////////////////////////////////////////////
284// This function is a simplified version of the mutek_printf() function.
285// The terminal index must be defined in the calling task context.
286// It doesn't use the IRQ_PUT interrupt, and the associated kernel buffer.
287// Only a limited number of formats are supported:
288//   - %d : signed decimal
289//   - %u : unsigned decimal
290//   - %x : hexadecimal
291//   - %c : char
292//   - %s : string
293// - Returns 0 if success, > 0 if error.
294////////////////////////////////////////////////////////////////////////////////////
295int giet_tty_printf(char * format, ...) 
296{
297    va_list ap;
298    va_start(ap, format);
299    unsigned int ret;
300
301    if (GIET_MONO_TTY)
302    {
303        ret = sys_call(SYSCALL_TTY_LOCK, 0, 0, 0, 0); // Get TTY lock
304    }
305
306printf_text:
307
308    while (*format) 
309    {
310        unsigned int i;
311        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
312        if (i) 
313        {
314            ret = sys_call(SYSCALL_TTY_WRITE, 
315                           (unsigned int)format,
316                           i, 
317                           0xFFFFFFFF,
318                           0);
319
320            if (ret != i) goto return_error;
321
322            format += i;
323        }
324        if (*format == '%') 
325        {
326            format++;
327            goto printf_arguments;
328        }
329    }
330
331    if (GIET_MONO_TTY)
332    {
333        ret = sys_call(SYSCALL_TTY_LOCK, 1, 0, 0, 0); // Release TTY lock
334    }
335
336    va_end(ap);
337    return 0;
338
339printf_arguments:
340
341    {
342        int val = va_arg(ap, long);
343        char buf[20];
344        char * pbuf;
345        unsigned int len = 0;
346        static const char HexaTab[] = "0123456789ABCDEF";
347        unsigned int i;
348
349        switch (*format++) {
350            case ('c'):             /* char conversion */
351                len = 1;
352                buf[0] = val;
353                pbuf = buf;
354                break;
355            case ('d'):             /* decimal signed integer */
356                if (val < 0) 
357                {
358                    val = -val;
359                    ret = sys_call(SYSCALL_TTY_WRITE, 
360                                   (unsigned int)"-",
361                                   1,
362                                   0xFFFFFFFF,
363                                   0);
364                    if (ret != 1) goto return_error;
365                }
366            case ('u'):             /* decimal unsigned integer */
367                for(i = 0; i < 10; i++) 
368                {
369                    buf[9 - i] = HexaTab[val % 10];
370                    if (!(val /= 10)) break;
371                }
372                len =  i + 1;
373                pbuf = &buf[9 - i];
374                break;
375            case ('x'):             /* hexadecimal integer */
376                ret = sys_call(SYSCALL_TTY_WRITE,
377                               (unsigned int)"0x",
378                               2,
379                               0xFFFFFFFF,
380                               0);
381                if (ret != 2) goto return_error;       /* return error */
382                for(i = 0; i < 8; i++) 
383                {
384                    buf[7 - i] = HexaTab[val % 16U];
385                    if (!(val /= 16U))  break;
386                }
387                len =  i + 1;
388                pbuf = &buf[7 - i];
389                break;
390            case ('s'):             /* string */
391                {
392                    char * str = (char *) val;
393                    while (str[len]) 
394                    {
395                        len++;
396                    }
397                    pbuf = (char *) val;
398                }
399                break;
400            default:
401                goto printf_text;
402        }
403
404        ret = sys_call(SYSCALL_TTY_WRITE, 
405                       (unsigned int)pbuf,
406                       len,
407                       0xFFFFFFFF,
408                       0);
409        if (ret != len)  goto return_error;
410       
411        goto printf_text;
412    }
413
414return_error:
415    if (GIET_MONO_TTY)
416    {
417        ret = sys_call(SYSCALL_TTY_LOCK, 1, 0, 0, 0); // Release TTY lock
418    }
419
420    return 1;
421}
422
423
424
425//////////////////////////////////////////////////////////////////////////////////
426/////////////////////  TIMER related system calls ////////////////////////////////
427//////////////////////////////////////////////////////////////////////////////////
428
429//////////////////////////////////////////////////////////////////////////////////
430// giet_timer_start()
431//////////////////////////////////////////////////////////////////////////////////
432// This function activates the private user timer allocated to the calling task
433// in the boot phase.
434// - Returns 0 if success, > 0 if error.
435//////////////////////////////////////////////////////////////////////////////////
436int giet_timer_start() 
437{
438    return sys_call( SYSCALL_TIMER_START, 
439                     0, 0, 0, 0 );
440}
441//////////////////////////////////////////////////////////////////////////////////
442// giet_timer_stop()
443//////////////////////////////////////////////////////////////////////////////////
444// This function activates the user timer allocated to the calling task.
445// - Returns 0 if success, > 0 if error.
446//////////////////////////////////////////////////////////////////////////////////
447int giet_timer_stop() 
448{
449    return sys_call( SYSCALL_TIMER_STOP, 
450                     0, 0, 0, 0 );
451}
452
453
454//////////////////////////////////////////////////////////////////////////////////
455///////////////  Frame buffer device related system calls  ///////////////////////
456//////////////////////////////////////////////////////////////////////////////////
457
458//////////////////////////////////////////////////////////////////////////////////
459// giet_fb_sync_write()
460//////////////////////////////////////////////////////////////////////////////////
461// This blocking function use a memory copy strategy to transfer data from a
462// user buffer to the frame buffer device in kernel space.
463//     offset : offset (in bytes) in the frame buffer
464//     buffer : base address of the memory buffer
465//     length : number of bytes to be transfered
466// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
467//////////////////////////////////////////////////////////////////////////////////
468int giet_fb_sync_write( unsigned int offset, 
469                        void *       buffer, 
470                        unsigned int length ) 
471{
472    return sys_call( SYSCALL_FB_SYNC_WRITE, 
473                     offset, 
474                     (unsigned int)buffer, 
475                     length, 
476                     0 );
477}
478//////////////////////////////////////////////////////////////////////////////////
479// giet_fb_sync_read()
480//////////////////////////////////////////////////////////////////////////////////
481// This blocking function use a memory copy strategy to transfer data from the
482// frame buffer device in kernel space to an user buffer.
483//     offset : offset (in bytes) in the frame buffer
484//     buffer : base address of the user buffer
485//     length : number of bytes to be transfered
486// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
487//////////////////////////////////////////////////////////////////////////////////
488int giet_fb_sync_read( unsigned int offset, 
489                       void *       buffer, 
490                       unsigned int length ) 
491{
492    return sys_call( SYSCALL_FB_SYNC_READ, 
493                     offset, 
494                     (unsigned int)buffer, 
495                     length, 
496                     0 );
497}
498//////////////////////////////////////////////////////////////////////////////////
499// giet_fb_cma_init()
500//////////////////////////////////////////////////////////////////////////////////
501// This function initializes the two chbuf SRC an DST used by the CMA controller
502// and activates the CMA channel allocated to the calling task.
503// - buf0   : first user buffer virtual address
504// - buf0   : second user buffer virtual address
505// - length : buffer size (bytes)
506// - Returns 0 if success, > 0 if error.
507//////////////////////////////////////////////////////////////////////////////////
508int giet_fb_cma_init( void *       buf0,
509                      void *       buf1,
510                      unsigned int length )
511{
512    return sys_call( SYSCALL_FB_CMA_INIT, 
513                     (unsigned int)buf0, 
514                     (unsigned int)buf1, 
515                     length, 
516                     0 );
517}
518//////////////////////////////////////////////////////////////////////////////////
519// giet_fb_cma_write()
520//////////////////////////////////////////////////////////////////////////////////
521// This function set the valid status for one of the SRC user buffer.
522// and reset the valid status for the DST frame buffer.
523// - bufffer_id : 0 => buf0 valid is set / not 0  => buf1 valid is set
524// - Returns 0 if success, > 0 if error.
525//////////////////////////////////////////////////////////////////////////////////
526int giet_fb_cma_write( unsigned int buffer_id )
527{
528    return sys_call( SYSCALL_FB_CMA_WRITE, 
529                     buffer_id, 
530                     0, 0, 0 );
531}
532//////////////////////////////////////////////////////////////////////////////////
533// giet_fb_cma_stop()
534//////////////////////////////////////////////////////////////////////////////////
535// This function desactivates the CMA channel allocated to the calling task.
536// - Returns 0 if success, > 0 if error.
537//////////////////////////////////////////////////////////////////////////////////
538int giet_fb_cma_stop( )
539{
540    return sys_call( SYSCALL_FB_CMA_STOP, 
541                     0, 0, 0, 0 );
542}
543
544
545//////////////////////////////////////////////////////////////////////////////////
546/////////////////////// NIC related system calls /////////////////////////////////
547//////////////////////////////////////////////////////////////////////////////////
548
549//////////////////////////////////////////////////////////////////////////////////
550// giet_nic_cma_init()
551//////////////////////////////////////////////////////////////////////////////////
552// This function initializes the memory chbuf used by the CMA controller,
553// activates the NIC channel allocated to the calling task, and the CMA channel.
554// - tx     : RX channel if 0 / TX channel if non 0
555// - buf0   : first user buffer virtual address
556// - buf1   : second user buffer virtual address
557// - length : buffer size (bytes)
558// - Returns 0 if success, > 0 if error
559//////////////////////////////////////////////////////////////////////////////////
560int giet_nic_cma_start()
561{
562    return sys_call( SYSCALL_NIC_CMA_START,
563                     0, 0, 0, 0 );
564}
565//////////////////////////////////////////////////////////////////////////////////
566// giet_nic_cma_stop()
567//////////////////////////////////////////////////////////////////////////////////
568// This function desactivates the NIC channel and the two CMA channels
569// allocated to the calling task.
570// - Returns 0 if success, > 0 if error.
571//////////////////////////////////////////////////////////////////////////////////
572int giet_nic_cma_stop( )
573{
574    return sys_call( SYSCALL_NIC_CMA_STOP,
575                     0, 0, 0, 0 );
576}
577
578
579//////////////////////////////////////////////////////////////////////////////////
580///////////////////// Miscellaneous system calls /////////////////////////////////
581//////////////////////////////////////////////////////////////////////////////////
582
583///////////////////////////////////////////////////////////////////////////////////
584// giet_assert()
585///////////////////////////////////////////////////////////////////////////////////
586// This function uses the giet_tty_puts() and giet_exit() system calls.
587///////////////////////////////////////////////////////////////////////////////////
588void giet_assert( unsigned int condition,
589                  char*        string )
590{
591    if ( condition == 0 )
592    {
593        giet_tty_puts( string );
594        giet_exit();
595    }
596}
597//////////////////////////////////////////////////////////////////////////////////
598// giet_vobj_get_vbase()
599//////////////////////////////////////////////////////////////////////////////////
600// This function writes in argument (vobj_vaddr) the virtual base address
601// of a vobj (defined in the mapping_info data structure), identified by
602// the two arguments (vspace_name and vobj_name).
603// The (vobj_type) argument is redundant, and used for coherence checking.
604// - Returns the address if success,  0 if error ( not defined or wrong type )
605//////////////////////////////////////////////////////////////////////////////////
606int giet_vobj_get_vbase( char*         vspace_name, 
607                         char*         vobj_name, 
608                         unsigned int  vobj_type, 
609                         unsigned int* vobj_vaddr ) 
610{
611    return sys_call( SYSCALL_VOBJ_GET_VBASE, 
612                     (unsigned int) vspace_name,
613                     (unsigned int) vobj_name,
614                     (unsigned int) vobj_type,
615                     (unsigned int) vobj_vaddr );
616}
617////////////////////////////////////////////////////////////////////////////////////
618// giet_proc_number()
619////////////////////////////////////////////////////////////////////////////////////
620// This function returns in the buffer argument the number of processors
621// in the cluster specified by the cluster_id argument.
622// - Returns 0 if success, > 0 if error ( cluster index too large )
623////////////////////////////////////////////////////////////////////////////////////
624int giet_proc_number( unsigned int  cluster_id, 
625                      unsigned int* buffer ) 
626{
627    return sys_call(SYSCALL_PROC_NUMBER, cluster_id, (unsigned int) buffer, 0, 0);
628}
629//////////////////////////////////////////////////////////////////////////////////
630// giet_exit()
631//////////////////////////////////////////////////////////////////////////////////
632// This function stops execution of the calling task with a TTY message,
633// the user task is descheduled and becomes not runable.
634// It does not consume processor cycles anymore.
635//////////////////////////////////////////////////////////////////////////////////
636void giet_exit() 
637{
638    sys_call( SYSCALL_EXIT,
639              0, 0, 0, 0 );
640}
641//////////////////////////////////////////////////////////////////////////////////
642// giet_context_switch()
643//////////////////////////////////////////////////////////////////////////////////
644// The user task calling this function is descheduled and
645// the processor is allocated to another task.
646//////////////////////////////////////////////////////////////////////////////////
647int giet_context_switch() 
648{
649    return sys_call( SYSCALL_CTX_SWITCH,
650                     0, 0, 0, 0 );
651}
652//////////////////////////////////////////////////////////////////////////////////
653// giet_proc_task_id()
654//////////////////////////////////////////////////////////////////////////////////
655// This functions returns the local task id.
656// If processor has n tasks the local task index is ranging from 0 to n-1
657//////////////////////////////////////////////////////////////////////////////////
658int giet_proc_task_id() 
659{
660    return sys_call( SYSCALL_LOCAL_TASK_ID, 
661                     0, 0, 0, 0 );
662}
663//////////////////////////////////////////////////////////////////////////////////
664// giet_heap_info()
665//////////////////////////////////////////////////////////////////////////////////
666// This function returns the base address and size of the current task's heap
667//////////////////////////////////////////////////////////////////////////////////
668int giet_heap_info( unsigned int* vaddr, 
669                             unsigned int* length ) 
670{
671    return sys_call( SYSCALL_HEAP_INFO, 
672                     (unsigned int)vaddr, 
673                     (unsigned int)length, 
674                     0, 0 );
675}
676//////////////////////////////////////////////////////////////////////////////////
677// giet_global_task_id()
678//////////////////////////////////////////////////////////////////////////////////
679// This functions returns the global task id, which is unique in all the giet.
680//////////////////////////////////////////////////////////////////////////////////
681int giet_global_task_id() 
682{
683    return sys_call( SYSCALL_GLOBAL_TASK_ID, 
684                     0, 0, 0, 0 );
685}
686
687//////////////////////////////////////////////////////////////////////////////////
688// giet_thread_id()
689//////////////////////////////////////////////////////////////////////////////////
690// This functions returns the thread index of the current task.
691//////////////////////////////////////////////////////////////////////////////////
692int giet_thread_id() 
693{
694    return sys_call( SYSCALL_THREAD_ID, 
695                     0, 0, 0, 0 );
696}
697
698///////////////////////////////////////////////////////////////////////////////////
699///////////////////// FAT related system calls ////////////////////////////////////
700///////////////////////////////////////////////////////////////////////////////////
701
702///////////////////////////////////////////////////////////////////////////////////
703// giet_fat_open()
704///////////////////////////////////////////////////////////////////////////////////
705// Open a file identified by a pathname, and contained in the system FAT.
706// The read/write flags are not supported yet: no effect.
707///////////////////////////////////////////////////////////////////////////////////
708int giet_fat_open( const char*   pathname, 
709                   unsigned int  flags )
710{
711    return sys_call( SYSCALL_FAT_OPEN, 
712                     (unsigned int)pathname, 
713                     flags,
714                     0, 0 );
715}
716///////////////////////////////////////////////////////////////////////////////////
717// giet_fat_read()
718///////////////////////////////////////////////////////////////////////////////////
719// Read "count" sectors from a file identified by "fd", skipping "offset"
720// sectors in file, and writing into the user "buffer".
721// The user buffer base address shoulb be 64 bytes aligned.
722///////////////////////////////////////////////////////////////////////////////////
723// This system call specification should evolve to the UNIX specification:
724// - count must be a number of bytes, with no alignment constraint on user buffer.
725// - offset argument should be removed and replaced by an implicit "lseek" pointer
726//   stored in the file descriptor.
727// This suppose to implement a sectors cache
728///////////////////////////////////////////////////////////////////////////////////
729int giet_fat_read( unsigned int fd, 
730                   void*        buffer, 
731                   unsigned int count,
732                   unsigned int offset )
733{
734    return sys_call( SYSCALL_FAT_READ,
735                     fd, 
736                     (unsigned int)buffer,
737                     count, 
738                     offset );
739}
740///////////////////////////////////////////////////////////////////////////////////
741// giet_fat_write()
742///////////////////////////////////////////////////////////////////////////////////
743// Write "count" sectors from a file identified by "fd", skipping "offset"
744// sectors in file, and reading from the user "buffer".
745// The user buffer base address shoulb be 64 bytes aligned.
746///////////////////////////////////////////////////////////////////////////////////
747// This system call specification should evolve to the UNIX specification:
748// - count must be a number of bytes, with no alignment constraint on buffer
749// - offset argument should be removed and replaced by an implicit "lseek" pointer
750//   stored in the file descriptor.
751// This suppose to implement a sectors cache
752///////////////////////////////////////////////////////////////////////////////////
753int giet_fat_write( unsigned int fd,
754                    void*        buffer, 
755                    unsigned int count,
756                    unsigned int offset )
757{
758    return sys_call( SYSCALL_FAT_WRITE, 
759                     fd, 
760                     (unsigned int)buffer,
761                     count, 
762                     offset );
763}
764///////////////////////////////////////////////////////////////////////////////////
765// giet_fat_lseek()
766///////////////////////////////////////////////////////////////////////////////////
767// Change the lseek file pointer value for a file identified by "fd".
768///////////////////////////////////////////////////////////////////////////////////
769int giet_fat_lseek( unsigned int fd, 
770                    unsigned int offset, 
771                    unsigned int whence)
772{
773    return sys_call( SYSCALL_FAT_LSEEK, 
774                     fd, 
775                     offset, 
776                     whence, 
777                     0 );
778}
779
780///////////////////////////////////////////////////////////////////////////////////
781// giet_fat_fstat()
782///////////////////////////////////////////////////////////////////////////////////
783// Return stats of a file identified by "fd".
784// (Only the file_size in sectors for this moment)
785///////////////////////////////////////////////////////////////////////////////////
786int giet_fat_fstat( unsigned int fd )
787{
788    return sys_call( SYSCALL_FAT_FSTAT,
789                     fd,
790                     0, 0, 0 );
791}
792
793///////////////////////////////////////////////////////////////////////////////////
794// giet_fat_close()
795///////////////////////////////////////////////////////////////////////////////////
796// Close a file identified by "fd".
797///////////////////////////////////////////////////////////////////////////////////
798int giet_fat_close( unsigned int fd )
799{
800    return sys_call( SYSCALL_FAT_CLOSE,
801                     fd,
802                     0, 0, 0 );
803}
804
805
806///////////////////////////////////////////////////////////////////////////////////
807////////////////// Pseudo system calls (no syscall instruction) ///////////////////
808///////////////////////////////////////////////////////////////////////////////////
809
810///////////////////////////////////////////////////////////////////////////////////
811// giet_rand()
812// This function returns a pseudo-random value derived from the processor cycle
813// count. This value is comprised between 0 & 65535.
814///////////////////////////////////////////////////////////////////////////////////
815int giet_rand() 
816{
817    unsigned int x = sys_call(SYSCALL_PROCTIME, 0, 0, 0, 0);
818    if ((x & 0xF) > 7) {
819        return (x*x & 0xFFFF);
820    }
821    else {
822        return (x*x*x & 0xFFFF);
823    }
824}
825///////////////////////////////////////////////////////////////////////////////////
826// memcpy()
827///////////////////////////////////////////////////////////////////////////////////
828inline void* memcpy( void*        dest, 
829                     const void*  source,
830                     unsigned int size ) 
831{
832    unsigned int*       dst = dest;
833    const unsigned int* src = source;
834
835    // word-by-word copy
836    if (!((unsigned int) dst & 3) && !((unsigned int) src & 3)) 
837    {
838        while (size > 3) 
839        {
840            *dst++ = *src++;
841            size -= 4;
842        }
843    }
844
845    unsigned char * cdst = (unsigned char *) dst;
846    unsigned char * csrc = (unsigned char *) src;
847
848    /* byte-by-byte copy */
849    while (size--) 
850    {
851        *cdst++ = *csrc++;
852    }
853    return dest;
854}
855
856// Local Variables:
857// tab-width: 4
858// c-basic-offset: 4
859// c-file-offsets:((innamespace . 0)(inline-open . 0))
860// indent-tabs-mode: nil
861// End:
862// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
863
Note: See TracBrowser for help on using the repository browser.