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

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