2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <sandboxfs.h>
26 DECLARE_GLOBAL_DATA_PTR
;
28 static block_dev_desc_t
*fs_dev_desc
;
29 static disk_partition_t fs_partition
;
30 static int fs_type
= FS_TYPE_ANY
;
32 static inline int fs_probe_unsupported(block_dev_desc_t
*fs_dev_desc
,
33 disk_partition_t
*fs_partition
)
35 printf("** Unrecognized filesystem type **\n");
39 static inline int fs_ls_unsupported(const char *dirname
)
44 static inline int fs_read_unsupported(const char *filename
, void *buf
,
50 static inline void fs_close_unsupported(void)
56 int (*probe
)(block_dev_desc_t
*fs_dev_desc
,
57 disk_partition_t
*fs_partition
);
58 int (*ls
)(const char *dirname
);
59 int (*read
)(const char *filename
, void *buf
, int offset
, int len
);
63 static struct fstype_info fstypes
[] = {
66 .fstype
= FS_TYPE_FAT
,
67 .probe
= fat_set_blk_dev
,
70 .read
= fat_read_file
,
75 .fstype
= FS_TYPE_EXT
,
76 .probe
= ext4fs_probe
,
77 .close
= ext4fs_close
,
79 .read
= ext4_read_file
,
84 .fstype
= FS_TYPE_SANDBOX
,
85 .probe
= sandbox_fs_set_blk_dev
,
86 .close
= sandbox_fs_close
,
88 .read
= fs_read_sandbox
,
92 .fstype
= FS_TYPE_ANY
,
93 .probe
= fs_probe_unsupported
,
94 .close
= fs_close_unsupported
,
95 .ls
= fs_ls_unsupported
,
96 .read
= fs_read_unsupported
,
100 static struct fstype_info
*fs_get_info(int fstype
)
102 struct fstype_info
*info
;
105 for (i
= 0, info
= fstypes
; i
< ARRAY_SIZE(fstypes
) - 1; i
++, info
++) {
106 if (fstype
== info
->fstype
)
110 /* Return the 'unsupported' sentinel */
114 int fs_set_blk_dev(const char *ifname
, const char *dev_part_str
, int fstype
)
116 struct fstype_info
*info
;
118 #ifdef CONFIG_NEEDS_MANUAL_RELOC
119 static int relocated
;
122 for (i
= 0, info
= fstypes
; i
< ARRAY_SIZE(fstypes
);
124 info
->probe
+= gd
->reloc_off
;
125 info
->close
+= gd
->reloc_off
;
126 info
->ls
+= gd
->reloc_off
;
127 info
->read
+= gd
->reloc_off
;
133 part
= get_device_and_partition(ifname
, dev_part_str
, &fs_dev_desc
,
138 for (i
= 0, info
= fstypes
; i
< ARRAY_SIZE(fstypes
); i
++, info
++) {
139 if (fstype
!= FS_TYPE_ANY
&& info
->fstype
!= FS_TYPE_ANY
&&
140 fstype
!= info
->fstype
)
143 if (!info
->probe(fs_dev_desc
, &fs_partition
)) {
144 fs_type
= info
->fstype
;
152 static void fs_close(void)
154 struct fstype_info
*info
= fs_get_info(fs_type
);
158 fs_type
= FS_TYPE_ANY
;
161 int fs_ls(const char *dirname
)
165 struct fstype_info
*info
= fs_get_info(fs_type
);
167 ret
= info
->ls(dirname
);
169 fs_type
= FS_TYPE_ANY
;
175 int fs_read(const char *filename
, ulong addr
, int offset
, int len
)
177 struct fstype_info
*info
= fs_get_info(fs_type
);
182 * We don't actually know how many bytes are being read, since len==0
183 * means read the whole file.
185 buf
= map_sysmem(addr
, len
);
186 ret
= info
->read(filename
, buf
, offset
, len
);
189 /* If we requested a specific number of bytes, check we got it */
190 if (ret
>= 0 && len
&& ret
!= len
) {
191 printf("** Unable to read file %s **\n", filename
);
199 int do_load(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[],
200 int fstype
, int cmdline_base
)
203 const char *addr_str
;
204 const char *filename
;
211 return CMD_RET_USAGE
;
213 return CMD_RET_USAGE
;
215 if (fs_set_blk_dev(argv
[1], (argc
>= 3) ? argv
[2] : NULL
, fstype
))
219 addr
= simple_strtoul(argv
[3], NULL
, cmdline_base
);
221 addr_str
= getenv("loadaddr");
222 if (addr_str
!= NULL
)
223 addr
= simple_strtoul(addr_str
, NULL
, 16);
225 addr
= CONFIG_SYS_LOAD_ADDR
;
230 filename
= getenv("bootfile");
232 puts("** No boot file defined **\n");
237 bytes
= simple_strtoul(argv
[5], NULL
, cmdline_base
);
241 pos
= simple_strtoul(argv
[6], NULL
, cmdline_base
);
246 len_read
= fs_read(filename
, addr
, pos
, bytes
);
247 time
= get_timer(time
);
251 printf("%d bytes read in %lu ms", len_read
, time
);
254 print_size(len_read
/ time
* 1000, "/s");
259 setenv_hex("filesize", len_read
);
264 int do_ls(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[],
268 return CMD_RET_USAGE
;
270 return CMD_RET_USAGE
;
272 if (fs_set_blk_dev(argv
[1], (argc
>= 3) ? argv
[2] : NULL
, fstype
))
275 if (fs_ls(argc
>= 4 ? argv
[3] : "/"))