OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [redboot/] [current/] [src/] [fs/] [fileio.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      fileio.c
4
//
5
//      RedBoot fileio support
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    nickg
43
// Contributors: dwmw2, msalter
44
// Date:         2004-11-21
45
// Purpose:      
46
// Description:  
47
//              
48
// This code is part of RedBoot (tm).
49
//
50
//####DESCRIPTIONEND####
51
//
52
//==========================================================================
53
 
54
// Shoot me. But I don't want struct timeval because redboot provides it.
55
#define _POSIX_SOURCE
56
#include <time.h>
57
#undef _POSIX_SOURCE
58
 
59
#include <redboot.h>
60
#include <errno.h>
61
#include <stdio.h>
62
#include <fcntl.h>
63
#include <unistd.h>
64
#include <string.h>
65
#ifdef CYGPKG_IO_FLASH
66
#include <pkgconf/io_flash.h>
67
#include <cyg/io/io.h>
68
#include <cyg/io/flash.h>
69
#include <cyg/io/config_keys.h>
70
#endif
71
#include <cyg/io/devtab.h>
72
#include <cyg/fileio/fileio.h>
73
#include <cyg/infra/cyg_ass.h>         // assertion macros
74
 
75
//==========================================================================
76
 
77
// Define table boundaries
78
CYG_HAL_TABLE_BEGIN( __FS_cmds_TAB__, FS_cmds);
79
CYG_HAL_TABLE_END( __FS_cmds_TAB_END__, FS_cmds);
80
 
81
extern struct cmd __FS_cmds_TAB__[], __FS_cmds_TAB_END__;
82
 
83
//==========================================================================
84
 
85
static void
86
fs_usage(char *why)
87
{
88
    diag_printf("*** invalid 'fs' command: %s\n", why);
89
    cmd_usage(__FS_cmds_TAB__, &__FS_cmds_TAB_END__, "fs ");
90
}
91
 
92
 
93
//==========================================================================
94
 
95
#define MAX_MOUNTS      4
96
 
97
static int mount_count = 0;
98
 
99
static struct
100
{
101
    char dev_str[PATH_MAX];
102
    char mp_str[PATH_MAX];
103
    char type_str[PATH_MAX];
104
} mounts[MAX_MOUNTS];
105
 
106
//==========================================================================
107
 
108
static void do_mount(int argc, char *argv[]);
109
static void do_umount(int argc, char *argv[]);
110
 
111
/* Temporary hack until flashv2 merged to trunk. We can't tell whether we're
112
 * working with flash v1 or v2 from the package version. So if legacy device isn't
113
 * defined we check whether, if there is a block device, there's a tell-tale define
114
 * that only exists with the v1 version.
115
 */
116
#if !defined(CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY) && \
117
     defined(CYGPKG_IO_FLASH_BLOCK_DEVICE) && \
118
     defined(CYGINT_IO_FLASH_BLOCK_CFG_1)
119
# define CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY 1
120
#endif
121
 
122
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY
123
#define FLASHPART "[-f <partition>] "
124
#else
125
#define FLASHPART
126
#endif
127
 
128
local_cmd_entry("mount",
129
                "Mount file system",
130
                FLASHPART "[-d <device>] -t <fstype> [<mountpoint>]",
131
                do_mount,
132
                FS_cmds
133
    );
134
local_cmd_entry("umount",
135
                "Unmount file system",
136
                "<mountpoint>",
137
                do_umount,
138
                FS_cmds
139
    );
140
 
141
//==========================================================================
142
 
143
// Mount disk/filesystem
144
static void
145
do_mount(int argc, char *argv[])
146
{
147
    char *dev_str = "<undefined>", *type_str, *mp_str;
148
    bool dev_set = false, type_set = false;
149
    struct option_info opts[3];
150
    int err, num_opts = 2;
151
    int i,m=0; /* Set to 0 to silence warning */
152
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY
153
    char *part_str;
154
    bool part_set = false;
155
#endif
156
 
157
    init_opts(&opts[0], 'd', true, OPTION_ARG_TYPE_STR,
158
              (void *)&dev_str, &dev_set, "device");
159
    init_opts(&opts[1], 't', true, OPTION_ARG_TYPE_STR,
160
              (void *)&type_str, &type_set, "fstype");
161
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY
162
    init_opts(&opts[2], 'f', true, OPTION_ARG_TYPE_STR,
163
              (void *)&part_str, &part_set, "partition");
164
    num_opts++;
165
#endif
166
 
167
    CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options");
168
 
169
    if (!scan_opts(argc, argv, 1, opts, num_opts, &mp_str, OPTION_ARG_TYPE_STR, "mountpoint"))
170
        return;
171
 
172
    if (!type_set) {
173
        err_printf("fs mount: Must specify file system type\n");
174
        return;
175
    }
176
 
177
    if( mp_str == 0 )
178
        mp_str = "/";
179
 
180
    if( mount_count >= MAX_MOUNTS )
181
    {
182
        err_printf("fs mount: Maximum number of mounts exceeded\n");
183
        return;
184
    }
185
 
186
#ifdef CYGPKG_IO_FLASH_BLOCK_DEVICE_LEGACY
187
    if (part_set) {
188
        cyg_uint32 len;
189
        cyg_io_handle_t h;
190
 
191
        if (dev_set && strcmp(dev_str, CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1)) {
192
            err_printf("fs mount: May only set one of <device> or <partition>\n");
193
            return;
194
        }
195
 
196
        dev_str = CYGDAT_IO_FLASH_BLOCK_DEVICE_NAME_1;
197
        len = (cyg_uint32)strlen(part_str);
198
 
199
        err = cyg_io_lookup(dev_str, &h);
200
        if (err < 0) {
201
            err_printf("fs mount: cyg_io_lookup of \"%s\" returned %d\n", dev_str, err);
202
            return;
203
        }
204
        err = cyg_io_set_config(h, CYG_IO_SET_CONFIG_FLASH_FIS_NAME,
205
                                part_str, &len);
206
        if (err < 0) {
207
            diag_printf("fs mount: FIS partition \"%s\" not found\n",
208
                        part_str);
209
            return;
210
        }
211
    }
212
#endif
213
 
214
    for( i = 0; i < MAX_MOUNTS; i++ )
215
    {
216
        if( mounts[i].mp_str[0] != '\0' )
217
        {
218
            if( strcmp(mounts[i].dev_str, dev_str ) == 0 )
219
            {
220
                err_printf("fs mount: Device %s already mounted\n",dev_str);
221
                return;
222
            }
223
        }
224
        else
225
            m = i;
226
    }
227
 
228
    strcpy( mounts[m].mp_str, mp_str );
229
    strcpy( mounts[m].dev_str, dev_str );
230
    strcpy( mounts[m].type_str, type_str );
231
 
232
    err = mount(mounts[m].dev_str, mounts[m].mp_str, mounts[m].type_str);
233
 
234
    if (err)
235
    {
236
        err_printf("fs mount: mount(%s,%s,%s) failed %d\n", dev_str, mp_str, type_str, errno);
237
        mounts[m].mp_str[0] = '\0'; // mount failed so don't let it appear mounted
238
    }
239
    else
240
    {
241
        if( mount_count == 0 )
242
            chdir( "/" );
243
        mount_count++;
244
    }
245
}
246
 
247
//==========================================================================
248
 
249
static void
250
do_umount(int argc, char *argv[])
251
{
252
    char *dir_str;
253
    int err;
254
    int i;
255
 
256
     if( mount_count == 0 )
257
     {
258
         err_printf("fs: No filesystems mounted\n");
259
         return;
260
     }
261
 
262
    if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "mountpoint"))
263
        return;
264
 
265
    if( dir_str == 0 )
266
        dir_str = "/";
267
 
268
    for( i = 0; i < MAX_MOUNTS; i++ )
269
    {
270
        if( strcmp(mounts[i].mp_str, dir_str ) == 0 )
271
            break;
272
    }
273
 
274
    if( i == MAX_MOUNTS )
275
    {
276
        err_printf("fs unmount: unknown mountpoint %s\n",dir_str);
277
        return;
278
    }
279
 
280
    err = umount (dir_str);
281
 
282
    if (err)
283
        err_printf("fs umount: unmount failed %d\n", errno);
284
    else
285
    {
286
        mounts[i].mp_str[0] = '\0';
287
        mount_count--;
288
        if( mount_count == 0 )
289
            chdir( "/" );
290
    }
291
 
292
}
293
 
294
//==========================================================================
295
 
296
#include <dirent.h>
297
 
298
static char rwx[8][4] = { "---", "r--", "-w-", "rw-", "--x", "r-x", "-wx", "rwx" };
299
 
300
static void
301
do_list(int argc, char * argv[])
302
{
303
     char * dir_str;
304
     DIR *dirp;
305
     char filename[PATH_MAX];
306
     char cwd[PATH_MAX];
307
     struct stat sbuf;
308
     int err;
309
 
310
     if( mount_count == 0 )
311
     {
312
         err_printf("fs: No filesystems mounted\n");
313
         return;
314
     }
315
 
316
     if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory"))
317
          return;
318
 
319
     if( dir_str == 0 )
320
     {
321
         dir_str = getcwd(cwd, sizeof(cwd));
322
     }
323
 
324
     dirp = opendir(dir_str);
325
     if (dirp==NULL) {
326
          err_printf("fs list: no such directory %s\n",dir_str);
327
          return;
328
     }
329
 
330
     for (;;) {
331
          struct dirent *entry = readdir(dirp);
332
 
333
          if( entry == NULL )
334
               break;
335
 
336
          strcpy(filename, dir_str);
337
          strcat(filename, "/");
338
          strcat(filename, entry->d_name);
339
 
340
          err = stat(filename, &sbuf);
341
          if (err < 0) {
342
               diag_printf("Unable to stat file %s\n", filename);
343
               continue;
344
          }
345
          diag_printf("%4d ", sbuf.st_ino);
346
          if (S_ISDIR(sbuf.st_mode)) diag_printf("d");
347
          if (S_ISCHR(sbuf.st_mode)) diag_printf("c");
348
          if (S_ISBLK(sbuf.st_mode)) diag_printf("b");
349
          if (S_ISREG(sbuf.st_mode)) diag_printf("-");
350
          if (S_ISLNK(sbuf.st_mode)) diag_printf("l");
351
          diag_printf("%s%s%s",    // Ho, humm, have to hard code the shifts
352
                      rwx[(sbuf.st_mode & S_IRWXU) >> 16],
353
                      rwx[(sbuf.st_mode & S_IRWXG) >> 19],
354
                      rwx[(sbuf.st_mode & S_IRWXO) >> 22]);
355
          diag_printf(" %2d size %6d %s\n",
356
                      sbuf.st_nlink,(int)sbuf.st_size,
357
                      entry->d_name);
358
     }
359
 
360
     closedir(dirp);
361
     return;
362
}
363
 
364
local_cmd_entry("list",
365
                "list directory contents",
366
                "[<directory>]",
367
                do_list,
368
                FS_cmds
369
    );
370
 
371
 
372
//==========================================================================
373
 
374
 
375
static void
376
do_mkdir(int argc, char * argv[])
377
{
378
    char *dir_str;
379
    int err;
380
 
381
     if( mount_count == 0 )
382
     {
383
         err_printf("fs: No filesystems mounted\n");
384
         return;
385
     }
386
 
387
    if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory") ||
388
        dir_str == NULL)
389
    {
390
        fs_usage("invalid arguments");
391
        return;
392
    }
393
 
394
    err = mkdir( dir_str, 0 );
395
 
396
    if( err != 0 )
397
        err_printf("fs mkdir: failed to create directory %s\n",dir_str);
398
}
399
 
400
local_cmd_entry("mkdir",
401
                "create directory",
402
                "<directory>",
403
                do_mkdir,
404
                FS_cmds
405
    );
406
 
407
//==========================================================================
408
 
409
static void
410
do_deldir(int argc, char * argv[])
411
{
412
    char *dir_str;
413
    int err;
414
 
415
     if( mount_count == 0 )
416
     {
417
         err_printf("fs: No filesystems mounted\n");
418
         return;
419
     }
420
 
421
    if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory") ||
422
        dir_str == NULL)
423
    {
424
        fs_usage("invalid arguments");
425
        return;
426
    }
427
 
428
    err = rmdir( dir_str );
429
 
430
    if( err != 0 )
431
        err_printf("fs deldir: failed to remove directory %s\n",dir_str);
432
}
433
 
434
local_cmd_entry("deldir",
435
                "delete directory",
436
                "<directory>",
437
                do_deldir,
438
                FS_cmds
439
    );
440
 
441
//==========================================================================
442
 
443
static void
444
do_del(int argc, char * argv[])
445
{
446
    char *name_str = NULL;
447
    int err;
448
 
449
     if( mount_count == 0 )
450
     {
451
         err_printf("fs: No filesystems mounted\n");
452
         return;
453
     }
454
 
455
    if (!scan_opts(argc, argv, 1, NULL, 0, &name_str, OPTION_ARG_TYPE_STR, "file") ||
456
        name_str == NULL)
457
    {
458
        fs_usage("invalid arguments");
459
        return;
460
    }
461
 
462
    err = unlink( name_str );
463
 
464
    if( err != 0 )
465
        err_printf("fs del: failed to delete file %s\n",name_str);
466
}
467
 
468
local_cmd_entry("del",
469
                "delete file",
470
                "<file>",
471
                do_del,
472
                FS_cmds
473
    );
474
 
475
//==========================================================================
476
 
477
static void
478
do_move(int argc, char * argv[])
479
{
480
    int err;
481
    __externC int rename( const char *oldname, const char *newname );
482
    if( mount_count == 0 )
483
    {
484
        err_printf("fs: No filesystems mounted\n");
485
        return;
486
    }
487
 
488
    if( argc != 3 )
489
        fs_usage("bad arguments to move command\n");
490
 
491
    err = rename( argv[1], argv[2] );
492
 
493
    if( err != 0 )
494
        err_printf("fs move: failed to move file %s to %s\n",argv[1],argv[2]);
495
}
496
 
497
local_cmd_entry("move",
498
                "move file",
499
                "<from> <to>",
500
                do_move,
501
                FS_cmds
502
    );
503
 
504
//==========================================================================
505
 
506
static void
507
do_cd(int argc, char * argv[])
508
{
509
    char *dir_str;
510
    int err;
511
 
512
     if( mount_count == 0 )
513
     {
514
         err_printf("fs: No filesystems mounted\n");
515
         return;
516
     }
517
 
518
    if (!scan_opts(argc, argv, 1, NULL, 0, &dir_str, OPTION_ARG_TYPE_STR, "directory"))
519
        return;
520
 
521
    if( dir_str == NULL )
522
        dir_str = "/";
523
 
524
    err = chdir( dir_str );
525
 
526
    if( err != 0 )
527
        err_printf("fs cd: failed to change directory %s\n",dir_str);
528
}
529
 
530
local_cmd_entry("cd",
531
                "change directory",
532
                "[<directory>]",
533
                do_cd,
534
                FS_cmds
535
    );
536
 
537
//==========================================================================
538
 
539
static void
540
do_write(int argc, char * argv[])
541
{
542
    char *name_str = NULL;
543
    int err;
544
    struct option_info opts[2];
545
    CYG_ADDRESS mem_addr = 0;
546
    unsigned long length = 0;
547
    bool mem_addr_set = false;
548
    bool length_set = false;
549
    int fd;
550
 
551
     if( mount_count == 0 )
552
     {
553
         err_printf("fs: No filesystems mounted\n");
554
         return;
555
     }
556
 
557
     init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
558
               (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address");
559
     init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM,
560
               (void *)&length, (bool *)&length_set, "image length");
561
 
562
    if (!scan_opts(argc, argv, 1, opts, 2, &name_str, OPTION_ARG_TYPE_STR, "file name") ||
563
        name_str == NULL)
564
    {
565
        fs_usage("invalid arguments");
566
        return;
567
    }
568
 
569
//    diag_printf("load_address %08x %08x\n",load_address,load_address_end);
570
//    diag_printf("ram %08x %08x\n",ram_start, ram_end);
571
//    diag_printf("file name %08x >%s<\n",name_str,name_str);
572
 
573
    if (!mem_addr_set &&
574
        (load_address >= (CYG_ADDRESS)ram_start) &&
575
        ((load_address_end) < (CYG_ADDRESS)ram_end))
576
    {
577
        mem_addr = load_address;
578
        mem_addr_set = true;
579
        if (!length_set)
580
        {
581
            length = load_address_end - load_address;
582
            length_set = true;
583
            // maybe get length from existing file size if no loaded
584
            // image?
585
        }
586
    }
587
 
588
    fd = open( name_str, O_WRONLY|O_CREAT|O_TRUNC );
589
 
590
    if( fd < 0 )
591
    {
592
        err_printf("fs write: Cannot open %s\n", name_str );
593
        return;
594
    }
595
 
596
//    diag_printf("write %08x %08x\n",mem_addr, length );
597
 
598
    err = write( fd, (void *)mem_addr, length );
599
 
600
    if( err != length )
601
    {
602
        err_printf("fs write: failed to write to file %d(%d) %d\n",err,length,errno);
603
    }
604
 
605
    err = close( fd );
606
 
607
    if( err != 0 )
608
        err_printf("fs write: close failed\n");
609
}
610
 
611
local_cmd_entry("write",
612
                "write data to file",
613
                "-b <mem_base> -l <image_length> <file_name>",
614
                do_write,
615
                FS_cmds
616
    );
617
 
618
//==========================================================================
619
 
620
__externC cyg_fstab_entry cyg_fstab[];
621
__externC cyg_fstab_entry cyg_fstab_end;
622
__externC cyg_mtab_entry cyg_mtab[];
623
__externC cyg_mtab_entry cyg_mtab_end;
624
 
625
static void
626
do_info(int argc, char * argv[])
627
{
628
    cyg_bool found = false;
629
    cyg_fstab_entry *f;
630
    cyg_devtab_entry_t *t;
631
 
632
    for( f = &cyg_fstab[0] ; f != &cyg_fstab_end; f++ )
633
    {
634
        if( !found )
635
        {
636
            diag_printf("Filesystems available:\n");
637
            found = true;
638
        }
639
        diag_printf("%s\n",f->name);
640
    }
641
 
642
    found = false;
643
    for (t = &__DEVTAB__[0]; t != &__DEVTAB_END__; t++)
644
    {
645
        if( (t->status & CYG_DEVTAB_STATUS_BLOCK) == 0 ||
646
            (t->status & CYG_DEVTAB_STATUS_AVAIL) == 0 )
647
            continue;
648
 
649
        if( !found )
650
        {
651
            diag_printf("\nDevices available:\n");
652
            found = true;
653
        }
654
        diag_printf("%s\n",t->name);
655
    }
656
 
657
    if( mount_count != 0 )
658
    {
659
        int i;
660
 
661
        diag_printf("\nMounted filesystems:\n");
662
        diag_printf("            Device               Filesystem Mounted on\n");
663
 
664
        for( i = 0; i < MAX_MOUNTS; i++ )
665
        {
666
            if( mounts[i].mp_str[0] != '\0' )
667
                diag_printf("%32s %10s %s\n", mounts[i].dev_str, mounts[i].type_str, mounts[i].mp_str);
668
        }
669
    }
670
}
671
 
672
local_cmd_entry("info",
673
                "filesystem info",
674
                "",
675
                do_info,
676
                FS_cmds
677
    );
678
 
679
//==========================================================================
680
 
681
static void
682
do_fs(int argc, char *argv[])
683
{
684
    struct cmd *cmd;
685
 
686
    if (argc < 2) {
687
        fs_usage("too few arguments");
688
        return;
689
    }
690
    if ((cmd = cmd_search(__FS_cmds_TAB__, &__FS_cmds_TAB_END__,
691
                          argv[1])) != (struct cmd *)0) {
692
        (cmd->fun)(argc-1, argv+1);
693
        return;
694
    }
695
    fs_usage("unrecognized command");
696
}
697
 
698
RedBoot_nested_cmd("fs",
699
            "Manage Filesystem files",
700
            "{cmds}",
701
            do_fs,
702
            __FS_cmds_TAB__, &__FS_cmds_TAB_END__
703
    );
704
 
705
 
706
//==========================================================================
707
 
708
static int fd;
709
 
710
externC int
711
fileio_stream_open(connection_info_t *info, int *err)
712
{
713
    char *filename = info->filename;
714
 
715
     if( mount_count == 0 )
716
     {
717
         diag_printf("fs: No filesystems mounted\n");
718
         return -1;
719
     }
720
 
721
    fd = open(filename, O_RDONLY);
722
    if (fd < 0) {
723
        diag_printf("fs: Open failed, error %d\n", errno);
724
        return -1;
725
    }
726
    return 0;
727
}
728
 
729
externC int
730
fileio_stream_read(char *buf, int size, int *err)
731
{
732
    int nread;
733
 
734
    if ((nread = read(fd, buf, size)) < 0) {
735
        *err = errno;
736
        return -1;
737
    }
738
    return nread;
739
}
740
 
741
externC void
742
fileio_stream_close(int *err)
743
{
744
    close(fd);
745
}
746
 
747
externC char *
748
fileio_error(int err)
749
{
750
    static char myerr[10];
751
 
752
    diag_sprintf(myerr, "error %d", err);
753
    return myerr;
754
}
755
 
756
//
757
// RedBoot interface
758
//
759
GETC_IO_FUNCS(fileio_io, fileio_stream_open, fileio_stream_close,
760
              0, fileio_stream_read, fileio_error);
761
RedBoot_load(file, fileio_io, true, true, 0);
762
 
763
//==========================================================================
764
// End of fileio.c
765
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.