source: soft/giet_vm/libs/stdio.c @ 203

Last change on this file since 203 was 203, checked in by alain, 12 years ago

Introducing support for XICU

File size: 29.8 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
2// File     : stdio.c         
3// Date     : 01/04/2010
4// Author   : alain greiner & Joel Porquet
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The stdio.c and stdio.h files are part of the GIET_VM nano-kernel.
8// This library contains all user-level functions that contain a system call
9// to access protected or shared ressources.
10///////////////////////////////////////////////////////////////////////////////////
11
12#include <stdarg.h>
13#include <stdio.h>
14
15#define SYSCALL_PROCID          0x00
16#define SYSCALL_PROCTIME        0x01
17#define SYSCALL_TTY_WRITE       0x02
18#define SYSCALL_TTY_READ        0x03
19#define SYSCALL_TIMER_START     0x04
20#define SYSCALL_TIMER_STOP      0x05
21#define SYSCALL_GCD_WRITE       0x06
22#define SYSCALL_GCD_READ        0x07
23#define SYSCALL_TTY_READ_IRQ    0x0A
24#define SYSCALL_TTY_WRITE_IRQ   0x0B
25#define SYSCALL_CTX_SWITCH      0x0D
26#define SYSCALL_EXIT            0x0E
27#define SYSCALL_PROC_NUMBER     0x0F
28#define SYSCALL_FB_SYNC_WRITE   0x10
29#define SYSCALL_FB_SYNC_READ    0x11
30#define SYSCALL_FB_WRITE        0x12
31#define SYSCALL_FB_READ         0x13
32#define SYSCALL_FB_COMPLETED    0x14
33#define SYSCALL_IOC_WRITE       0x15
34#define SYSCALL_IOC_READ        0x16
35#define SYSCALL_IOC_COMPLETED   0x17
36#define SYSCALL_VOBJ_GET_VBASE  0x1A
37
38//////////////////////////////////////////////////////////////////////////////////
39// sys_call()
40// This generic C function is used to implement all system calls.
41// It writes the system call arguments in the proper registers,
42// and tells GCC what has been modified by system call execution.
43//////////////////////////////////////////////////////////////////////////////////
44static inline unsigned int sys_call( unsigned int call_no,
45                                     unsigned int arg_0, 
46                                     unsigned int arg_1, 
47                                     unsigned int arg_2, 
48                                     unsigned int arg_3)
49{
50    register unsigned int reg_no_and_output asm("v0") = call_no;
51    register unsigned int reg_a0            asm("a0") = arg_0;
52    register unsigned int reg_a1            asm("a1") = arg_1;
53    register unsigned int reg_a2            asm("a2") = arg_2;
54    register unsigned int reg_a3            asm("a3") = arg_3;
55
56    asm volatile(
57            "syscall"
58            : "=r" (reg_no_and_output)  /* output argument */
59            : "r" (reg_a0),             /* input arguments */
60              "r" (reg_a1),
61              "r" (reg_a2),
62              "r" (reg_a3),
63              "r" (reg_no_and_output)
64            : "memory",
65            /* These persistant registers will be saved on the stack by the
66             * compiler only if they contain relevant data. */
67            "at",
68            "v1",
69            "ra",
70            "t0",
71            "t1",
72            "t2",
73            "t3",
74            "t4",
75            "t5",
76            "t6",
77            "t7",
78            "t8",
79            "t9"
80               );
81    return reg_no_and_output;
82}
83
84/////    MIPS32 related system calls  /////
85
86////////////////////////////////////////////////////////////////////////////////////
87// giet_procid()
88////////////////////////////////////////////////////////////////////////////////////
89// This function returns the processor identifier.
90////////////////////////////////////////////////////////////////////////////////////
91unsigned int giet_procid()
92{
93    return sys_call(SYSCALL_PROCID, 
94                    0, 0, 0, 0);
95}
96////////////////////////////////////////////////////////////////////////////////////
97// giet_proctime()
98////////////////////////////////////////////////////////////////////////////////////
99// This function returns the local processor time (clock cycles since boot)
100////////////////////////////////////////////////////////////////////////////////////
101unsigned int giet_proctime()
102{
103    return sys_call(SYSCALL_PROCTIME, 
104                    0, 0, 0, 0);
105}
106
107//////  TTY device related system calls /////
108
109////////////////////////////////////////////////////////////////////////////////////
110// giet_tty_putc()
111////////////////////////////////////////////////////////////////////////////////////
112// This function displays a single ascii character on a terminal.
113// The terminal index must be defined in the task context in the boot phase.
114// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
115// - Returns 1 if the character has been written, 0 otherwise.
116////////////////////////////////////////////////////////////////////////////////////
117unsigned int giet_tty_putc(char byte)
118{
119    return sys_call(SYSCALL_TTY_WRITE,
120                    (unsigned int)(&byte),
121                    1,
122                    0,0);
123}
124////////////////////////////////////////////////////////////////////////////////////
125// giet_tty_puts()
126////////////////////////////////////////////////////////////////////////////////////
127// This function displays a string on a terminal.
128// The terminal index must be defined in the task context in the boot phase.
129// The string must be terminated by a NUL character.
130// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
131// - Returns the number of written characters.
132////////////////////////////////////////////////////////////////////////////////////
133unsigned int giet_tty_puts(char *buf)
134{
135    unsigned int length = 0;
136    while (buf[length] != 0)
137    {
138        length++;
139    }
140    return sys_call(SYSCALL_TTY_WRITE,
141                    (unsigned int)buf,
142                    length,
143                    0,0);
144}
145////////////////////////////////////////////////////////////////////////////////////
146// giet_tty_putw()
147////////////////////////////////////////////////////////////////////////////////////
148// This function displays the value of a 32-bit word with decimal characters.
149// The terminal index must be defined in the task context in the boot phase.
150// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
151// Returns the number of written characters (should be equal to ten).
152////////////////////////////////////////////////////////////////////////////////////
153unsigned int giet_tty_putw(unsigned int val)
154{
155    char buf[10];
156    unsigned int i;
157    for (i = 0; i < 10; i++)
158    {
159        buf[9-i] = (val % 10) + 0x30;
160        val = val / 10;
161    }
162    return sys_call(SYSCALL_TTY_WRITE,
163                    (unsigned int)buf,
164                    10,
165                    0,0);
166}
167
168////////////////////////////////////////////////////////////////////////////////////
169// giet_tty_getc_no_irq()
170////////////////////////////////////////////////////////////////////////////////////
171// This blocking function fetches a single ascii character from a terminal.
172// The terminal index must be defined in the task context in the boot phase.
173// It doesn't use the IRQ_GET interrupt, and the associated kernel buffer.
174// - Returns necessarily 0 when completed.
175////////////////////////////////////////////////////////////////////////////////////
176unsigned int giet_tty_getc_no_irq(char *byte)
177{
178    unsigned int ret = 0;
179    while (ret == 0)
180    {
181        ret = sys_call(SYSCALL_TTY_READ,
182                       (unsigned int)byte,
183                       1,
184                       0,0);
185    }
186    return 0;
187}
188////////////////////////////////////////////////////////////////////////////////////
189// giet_tty_getc()
190////////////////////////////////////////////////////////////////////////////////////
191// This blocking function fetches a single ascii character from a terminal.
192// The terminal index must be defined in the task context in the boot phase.
193// It uses the IRQ_GET interrupt, and the associated kernel buffer.
194// - Returns 0 when completed.
195////////////////////////////////////////////////////////////////////////////////////
196unsigned int giet_tty_getc(char *byte)
197{
198    unsigned int ret = 0;
199    while (ret == 0)
200    {
201        ret = sys_call(SYSCALL_TTY_READ_IRQ,
202                       (unsigned int)byte,
203                       1,
204                       0,0);
205    }
206    return 0;
207}
208////////////////////////////////////////////////////////////////////////////////////
209// giet_tty_gets()
210////////////////////////////////////////////////////////////////////////////////////
211// This blocking function fetches a string from a terminal to a fixed length buffer.
212// The terminal index must be defined in the task context in the boot phase.
213// It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
214// - Returns 0 when completed.
215// - Up to (bufsize - 1) characters (including the non printable characters)
216//   will be copied into buffer, and the string is always completed by a NUL
217//   character.
218// - The <LF> character is interpreted, as the function close the string with a
219//   NUL character if <LF> is read.
220// - The <DEL> character is interpreted, and the corresponding character(s) are
221//   removed from the target buffer.
222////////////////////////////////////////////////////////////////////////////////////
223unsigned int giet_tty_gets( char*                       buf, 
224                            unsigned int        bufsize )
225{
226    unsigned int ret;
227    unsigned char byte;
228    unsigned int index = 0;
229
230    while (index < (bufsize - 1))
231    {
232        do {
233            ret = sys_call(SYSCALL_TTY_READ_IRQ,
234                           (unsigned int)(&byte),
235                           1,
236                           0,0);
237        } while (ret != 1);
238
239        if ( byte == 0x0A )
240            break; /* LF */
241        else if ((byte == 0x7F) && (index > 0))
242            index--; /* DEL */
243        else
244        {
245            buf[index] = byte;
246            index++;
247        }
248    }
249    buf[index] = 0;
250    return 0;
251}
252////////////////////////////////////////////////////////////////////////////////////
253// giet_tty_getw()
254////////////////////////////////////////////////////////////////////////////////////
255// This blocking function fetches a string of decimal characters (most
256// significant digit first) to build a 32-bit unsigned integer.
257// The terminal index must be defined in the task context in the boot phase.
258// It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
259// - Returns necessarily 0 when completed.
260//
261// - The non-blocking system function _tty_read_irq is called several times,
262//   and the decimal characters are written in a 32 characters buffer until a
263//   <LF> character is read.
264// - The <DEL> character is interpreted, and previous characters can be
265//   cancelled. All others characters are ignored.
266// - When the <LF> character is received, the string is converted to an
267//   unsigned int value. If the number of decimal digit is too large for the 32
268//   bits range, the zero value is returned.
269////////////////////////////////////////////////////////////////////////////////////
270unsigned int giet_tty_getw(unsigned int *val)
271{
272    unsigned char buf[32];
273    unsigned char byte;
274    unsigned int save = 0;
275    unsigned int dec = 0;
276    unsigned int done = 0;
277    unsigned int overflow = 0;
278    unsigned int max = 0;
279    unsigned int i;
280    unsigned int ret;
281
282    while (done == 0)
283    {
284        do {
285            ret = sys_call(SYSCALL_TTY_READ_IRQ,
286                           (unsigned int)(&byte),
287                           1,
288                           0,0);
289        } while (ret != 1);
290
291        if ((byte > 0x2F) && (byte < 0x3A)) /* decimal character */
292        {
293            buf[max] = byte;
294            max++;
295            giet_tty_putc(byte);
296        }
297        else if ((byte == 0x0A) || (byte == 0x0D)) /* LF or CR character */
298        {
299            done = 1;
300        }
301        else if (byte == 0x7F) /* DEL character */
302        {
303            if (max > 0)
304            {
305                max--; /* cancel the character */
306                giet_tty_putc(0x08);
307                giet_tty_putc(0x20);
308                giet_tty_putc(0x08);
309            }
310        }
311        if (max == 32) /* decimal string overflow */
312        {
313            for (i = 0; i < max; i++) /* cancel the string */
314            {
315                giet_tty_putc(0x08);
316                giet_tty_putc(0x20);
317                giet_tty_putc(0x08);
318            }
319            giet_tty_putc(0x30);
320            *val = 0; /* return 0 value */
321            return 0;
322        }
323    }
324
325    /* string conversion */
326    for (i = 0; i < max; i++)
327    {
328        dec = dec * 10 + (buf[i] - 0x30);
329        if (dec < save)
330            overflow = 1;
331        save = dec;
332    }
333
334    /* check overflow */
335    if (overflow == 0)
336    {
337        *val = dec; /* return decimal value */
338    }
339    else
340    {
341        for (i = 0; i < max; i++) /* cancel the string */
342        {
343            giet_tty_putc(0x08);
344            giet_tty_putc(0x20);
345            giet_tty_putc(0x08);
346        }
347        giet_tty_putc(0x30);
348        *val = 0; /* return 0 value */
349    }
350    return 0;
351}
352////////////////////////////////////////////////////////////////////////////////////
353// giet_tty_printf()
354////////////////////////////////////////////////////////////////////////////////////
355// This function is a simplified version of the mutek_printf() function.
356// The terminal index must be defined in the calling task context.
357// It doesn't use the IRQ_PUT interrupt, and the associated kernel buffer.
358// Only a limited number of formats are supported:
359//   - %d : signed decimal
360//   - %u : unsigned decimal
361//   - %x : hexadecimal
362//   - %c : char
363//   - %s : string
364// - Returns 0 if success, > 0 if error.
365////////////////////////////////////////////////////////////////////////////////////
366unsigned int giet_tty_printf(char *format, ...)
367{
368    va_list ap;
369    va_start(ap, format);
370    unsigned int ret;
371
372printf_text:
373
374    while (*format) {
375        unsigned int i;
376        for (i = 0; format[i] && format[i] != '%'; i++)
377            ;
378        if (i) {
379            ret = sys_call(SYSCALL_TTY_WRITE,
380                    (unsigned int)format,
381                    i,
382                    0,0);
383            if (ret != i)
384                return 1; /* return error */
385            format += i;
386        }
387        if (*format == '%') {
388            format++;
389            goto printf_arguments;
390        }
391    }
392
393    va_end(ap);
394    return 0;
395
396printf_arguments:
397
398    {
399        int         val = va_arg(ap, long);
400        char            buf[20];
401        char*           pbuf;
402        unsigned int        len = 0;
403        static const char   HexaTab[] = "0123456789ABCDEF";
404        unsigned int        i;
405
406        switch (*format++) {
407            case ('c'):             /* char conversion */
408                len = 1;
409                buf[0] = val;
410                pbuf = buf;
411                break;
412            case ('d'):             /* decimal signed integer */
413                if (val < 0) {
414                    val = -val;
415                    ret = sys_call(SYSCALL_TTY_WRITE,
416                            (unsigned int)"-",
417                            1,
418                            0,0);
419                    if (ret != 1)
420                        return 1; /* return error */
421                }
422            case ('u'):             /* decimal unsigned integer */
423                for( i=0 ; i<10 ; i++) {
424                    buf[9-i] = HexaTab[val % 10];
425                    if (!(val /= 10)) break;
426                }
427                len =  i+1;
428                pbuf = &buf[9-i];
429                break;
430            case ('x'):             /* hexadecimal integer */
431                ret = sys_call(SYSCALL_TTY_WRITE,
432                        (unsigned int)"0x",
433                        2,
434                        0,0);
435                if (ret != 2)
436                    return 1; /* return error */
437                for( i=0 ; i<8 ; i++) {
438                    buf[7-i] = HexaTab[val % 16U];
439                    if (!(val /= 16U)) break;
440                }
441                len =  i+1;
442                pbuf = &buf[7-i];
443                break;
444            case ('s'):             /* string */
445                {
446                    char *str = (char*)val;
447                    while ( str[len] ) len++;
448                    pbuf = (char*)val;
449                }
450                break;
451            default:
452                goto printf_text;
453        }
454
455        ret = sys_call(SYSCALL_TTY_WRITE,
456                (unsigned int)pbuf,
457                len,
458                0,0);
459        if (ret != len)
460            return 1;
461        goto printf_text;
462    }
463}
464
465
466/////  TIMER related system calls //////
467
468//////////////////////////////////////////////////////////////////////////////////
469// giet_timer_start()
470//////////////////////////////////////////////////////////////////////////////////
471// This function activates the private user timer allocated to the calling task
472// in the boot phase.
473// - Returns 0 if success, > 0 if error.
474//////////////////////////////////////////////////////////////////////////////////
475unsigned int giet_timer_start()
476{
477    return sys_call(SYSCALL_TIMER_START,
478                   0,0,0,0);
479}
480//////////////////////////////////////////////////////////////////////////////////
481// giet_timer_stop()
482//////////////////////////////////////////////////////////////////////////////////
483// This function activates the user timer allocated to the calling task.
484// - Returns 0 if success, > 0 if error.
485//////////////////////////////////////////////////////////////////////////////////
486unsigned int giet_timer_stop()
487{
488    return sys_call(SYSCALL_TIMER_STOP,
489                   0,0,0,0);
490}
491
492/////  GCD (Greatest Common Divider) related system calls
493
494#define GCD_OPA     0
495#define GCD_OPB     1
496#define GCD_START   2
497#define GCD_STATUS  3
498
499//////////////////////////////////////////////////////////////////////////////////
500// giet_gcd_set_opa()
501//////////////////////////////////////////////////////////////////////////////////
502// This function sets the operand A in the GCD coprocessor.
503// - Returns 0 if success, > 0 if error.
504//////////////////////////////////////////////////////////////////////////////////
505unsigned int giet_gcd_set_opa(unsigned int val)
506{
507    return sys_call(SYSCALL_GCD_WRITE,
508                    GCD_OPA,
509                    val,
510                    0, 0);
511}
512//////////////////////////////////////////////////////////////////////////////////
513//      giet_gcd_set_opb()
514//////////////////////////////////////////////////////////////////////////////////
515// This function sets operand B in the GCD coprocessor.
516// - Returns 0 if success, > 0 if error.
517//////////////////////////////////////////////////////////////////////////////////
518unsigned int giet_gcd_set_opb(unsigned int val)
519{
520    return sys_call(SYSCALL_GCD_WRITE,
521                    GCD_OPB,
522                    val,
523                    0, 0);
524}
525//////////////////////////////////////////////////////////////////////////////////
526//      giet_gcd_start()
527//////////////////////////////////////////////////////////////////////////////////
528// This function starts the computation in the GCD coprocessor.
529// - Returns 0 if success, > 0 if error.
530//////////////////////////////////////////////////////////////////////////////////
531unsigned int giet_gcd_start()
532{
533    return sys_call(SYSCALL_GCD_WRITE,
534                    GCD_START,
535                    0, 0, 0);
536}
537//////////////////////////////////////////////////////////////////////////////////
538//      giet_gcd_get_status()
539//////////////////////////////////////////////////////////////////////////////////
540// This function gets the status fromn the GCD coprocessor.
541// - The value is 0 when the coprocessor is idle (computation completed).
542//////////////////////////////////////////////////////////////////////////////////
543unsigned int giet_gcd_get_status(unsigned int *val)
544{
545    return sys_call(SYSCALL_GCD_READ,
546            GCD_STATUS,
547            (unsigned int)val,
548            0, 0);
549}
550//////////////////////////////////////////////////////////////////////////////////
551//      giet_gcd_get_result()
552//////////////////////////////////////////////////////////////////////////////////
553// This function gets the result of the computation from the GCD coprocessor.
554//////////////////////////////////////////////////////////////////////////////////
555unsigned int giet_gcd_get_result(unsigned int *val)
556{
557    return sys_call(SYSCALL_GCD_READ,
558            GCD_OPA,
559            (unsigned int)val,
560            0, 0);
561}
562
563///// Block device related system calls  /////
564
565//////////////////////////////////////////////////////////////////////////////////
566//      giet_ioc_write()
567//////////////////////////////////////////////////////////////////////////////////
568// Transfer data from a memory buffer to a file on the block_device.
569//     lba    : Logical Block Address (first block index)
570//     buffer : base address of the memory buffer
571//     count  : number of blocks to be transfered
572// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
573//////////////////////////////////////////////////////////////////////////////////
574unsigned int giet_ioc_write( unsigned int       lba, 
575                             void*                      buffer, 
576                             unsigned int       count)
577{
578    return sys_call(SYSCALL_IOC_WRITE,
579            lba,
580            (unsigned int)buffer,
581            count,
582            0);
583}
584//////////////////////////////////////////////////////////////////////////////////
585// giet_ioc_read()
586//////////////////////////////////////////////////////////////////////////////////
587// Transfer data from a file on the block_device to a memory buffer.
588//     lba    : Logical Block Address (first block index)
589//     buffer : base address of the memory buffer
590//     count  : number of blocks to be transfered
591// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
592//////////////////////////////////////////////////////////////////////////////////
593unsigned int giet_ioc_read( unsigned int                lba, 
594                            void*                               buffer, 
595                            unsigned int                count )
596{
597    return sys_call(SYSCALL_IOC_READ,
598            lba,
599            (unsigned int)buffer,
600            count,
601            0);
602}
603//////////////////////////////////////////////////////////////////////////////////
604// giet_ioc_completed()
605//////////////////////////////////////////////////////////////////////////////////
606// This blocking function returns 0 when the I/O transfer is
607// successfully completed, and returns 1 if an address error has been detected.
608//////////////////////////////////////////////////////////////////////////////////
609unsigned int giet_ioc_completed()
610{
611    return sys_call(SYSCALL_IOC_COMPLETED,
612            0, 0, 0, 0);
613}
614
615/////  Frame buffer device related system calls  /////
616
617//////////////////////////////////////////////////////////////////////////////////
618// giet_fb_sync_write()
619//////////////////////////////////////////////////////////////////////////////////
620// This blocking function use a memory copy strategy to transfer data from a
621// user buffer to the frame buffer device in kernel space.
622//     offset : offset (in bytes) in the frame buffer
623//     buffer : base address of the memory buffer
624//     length : number of bytes to be transfered
625// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
626//////////////////////////////////////////////////////////////////////////////////
627unsigned int giet_fb_sync_write( unsigned int   offset, 
628                                 void*                  buffer, 
629                                 unsigned int   length )
630{
631    return sys_call(SYSCALL_FB_SYNC_WRITE,
632            offset,
633            (unsigned int)buffer,
634            length,
635            0);
636}
637//////////////////////////////////////////////////////////////////////////////////
638// giet_fb_sync_read()
639//////////////////////////////////////////////////////////////////////////////////
640// This blocking function use a memory copy strategy to transfer data from the
641// frame buffer device in kernel space to an user buffer.
642//     offset : offset (in bytes) in the frame buffer
643//     buffer : base address of the user buffer
644//     length : number of bytes to be transfered
645// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
646//////////////////////////////////////////////////////////////////////////////////
647unsigned int giet_fb_sync_read( unsigned int    offset, 
648                                void*                   buffer, 
649                                unsigned int    length )
650{
651    return sys_call(SYSCALL_FB_SYNC_READ,
652            offset,
653            (unsigned int)buffer,
654            length,
655            0);
656}
657//////////////////////////////////////////////////////////////////////////////////
658// giet_fb_write()
659//////////////////////////////////////////////////////////////////////////////////
660// This non-blocking function use the DMA coprocessor to transfer data from a
661// user buffer to the frame buffer device in kernel space.
662// - offset : offset (in bytes) in the frame buffer
663// - buffer : base address of the user buffer
664// - length : number of bytes to be transfered
665// The transfer completion is signaled by an IRQ, and must be tested by the
666// fb_completed() function.
667// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
668//////////////////////////////////////////////////////////////////////////////////
669unsigned int giet_fb_write( unsigned int        offset, 
670                            void*                       buffer, 
671                            unsigned int        length )
672{
673    return sys_call(SYSCALL_FB_WRITE,
674            offset,
675            (unsigned int)buffer,
676            length,
677            0);
678}
679//////////////////////////////////////////////////////////////////////////////////
680// giet_fb_read()
681//////////////////////////////////////////////////////////////////////////////////
682// This non-blocking function use the DMA coprocessor to transfer data from the
683// frame buffer device in kernel space to an user buffer.
684// - offset : offset (in bytes) in the frame buffer
685// - buffer : base address of the memory buffer
686// - length : number of bytes to be transfered
687// The transfer completion is signaled by an IRQ, and must be tested by the
688// fb_completed() function.
689// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
690//////////////////////////////////////////////////////////////////////////////////
691unsigned int giet_fb_read( unsigned int         offset, 
692                           void*                        buffer, 
693                           unsigned int         length )
694{
695    return sys_call(SYSCALL_FB_READ,
696                    offset,
697                    (unsigned int)buffer,
698                    length,
699                    0);
700}
701//////////////////////////////////////////////////////////////////////////////////
702// giet_fb_completed()
703//////////////////////////////////////////////////////////////////////////////////
704// This blocking function returns when the transfer is completed.
705// - Returns 0 if success, > 0 if error.
706//////////////////////////////////////////////////////////////////////////////////
707unsigned int giet_fb_completed()
708{
709    return sys_call(SYSCALL_FB_COMPLETED,
710                    0, 0, 0, 0);
711}
712
713///// Miscellaneous related system calls /////
714
715//////////////////////////////////////////////////////////////////////////////////
716// giet_vobj_get_vbase()
717//////////////////////////////////////////////////////////////////////////////////
718// This function writes in argument (vobj_vaddr) the virtual base address
719// of a vobj (defined in the mapping_info data structure), identified by
720// the two arguments (vspace_name and vobj_name).
721// The (vobj_type) argument is redundant, and used for coherence checking.
722// - Returns the address if success,  0 if error ( not defined or wrong type )
723//////////////////////////////////////////////////////////////////////////////////
724unsigned int giet_vobj_get_vbase( char*                 vspace_name, 
725                                  char*                 vobj_name,
726                                  unsigned int  vobj_type, 
727                                  unsigned int* vobj_vaddr )
728{
729    return sys_call(SYSCALL_VOBJ_GET_VBASE, 
730                    (unsigned int)vspace_name,
731                    (unsigned int)vobj_name,
732                    (unsigned int)vobj_type,
733                    (unsigned int)vobj_vaddr);
734}
735
736////////////////////////////////////////////////////////////////////////////////////
737// giet_proc_number()
738////////////////////////////////////////////////////////////////////////////////////
739// This function returns in the buffer argument the number of processors
740// in the cluster specified by the cluster_id argument.
741// - Returns 0 if success, > 0 if error ( cluster index too large )
742////////////////////////////////////////////////////////////////////////////////////
743unsigned int giet_proc_number( unsigned int             cluster_id,
744                               unsigned int*    buffer )
745{
746    return sys_call(SYSCALL_PROC_NUMBER, 
747                    cluster_id,
748                    (unsigned int)buffer,
749                    0, 0);
750}
751
752/////  Miscellaneous system calls /////
753
754//////////////////////////////////////////////////////////////////////////////////
755// giet_task_exit()
756//////////////////////////////////////////////////////////////////////////////////
757// This function stops execution of the calling task with a TTY message,
758// and enter an infinite loop.
759// The task is blocked, but it still consume processor cycles ...
760//////////////////////////////////////////////////////////////////////////////////
761void giet_exit()
762{
763    sys_call(SYSCALL_EXIT, 
764             0, 0, 0, 0);
765}
766///////////////////////////////////////////////////////////////////////////////////
767// giet_rand()
768// This function returns a pseudo-random value derived from the processor cycle
769// count. This value is comprised between 0 & 65535.
770///////////////////////////////////////////////////////////////////////////////////
771unsigned int giet_rand()
772{
773    unsigned int x = sys_call(SYSCALL_PROCTIME, 
774                              0, 0, 0, 0);
775    if((x & 0xF) > 7)
776        return (x*x & 0xFFFF);
777    else
778        return (x*x*x & 0xFFFF);
779}
780//////////////////////////////////////////////////////////////////////////////////
781// giet_ctx_switch()
782// The user task calling this function is descheduled and
783// the processor is allocated to another task.
784//////////////////////////////////////////////////////////////////////////////////
785unsigned int giet_ctx_switch()
786{
787    return sys_call(SYSCALL_CTX_SWITCH, 
788                    0, 0, 0, 0);
789}
790
791
Note: See TracBrowser for help on using the repository browser.