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

Last change on this file since 254 was 253, checked in by alain, 11 years ago

1/ introducing support to display images on the frame buffer
with the vci_chbuf_dma (in stdio.c and drivers.c)
2/ introducing support for mem_cache configuration segment
as the memory cache is considered as another addressable peripheral type
(in drivers.c)
3/ Introducing the new "increment" parameter in the mapping header.
This parameter define the virtual address increment for the vsegs
associated to the replicated peripherals (ICU, XICU, MDMA, TIMER, MMC).
This parameter is mandatory, and all map.xml files the "mappings"
directory have been updated.

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