mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
691 lines
21 KiB
C
691 lines
21 KiB
C
/*
|
|
* function for test and debug
|
|
*
|
|
* Copyright (C) 2011 Rochchip, Inc.
|
|
* Author: Hsl
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* relative files: drivers/dbg/ , arch/arm/kernel/entry-common.S
|
|
* LOG:
|
|
* 20110127, HSL@RK,add get user regs support and kernel io support.
|
|
*/
|
|
|
|
/* #define DEBUG */
|
|
#include <linux/kallsyms.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/version.h>
|
|
|
|
|
|
/*
|
|
* 20090725,hsl,some debug function start from here
|
|
*/
|
|
#include <linux/mm.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/mmzone.h>
|
|
#include <linux/rtc.h>
|
|
|
|
#include <asm/sections.h>
|
|
#include <asm/stacktrace.h>
|
|
#include <asm/io.h>
|
|
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
|
|
#define FIND_TASK_BY_PID(x) pid_task(find_vpid(x), PIDTYPE_PID)
|
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
|
|
#define FIND_TASK_BY_PID(x) find_task_by_vpid(x)
|
|
#else
|
|
#define FIND_TASK_BY_PID(x) find_task_by_pid(x)
|
|
#endif
|
|
|
|
extern int __scu_call_wrap(unsigned long *argv , int argc , int fun );
|
|
extern void ret_fast_syscall( void );
|
|
|
|
void rk28_printk_mem( unsigned int * addr , int words , unsigned int* show_addr )
|
|
{
|
|
unsigned int * reg_base = addr ;
|
|
if( show_addr == NULL ){
|
|
show_addr = addr;
|
|
}
|
|
while( words > 0 ) {
|
|
printk("%p:%08x %08x %08x %08x\n" ,show_addr ,
|
|
reg_base[0],reg_base[1],reg_base[2],reg_base[3]);
|
|
words -= 4;
|
|
reg_base += 4;
|
|
show_addr += 4;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* type define :
|
|
* first for function name ,
|
|
* ',' for argument.
|
|
* \' : char
|
|
* \" : string.
|
|
* other : for int,short,0x for hex.0 for octal.
|
|
* 20090811,for easy use , 0x or 0-9 start means num , other ,means string .
|
|
* len = 1 string for char.
|
|
* 20100420,add nagative support.
|
|
*/
|
|
int dbg_get_arg( char ** pp )
|
|
{
|
|
char * p = *pp;
|
|
char *t;
|
|
int ret;
|
|
int len ;
|
|
int nag = 0;
|
|
int bnum = 0;
|
|
if( p[0] == '-' ) {
|
|
nag = 1;
|
|
p++;
|
|
}
|
|
if( p[0] == '0' ) {
|
|
if( ( p[1] == 'x' || p[1] == 'X' ) ) {
|
|
p+= 2;
|
|
len = sscanf(p,"%x" , &ret );
|
|
p += len;
|
|
} else {
|
|
if( p[1] == 0 || p[1] == ',' ) {
|
|
ret = 0; /* only one '0' , must be zero */
|
|
p++;
|
|
} else {
|
|
p+= 1;
|
|
len = sscanf(p,"%o" , &ret );
|
|
p += len;
|
|
}
|
|
}
|
|
bnum = 1;
|
|
} else if( p[0] >= '1' && p[0] <= '9' ) {
|
|
len = sscanf(p,"%d" , (int*)&ret );
|
|
p += len;
|
|
bnum = 1;
|
|
} else if( p[0] == '\'' ) {
|
|
ret = p[1];
|
|
p++;
|
|
} else { /* all for string */
|
|
if ( p[0] == '\"' ) {
|
|
if( p[1] == '\"' ) { /* NULL string */
|
|
ret = 0;
|
|
p+=2;
|
|
} else {
|
|
ret = (unsigned long)(p+1);
|
|
t = strchr( p+1 , '\"' );
|
|
if( t ) {
|
|
*t = 0;
|
|
p = t+1 ;
|
|
} else {
|
|
p++;
|
|
}
|
|
}
|
|
} else {
|
|
if( *p == ',' ) {/* empty ,as NULL string */
|
|
ret = 0;
|
|
p--;
|
|
} else if( *p == ' ' || *p == 0 ) /* one char string ,as char.*/
|
|
ret = *p;
|
|
else /* as string */
|
|
ret = (unsigned long)(p);
|
|
p++;
|
|
}
|
|
}
|
|
t = strchr( p , ',' );
|
|
if( t ) {
|
|
*t = 0;
|
|
*pp = t+1;
|
|
} else { /* p should be the last one */
|
|
while(*p != ' ' && *p != 0 && *p != '\n' )
|
|
p++;
|
|
*p = 0;
|
|
*pp = p;
|
|
}
|
|
if( nag && bnum )
|
|
ret = 0-ret;
|
|
return ret;
|
|
}
|
|
int dbg_parse_cmd( char * cdb )
|
|
{
|
|
unsigned long reg[6];
|
|
unsigned long fun;
|
|
int argc = 0 ;
|
|
char *p = cdb ;
|
|
char *sym = p;
|
|
int ret;
|
|
|
|
//SCU_BUG("CMD=%s\n" , cdb);
|
|
memset( reg , 0 , sizeof reg );
|
|
p = strchr(p , ',');
|
|
if( p ) {
|
|
*p++ = 0;
|
|
while( *p && argc < 6) {
|
|
reg[argc++] = (unsigned long)dbg_get_arg( &p );
|
|
}
|
|
}
|
|
//debug_print("sym=%s,argc=%d,db=%s\n" , sym ,argc , cdb );
|
|
if( sym[0] == '0' && ( sym[1] == 'x' || sym[1] == 'X' ) ) {
|
|
fun = 0;
|
|
sscanf(sym+2,"%lx" , &fun );
|
|
} else {
|
|
fun = kallsyms_lookup_name(sym);
|
|
//debug_print("after lookup symbols,sym=%s,fun=0x%p\n" , sym ,fun);
|
|
}
|
|
|
|
/* 20100409,HSL@RK,use printk to print to buffer.
|
|
*/
|
|
printk("@CALL@ %s(0x%p),argc=%d\n" , sym , (void*)fun , argc);
|
|
if( fun ) {
|
|
ret = __scu_call_wrap( reg,argc,fun);
|
|
} else {
|
|
ret = -EIO;
|
|
}
|
|
/* 20100722,"@return" for function print end tag.
|
|
*/
|
|
printk("@return 0x%x(%d)\n" , ret , ret);
|
|
return ret;
|
|
}
|
|
|
|
#if 0
|
|
/**
|
|
* check arg be a string or int or symbol addr .
|
|
* 1: string , 2: kernel sym , 0:other
|
|
*/
|
|
int rk28_arg_string( unsigned long arg )
|
|
{
|
|
if( arg > (unsigned long)&_end && arg < 0xc8000000 )
|
|
return 1;
|
|
if( arg >= (unsigned long)&_text && arg < (unsigned long)&_end )
|
|
return 2;
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
static struct pt_regs * unwind_get_regs(struct task_struct *tsk)
|
|
{
|
|
struct stackframe frame;
|
|
register unsigned long current_sp asm ("sp");
|
|
int found = 0;
|
|
//unsigned long sc;
|
|
|
|
if (!tsk)
|
|
tsk = current;
|
|
|
|
printk("tsk = %p,comm=%s,pid=%d,pgd=0x%p\n", tsk , tsk->comm , tsk->pid , tsk->mm->pgd );
|
|
if (tsk == current) {
|
|
frame.fp = (unsigned long)__builtin_frame_address(0);
|
|
frame.sp = current_sp;
|
|
frame.lr = (unsigned long)__builtin_return_address(0);
|
|
frame.pc = (unsigned long)unwind_get_regs;
|
|
} else {
|
|
/* task blocked in __switch_to */
|
|
frame.fp = thread_saved_fp(tsk);
|
|
frame.sp = thread_saved_sp(tsk);
|
|
/*
|
|
* The function calling __switch_to cannot be a leaf function
|
|
* so LR is recovered from the stack.
|
|
*/
|
|
frame.lr = 0;
|
|
frame.pc = thread_saved_pc(tsk);
|
|
}
|
|
|
|
while (1) {
|
|
int urc;
|
|
//unsigned long where = frame.pc;
|
|
|
|
urc = unwind_frame(&frame);
|
|
if (urc < 0)
|
|
break;
|
|
//dump_backtrace_entry(where, frame.pc, frame.sp - 4);
|
|
if( frame.pc == (unsigned long)ret_fast_syscall ){
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
if( !found )
|
|
return NULL;
|
|
#if 0
|
|
//printk("FRAME:sp=0x%lx,pc=0x%lx,lr=0x%lx,fp=0x%lx\n" , frame.sp,frame.pc,frame.lr,frame.fp );
|
|
//rk28_printk_mem((unsigned int*)(frame.sp-sizeof(struct pt_regs)),2*sizeof(struct pt_regs)/4+8, NULL );
|
|
sc =*( (unsigned long*)(frame.sp-4));
|
|
if( sc >= (unsigned long)&_text && sc < (unsigned long)&_end ){
|
|
print_symbol("sys call=%s\n",sc );
|
|
}
|
|
#endif
|
|
return (struct pt_regs *)(frame.sp+8); // 8 for reg r4,r5 as fifth and sixth args.
|
|
}
|
|
|
|
struct pt_regs * __scu_get_regs( void )
|
|
{
|
|
return unwind_get_regs( NULL );
|
|
}
|
|
|
|
struct pt_regs * scu_get_task_regs( int pid )
|
|
{
|
|
struct task_struct *t = FIND_TASK_BY_PID( pid );
|
|
return unwind_get_regs( t );
|
|
}
|
|
|
|
/*
|
|
* f: bit0: show kernel , bit1: dump user.
|
|
*/
|
|
int tstack( int pid , int f)
|
|
{
|
|
struct pt_regs * preg;
|
|
struct task_struct *t = FIND_TASK_BY_PID( pid );
|
|
|
|
if( !t ){
|
|
printk("NO task found for pid %d\n" ,pid );
|
|
t = current ;
|
|
}
|
|
preg = unwind_get_regs( t );
|
|
if( f& 1 ) {
|
|
show_stack( t , NULL );
|
|
}
|
|
if( !preg ) {
|
|
printk("NO user stack found for task %s(%d)\n" , t->comm , t->pid );
|
|
} else {
|
|
//printk("user stack found for task %s(%d):\n" , t->comm , t->pid );
|
|
__show_regs( preg );
|
|
if( f & 2 ) {
|
|
#define SHOW_STACK_SIZE (2*1024)
|
|
int len;
|
|
unsigned int *ps = (unsigned int*)kmalloc( SHOW_STACK_SIZE , GFP_KERNEL);
|
|
if( ps ) {
|
|
len = access_process_vm( t , preg->ARM_sp , ps , SHOW_STACK_SIZE, 0 );
|
|
rk28_printk_mem( ps , len/4 , (unsigned int* )preg->ARM_sp );
|
|
kfree( ps );
|
|
}
|
|
}
|
|
}
|
|
return pid;
|
|
}
|
|
|
|
#if 0
|
|
void __rk_force_signal(struct task_struct *tsk, unsigned long addr,
|
|
unsigned int sig, int code )
|
|
{
|
|
struct siginfo si;
|
|
printk("%s::send sig %d to task %s\n" , __func__ , sig , tsk->comm );
|
|
si.si_signo = sig;
|
|
si.si_errno = 0;
|
|
si.si_code = code;
|
|
si.si_addr = (void __user *)addr;
|
|
force_sig_info(sig, &si, tsk);
|
|
}
|
|
int rksignal( int pid , int sig )
|
|
{
|
|
struct task_struct *t = FIND_TASK_BY_PID( pid );
|
|
if( !t )
|
|
t = current ;
|
|
__rk_force_signal( t , 0xc0002234 , sig , 0x524b4b52 );
|
|
return 0x201;
|
|
}
|
|
|
|
#include <linux/tty.h>
|
|
#include <linux/console.h>
|
|
#include <linux/tty_flip.h>
|
|
extern struct console *console_drivers;
|
|
// like : echo rk28_uart_input,"\"pwd|ls,echo fdfdf\"">active
|
|
int rk28_uart_input( char * str )
|
|
{
|
|
char * p = str;
|
|
int indx;
|
|
struct tty_driver *tty_drv = console_drivers->device( console_drivers , &indx );
|
|
struct tty_struct *tty_s = tty_drv->ttys[indx ];
|
|
int flag = TTY_NORMAL;
|
|
|
|
printk("indx=%d, tty drv=%p,tty_s=%p,cur console=%s,next console=%p\n", indx , tty_drv , tty_s ,
|
|
console_drivers->name , console_drivers->next );
|
|
//printk("cmd=%s\n" , str );
|
|
if( !p )
|
|
return -EIO;
|
|
|
|
while( *p ) {
|
|
if( *p == ',' )
|
|
*p = '\n';
|
|
p++;
|
|
}
|
|
*p++ = '\n';
|
|
*p = 0;
|
|
|
|
p = str;
|
|
while( *p ) {
|
|
tty_insert_flip_char(tty_s, *p , flag);
|
|
p++;
|
|
}
|
|
|
|
tty_flip_buffer_push( tty_s );
|
|
return 0x28;
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
extern int kernel_getlog( char ** start , int * offset , int* len );
|
|
int rk28_write_file( char *filename )
|
|
{
|
|
char *procmtd = "/proc/mtd";
|
|
struct file *filp = NULL;
|
|
loff_t pos;
|
|
long fd;
|
|
|
|
ssize_t l=0;
|
|
char pathname[64];
|
|
char buf[1024] ;
|
|
mm_segment_t old_fs;
|
|
struct rtc_time tm;
|
|
ktime_t now;
|
|
char *tmpbuf;
|
|
int mtdidx=0;
|
|
int mtdsize = 0x200000; // 2M
|
|
char *log_buf;
|
|
int log_len;
|
|
|
|
debug_print("%s: filename=%s\n" , __func__ , filename );
|
|
|
|
old_fs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
fd = sys_open( procmtd , O_RDONLY , 0 );
|
|
if( fd >= 0 ) {
|
|
memset( buf , 0 , 1024 );
|
|
l = sys_read( fd , buf , 1024 );
|
|
// debug_print("/proc/mtd,total byte=%d\n" , l );
|
|
tmpbuf = strstr( buf , filename );
|
|
if( tmpbuf ) {
|
|
tmpbuf[10] = 0;
|
|
mtdsize = simple_strtoul(tmpbuf-19, NULL , 16);
|
|
mtdidx = tmpbuf[-22];
|
|
//debug_print("size=%s\n,idx=%s\nmtdsize=%x , mtdidx=%d" , tmpbuf-19 , tmpbuf - 22 ,
|
|
// mtdsize , mtdidx );
|
|
mtdsize *= 512;
|
|
mtdidx -= '0';
|
|
}
|
|
sys_close( fd );
|
|
} else {
|
|
debug_print("open %s failed\n" , procmtd );
|
|
}
|
|
sprintf(pathname , "/dev/block/mtdblock%d" , mtdidx );
|
|
filp = filp_open(pathname, O_WRONLY , 0);
|
|
if( IS_ERR(filp) ) {
|
|
debug_print("open %s failed n" , pathname );
|
|
goto out_print;
|
|
}
|
|
if (!(filp->f_op->write || filp->f_op->aio_write)) {
|
|
debug_print("can not write file %s \n" , pathname );
|
|
goto close_file;
|
|
}
|
|
now = ktime_get();
|
|
rtc_time_to_tm( now.tv.sec , &tm );
|
|
printk( "\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
|
|
"++++++++++RECORD LOG AT %04d-%02d-%02d %02d:%02d:%02d++++++++++\n"
|
|
"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n\n\n"
|
|
,
|
|
tm.tm_year+1900 , tm.tm_mon , tm.tm_mday , tm.tm_hour , tm.tm_min , tm.tm_sec );
|
|
/* 20090924,HSL,FTL only intial first 256M at loader , MUST write 32 sector one time */
|
|
//debug_print("write first pack , pos=%d\n" , pos ); /* pos = 2 ?? */
|
|
kernel_getlog(&log_buf , NULL , &log_len );
|
|
log_len = (log_len+(32*512-1)) / (32*512) * (32*512);
|
|
pos = 0;
|
|
l = vfs_write( filp , log_buf , log_len , &pos );
|
|
do_fsync(filp, 1);
|
|
close_file:
|
|
filp_close(filp , NULL);
|
|
out_print:
|
|
set_fs(old_fs);
|
|
debug_print("\nlog len=%d,write=%d\n" ,log_len , l);
|
|
return 0x2b;
|
|
}
|
|
#endif
|
|
|
|
#if 1
|
|
/*
|
|
*
|
|
* 20091027,2808SDK,
|
|
* lcd off:byte:81748000,word:39100000.
|
|
* lcd on: byte:90742000,word:43158000 %9.5
|
|
*
|
|
* 20091111,2806 ruiguan,
|
|
* lcd off: byte: 81883000,word: 39209000
|
|
* lcd on: byte: 90843000,word: 43260000
|
|
|
|
* 20100516,281x, 133 ddr , lcd on.
|
|
* need 151432000 ns to copy 4096 Kbytes
|
|
* need 85340000 ns to copy 1024 Kwords
|
|
LCD OFF.
|
|
* need 144880000 ns to copy 4096 Kbytes
|
|
* need 83100000 ns to copy 1024 Kwords
|
|
20100517,281x,200M ddr lcd on.
|
|
* need 90024000 ns to copy 4096 Kbytes
|
|
* need 47668000 ns to copy 1024 Kwords
|
|
lcd off
|
|
need 87564000 ns to copy 4096 Kbytes
|
|
need 46956000 ns to copy 1024 Kwords
|
|
20100518,266M ddr. lcd on
|
|
need 84460000 ns to copy 4096 Kbytes
|
|
need 41036000 ns to copy 1024 Kwords
|
|
|
|
need 204568000 ns to copy 4096 Kbytes
|
|
need 116388000 ns to copy 1024 Kwords
|
|
|
|
ddr 330M,lcd on.
|
|
need 81944000 ns to copy 4096 Kbytes
|
|
need 37640000 ns to copy 1024 Kwords
|
|
ahb 180M.ddr 330M.
|
|
need 88908000 ns to copy 4096 Kbytes
|
|
need 38108000 ns to copy 1024 Kwords
|
|
|
|
ahb 200M,DDR 380M,lcd on.
|
|
need 79456000 ns to copy 4096 Kbytes
|
|
need 34216000 ns to copy 1024 Kwords %0.14.
|
|
|
|
need 79432000 ns to copy 4096 Kbytes
|
|
need 34204000 ns to copy 1024 Kwords
|
|
LCD OFF.
|
|
need 77260000 ns to copy 4096 Kbytes
|
|
need 33768000 ns to copy 1024 Kwords
|
|
|
|
need 77228000 ns to copy 4096 Kbytes
|
|
need 33764000 ns to copy 1024 Kwords %0.01
|
|
*/
|
|
|
|
/*
|
|
on rk29
|
|
dyn desktop:
|
|
[ 63.010000] @CALL@ rk28_memcpy(0xc070148c),argc=0
|
|
[ 63.100000] need 90342667 ns to copy 4096 Kbytes
|
|
[ 63.140000] need 38885333 ns to copy 1024 Kwords
|
|
[ 63.160000] need 13030791 ns to memcpy 4096 Kbytes
|
|
[ 63.160000] @return 0x2c(44)
|
|
# echo rk28_memcpy > cal
|
|
[ 65.680000] @CALL@ rk28_memcpy(0xc070148c),argc=0
|
|
[ 65.740000] need 57542915 ns to copy 4096 Kbytes
|
|
[ 65.770000] need 30017666 ns to copy 1024 Kwords
|
|
[ 65.810000] need 32929083 ns to memcpy 4096 Kbytes
|
|
[ 65.810000] @return 0x2c(44)
|
|
# echo rk28_memcpy > cal
|
|
[ 67.400000] @CALL@ rk28_memcpy(0xc070148c),argc=0
|
|
[ 67.460000] need 52001876 ns to copy 4096 Kbytes
|
|
[ 67.490000] need 29809209 ns to copy 1024 Kwords
|
|
# [ 67.510000] need 20318709 ns to memcpy 4096 Kbytes
|
|
[ 67.510000] @return 0x2c(44)
|
|
# echo rk28_memcpy > cal
|
|
[ 71.800000] @CALL@ rk28_memcpy(0xc070148c),argc=0
|
|
[ 71.860000] need 57265835 ns to copy 4096 Kbytes
|
|
[ 71.900000] need 32522127 ns to copy 1024 Kwords
|
|
[ 71.930000] need 27615668 ns to memcpy 4096 Kbytes
|
|
[ 71.930000] @return 0x2c(44)
|
|
|
|
|
|
static desktop:
|
|
|
|
[ 171.880000] @CALL@ rk28_memcpy(0xc070148c),argc=0
|
|
[ 171.910000] need 27547043 ns to copy 4096 Kbytes
|
|
[ 171.920000] need 8993501 ns to copy 1024 Kwords
|
|
[ 171.930000] need 6791584 ns to memcpy 4096 Kbytes
|
|
[ 171.930000] @return 0x2c(44)
|
|
# echo rk28_memcpy > cal
|
|
[ 174.050000] @CALL@ rk28_memcpy(0xc070148c),argc=0
|
|
[ 174.080000] need 26437334 ns to copy 4096 Kbytes
|
|
[ 174.090000] need 8701667 ns to copy 1024 Kwords
|
|
[ 174.100000] need 6639375 ns to memcpy 4096 Kbytes
|
|
[ 174.100000] @return 0x2c(44)
|
|
# echo rk28_memcpy > cal
|
|
[ 176.290000] @CALL@ rk28_memcpy(0xc070148c),argc=0
|
|
[ 176.320000] need 26692502 ns to copy 4096 Kbytes
|
|
[ 176.330000] need 8659126 ns to copy 1024 Kwords
|
|
[ 176.340000] need 6702001 ns to memcpy 4096 Kbytes
|
|
[ 176.340000] @return 0x2c(44)
|
|
# echo rk28_memcpy > cal
|
|
[ 177.710000] @CALL@ rk28_memcpy(0xc070148c),argc=0
|
|
[ 177.740000] need 27578291 ns to copy 4096 Kbytes
|
|
[ 177.750000] need 8740042 ns to copy 1024 Kwords
|
|
[ 177.760000] need 6727458 ns to memcpy 4096 Kbytes
|
|
[ 177.760000] @return 0x2c(44)
|
|
|
|
*/
|
|
int rkmemcpy( void )
|
|
{
|
|
#define PAGE_ORDER 7
|
|
ktime_t now0,now1;
|
|
|
|
unsigned long pg;
|
|
unsigned long src = 0xc0010000;
|
|
int i = 8,k=0;
|
|
int bytes = ((1<<PAGE_ORDER)*PAGE_SIZE);
|
|
|
|
pg = __get_free_pages(GFP_KERNEL , PAGE_ORDER );
|
|
if( !pg ) {
|
|
printk("alloc %d pages total %dK bytes failed\n" , (1<<PAGE_ORDER) , bytes/(1024));
|
|
return -ENOMEM;
|
|
}
|
|
now0 = ktime_get();
|
|
while( k < i ) {
|
|
char *p = (char*)pg;
|
|
char *q = (char*)src;
|
|
char *m = q+bytes;
|
|
while( q < m )
|
|
*p++ = *q++;
|
|
k++;
|
|
}
|
|
now1 = ktime_get();;
|
|
printk("need %Ld ns to copy %d Kbytes \n" ,
|
|
ktime_to_ns( ktime_sub( now1 , now0 ) ), bytes * i /1024 );
|
|
now0 = ktime_get();
|
|
k = 0;
|
|
while( k < i ) {
|
|
int *p = (int*)pg;
|
|
int *q = (int*)src;
|
|
int *m = q+bytes/sizeof(int);
|
|
while( q < m )
|
|
*p++ = *q++;
|
|
k++;
|
|
}
|
|
now1 = ktime_get();
|
|
|
|
printk("need %Ld ns to copy %d Kwords \n" ,
|
|
ktime_to_ns( ktime_sub( now1 , now0 ) ), bytes * i / sizeof (int) /1024 );
|
|
|
|
now0 = ktime_get();
|
|
for( k = 0 ; k < i ; k++ )
|
|
memcpy((void*)pg,(void*)src , bytes );
|
|
now1 = ktime_get();
|
|
printk("need %Ld ns to memcpy %d Kbytes \n" ,
|
|
ktime_to_ns( ktime_sub( now1 , now0 ) ), bytes * i / 1024 );
|
|
|
|
free_pages( pg , PAGE_ORDER );
|
|
return 0x2c;
|
|
}
|
|
#endif
|
|
|
|
int rknow( int loop , int prtk )
|
|
{
|
|
ktime_t ktime_now;
|
|
struct timespec ts;
|
|
struct rtc_time tm;
|
|
|
|
if( loop > 20 )
|
|
loop = 20;
|
|
do {
|
|
ktime_now = ktime_get();
|
|
getnstimeofday(&ts);
|
|
rtc_time_to_tm(ts.tv_sec, &tm);
|
|
printk("now=%lld ns "
|
|
"(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
|
|
ktime_to_ns(ktime_now),
|
|
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
|
tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
|
|
udelay( 31 );
|
|
loop --;
|
|
}while( loop > 0 );
|
|
return 0x2c;
|
|
}
|
|
|
|
#if 0
|
|
/* 1,2=0 , 0 = lr */
|
|
void rk28_return( void )
|
|
{
|
|
printk("return addr:\n 0: 0x%p " "1: 0x%p " "2: 0x%p\n", __builtin_return_address(0) ,
|
|
__builtin_return_address(1) , __builtin_return_address(2));
|
|
}
|
|
#endif
|
|
|
|
int dl( int ms )
|
|
{
|
|
mdelay( ms );
|
|
printk("delay %d ms\n" , ms );
|
|
return ms;
|
|
}
|
|
|
|
int irq_dl( int ms )
|
|
{
|
|
unsigned long flags;
|
|
local_irq_save(flags);
|
|
mdelay( ms );
|
|
local_irq_restore(flags);
|
|
printk("delay %d ms\n" , ms );
|
|
return ms;
|
|
}
|
|
|
|
/*
|
|
* read a phy addr value , len is word.
|
|
*/
|
|
int dd( unsigned int phy_addr,int len ,unsigned int value )
|
|
{
|
|
int size = len*4;
|
|
unsigned int * ptr;
|
|
int wr = 0;
|
|
int map = 0;
|
|
if( !len ){
|
|
printk("invalid len=%d\n" , len );
|
|
return 0;
|
|
}
|
|
/* we want to write? write 0?*/
|
|
if( value || len == 1 ) {
|
|
size = 4;
|
|
wr = 1;
|
|
}
|
|
if(phy_addr < PAGE_OFFSET ) {
|
|
ptr = (unsigned int *)ioremap( phy_addr , size );
|
|
if( !ptr ) {
|
|
printk("map addr 0x%x failed\n" , phy_addr );
|
|
return -ENOMEM;
|
|
}
|
|
map = 1;
|
|
} else {
|
|
ptr = (unsigned int *)phy_addr;
|
|
}
|
|
if( wr ) {
|
|
*ptr = value ;
|
|
dmb();
|
|
}
|
|
rk28_printk_mem( ptr , len , (unsigned int*)phy_addr );
|
|
if( map ) {
|
|
iounmap(ptr);
|
|
}
|
|
return size;
|
|
}
|
|
|