1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Test commands File: cfe_tests.c
6 * A temporary sandbox for misc test routines and commands.
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 ********************************************************************* */
50 #include "lib_types.h"
51 #include "lib_string.h"
52 #include "lib_queue.h"
53 #include "lib_malloc.h"
54 #include "lib_printf.h"
57 #include "cfe_device.h"
58 #include "cfe_console.h"
59 #include "cfe_devfuncs.h"
60 #include "cfe_timer.h"
61 #include "cfe_ioctl.h"
63 #include "cfe_error.h"
66 #include "ui_command.h"
70 #include "net_ether.h"
74 #include "cfe_fileops.h"
76 #include "cfe_bootblock.h"
80 #include "bsp_config.h"
82 #include "dev_flash.h"
86 extern long prog_entrypt
;
87 extern void cfe_go(void);
89 extern int vapi_flushtest(void);
91 int ui_init_testcmds(void);
92 static int ui_cmd_timertest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
93 static int ui_cmd_ethertest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
94 static int ui_cmd_disktest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
95 static int ui_cmd_exittest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
96 static int ui_cmd_fstest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
97 static int ui_cmd_copydisk(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
98 static int ui_cmd_bootblock(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
99 static int ui_cmd_flashtest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
100 static int ui_cmd_flashcopy(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
101 static int ui_cmd_readnvram(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
102 static int ui_cmd_erasenvram(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
104 static int ui_cmd_memorytest(ui_cmdline_t
*cmd
,int argc
,char *argv
[]);
107 extern int cfe_elfload(fileio_dispatch_t
*ops
,char *file
,int flags
,unsigned long *ept
);
109 static unsigned long rand(void)
111 static unsigned long seed
= 1;
117 t
= 16807 * lo
- 2836 * hi
;
118 if (t
<= 0) t
+= 0x7fffffff;
124 int ui_init_testcmds(void)
127 cmd_addcmd("test timer",
134 cmd_addcmd("test exit",
137 "Try the firmware restart command",
141 cmd_addcmd("test disk",
144 "Do a disk test, reading random sectors on the disk",
145 "test disk device-name",
148 cmd_addcmd("test ether",
151 "Do an ethernet test, reading packets from the net",
152 "test ether device-name",
155 cmd_addcmd("test flash",
158 "Read manufacturer ID from flash",
162 cmd_addcmd("flashcopy",
165 "Copy flash to flash",
166 "flashcopy sourcedev destdev",
169 cmd_addcmd("test fatfs",
172 "Do a FAT file system test",
173 "test fatfs device-name",
176 cmd_addcmd("copydisk",
179 "Copy a remote disk image to a local disk device via TFTP",
180 "copydisk host:filename device-name [offset]",
183 cmd_addcmd("nvram read",
187 "test nvram devname offset",
190 cmd_addcmd("nvram erase",
194 "erasenvram devname",
197 cmd_addcmd("show boot",
200 "Display boot block from device,",
201 "show boot device-name\n\n"
202 "This command displays the boot block on the specified device. The\n"
203 "device-name parameter identifies a block device (disk, tape, CD-ROM)\n"
204 "to be scanned for boot blocks. The first boot block found will be\n"
209 cmd_addcmd("memorytest",
212 "Extensive memory test",
219 static int ui_cmd_readnvram(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
229 dev
= cmd_getarg(cmd
,0);
230 if (!dev
) return ui_showusage(cmd
);
232 tok
= cmd_getarg(cmd
,1);
233 if (tok
) offset
= xtoi(tok
);
238 ui_showerror(fd
,"could not open NVRAM");
242 res
= cfe_readblk(fd
,offset
,buf
,512);
243 printf("Offset %d Result %d\n",offset
,res
);
244 for (idx
= 0; idx
< 512; idx
++) {
245 if ((idx
% 16) == 0) printf("\n");
246 printf("%02X ",buf
[idx
]);
255 static int ui_cmd_erasenvram(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
259 uint8_t buffer
[2048];
266 dev
= cmd_getarg(cmd
,0);
267 if (!dev
) return ui_showusage(cmd
);
270 if ((tok
= cmd_getarg(cmd
,1))) offset
= xtoi(tok
);
273 if ((tok
= cmd_getarg(cmd
,2))) length
= xtoi(tok
);
274 if (length
> 2048) length
= 2048;
277 if ((tok
= cmd_getarg(cmd
,3))) data
= xtoi(tok
);
281 ui_showerror(fd
,"could not open NVRAM");
285 if (cmd_sw_isset(cmd
,"-pattern")) {
286 memset(buffer
,0,sizeof(buffer
));
287 for (res
= 0; res
< 2048; res
++) {
288 buffer
[res
] = res
& 0xFF;
291 else memset(buffer
,data
,sizeof(buffer
));
293 printf("Fill offset %04X length %04X\n",offset
,length
);
295 res
= cfe_writeblk(fd
,offset
,buffer
,length
);
297 printf("write returned %d\n",res
);
304 static int ui_cmd_flashcopy(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
312 buffer
= KMALLOC(1024,0);
313 if (!buffer
) return -1;
315 sf
= cmd_getarg(cmd
,0);
316 df
= cmd_getarg(cmd
,1);
318 return ui_showusage(cmd
);
323 ui_showerror(sfd
,"Could not open source device %s\n",sf
);
329 ui_showerror(sfd
,"Could not open destination device %s\n",df
);
335 printf("Erasing destination device %s...",df
);
337 res
= cfe_ioctl(dfd
,IOCTL_FLASH_ERASE_ALL
,NULL
,0,NULL
,0);
340 ui_showerror(res
,"Failed: ");
351 for (idx
= 0; idx
< 2048; idx
++) {
352 cfe_readblk(sfd
,idx
*1024,buffer
,1024);
353 cfe_writeblk(dfd
,idx
*1024,buffer
,1024);
354 if ((idx
% 256) == 0) printf(".");
367 static int ui_cmd_flashtest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
374 flash_sector_t sector
;
375 nvram_info_t nvraminfo
;
377 fd
= cfe_open(cmd_getarg(cmd
,0));
378 if (fd
< 0) return fd
;
380 res
= cfe_ioctl(fd
,IOCTL_NVRAM_GETINFO
,(uint8_t *) &nvraminfo
,sizeof(nvram_info_t
),&retlen
,0);
382 printf("NVRAM: Offset %08X Size %08X EraseFlg %d\n",
383 nvraminfo
.nvram_offset
,nvraminfo
.nvram_size
,nvraminfo
.nvram_eraseflg
);
386 res
= cfe_ioctl(fd
,IOCTL_FLASH_GETINFO
,(uint8_t *) &info
,sizeof(flash_info_t
),&retlen
,0);
388 printf("FLASH: Base %016llX size %08X type %02X flags %08X\n",
389 info
.flash_base
,info
.flash_size
,info
.flash_type
,info
.flash_flags
);
394 sector
.flash_sector_idx
= idx
;
395 res
= cfe_ioctl(fd
,IOCTL_FLASH_GETSECTORS
,(uint8_t *) §or
,sizeof(flash_sector_t
),&retlen
,0);
397 printf("ioctl error\n");
400 if (sector
.flash_sector_status
== FLASH_SECTOR_INVALID
) break;
401 printf("Sector %d offset %08X size %d\n",
402 sector
.flash_sector_idx
,
403 sector
.flash_sector_offset
,
404 sector
.flash_sector_size
);
415 static int ui_cmd_bootblock(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
419 struct boot_block bootblock
;
430 tok
= cmd_getarg(cmd
,0);
435 xprintf("Could not open device; %d\n",fh
);
438 for (sec
= 0; sec
< BOOT_BLOCK_MAXLOC
; sec
++) {
439 res
= cfe_readblk(fh
,sec
* BOOT_BLOCK_BLOCKSIZE
,
440 (unsigned char *) &bootblock
,sizeof(bootblock
));
442 if (bootblock
.bb_magic
!= BOOT_MAGIC_NUMBER
) {
445 xprintf("Found boot block in sector %d\n", sec
);
446 if (res
!= sizeof(bootblock
)) {
447 xprintf("Could not read boot block\n");
452 xprintf("Boot block data:\n");
453 for (idx
= 59; idx
< 64; idx
++) {
454 xprintf(" %d: %016llX\n",idx
,bootblock
.bb_data
[idx
]);
458 xprintf("Boot block version is %d\n",
459 (uint32_t) ((bootblock
.bb_hdrinfo
& BOOT_HDR_VER_MASK
) >> BOOT_HDR_VER_SHIFT
));
460 xprintf("Boot block flags are %02X\n",
461 (uint32_t) ((bootblock
.bb_hdrinfo
& BOOT_HDR_FLAGS_MASK
) >> 56));
462 checksum
= ((uint32_t) (bootblock
.bb_hdrinfo
& BOOT_HDR_CHECKSUM_MASK
));
463 checksumd
= ((uint32_t) ((bootblock
.bb_secsize
& BOOT_DATA_CHECKSUM_MASK
) >> BOOT_DATA_CHECKSUM_SHIFT
));
464 bootblock
.bb_hdrinfo
&= ~BOOT_HDR_CHECKSUM_MASK
;
465 secsize
= ((uint32_t) (bootblock
.bb_secsize
& BOOT_SECSIZE_MASK
));
466 secoffset
= bootblock
.bb_secstart
;
468 xprintf("Boot code is %d bytes at %016llX\n",secsize
,secoffset
);
470 CHECKSUM_BOOT_DATA(&(bootblock
.bb_magic
),BOOT_BLOCK_SIZE
,&calcsum
);
472 if (checksum
!= calcsum
) {
473 xprintf("Header checksum does not match Blk=%08X Calc=%08X\n",
477 xprintf("Header checksum is ok\n");
480 code
= KMALLOC(secsize
,0);
482 res
= cfe_readblk(fh
,secoffset
,code
,secsize
);
483 if (res
!= secsize
) {
484 xprintf("Could not read boot code\n");
489 CHECKSUM_BOOT_DATA(code
,secsize
,&calcsum
);
490 if (calcsum
== checksumd
) xprintf("Boot code checksum is ok\n");
491 else xprintf("Boot code checksum is incorrect (Calc=%08X, Blk=%08X)\n",
497 if (sec
== BOOT_BLOCK_MAXLOC
) {
498 xprintf("No valid boot blocks found in the first %d sectors\n",
507 static int ui_cmd_exittest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
512 x
= cmd_getarg(cmd
,0);
513 if (x
) val
= atoi(x
);
520 extern int fatfs_fileop_dir(void *fsctx
);
522 static int ui_cmd_fstest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
528 uint8_t buffer
[1000];
532 tok
= cmd_getarg(cmd
,0);
535 fname
= cmd_getarg(cmd
,1);
537 res
= fs_init("fat",&fsctx
,tok
);
539 xprintf("Could not init file system: %s\n",cfe_errortext(res
));
544 fatfs_fileop_dir(fsctx
->fsctx
);
547 res
= fs_open(fsctx
,&filectx
,fname
,FILE_MODE_READ
);
549 xprintf("Could not open %s: %s\n",fname
,cfe_errortext(res
));
555 res
= fs_read(fsctx
,filectx
,buffer
,sizeof(buffer
));
558 if (res
!= sizeof(buffer
)) break;
561 if (res
< 0) xprintf("read error %s\n",cfe_errortext(res
));
562 else xprintf("Total bytes read: %d\n",total
);
563 fs_close(fsctx
,filectx
);
571 static int ui_cmd_copydisk(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
577 uint8_t buffer
[1024];
585 fname
= cmd_getarg(cmd
,0);
586 if (!fname
) return ui_showusage(cmd
);
588 devname
= cmd_getarg(cmd
,1);
589 if (!devname
) return ui_showusage(cmd
);
591 toffset
= cmd_getarg(cmd
,2);
592 if (!toffset
) offset
= 0; else offset
= atoi(toffset
);
594 if ((cfe_getdevinfo(devname
) & CFE_DEV_MASK
) != CFE_DEV_DISK
) {
595 xprintf("Device %s is not a disk.\n",devname
);
596 return CFE_ERR_INV_PARAM
;
599 fh
= cfe_open(devname
);
601 return ui_showerror(fh
,"Could not open device %s",devname
);
604 res
= fs_init("tftp",&fsctx
,"");
606 return ui_showerror(res
,"Could not init file system");
609 res
= fs_open(fsctx
,&filectx
,fname
,FILE_MODE_READ
);
611 return ui_showerror(res
,"Could not open %s",fname
);
617 res
= fs_read(fsctx
,filectx
,buffer
,sizeof(buffer
));
619 if (res
> 0) cfe_writeblk(fh
,total
+offset
*512,buffer
,res
);
621 if (res
!= sizeof(buffer
)) break;
628 if (res
< 0) xprintf("read error %s\n",cfe_errortext(res
));
629 else xprintf("Total bytes read: %d\n",total
);
630 fs_close(fsctx
,filectx
);
639 static int ui_cmd_ethertest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
643 uint8_t packet
[2048];
647 tok
= cmd_getarg(cmd
,0);
652 xprintf("Could not open device: %s\n",cfe_errortext(fh
));
656 xprintf("Receiving... prese enter to stop\n");
657 while (!console_status()) {
658 res
= cfe_read(fh
,packet
,sizeof(packet
));
659 if (res
== 0) continue;
661 xprintf("Read error: %s\n",cfe_errortext(res
));
666 if (res
> 32) res
= 32;
668 for (idx
= 0; idx
< res
; idx
++) {
669 xprintf("%02X",packet
[idx
]);
670 if ((idx
== 5) || (idx
== 11) || (idx
== 13)) xprintf(" ");
682 static int ui_cmd_disktest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
691 unsigned char buffer
[2048];
696 tok
= cmd_getarg(cmd
,0);
699 tok2
= cmd_getarg(cmd
,1);
703 xprintf("Could not open device: %s\n",cfe_errortext(fh
));
707 xprintf("device opened ok\n");
709 sectors
= 0; secsize
= 0;
710 cfe_ioctl(fh
,IOCTL_BLOCK_GETTOTALBLOCKS
,(uint8_t *) §ors
,sizeof(sectors
),&res
,0);
711 cfe_ioctl(fh
,IOCTL_BLOCK_GETBLOCKSIZE
,(uint8_t *) &secsize
,sizeof(secsize
),&res
,0);
712 printf("Total sectors: %lld Sector size: %d\n",sectors
,secsize
);
713 if (secsize
== 0) secsize
= 512;
714 if (sectors
== 0) sectors
= 100000;
718 offset
= (cfe_offset_t
) secnum
* (cfe_offset_t
) secsize
;
719 res
= cfe_readblk(fh
,offset
,buffer
,secsize
);
720 if (res
!= secsize
) {
721 xprintf("disk error: %d sector %d\n",res
,secnum
);
724 for (idx
= 0; idx
< secsize
; idx
+=16) {
725 xprintf("%04X: ",idx
);
726 for (idx2
= 0; idx2
< 16; idx2
++) {
727 xprintf("%02X ",buffer
[idx
+idx2
]);
729 for (idx2
= 0; idx2
< 16; idx2
++) {
730 if ((buffer
[idx
+idx2
] < 32) ||
731 (buffer
[idx
+idx2
] > 127)) {
735 xprintf("%c",buffer
[idx
+idx2
]);
743 if (cmd_sw_isset(cmd
,"-random")) {
744 while (!console_status()) {
746 secnum
= rand() % sectors
;
747 offset
= (cfe_offset_t
) secnum
* (cfe_offset_t
) secsize
;
748 res
= cfe_readblk(fh
,offset
,buffer
,secsize
);
749 if (res
!= secsize
) {
750 xprintf("disk error: %d sector %d\n",res
,secnum
);
754 if ((count
% 1000) == 0) xprintf("%d ",count
);
765 static int ui_cmd_timertest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
771 while (!console_status()) {
773 if (t
!= cfe_ticks
) {
774 xprintf("Time is %lld\n",cfe_ticks
);
786 /* extensive memory tests */
788 static void inline uacwrite(long *srcadr
,long *dstadr
)
790 __asm
__volatile ("ld $8, 0(%0) ; "
799 "sync" :: "r"(srcadr
),"r"(dstadr
) : "$8","$9","$10","$11");
803 #define TEST_DATA_LEN 4
804 #define CACHE_LINE_LEN 32
806 static int ui_cmd_memorytest(ui_cmdline_t
*cmd
,int argc
,char *argv
[])
809 static long test_data
[TEST_DATA_LEN
] = {
810 // 0, 0, 0, 0, /* one cache line */
811 // -1, -1, -1, -1, /* one cache line */
812 0xaaaaaaaaaaaaaaaa, 0x5555555555555555, 0xcccccccccccccccc, 0x3333333333333333, /* one cache line */
817 uint64_t arena_start
, arena_size
;
818 long phys_addr
, offset
, mem_base
, cache_mem_base
, i
;
819 long *dst_adr
, *cache_dst_adr
;
827 xprintf("arenas:\n");
828 while (cfe_arena_enum(arena
, &arena_type
, &arena_start
, &arena_size
, FALSE
) == 0) {
829 phys_addr
= (long) arena_start
; /* actual physical address */
830 mem_base
= PHYS_TO_XKPHYS(K_CALG_UNCACHED_ACCEL
, phys_addr
); /* virtual address */
831 xprintf("phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr
, mem_base
, arena_size
);
839 while (cfe_arena_enum(arena
, &arena_type
, &arena_start
, &arena_size
, FALSE
) == 0) {
841 test_data
[0] = 0xAAAAAAAAAAAAAAAA;
842 test_data
[1] = 0x5555555555555555;
843 test_data
[2] = 0xCCCCCCCCCCCCCCCC;
844 test_data
[3] = 0x3333333333333333;
846 phys_addr
= (long) arena_start
; /* actual physical address */
847 mem_base
= PHYS_TO_XKPHYS(K_CALG_UNCACHED_ACCEL
, phys_addr
); /* virtual address */
848 cache_mem_base
= PHYS_TO_K0(phys_addr
);
850 xprintf("phys = %016llX, virt = %016llX, size = %016llX\n", phys_addr
, mem_base
, arena_size
);
852 xprintf("Writing: a/5/c/e\n");
854 for (offset
= 0; (offset
< arena_size
); offset
+= CACHE_LINE_LEN
) {
855 dst_adr
= (long*)(mem_base
+offset
);
856 uacwrite(test_data
, dst_adr
);
859 xprintf("Reading: a/5/c/e\n");
861 for (offset
= 0; (offset
< arena_size
); offset
+= CACHE_LINE_LEN
) {
862 dst_adr
= (long*)(mem_base
+offset
);
863 cache_dst_adr
= (long*)(mem_base
+offset
);
864 for (i
= 0; i
< TEST_DATA_LEN
; i
++) {
865 cda
= cache_dst_adr
[i
];
868 xprintf("mem[%4d] %016llX != %016llX\n",
869 mem_base
+offset
+i
, cda
, tda
);
884 xprintf("Writing: address|5555/inv/aaaa|address\n");
887 for (offset
= 0; (offset
< arena_size
); offset
+= CACHE_LINE_LEN
) {
888 dst_adr
= (long*)(mem_base
+offset
);
889 test_data
[0] = ((long)dst_adr
<<32)|0x55555555;
890 test_data
[1] = ~test_data
[0];
891 test_data
[2] = 0xaaaaaaaa00000000|((long)dst_adr
& 0xffffffff);
892 test_data
[3] = ~test_data
[2];
893 uacwrite(test_data
, dst_adr
);
896 xprintf("Reading: address|5555/inv/aaaa|address\n");
898 for (offset
= 0; (offset
< arena_size
); offset
+= CACHE_LINE_LEN
) {
899 dst_adr
= (long*)(mem_base
+offset
);
900 test_data
[0] = ((long)dst_adr
<<32)|0x55555555;
901 test_data
[1] = ~test_data
[0];
902 test_data
[2] = 0xaaaaaaaa00000000|((long)dst_adr
& 0xffffffff);
903 test_data
[3] = ~test_data
[2];
904 cache_dst_adr
= (long*)(mem_base
+offset
);
905 for (i
= 0; i
< TEST_DATA_LEN
; i
++) {
906 cda
= cache_dst_adr
[i
];
909 xprintf("mem[%4d] %016llX != %016llX\n",
910 mem_base
+offset
+i
,cda
,tda
);
925 if (error
) printf("Failing address: %016llX\n",mem_base
+offset
);
927 return error
? -1 : 0;