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/>.
24 DECLARE_GLOBAL_DATA_PTR
;
26 static block_dev_desc_t
*fs_dev_desc
;
27 static disk_partition_t fs_partition
;
28 static int fs_type
= FS_TYPE_ANY
;
30 static inline int fs_probe_unsupported(void)
32 printf("** Unrecognized filesystem type **\n");
36 static inline int fs_ls_unsupported(const char *dirname
)
38 printf("** Unrecognized filesystem type **\n");
42 static inline int fs_read_unsupported(const char *filename
, ulong addr
,
45 printf("** Unrecognized filesystem type **\n");
49 static inline void fs_close_unsupported(void)
54 static int fs_probe_fat(void)
56 return fat_set_blk_dev(fs_dev_desc
, &fs_partition
);
59 static void fs_close_fat(void)
63 #define fs_ls_fat file_fat_ls
65 static int fs_read_fat(const char *filename
, ulong addr
, int offset
, int len
)
69 len_read
= file_fat_read_at(filename
, offset
,
70 (unsigned char *)addr
, len
);
72 printf("** Unable to read file %s **\n", filename
);
79 static inline int fs_probe_fat(void)
84 static inline void fs_close_fat(void)
88 #define fs_ls_fat fs_ls_unsupported
89 #define fs_read_fat fs_read_unsupported
93 static int fs_probe_ext(void)
95 ext4fs_set_blk_dev(fs_dev_desc
, &fs_partition
);
97 if (!ext4fs_mount(fs_partition
.size
)) {
105 static void fs_close_ext(void)
110 #define fs_ls_ext ext4fs_ls
112 static int fs_read_ext(const char *filename
, ulong addr
, int offset
, int len
)
118 printf("** Cannot support non-zero offset **\n");
122 file_len
= ext4fs_open(filename
);
124 printf("** File not found %s **\n", filename
);
132 len_read
= ext4fs_read((char *)addr
, len
);
135 if (len_read
!= len
) {
136 printf("** Unable to read file %s **\n", filename
);
143 static inline int fs_probe_ext(void)
148 static inline void fs_close_ext(void)
152 #define fs_ls_ext fs_ls_unsupported
153 #define fs_read_ext fs_read_unsupported
159 int (*ls
)(const char *dirname
);
160 int (*read
)(const char *filename
, ulong addr
, int offset
, int len
);
164 static struct fstype_info fstypes
[] = {
167 .fstype
= FS_TYPE_FAT
,
168 .probe
= fs_probe_fat
,
169 .close
= fs_close_fat
,
174 #ifdef CONFIG_FS_EXT4
176 .fstype
= FS_TYPE_EXT
,
177 .probe
= fs_probe_ext
,
178 .close
= fs_close_ext
,
184 .fstype
= FS_TYPE_ANY
,
185 .probe
= fs_probe_unsupported
,
186 .close
= fs_close_unsupported
,
187 .ls
= fs_ls_unsupported
,
188 .read
= fs_read_unsupported
,
192 int fs_set_blk_dev(const char *ifname
, const char *dev_part_str
, int fstype
)
194 struct fstype_info
*info
;
196 #ifdef CONFIG_NEEDS_MANUAL_RELOC
197 static int relocated
;
200 for (i
= 0, info
= fstypes
; i
< ARRAY_SIZE(fstypes
);
202 info
->probe
+= gd
->reloc_off
;
203 info
->close
+= gd
->reloc_off
;
204 info
->ls
+= gd
->reloc_off
;
205 info
->read
+= gd
->reloc_off
;
211 part
= get_device_and_partition(ifname
, dev_part_str
, &fs_dev_desc
,
216 for (i
= 0, info
= fstypes
; i
< ARRAY_SIZE(fstypes
); i
++, info
++) {
217 if (fstype
!= FS_TYPE_ANY
&& info
->fstype
!= FS_TYPE_ANY
&&
218 fstype
!= info
->fstype
)
221 if (!info
->probe()) {
222 fs_type
= info
->fstype
;
230 static void fs_close(void)
243 fs_type
= FS_TYPE_ANY
;
246 int fs_ls(const char *dirname
)
252 ret
= fs_ls_fat(dirname
);
255 ret
= fs_ls_ext(dirname
);
258 ret
= fs_ls_unsupported(dirname
);
267 int fs_read(const char *filename
, ulong addr
, int offset
, int len
)
273 ret
= fs_read_fat(filename
, addr
, offset
, len
);
276 ret
= fs_read_ext(filename
, addr
, offset
, len
);
279 ret
= fs_read_unsupported(filename
, addr
, offset
, len
);
288 int do_load(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[],
289 int fstype
, int cmdline_base
)
292 const char *addr_str
;
293 const char *filename
;
300 return CMD_RET_USAGE
;
302 return CMD_RET_USAGE
;
304 if (fs_set_blk_dev(argv
[1], (argc
>= 3) ? argv
[2] : NULL
, fstype
))
308 addr
= simple_strtoul(argv
[3], NULL
, cmdline_base
);
310 addr_str
= getenv("loadaddr");
311 if (addr_str
!= NULL
)
312 addr
= simple_strtoul(addr_str
, NULL
, 16);
314 addr
= CONFIG_SYS_LOAD_ADDR
;
319 filename
= getenv("bootfile");
321 puts("** No boot file defined **\n");
326 bytes
= simple_strtoul(argv
[5], NULL
, cmdline_base
);
330 pos
= simple_strtoul(argv
[6], NULL
, cmdline_base
);
335 len_read
= fs_read(filename
, addr
, pos
, bytes
);
336 time
= get_timer(time
);
340 printf("%d bytes read in %lu ms", len_read
, time
);
343 print_size(len_read
/ time
* 1000, "/s");
348 setenv_hex("filesize", len_read
);
353 int do_ls(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[],
357 return CMD_RET_USAGE
;
359 return CMD_RET_USAGE
;
361 if (fs_set_blk_dev(argv
[1], (argc
>= 3) ? argv
[2] : NULL
, fstype
))
364 if (fs_ls(argc
>= 4 ? argv
[3] : "/"))