1 /* 2 * This program is distributed in the hope that it will be useful, 3 * but WITHOUT ANY WARRANTY; without even the implied warranty of 4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 5 * GNU General Public License for more details. 6 * 7 * You should have received a copy of the GNU General Public License 8 * along with this program; if not, write to the Free Software 9 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 10 */ 11 #include <stdlib.h> 12 #include <common.h> 13 #include <console.h> 14 #include <bootretry.h> 15 #include <cli.h> 16 #include <command.h> 17 #include <console.h> 18 #include <malloc.h> 19 #include <inttypes.h> 20 #include <mapmem.h> 21 #include <asm/io.h> 22 #include <linux/compiler.h> 23 24 DECLARE_GLOBAL_DATA_PTR; 25 26 #define AST_RNG_TYPE 0x1e6e2520 27 #define AST_RNG 0x1e6e2524 28 29 #define PBSTR "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||" 30 #define PBWIDTH 60 31 32 void printProgress(int numerator, int denominator, char *format, ...) 33 { 34 int val = numerator * 100 / denominator; 35 int lpad = numerator * PBWIDTH / denominator; 36 int rpad = PBWIDTH - lpad; 37 char buffer[256]; 38 va_list aptr; 39 40 va_start(aptr, format); 41 vsprintf(buffer, format, aptr); 42 va_end(aptr); 43 44 printf("\r%3d%% [%.*s%*s] %s", val, lpad, PBSTR, rpad, "", buffer); 45 if (numerator == denominator) 46 printf("\n"); 47 } 48 49 void wait_new_rng(void) 50 { 51 52 int i; 53 // unsigned long long start, end; 54 // long long time; 55 56 // start = get_ticks(); 57 58 // take 3456 kicks time, about 2.88us 59 i = 200; 60 while (i--) { 61 asm(""); 62 } 63 64 // end = get_ticks(); 65 // time = end - start; 66 // printf("%llu %llu %lld\n", start, end, time); 67 } 68 69 static int do_ast_rng(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 70 { 71 int i, j; 72 int type; 73 int len; 74 phys_addr_t addr; 75 char *buf; 76 77 if (argc != 4) 78 return CMD_RET_USAGE; 79 type = simple_strtoul(argv[1], NULL, 16); 80 addr = simple_strtoul(argv[2], NULL, 16); 81 len = simple_strtoul(argv[3], NULL, 16); 82 buf = map_physmem(addr, len, MAP_WRBACK); 83 84 if (type > 7) 85 return CMD_RET_USAGE; 86 writel((type & 0x7) << 1, AST_RNG_TYPE); 87 88 wait_new_rng(); 89 90 for (i = 0; i < len; i++) { 91 if (i % 1000 == 0) 92 printProgress(i, len, ""); 93 buf[i] = 0; 94 for (j = 0; j < 8; j++) { 95 buf[i] |= (readl(AST_RNG) & 0x1) << j; 96 wait_new_rng(); 97 } 98 } 99 100 printProgress(len, len, ""); 101 102 return CMD_RET_SUCCESS; 103 } 104 105 U_BOOT_CMD( 106 rng, 4, 0, do_ast_rng, 107 "ASPEED true random number generator", 108 "rng <type> <addr> <len>\n" 109 " type: 0~7\n" 110 ); 111