1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Commands to test block devices File: ui_test_disk.c
6 * Commands to manipulate block devices live here.
8 * Author: Mitch Lichtenberg (mpl@broadcom.com)
10 *********************************************************************
12 * Copyright 2000,2001,2002,2003
13 * Broadcom Corporation. All rights reserved.
15 * This software is furnished under license and may be used and
16 * copied only in accordance with the following terms and
17 * conditions. Subject to these conditions, you may download,
18 * copy, install, use, modify and distribute modified or unmodified
19 * copies of this software in source and/or binary form. No title
20 * or ownership is transferred hereby.
22 * 1) Any source code used, modified or distributed must reproduce
23 * and retain this copyright notice and list of conditions
24 * as they appear in the source file.
26 * 2) No right is granted to use any trade name, trademark, or
27 * logo of Broadcom Corporation. The "Broadcom Corporation"
28 * name may not be used to endorse or promote products derived
29 * from this software without the prior written permission of
30 * Broadcom Corporation.
32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44 * THE POSSIBILITY OF SUCH DAMAGE.
45 ********************************************************************* */
48 #include "lib_types.h"
49 #include "lib_string.h"
50 #include "lib_queue.h"
51 #include "lib_malloc.h"
52 #include "lib_printf.h"
55 #include "cfe_device.h"
56 #include "cfe_console.h"
57 #include "cfe_error.h"
58 #include "cfe_ioctl.h"
59 #include "cfe_devfuncs.h"
60 #include "ui_command.h"
63 #include "cfe_fileops.h"
64 #include "cfe_bootblock.h"
67 static int ui_cmd_disktest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
68 static int ui_cmd_fstest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
69 static int ui_cmd_copydisk(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
70 static int ui_cmd_bootblock(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
72 int ui_init_disktestcmds(void);
74 int ui_init_disktestcmds(void)
77 cmd_addcmd("test disk",
80 "Do a disk test, read/write sectors on the disk",
81 "test disk device-name [-random | sector# | {-w sector offset byte}]",
83 "-w;Write a byte at offset in sector.**DANGER!! BE CAREFUL WHICH DEVICE YOU WRITE TO.**");
85 cmd_addcmd("test fatfs",
88 "Do a FAT file system test",
89 "test fatfs device-name",
92 cmd_addcmd("copydisk",
95 "Copy a remote disk image to a local disk device via TFTP",
96 "copydisk host:filename device-name [offset]",
99 cmd_addcmd("show boot",
102 "Display boot block from device,",
103 "show boot device-name\n\n"
104 "This command displays the boot block on the specified device. The\n"
105 "device-name parameter identifies a block device (disk, tape, CD-ROM)\n"
106 "to be scanned for boot blocks. The first boot block found will be\n"
113 static unsigned long rand(void)
115 static unsigned long seed
= 1;
121 t
= 16807 * lo
- 2836 * hi
;
122 if (t
<= 0) t
+= 0x7fffffff;
128 static int ui_cmd_bootblock(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
132 struct boot_block bootblock
;
143 tok
= cmd_getarg(cmd
,0);
148 xprintf("Could not open device; %d\n",fh
);
151 for (sec
= 0; sec
< BOOT_BLOCK_MAXLOC
; sec
++) {
152 res
= cfe_readblk(fh
,sec
* BOOT_BLOCK_BLOCKSIZE
,
153 (unsigned char *) &bootblock
,sizeof(bootblock
));
155 if (bootblock
.bb_magic
!= BOOT_MAGIC_NUMBER
) {
158 xprintf("Found boot block in sector %d\n", sec
);
159 if (res
!= sizeof(bootblock
)) {
160 xprintf("Could not read boot block\n");
165 xprintf("Boot block data:\n");
166 for (idx
= 59; idx
< 64; idx
++) {
167 xprintf(" %d: %016llX\n",idx
,bootblock
.bb_data
[idx
]);
171 xprintf("Boot block version is %d\n",
172 (uint32_t) ((bootblock
.bb_hdrinfo
& BOOT_HDR_VER_MASK
) >> BOOT_HDR_VER_SHIFT
));
173 xprintf("Boot block flags are %02X\n",
174 (uint32_t) ((bootblock
.bb_hdrinfo
& BOOT_HDR_FLAGS_MASK
) >> 56));
175 checksum
= ((uint32_t) (bootblock
.bb_hdrinfo
& BOOT_HDR_CHECKSUM_MASK
));
176 checksumd
= ((uint32_t) ((bootblock
.bb_secsize
& BOOT_DATA_CHECKSUM_MASK
) >> BOOT_DATA_CHECKSUM_SHIFT
));
177 bootblock
.bb_hdrinfo
&= ~BOOT_HDR_CHECKSUM_MASK
;
178 secsize
= ((uint32_t) (bootblock
.bb_secsize
& BOOT_SECSIZE_MASK
));
179 secoffset
= bootblock
.bb_secstart
;
181 xprintf("Boot code is %d bytes at %016llX\n",secsize
,secoffset
);
183 CHECKSUM_BOOT_DATA(&(bootblock
.bb_magic
),BOOT_BLOCK_SIZE
,&calcsum
);
185 if (checksum
!= calcsum
) {
186 xprintf("Header checksum does not match Blk=%08X Calc=%08X\n",
190 xprintf("Header checksum is ok\n");
193 code
= KMALLOC(secsize
,0);
195 res
= cfe_readblk(fh
,secoffset
,code
,secsize
);
196 if (res
!= secsize
) {
197 xprintf("Could not read boot code\n");
202 CHECKSUM_BOOT_DATA(code
,secsize
,&calcsum
);
203 if (calcsum
== checksumd
) xprintf("Boot code checksum is ok\n");
204 else xprintf("Boot code checksum is incorrect (Calc=%08X, Blk=%08X)\n",
210 if (sec
== BOOT_BLOCK_MAXLOC
) {
211 xprintf("No valid boot blocks found in the first %d sectors\n",
223 extern int fatfs_fileop_dir(void *fsctx
);
225 static int ui_cmd_fstest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
231 uint8_t buffer
[1000];
235 tok
= cmd_getarg(cmd
,0);
238 fname
= cmd_getarg(cmd
,1);
240 res
= fs_init("fat",&fsctx
,tok
);
242 xprintf("Could not init file system: %s\n",cfe_errortext(res
));
247 fatfs_fileop_dir(fsctx
->fsctx
);
250 res
= fs_open(fsctx
,&filectx
,fname
,FILE_MODE_READ
);
252 xprintf("Could not open %s: %s\n",fname
,cfe_errortext(res
));
258 res
= fs_read(fsctx
,filectx
,buffer
,sizeof(buffer
));
261 if (res
!= sizeof(buffer
)) break;
264 if (res
< 0) xprintf("read error %s\n",cfe_errortext(res
));
265 else xprintf("Total bytes read: %d\n",total
);
266 fs_close(fsctx
,filectx
);
274 static int ui_cmd_copydisk(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
280 uint8_t buffer
[1024];
288 fname
= cmd_getarg(cmd
,0);
289 if (!fname
) return ui_showusage(cmd
);
291 devname
= cmd_getarg(cmd
,1);
292 if (!devname
) return ui_showusage(cmd
);
294 toffset
= cmd_getarg(cmd
,2);
295 if (!toffset
) offset
= 0; else offset
= atoi(toffset
);
297 if ((cfe_getdevinfo(devname
) & CFE_DEV_MASK
) != CFE_DEV_DISK
) {
298 xprintf("Device %s is not a disk.\n",devname
);
299 return CFE_ERR_INV_PARAM
;
302 fh
= cfe_open(devname
);
304 return ui_showerror(fh
,"Could not open device %s",devname
);
307 res
= fs_init("tftp",&fsctx
,"");
309 return ui_showerror(res
,"Could not init file system");
312 res
= fs_open(fsctx
,&filectx
,fname
,FILE_MODE_READ
);
314 return ui_showerror(res
,"Could not open %s",fname
);
320 res
= fs_read(fsctx
,filectx
,buffer
,sizeof(buffer
));
322 if (res
> 0) cfe_writeblk(fh
,total
+offset
*512,buffer
,res
);
324 if (res
!= sizeof(buffer
)) break;
331 if (res
< 0) xprintf("read error %s\n",cfe_errortext(res
));
332 else xprintf("Total bytes read: %d\n",total
);
333 fs_close(fsctx
,filectx
);
341 static int ui_cmd_disktest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
352 unsigned char buffer
[2048];
359 tok
= cmd_getarg(cmd
,0);
362 tok2
= cmd_getarg(cmd
,1);
363 tok3
= cmd_getarg(cmd
,2);
364 tok4
= cmd_getarg(cmd
,3);
368 xprintf("Could not open device: %s\n",cfe_errortext(fh
));
372 xprintf("device opened ok\n");
374 sectors
= 0; secsize
= 0;
375 cfe_ioctl(fh
,IOCTL_BLOCK_GETTOTALBLOCKS
,(uint8_t *) §ors
,sizeof(sectors
),&res
,0);
376 cfe_ioctl(fh
,IOCTL_BLOCK_GETBLOCKSIZE
,(uint8_t *) &secsize
,sizeof(secsize
),&res
,0);
377 printf("Total sectors: %lld Sector size: %d\n",sectors
,secsize
);
378 if (secsize
== 0) secsize
= 512;
379 if (sectors
== 0) sectors
= 100000;
383 offset
= (cfe_offset_t
) secnum
* (cfe_offset_t
) secsize
;
384 if (cmd_sw_isset(cmd
,"-w")) {
385 secoffset
= atoi(tok3
);
386 byte
= (uint8_t) xtoq(tok4
);
387 res
= cfe_writeblk(fh
,offset
+secoffset
,&byte
,1);
389 xprintf("Write failed\n");
393 res
= cfe_readblk(fh
,offset
,buffer
,secsize
);
394 if (res
!= secsize
) {
395 xprintf("disk error: %d sector %d\n",res
,secnum
);
398 for (idx
= 0; idx
< secsize
; idx
+=16) {
399 xprintf("%04X: ",idx
);
400 for (idx2
= 0; idx2
< 16; idx2
++) {
401 xprintf("%02X ",buffer
[idx
+idx2
]);
403 for (idx2
= 0; idx2
< 16; idx2
++) {
404 if ((buffer
[idx
+idx2
] < 32) ||
405 (buffer
[idx
+idx2
] > 127)) {
409 xprintf("%c",buffer
[idx
+idx2
]);
417 if (cmd_sw_isset(cmd
,"-random")) {
418 while (!console_status()) {
420 secnum
= rand() % sectors
;
421 offset
= (cfe_offset_t
) secnum
* (cfe_offset_t
) secsize
;
422 res
= cfe_readblk(fh
,offset
,buffer
,secsize
);
423 if (res
!= secsize
) {
424 xprintf("disk error: %d sector %d\n",res
,secnum
);
428 if ((count
% 1000) == 0) xprintf("%d ",count
);