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

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

Ajout du malloc dans le Giet.

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