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

Last change on this file since 231 was 228, checked in by meunier, 12 years ago

Added support for memspaces and const.
Added an interrupt masking to the "giet_context_switch" syscall
Corrected two bugs in boot/boot_init.c (one minor and one regarding barriers initialization)
Reformatted the code in all files.

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