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

Last change on this file since 237 was 237, checked in by meunier, 11 years ago

Adding a syscall to allow a user to know the block size with which the block device has been configured.

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