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

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

Introducing support for Network controller

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