source: soft/giet_vm/giet_libs/stdio.c @ 262

Last change on this file since 262 was 260, checked in by devigne, 11 years ago

Add a new syscall : giet_fat_fstat, allowing to a user application to know the
size (in sectors) of an open file.

  • Property svn:executable set to *
File size: 32.1 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
16////////////////////////////////////////////////////////////////////////////////////
17//////////////////////  MIPS32 related system calls  ///////////////////////////////
18////////////////////////////////////////////////////////////////////////////////////
19
20////////////////////////////////////////////////////////////////////////////////////
21// giet_procid()
22////////////////////////////////////////////////////////////////////////////////////
23// This function returns the processor identifier.
24////////////////////////////////////////////////////////////////////////////////////
25int giet_procid() 
26{
27    return sys_call( SYSCALL_PROCID,
28                     0, 0, 0, 0 );
29}
30////////////////////////////////////////////////////////////////////////////////////
31// giet_proctime()
32////////////////////////////////////////////////////////////////////////////////////
33// This function returns the local processor time (clock cycles since boot)
34////////////////////////////////////////////////////////////////////////////////////
35int giet_proctime() 
36{
37    return sys_call( SYSCALL_PROCTIME, 
38                     0, 0, 0, 0 );
39}
40
41
42////////////////////////////////////////////////////////////////////////////////////
43/////////////////////  TTY device related system calls /////////////////////////////
44////////////////////////////////////////////////////////////////////////////////////
45
46////////////////////////////////////////////////////////////////////////////////////
47// giet_tty_putc()
48////////////////////////////////////////////////////////////////////////////////////
49// This function displays a single ascii character on a terminal.
50// The terminal index must be defined in the task context in the boot phase.
51// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
52// - Returns 1 if the character has been written, 0 otherwise.
53////////////////////////////////////////////////////////////////////////////////////
54int giet_tty_putc(char byte) 
55{
56    return sys_call(SYSCALL_TTY_WRITE, 
57                    (unsigned int)(&byte),
58                    1, 
59                    0xFFFFFFFF, 
60                    0);
61}
62////////////////////////////////////////////////////////////////////////////////////
63// giet_tty_puts()
64////////////////////////////////////////////////////////////////////////////////////
65// This function displays a string on a terminal.
66// The terminal index must be defined in the task context in the boot phase.
67// The string must be terminated by a NUL character.
68// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
69// - Returns the number of written characters.
70////////////////////////////////////////////////////////////////////////////////////
71int giet_tty_puts(char * buf) 
72{
73    unsigned int length = 0;
74    while (buf[length] != 0) { length++; }
75    return sys_call(SYSCALL_TTY_WRITE, 
76                   (unsigned int)buf, 
77                   length, 
78                   0xFFFFFFFF, 
79                   0);
80}
81////////////////////////////////////////////////////////////////////////////////////
82// giet_tty_putw()
83////////////////////////////////////////////////////////////////////////////////////
84// This function displays the value of a 32-bit word with decimal characters.
85// The terminal index must be defined in the task context in the boot phase.
86// It doesn't use the TTY_PUT_IRQ interrupt, and the associated kernel buffer.
87// Returns the number of written characters (should be equal to ten).
88////////////////////////////////////////////////////////////////////////////////////
89int giet_tty_putw(unsigned int val) 
90{
91    char buf[10];
92    unsigned int i;
93    for (i = 0; i < 10; i++) 
94    {
95        buf[9 - i] = (val % 10) + 0x30;
96        val = val / 10;
97    }
98    return sys_call(SYSCALL_TTY_WRITE, 
99                   (unsigned int)buf,
100                   10,
101                   0xFFFFFFFF,
102                   0);
103}
104////////////////////////////////////////////////////////////////////////////////////
105// giet_tty_getc()
106////////////////////////////////////////////////////////////////////////////////////
107// This blocking function fetches a single ascii character from a terminal.
108// The terminal index must be defined in the task context in the boot phase.
109// It uses the IRQ_GET interrupt, and the associated kernel buffer.
110// - Returns 0 when completed.
111////////////////////////////////////////////////////////////////////////////////////
112int giet_tty_getc(char * byte) 
113{
114    unsigned int ret = 0;
115    while (ret == 0) 
116    {
117        ret = sys_call(SYSCALL_TTY_READ, 
118                      (unsigned int)byte,  // buffer address
119                      1,                   // number of characters
120                      0xFFFFFFFF,          // channel index from task context
121                      0);
122    }
123    return 0;
124}
125////////////////////////////////////////////////////////////////////////////////////
126// giet_tty_gets()
127////////////////////////////////////////////////////////////////////////////////////
128// This blocking function fetches a string from a terminal to a fixed length buffer.
129// The terminal index must be defined in the task context in the boot phase.
130// It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
131// - Returns 0 when completed.
132// - Up to (bufsize - 1) characters (including the non printable characters)
133//   will be copied into buffer, and the string is always completed by a NUL
134//   character.
135// - The <LF> character is interpreted, and the function close the string with a
136//   NUL character if <LF> is read.
137// - The <DEL> character is interpreted, and the corresponding character(s) are
138//   removed from the target buffer.
139////////////////////////////////////////////////////////////////////////////////////
140int giet_tty_gets( char*        buf, 
141                   unsigned int bufsize) 
142{
143    unsigned int ret;
144    unsigned char byte;
145    unsigned int index = 0;
146
147    while (index < (bufsize - 1)) 
148    {
149        do 
150        { 
151            ret = sys_call(SYSCALL_TTY_READ, 
152                           (unsigned int)(&byte),
153                           1,
154                           0xFFFFFFFF,
155                           0);
156        } 
157        while (ret != 1);
158
159        if (byte == 0x0A)  /* LF */
160        {
161            break; 
162        }
163        else if ((byte == 0x7F) && (index > 0))  /* DEL */
164        {
165            index--; 
166        }
167        else 
168        {
169            buf[index] = byte;
170            index++;
171        }
172    }
173    buf[index] = 0;
174    return 0;
175}
176////////////////////////////////////////////////////////////////////////////////////
177// giet_tty_getw()
178////////////////////////////////////////////////////////////////////////////////////
179// This blocking function fetches a string of decimal characters (most
180// significant digit first) to build a 32-bit unsigned integer.
181// The terminal index must be defined in the task context in the boot phase.
182// It uses the TTY_GET_IRQ interrupt, anf the associated kernel buffer.
183// - Returns necessarily 0 when completed.
184//
185// - The non-blocking system function _tty_read_irq is called several times,
186//   and the decimal characters are written in a 32 characters buffer until a
187//   <LF> character is read.
188// - The <DEL> character is interpreted, and previous characters can be
189//   cancelled. All others characters are ignored.
190// - When the <LF> character is received, the string is converted to an
191//   unsigned int value. If the number of decimal digit is too large for the 32
192//   bits range, the zero value is returned.
193////////////////////////////////////////////////////////////////////////////////////
194int giet_tty_getw(unsigned int * val) 
195{
196    unsigned char buf[32];
197    unsigned char byte;
198    unsigned int save = 0;
199    unsigned int dec = 0;
200    unsigned int done = 0;
201    unsigned int overflow = 0;
202    unsigned int max = 0;
203    unsigned int i;
204    unsigned int ret;
205
206    while (done == 0) 
207    {
208        do 
209        { 
210            ret = sys_call(SYSCALL_TTY_READ,
211                           (unsigned int)(&byte),
212                           1,
213                           0xFFFFFFFF,
214                           0); 
215        } 
216        while (ret != 1);
217
218        if ((byte > 0x2F) && (byte < 0x3A))  /* decimal character */
219        {
220            buf[max] = byte;
221            max++;
222            giet_tty_putc(byte);
223        }
224        else if ((byte == 0x0A))   /* LF */
225        {
226            done = 1;
227        }
228        else if (byte == 0x7F)   /* DEL */
229        {
230            if (max > 0) 
231            {
232                max--;      /* cancel the character */
233                giet_tty_putc(0x08);
234                giet_tty_putc(0x20);
235                giet_tty_putc(0x08);
236            }
237        }
238        if (max == 32)  /* decimal string overflow */
239        {
240            for (i = 0; i < max; i++) 
241            {
242                /* cancel the string */
243                giet_tty_putc(0x08);
244                giet_tty_putc(0x20);
245                giet_tty_putc(0x08);
246            }
247            giet_tty_putc(0x30);
248            *val = 0;      /* return 0 value */
249            return 0;
250        }
251    }
252
253    /* string conversion */
254    for (i = 0; i < max; i++) 
255    {
256        dec = dec * 10 + (buf[i] - 0x30);
257        if (dec < save)  overflow = 1; 
258        save = dec;
259    }
260
261    /* check overflow */
262    if (overflow == 0) 
263    {
264        *val = dec; /* return decimal value */
265    }
266    else 
267    {
268        for (i = 0; i < max; i++) 
269        {
270            /* cancel the string */
271            giet_tty_putc(0x08);
272            giet_tty_putc(0x20);
273            giet_tty_putc(0x08);
274        }
275        giet_tty_putc(0x30);
276        *val = 0;         /* return 0 value */
277    }
278    return 0;
279}
280////////////////////////////////////////////////////////////////////////////////////
281// giet_tty_printf()
282////////////////////////////////////////////////////////////////////////////////////
283// This function is a simplified version of the mutek_printf() function.
284// The terminal index must be defined in the calling task context.
285// It doesn't use the IRQ_PUT interrupt, and the associated kernel buffer.
286// Only a limited number of formats are supported:
287//   - %d : signed decimal
288//   - %u : unsigned decimal
289//   - %x : hexadecimal
290//   - %c : char
291//   - %s : string
292// - Returns 0 if success, > 0 if error.
293////////////////////////////////////////////////////////////////////////////////////
294int giet_tty_printf(char * format, ...) 
295{
296    va_list ap;
297    va_start(ap, format);
298    unsigned int ret;
299
300printf_text:
301
302    while (*format) 
303    {
304        unsigned int i;
305        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
306        if (i) 
307        {
308            ret = sys_call(SYSCALL_TTY_WRITE, 
309                           (unsigned int)format,
310                           i, 
311                           0xFFFFFFFF,
312                           0);
313            if (ret != i)  return 1;     /* return error */ 
314            format += i;
315        }
316        if (*format == '%') 
317        {
318            format++;
319            goto printf_arguments;
320        }
321    }
322
323    va_end(ap);
324    return 0;
325
326printf_arguments:
327
328    {
329        int val = va_arg(ap, long);
330        char buf[20];
331        char * pbuf;
332        unsigned int len = 0;
333        static const char HexaTab[] = "0123456789ABCDEF";
334        unsigned int i;
335
336        switch (*format++) {
337            case ('c'):             /* char conversion */
338                len = 1;
339                buf[0] = val;
340                pbuf = buf;
341                break;
342            case ('d'):             /* decimal signed integer */
343                if (val < 0) 
344                {
345                    val = -val;
346                    ret = sys_call(SYSCALL_TTY_WRITE, 
347                                   (unsigned int)"-",
348                                   1,
349                                   0xFFFFFFFF,
350                                   0);
351                    if (ret != 1)  return 1;     /* return error */
352                }
353            case ('u'):             /* decimal unsigned integer */
354                for(i = 0; i < 10; i++) 
355                {
356                    buf[9 - i] = HexaTab[val % 10];
357                    if (!(val /= 10)) break;
358                }
359                len =  i + 1;
360                pbuf = &buf[9 - i];
361                break;
362            case ('x'):             /* hexadecimal integer */
363                ret = sys_call(SYSCALL_TTY_WRITE,
364                               (unsigned int)"0x",
365                               2,
366                               0xFFFFFFFF,
367                               0);
368                if (ret != 2) return 1;       /* return error */
369                for(i = 0; i < 8; i++) 
370                {
371                    buf[7 - i] = HexaTab[val % 16U];
372                    if (!(val /= 16U))  break;
373                }
374                len =  i + 1;
375                pbuf = &buf[7 - i];
376                break;
377            case ('s'):             /* string */
378                {
379                    char * str = (char *) val;
380                    while (str[len]) 
381                    {
382                        len++;
383                    }
384                    pbuf = (char *) val;
385                }
386                break;
387            default:
388                goto printf_text;
389        }
390
391        ret = sys_call(SYSCALL_TTY_WRITE, 
392                       (unsigned int)pbuf,
393                       len,
394                       0xFFFFFFFF,
395                       0);
396        if (ret != len)  return 1;
397        goto printf_text;
398    }
399}
400
401
402
403//////////////////////////////////////////////////////////////////////////////////
404/////////////////////  TIMER related system calls ////////////////////////////////
405//////////////////////////////////////////////////////////////////////////////////
406
407//////////////////////////////////////////////////////////////////////////////////
408// giet_timer_start()
409//////////////////////////////////////////////////////////////////////////////////
410// This function activates the private user timer allocated to the calling task
411// in the boot phase.
412// - Returns 0 if success, > 0 if error.
413//////////////////////////////////////////////////////////////////////////////////
414int giet_timer_start() 
415{
416    return sys_call( SYSCALL_TIMER_START, 
417                     0, 0, 0, 0 );
418}
419//////////////////////////////////////////////////////////////////////////////////
420// giet_timer_stop()
421//////////////////////////////////////////////////////////////////////////////////
422// This function activates the user timer allocated to the calling task.
423// - Returns 0 if success, > 0 if error.
424//////////////////////////////////////////////////////////////////////////////////
425int giet_timer_stop() 
426{
427    return sys_call( SYSCALL_TIMER_STOP, 
428                     0, 0, 0, 0 );
429}
430
431
432//////////////////////////////////////////////////////////////////////////////////
433///////////////  Frame buffer device related system calls  ///////////////////////
434//////////////////////////////////////////////////////////////////////////////////
435
436//////////////////////////////////////////////////////////////////////////////////
437// giet_fb_sync_write()
438//////////////////////////////////////////////////////////////////////////////////
439// This blocking function use a memory copy strategy to transfer data from a
440// user buffer to the frame buffer device in kernel space.
441//     offset : offset (in bytes) in the frame buffer
442//     buffer : base address of the memory buffer
443//     length : number of bytes to be transfered
444// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
445//////////////////////////////////////////////////////////////////////////////////
446int giet_fb_sync_write( unsigned int offset, 
447                        void *       buffer, 
448                        unsigned int length ) 
449{
450    return sys_call( SYSCALL_FB_SYNC_WRITE, 
451                     offset, 
452                     (unsigned int)buffer, 
453                     length, 
454                     0 );
455}
456//////////////////////////////////////////////////////////////////////////////////
457// giet_fb_sync_read()
458//////////////////////////////////////////////////////////////////////////////////
459// This blocking function use a memory copy strategy to transfer data from the
460// frame buffer device in kernel space to an user buffer.
461//     offset : offset (in bytes) in the frame buffer
462//     buffer : base address of the user buffer
463//     length : number of bytes to be transfered
464// - Returns 0 if success, > 0 if error (e.g. memory buffer not in user space).
465//////////////////////////////////////////////////////////////////////////////////
466int giet_fb_sync_read( unsigned int offset, 
467                       void *       buffer, 
468                       unsigned int length ) 
469{
470    return sys_call( SYSCALL_FB_SYNC_READ, 
471                     offset, 
472                     (unsigned int)buffer, 
473                     length, 
474                     0 );
475}
476//////////////////////////////////////////////////////////////////////////////////
477// giet_fb_cma_init()
478//////////////////////////////////////////////////////////////////////////////////
479// This function initializes the two chbuf SRC an DST used by the CMA controller
480// and activates the CMA channel allocated to the calling task.
481// - buf0   : first user buffer virtual address
482// - buf0   : second user buffer virtual address
483// - length : buffer size (bytes)
484// - Returns 0 if success, > 0 if error.
485//////////////////////////////////////////////////////////////////////////////////
486int giet_fb_cma_init( void *       buf0,
487                      void *       buf1,
488                      unsigned int length )
489{
490    return sys_call( SYSCALL_FB_CMA_INIT, 
491                     (unsigned int)buf0, 
492                     (unsigned int)buf1, 
493                     length, 
494                     0 );
495}
496//////////////////////////////////////////////////////////////////////////////////
497// giet_fb_cma_write()
498//////////////////////////////////////////////////////////////////////////////////
499// This function set the valid status for one of the SRC user buffer.
500// and reset the valid status for the DST frame buffer.
501// - bufffer_id : 0 => buf0 valid is set / not 0  => buf1 valid is set
502// - Returns 0 if success, > 0 if error.
503//////////////////////////////////////////////////////////////////////////////////
504int giet_fb_cma_write( unsigned int buffer_id )
505{
506    return sys_call( SYSCALL_FB_CMA_WRITE, 
507                     buffer_id, 
508                     0, 0, 0 );
509}
510//////////////////////////////////////////////////////////////////////////////////
511// giet_fb_cma_stop()
512//////////////////////////////////////////////////////////////////////////////////
513// This function desactivates the CMA channel allocated to the calling task.
514// - Returns 0 if success, > 0 if error.
515//////////////////////////////////////////////////////////////////////////////////
516int giet_fb_cma_stop( )
517{
518    return sys_call( SYSCALL_FB_CMA_STOP, 
519                     0, 0, 0, 0 );
520}
521
522
523//////////////////////////////////////////////////////////////////////////////////
524/////////////////////// NIC related system calls /////////////////////////////////
525//////////////////////////////////////////////////////////////////////////////////
526
527//////////////////////////////////////////////////////////////////////////////////
528// giet_nic_cma_init()
529//////////////////////////////////////////////////////////////////////////////////
530// This function initializes the memory chbuf used by the CMA controller,
531// activates the NIC channel allocated to the calling task, and the CMA channel.
532// - tx     : RX channel if 0 / TX channel if non 0
533// - buf0   : first user buffer virtual address
534// - buf1   : second user buffer virtual address
535// - length : buffer size (bytes)
536// - Returns 0 if success, > 0 if error
537//////////////////////////////////////////////////////////////////////////////////
538int giet_nic_cma_start()
539{
540    return sys_call( SYSCALL_NIC_CMA_START,
541                     0, 0, 0, 0 );
542}
543//////////////////////////////////////////////////////////////////////////////////
544// giet_nic_cma_stop()
545//////////////////////////////////////////////////////////////////////////////////
546// This function desactivates the NIC channel and the two CMA channels
547// allocated to the calling task.
548// - Returns 0 if success, > 0 if error.
549//////////////////////////////////////////////////////////////////////////////////
550int giet_nic_cma_stop( )
551{
552    return sys_call( SYSCALL_NIC_CMA_STOP,
553                     0, 0, 0, 0 );
554}
555
556
557//////////////////////////////////////////////////////////////////////////////////
558///////////////////// Miscellaneous system calls /////////////////////////////////
559//////////////////////////////////////////////////////////////////////////////////
560
561///////////////////////////////////////////////////////////////////////////////////
562// giet_assert()
563///////////////////////////////////////////////////////////////////////////////////
564// This function uses the giet_tty_puts() and giet_exit() system calls.
565///////////////////////////////////////////////////////////////////////////////////
566void giet_assert( unsigned int condition,
567                  char*        string )
568{
569    if ( condition == 0 )
570    {
571        giet_tty_puts( string );
572        giet_exit();
573    }
574}
575//////////////////////////////////////////////////////////////////////////////////
576// giet_vobj_get_vbase()
577//////////////////////////////////////////////////////////////////////////////////
578// This function writes in argument (vobj_vaddr) the virtual base address
579// of a vobj (defined in the mapping_info data structure), identified by
580// the two arguments (vspace_name and vobj_name).
581// The (vobj_type) argument is redundant, and used for coherence checking.
582// - Returns the address if success,  0 if error ( not defined or wrong type )
583//////////////////////////////////////////////////////////////////////////////////
584int giet_vobj_get_vbase( char*         vspace_name, 
585                         char*         vobj_name, 
586                         unsigned int  vobj_type, 
587                         unsigned int* vobj_vaddr ) 
588{
589    return sys_call( SYSCALL_VOBJ_GET_VBASE, 
590                     (unsigned int) vspace_name,
591                     (unsigned int) vobj_name,
592                     (unsigned int) vobj_type,
593                     (unsigned int) vobj_vaddr );
594}
595////////////////////////////////////////////////////////////////////////////////////
596// giet_proc_number()
597////////////////////////////////////////////////////////////////////////////////////
598// This function returns in the buffer argument the number of processors
599// in the cluster specified by the cluster_id argument.
600// - Returns 0 if success, > 0 if error ( cluster index too large )
601////////////////////////////////////////////////////////////////////////////////////
602int giet_proc_number( unsigned int  cluster_id, 
603                      unsigned int* buffer ) 
604{
605    return sys_call(SYSCALL_PROC_NUMBER, cluster_id, (unsigned int) buffer, 0, 0);
606}
607//////////////////////////////////////////////////////////////////////////////////
608// giet_exit()
609//////////////////////////////////////////////////////////////////////////////////
610// This function stops execution of the calling task with a TTY message,
611// the user task is descheduled and becomes not runable.
612// It does not consume processor cycles anymore.
613//////////////////////////////////////////////////////////////////////////////////
614void giet_exit() 
615{
616    sys_call( SYSCALL_EXIT,
617              0, 0, 0, 0 );
618}
619//////////////////////////////////////////////////////////////////////////////////
620// giet_context_switch()
621//////////////////////////////////////////////////////////////////////////////////
622// The user task calling this function is descheduled and
623// the processor is allocated to another task.
624//////////////////////////////////////////////////////////////////////////////////
625int giet_context_switch() 
626{
627    return sys_call( SYSCALL_CTX_SWITCH,
628                     0, 0, 0, 0 );
629}
630//////////////////////////////////////////////////////////////////////////////////
631// giet_proc_task_id()
632//////////////////////////////////////////////////////////////////////////////////
633// This functions returns the local task id.
634// If processor has n tasks the local task index is ranging from 0 to n-1
635//////////////////////////////////////////////////////////////////////////////////
636int giet_proc_task_id() 
637{
638    return sys_call( SYSCALL_LOCAL_TASK_ID, 
639                     0, 0, 0, 0 );
640}
641//////////////////////////////////////////////////////////////////////////////////
642// giet_heap_info()
643//////////////////////////////////////////////////////////////////////////////////
644// This function returns the base address and size of the current task's heap
645//////////////////////////////////////////////////////////////////////////////////
646int giet_heap_info( unsigned int* vaddr, 
647                             unsigned int* length ) 
648{
649    return sys_call( SYSCALL_HEAP_INFO, 
650                     (unsigned int)vaddr, 
651                     (unsigned int)length, 
652                     0, 0 );
653}
654//////////////////////////////////////////////////////////////////////////////////
655// giet_global_task_id()
656//////////////////////////////////////////////////////////////////////////////////
657// This functions returns the global task id, which is unique in all the giet.
658//////////////////////////////////////////////////////////////////////////////////
659int giet_global_task_id() 
660{
661    return sys_call( SYSCALL_GLOBAL_TASK_ID, 
662                     0, 0, 0, 0 );
663}
664
665///////////////////////////////////////////////////////////////////////////////////
666///////////////////// FAT related system calls ////////////////////////////////////
667///////////////////////////////////////////////////////////////////////////////////
668
669///////////////////////////////////////////////////////////////////////////////////
670// giet_fat_open()
671///////////////////////////////////////////////////////////////////////////////////
672// Open a file identified by a pathname, and contained in the system FAT.
673// The read/write flags are not supported yet: no effect.
674///////////////////////////////////////////////////////////////////////////////////
675int giet_fat_open( const char*   pathname, 
676                   unsigned int  flags )
677{
678    return sys_call( SYSCALL_FAT_OPEN, 
679                     (unsigned int)pathname, 
680                     flags,
681                     0, 0 );
682}
683///////////////////////////////////////////////////////////////////////////////////
684// giet_fat_read()
685///////////////////////////////////////////////////////////////////////////////////
686// Read "count" sectors from a file identified by "fd", skipping "offset"
687// sectors in file, and writing into the user "buffer".
688// The user buffer base address shoulb be 64 bytes aligned.
689///////////////////////////////////////////////////////////////////////////////////
690// This system call specification should evolve to the UNIX specification:
691// - count must be a number of bytes, with no alignment constraint on user buffer.
692// - offset argument should be removed and replaced by an implicit "lseek" pointer
693//   stored in the file descriptor.
694// This suppose to implement a sectors cache
695///////////////////////////////////////////////////////////////////////////////////
696int giet_fat_read( unsigned int fd, 
697                   void*        buffer, 
698                   unsigned int count,
699                   unsigned int offset )
700{
701    return sys_call( SYSCALL_FAT_READ,
702                     fd, 
703                     (unsigned int)buffer,
704                     count, 
705                     offset );
706}
707///////////////////////////////////////////////////////////////////////////////////
708// giet_fat_write()
709///////////////////////////////////////////////////////////////////////////////////
710// Write "count" sectors from a file identified by "fd", skipping "offset"
711// sectors in file, and reading from the user "buffer".
712// The user buffer base address shoulb be 64 bytes aligned.
713///////////////////////////////////////////////////////////////////////////////////
714// This system call specification should evolve to the UNIX specification:
715// - count must be a number of bytes, with no alignment constraint on buffer
716// - offset argument should be removed and replaced by an implicit "lseek" pointer
717//   stored in the file descriptor.
718// This suppose to implement a sectors cache
719///////////////////////////////////////////////////////////////////////////////////
720int giet_fat_write( unsigned int fd,
721                    void*        buffer, 
722                    unsigned int count,
723                    unsigned int offset )
724{
725    return sys_call( SYSCALL_FAT_WRITE, 
726                     fd, 
727                     (unsigned int)buffer,
728                     count, 
729                     offset );
730}
731///////////////////////////////////////////////////////////////////////////////////
732// giet_fat_lseek()
733///////////////////////////////////////////////////////////////////////////////////
734// Change the lseek file pointer value for a file identified by "fd".
735///////////////////////////////////////////////////////////////////////////////////
736int giet_fat_lseek( unsigned int fd, 
737                    unsigned int offset, 
738                    unsigned int whence)
739{
740    return sys_call( SYSCALL_FAT_LSEEK, 
741                     fd, 
742                     offset, 
743                     whence, 
744                     0 );
745}
746
747///////////////////////////////////////////////////////////////////////////////////
748// giet_fat_fstat()
749///////////////////////////////////////////////////////////////////////////////////
750// Return stats of a file identified by "fd".
751// (Only the file_size in sectors for this moment)
752///////////////////////////////////////////////////////////////////////////////////
753int giet_fat_fstat( unsigned int fd )
754{
755    return sys_call( SYSCALL_FAT_FSTAT,
756                     fd,
757                     0, 0, 0 );
758}
759
760///////////////////////////////////////////////////////////////////////////////////
761// giet_fat_close()
762///////////////////////////////////////////////////////////////////////////////////
763// Close a file identified by "fd".
764///////////////////////////////////////////////////////////////////////////////////
765int giet_fat_close( unsigned int fd )
766{
767    return sys_call( SYSCALL_FAT_CLOSE,
768                     fd,
769                     0, 0, 0 );
770}
771
772
773///////////////////////////////////////////////////////////////////////////////////
774////////////////// Pseudo system calls (no syscall instruction) ///////////////////
775///////////////////////////////////////////////////////////////////////////////////
776
777///////////////////////////////////////////////////////////////////////////////////
778// giet_rand()
779// This function returns a pseudo-random value derived from the processor cycle
780// count. This value is comprised between 0 & 65535.
781///////////////////////////////////////////////////////////////////////////////////
782int giet_rand() 
783{
784    unsigned int x = sys_call(SYSCALL_PROCTIME, 0, 0, 0, 0);
785    if ((x & 0xF) > 7) {
786        return (x*x & 0xFFFF);
787    }
788    else {
789        return (x*x*x & 0xFFFF);
790    }
791}
792///////////////////////////////////////////////////////////////////////////////////
793// memcpy()
794///////////////////////////////////////////////////////////////////////////////////
795inline void* memcpy( void*        dest, 
796                     const void*  source,
797                     unsigned int size ) 
798{
799    unsigned int*       dst = dest;
800    const unsigned int* src = source;
801
802    // word-by-word copy
803    if (!((unsigned int) dst & 3) && !((unsigned int) src & 3)) 
804    {
805        while (size > 3) 
806        {
807            *dst++ = *src++;
808            size -= 4;
809        }
810    }
811
812    unsigned char * cdst = (unsigned char *) dst;
813    unsigned char * csrc = (unsigned char *) src;
814
815    /* byte-by-byte copy */
816    while (size--) 
817    {
818        *cdst++ = *csrc++;
819    }
820    return dest;
821}
822
823// Local Variables:
824// tab-width: 4
825// c-basic-offset: 4
826// c-file-offsets:((innamespace . 0)(inline-open . 0))
827// indent-tabs-mode: nil
828// End:
829// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
830
Note: See TracBrowser for help on using the repository browser.