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

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

Introducing the giet_vm and some example applications

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