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

Last change on this file since 255 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
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
[253]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
[255]47#define SYSCALL_SIM_HELPER_ACCESS 0x20
[158]48
49//////////////////////////////////////////////////////////////////////////////////
[165]50// sys_call()
[158]51// This generic C function is used to implement all system calls.
[165]52// It writes the system call arguments in the proper registers,
53// and tells GCC what has been modified by system call execution.
[158]54//////////////////////////////////////////////////////////////////////////////////
[253]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{
[158]61    register unsigned int reg_no_and_output asm("v0") = call_no;
[228]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;
[158]66
67    asm volatile(
68            "syscall"
69            : "=r" (reg_no_and_output)  /* output argument */
70            : "r" (reg_a0),             /* input arguments */
[228]71            "r" (reg_a1),
72            "r" (reg_a2),
73            "r" (reg_a3),
74            "r" (reg_no_and_output)
[158]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
[228]95/////      MIPS32 related system calls  /////
[158]96
97////////////////////////////////////////////////////////////////////////////////////
[165]98// giet_procid()
99////////////////////////////////////////////////////////////////////////////////////
[158]100// This function returns the processor identifier.
101////////////////////////////////////////////////////////////////////////////////////
[228]102unsigned int giet_procid() {
103    return sys_call(SYSCALL_PROCID, 0, 0, 0, 0);
[158]104}
[228]105
106
[158]107////////////////////////////////////////////////////////////////////////////////////
[165]108// giet_proctime()
109////////////////////////////////////////////////////////////////////////////////////
[158]110// This function returns the local processor time (clock cycles since boot)
111////////////////////////////////////////////////////////////////////////////////////
[238]112unsigned int giet_proctime() 
113{
[228]114    return sys_call(SYSCALL_PROCTIME, 0, 0, 0, 0);
[158]115}
116
117
[253]118//////  TTY device related system calls /////
[228]119
[158]120////////////////////////////////////////////////////////////////////////////////////
[165]121// giet_tty_putc()
122////////////////////////////////////////////////////////////////////////////////////
[158]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////////////////////////////////////////////////////////////////////////////////////
[238]128unsigned int giet_tty_putc(char byte) 
129{
[228]130    return sys_call(SYSCALL_TTY_WRITE, (unsigned int) (&byte), 1, 0, 0);
[158]131}
132////////////////////////////////////////////////////////////////////////////////////
[165]133// giet_tty_puts()
134////////////////////////////////////////////////////////////////////////////////////
[158]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////////////////////////////////////////////////////////////////////////////////////
[238]141unsigned int giet_tty_puts(char * buf) 
142{
[158]143    unsigned int length = 0;
[238]144    while (buf[length] != 0) { length++; }
[228]145    return sys_call(SYSCALL_TTY_WRITE, (unsigned int) buf, length, 0, 0);
[158]146}
147////////////////////////////////////////////////////////////////////////////////////
[165]148// giet_tty_putw()
149////////////////////////////////////////////////////////////////////////////////////
[158]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////////////////////////////////////////////////////////////////////////////////////
[238]155unsigned int giet_tty_putw(unsigned int val) 
156{
[158]157    char buf[10];
158    unsigned int i;
[238]159    for (i = 0; i < 10; i++) 
160    {
[228]161        buf[9 - i] = (val % 10) + 0x30;
[158]162        val = val / 10;
163    }
[228]164    return sys_call(SYSCALL_TTY_WRITE, (unsigned int) buf, 10, 0, 0);
[158]165}
166////////////////////////////////////////////////////////////////////////////////////
[165]167// giet_tty_getc()
168////////////////////////////////////////////////////////////////////////////////////
[158]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////////////////////////////////////////////////////////////////////////////////////
[238]174unsigned int giet_tty_getc(char * byte) 
175{
[158]176    unsigned int ret = 0;
[238]177    while (ret == 0) 
178    {
[228]179        ret = sys_call(SYSCALL_TTY_READ, (unsigned int)byte, 1, 0, 0);
[158]180    }
181    return 0;
182}
183////////////////////////////////////////////////////////////////////////////////////
[165]184// giet_tty_gets()
185////////////////////////////////////////////////////////////////////////////////////
[158]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.
[238]193// - The <LF> character is interpreted, and the function close the string with a
[158]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////////////////////////////////////////////////////////////////////////////////////
[238]198unsigned int giet_tty_gets( char*        buf, 
199                            unsigned int bufsize) 
200{
[158]201    unsigned int ret;
202    unsigned char byte;
203    unsigned int index = 0;
204
[238]205    while (index < (bufsize - 1)) 
206    {
207        do { ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0); } 
208        while (ret != 1);
[158]209
[238]210        if (byte == 0x0A)  /* LF */
211        {
212            break; 
[228]213        }
[238]214        else if ((byte == 0x7F) && (index > 0))  /* DEL */
215        {
216            index--; 
[228]217        }
[238]218        else 
219        {
[158]220            buf[index] = byte;
221            index++;
222        }
223    }
224    buf[index] = 0;
225    return 0;
226}
227////////////////////////////////////////////////////////////////////////////////////
[165]228// giet_tty_getw()
229////////////////////////////////////////////////////////////////////////////////////
[158]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////////////////////////////////////////////////////////////////////////////////////
[238]245unsigned int giet_tty_getw(unsigned int * val) 
246{
[158]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
[238]257    while (done == 0) 
258    {
259        do { ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0); } 
260        while (ret != 1);
[158]261
[238]262        if ((byte > 0x2F) && (byte < 0x3A))  /* decimal character */
263        {
[158]264            buf[max] = byte;
265            max++;
[165]266            giet_tty_putc(byte);
[158]267        }
[238]268        else if ((byte == 0x0A))   /* LF */
269        {
[158]270            done = 1;
271        }
[238]272        else if (byte == 0x7F)   /* DEL */
273        {
274            if (max > 0) 
275            {
276                max--;      /* cancel the character */
[165]277                giet_tty_putc(0x08);
278                giet_tty_putc(0x20);
279                giet_tty_putc(0x08);
[158]280            }
281        }
[238]282        if (max == 32)  /* decimal string overflow */
283        {
284            for (i = 0; i < max; i++) 
285            {
[228]286                /* cancel the string */
[165]287                giet_tty_putc(0x08);
288                giet_tty_putc(0x20);
289                giet_tty_putc(0x08);
[158]290            }
[165]291            giet_tty_putc(0x30);
[238]292            *val = 0;      /* return 0 value */
[158]293            return 0;
294        }
295    }
296
297    /* string conversion */
[238]298    for (i = 0; i < max; i++) 
299    {
[158]300        dec = dec * 10 + (buf[i] - 0x30);
[238]301        if (dec < save)  overflow = 1; 
[158]302        save = dec;
303    }
304
305    /* check overflow */
[238]306    if (overflow == 0) 
307    {
[158]308        *val = dec; /* return decimal value */
309    }
[238]310    else 
311    {
312        for (i = 0; i < max; i++) 
313        {
[228]314            /* cancel the string */
[165]315            giet_tty_putc(0x08);
316            giet_tty_putc(0x20);
317            giet_tty_putc(0x08);
[158]318        }
[165]319        giet_tty_putc(0x30);
[238]320        *val = 0;         /* return 0 value */
[158]321    }
322    return 0;
323}
324////////////////////////////////////////////////////////////////////////////////////
[165]325// giet_tty_printf()
326////////////////////////////////////////////////////////////////////////////////////
[158]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////////////////////////////////////////////////////////////////////////////////////
[238]338unsigned int giet_tty_printf(char * format, ...) 
339{
[158]340    va_list ap;
341    va_start(ap, format);
342    unsigned int ret;
343
344printf_text:
345
[238]346    while (*format) 
347    {
[158]348        unsigned int i;
[228]349        for (i = 0; format[i] && format[i] != '%'; i++);
[238]350        if (i) 
351        {
[228]352            ret = sys_call(SYSCALL_TTY_WRITE, (unsigned int) format, i, 0, 0);
[238]353            if (ret != i)  return 1; /* return error */ 
[158]354            format += i;
355        }
[238]356        if (*format == '%') 
357        {
[158]358            format++;
359            goto printf_arguments;
360        }
361    }
362
363    va_end(ap);
364    return 0;
365
366printf_arguments:
367
368    {
[228]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;
[158]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;
[228]385                    ret = sys_call(SYSCALL_TTY_WRITE, (unsigned int)"-", 1, 0, 0);
386                    if (ret != 1) {
[158]387                        return 1; /* return error */
[228]388                    }
[158]389                }
390            case ('u'):             /* decimal unsigned integer */
[228]391                for(i = 0; i < 10; i++) {
392                    buf[9 - i] = HexaTab[val % 10];
393                    if (!(val /= 10)) {
394                        break;
395                    }
[158]396                }
[228]397                len =  i + 1;
398                pbuf = &buf[9 - i];
[158]399                break;
400            case ('x'):             /* hexadecimal integer */
[228]401                ret = sys_call(SYSCALL_TTY_WRITE, (unsigned int) "0x", 2, 0, 0);
402                if (ret != 2) {
[158]403                    return 1; /* return error */
404                }
[228]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];
[158]413                break;
414            case ('s'):             /* string */
415                {
[228]416                    char * str = (char *) val;
417                    while (str[len]) {
418                        len++;
419                    }
420                    pbuf = (char *) val;
[158]421                }
422                break;
423            default:
424                goto printf_text;
425        }
426
[228]427        ret = sys_call(SYSCALL_TTY_WRITE, (unsigned int) pbuf, len, 0, 0);
428        if (ret != len) {
[158]429            return 1;
[228]430        }
[158]431        goto printf_text;
432    }
433}
434
[203]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//////////////////////////////////////////////////////////////////////////////////
[253]445unsigned int giet_timer_start() 
446{
[228]447    return sys_call(SYSCALL_TIMER_START, 0, 0, 0, 0);
[203]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//////////////////////////////////////////////////////////////////////////////////
[253]455unsigned int giet_timer_stop() 
456{
[228]457    return sys_call(SYSCALL_TIMER_STOP, 0, 0, 0, 0);
[203]458}
459
[228]460
[165]461/////  GCD (Greatest Common Divider) related system calls
[158]462
463#define GCD_OPA     0
464#define GCD_OPB     1
465#define GCD_START   2
466#define GCD_STATUS  3
467
468//////////////////////////////////////////////////////////////////////////////////
[165]469// giet_gcd_set_opa()
470//////////////////////////////////////////////////////////////////////////////////
[158]471// This function sets the operand A in the GCD coprocessor.
472// - Returns 0 if success, > 0 if error.
473//////////////////////////////////////////////////////////////////////////////////
[253]474unsigned int giet_gcd_set_opa(unsigned int val) 
475{
[228]476    return sys_call(SYSCALL_GCD_WRITE, GCD_OPA, val, 0, 0);
[158]477}
478//////////////////////////////////////////////////////////////////////////////////
[228]479//     giet_gcd_set_opb()
[165]480//////////////////////////////////////////////////////////////////////////////////
[158]481// This function sets operand B in the GCD coprocessor.
482// - Returns 0 if success, > 0 if error.
483//////////////////////////////////////////////////////////////////////////////////
[253]484unsigned int giet_gcd_set_opb(unsigned int val) 
485{
[228]486    return sys_call(SYSCALL_GCD_WRITE, GCD_OPB, val, 0, 0);
[158]487}
488//////////////////////////////////////////////////////////////////////////////////
[228]489//     giet_gcd_start()
[165]490//////////////////////////////////////////////////////////////////////////////////
[158]491// This function starts the computation in the GCD coprocessor.
492// - Returns 0 if success, > 0 if error.
493//////////////////////////////////////////////////////////////////////////////////
[253]494unsigned int giet_gcd_start() 
495{
[228]496    return sys_call(SYSCALL_GCD_WRITE, GCD_START, 0, 0, 0);
[158]497}
498//////////////////////////////////////////////////////////////////////////////////
[228]499//     giet_gcd_get_status()
[165]500//////////////////////////////////////////////////////////////////////////////////
[158]501// This function gets the status fromn the GCD coprocessor.
502// - The value is 0 when the coprocessor is idle (computation completed).
503//////////////////////////////////////////////////////////////////////////////////
[253]504unsigned int giet_gcd_get_status(unsigned int * val) 
505{
[228]506    return sys_call(SYSCALL_GCD_READ, GCD_STATUS, (unsigned int) val, 0, 0);
[158]507}
508//////////////////////////////////////////////////////////////////////////////////
[228]509//     giet_gcd_get_result()
[165]510//////////////////////////////////////////////////////////////////////////////////
[158]511// This function gets the result of the computation from the GCD coprocessor.
512//////////////////////////////////////////////////////////////////////////////////
[253]513unsigned int giet_gcd_get_result(unsigned int * val) 
514{
[228]515    return sys_call(SYSCALL_GCD_READ, GCD_OPA, (unsigned int) val, 0, 0);
[158]516}
517
[228]518
[158]519///// Block device related system calls  /////
520
521//////////////////////////////////////////////////////////////////////////////////
[228]522//     giet_ioc_write()
[165]523//////////////////////////////////////////////////////////////////////////////////
[158]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//////////////////////////////////////////////////////////////////////////////////
[253]530unsigned int giet_ioc_write( unsigned int lba, 
531                             void *       buffer, 
532                             unsigned int count) 
533{
[228]534    return sys_call(SYSCALL_IOC_WRITE, lba, (unsigned int) buffer, count, 0);
[158]535}
536//////////////////////////////////////////////////////////////////////////////////
[165]537// giet_ioc_read()
538//////////////////////////////////////////////////////////////////////////////////
[158]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//////////////////////////////////////////////////////////////////////////////////
[253]545unsigned int giet_ioc_read( unsigned int lba, 
546                            void *       buffer, 
547                            unsigned int count ) 
548{
[228]549    return sys_call(SYSCALL_IOC_READ, lba, (unsigned int) buffer, count, 0);
[158]550}
551//////////////////////////////////////////////////////////////////////////////////
[165]552// giet_ioc_completed()
553//////////////////////////////////////////////////////////////////////////////////
[158]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//////////////////////////////////////////////////////////////////////////////////
[253]557unsigned int giet_ioc_completed() 
558{
[228]559    return sys_call(SYSCALL_IOC_COMPLETED, 0, 0, 0, 0);
[158]560}
[237]561//////////////////////////////////////////////////////////////////////////////////
562// giet_ioc_block_size()
563//////////////////////////////////////////////////////////////////////////////////
564// This blocking function returns the block_size (in bytes) of the block device
565//////////////////////////////////////////////////////////////////////////////////
[253]566unsigned int giet_ioc_block_size() 
567{
[237]568    return sys_call(SYSCALL_IOC_BLOCK_SIZE, 0, 0, 0, 0);
569}
570
571
[158]572/////  Frame buffer device related system calls  /////
573
574//////////////////////////////////////////////////////////////////////////////////
[165]575// giet_fb_sync_write()
576//////////////////////////////////////////////////////////////////////////////////
[158]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//////////////////////////////////////////////////////////////////////////////////
[253]584unsigned int giet_fb_sync_write( unsigned int offset, 
585                                 void *       buffer, 
586                                 unsigned int length ) 
587{
[228]588    return sys_call(SYSCALL_FB_SYNC_WRITE, offset, (unsigned int) buffer, length, 0);
[158]589}
590//////////////////////////////////////////////////////////////////////////////////
[165]591// giet_fb_sync_read()
592//////////////////////////////////////////////////////////////////////////////////
[158]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//////////////////////////////////////////////////////////////////////////////////
[253]600unsigned int giet_fb_sync_read( unsigned int offset, 
601                                void *       buffer, 
602                                unsigned int length ) 
603{
[228]604    return sys_call(SYSCALL_FB_SYNC_READ, offset, (unsigned int) buffer, length, 0);
[158]605}
606//////////////////////////////////////////////////////////////////////////////////
[253]607// giet_fb_dma_write()
[165]608//////////////////////////////////////////////////////////////////////////////////
[158]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//////////////////////////////////////////////////////////////////////////////////
[253]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);
[158]623}
624//////////////////////////////////////////////////////////////////////////////////
[253]625// giet_fb_dma_read()
[165]626//////////////////////////////////////////////////////////////////////////////////
[158]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//////////////////////////////////////////////////////////////////////////////////
[253]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);
[158]641}
642//////////////////////////////////////////////////////////////////////////////////
[253]643// giet_fb_dma_completed()
[165]644//////////////////////////////////////////////////////////////////////////////////
[158]645// This blocking function returns when the transfer is completed.
646// - Returns 0 if success, > 0 if error.
647//////////////////////////////////////////////////////////////////////////////////
[253]648unsigned int giet_fb_dma_completed() 
649{
650    return sys_call(SYSCALL_FB_DMA_COMPLETED, 0, 0, 0, 0);
[158]651}
[253]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}
[158]690
[228]691
[253]692//////// NIC related system calls ////////
693
[218]694//////////////////////////////////////////////////////////////////////////////////
[253]695// giet_nic_cma_rx_init()
[218]696//////////////////////////////////////////////////////////////////////////////////
[253]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)
[218]703// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
704//////////////////////////////////////////////////////////////////////////////////
[253]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);
[218]710}
711//////////////////////////////////////////////////////////////////////////////////
[253]712// giet_nic_cma_tx_init()
[218]713//////////////////////////////////////////////////////////////////////////////////
[253]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)
[218]720// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
721//////////////////////////////////////////////////////////////////////////////////
[253]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);
[218]727}
728//////////////////////////////////////////////////////////////////////////////////
[253]729// giet_nic_cma_stop()
[218]730//////////////////////////////////////////////////////////////////////////////////
[253]731// This function desactivates the NIC channel and the two CMA channels
732// allocated to the calling task.
[218]733// - Returns 0 if success, > 0 if error.
734//////////////////////////////////////////////////////////////////////////////////
[253]735unsigned int giet_nic_cma_stop( )
736{
737    return sys_call(SYSCALL_NIC_CMA_STOP, 0, 0, 0, 0);
[218]738}
739
[228]740
[253]741///// Miscellaneous system calls /////
[158]742
743//////////////////////////////////////////////////////////////////////////////////
[165]744// giet_vobj_get_vbase()
[158]745//////////////////////////////////////////////////////////////////////////////////
[165]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//////////////////////////////////////////////////////////////////////////////////
[253]752unsigned int giet_vobj_get_vbase( char*         vspace_name, 
753                                  char*         vobj_name, 
754                                  unsigned int  vobj_type, 
755                                  unsigned int* vobj_vaddr ) 
756{
[160]757    return sys_call(SYSCALL_VOBJ_GET_VBASE, 
[228]758            (unsigned int) vspace_name,
759            (unsigned int) vobj_name,
760            (unsigned int) vobj_type,
761            (unsigned int) vobj_vaddr);
[158]762}
763////////////////////////////////////////////////////////////////////////////////////
[165]764// giet_proc_number()
765////////////////////////////////////////////////////////////////////////////////////
[158]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////////////////////////////////////////////////////////////////////////////////////
[253]770unsigned int giet_proc_number( unsigned int  cluster_id, 
771                               unsigned int* buffer ) 
772{
[228]773    return sys_call(SYSCALL_PROC_NUMBER, cluster_id, (unsigned int) buffer, 0, 0);
[158]774}
775//////////////////////////////////////////////////////////////////////////////////
[253]776// giet_exit()
[165]777//////////////////////////////////////////////////////////////////////////////////
[158]778// This function stops execution of the calling task with a TTY message,
[253]779// and the task is descheduled and becomes not runable.
780// It does not consume processor cycles anymore.
[158]781//////////////////////////////////////////////////////////////////////////////////
[253]782void giet_exit() 
783{
[228]784    sys_call(SYSCALL_EXIT, 0, 0, 0, 0);
[158]785}
786//////////////////////////////////////////////////////////////////////////////////
[228]787// giet_context_switch()
[158]788// The user task calling this function is descheduled and
789// the processor is allocated to another task.
790//////////////////////////////////////////////////////////////////////////////////
[253]791unsigned int giet_context_switch() 
792{
[228]793    return sys_call(SYSCALL_CTX_SWITCH, 0, 0, 0, 0);
[158]794}
[228]795//////////////////////////////////////////////////////////////////////////////////
[232]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)
[228]799//////////////////////////////////////////////////////////////////////////////////
[253]800unsigned int giet_proc_task_id() 
801{
802    return sys_call(SYSCALL_LOCAL_TASK_ID, 0, 0, 0, 0);
[228]803}
[232]804//////////////////////////////////////////////////////////////////////////////////
805// giet_heap_info()
806// This function returns the base address and size of the current task's heap
807//////////////////////////////////////////////////////////////////////////////////
[253]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);
[232]812}
813//////////////////////////////////////////////////////////////////////////////////
814// giet_global_task_id()
[253]815// This functions returns the global task id, which is unique in all the giet.
[232]816//////////////////////////////////////////////////////////////////////////////////
[253]817unsigned int giet_global_task_id() 
818{
[232]819    return sys_call(SYSCALL_GLOBAL_TASK_ID, 0, 0, 0, 0);
820}
[253]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}
[232]834
[253]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
[255]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
[228]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.