rk: add ft test

This commit is contained in:
xxx
2013-06-04 14:47:06 +08:00
parent b1bdb9886f
commit 4355dc0e4a
7 changed files with 741 additions and 0 deletions

View File

@@ -47,5 +47,10 @@ config PM_TEST_DELAYLINE
bool "Get delayline value"
help
Use to get delayline value
config PM_TEST_FT
bool "Test kernel for FT"
help
Use to test kernel for FT
endif

1
arch/arm/plat-rk/rk_pm_tests/Makefile Normal file → Executable file
View File

@@ -9,3 +9,4 @@ obj-$(CONFIG_PM_TEST_CPU_USAGE) += cpu_usage.o
obj-$(CONFIG_PM_TEST_SUSPEND_DBG) += rk_suspend_test.o
obj-$(CONFIG_PM_TEST_CLK_AUTO_VOLT) += clk_auto_volt.o
obj-$(CONFIG_PM_TEST_DELAYLINE) += delayline.o
obj-$(CONFIG_PM_TEST_FT) += ft/

View File

@@ -0,0 +1,3 @@
obj-y += ft_cpu_tst.o
obj-y += ft_cpu_tst1.o
obj-y += ft_test.o

View File

@@ -0,0 +1,228 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
//#include <asm/memory.h>
//#include <mach/io.h>
.text
//_off 12 -20
.macro test_cpus_pc_jump , _base,_reg, _off
ldr \_reg,[pc]
str \_reg,[\_base]
mov \_reg,pc
str \_reg,[\_base,#4]
add \_reg,\_off //pc offset
str \_reg,[\_base,#8]// offset start
ldr pc, [\_base,#8]
ldr \_reg,[pc]
ldr \_reg,[pc]
.endm
.macro cpus_tst_get_opcode, _reg0
lsl \_reg0,\_reg0,#4
lsr \_reg0,\_reg0,#24
.endm
.macro cpus_tst_code_lsl , _reg0
ldr \_reg0,[pc]
mov \_reg0,\_reg0
lsl \_reg0,\_reg0,#4
lsr \_reg0,\_reg0,#24
cmp \_reg0,#0x1a
bne l1_test_error
.endm
.macro cpus_tst_code_lsr , _reg0
ldr \_reg0,[pc]
lsl \_reg0,\_reg0,#4
lsr \_reg0,\_reg0,#24
cmp \_reg0,#0x1a
bne l1_test_error
.endm
.macro cpus_tst_code_cmp, _reg0
ldr \_reg0,[pc,#4]
lsl \_reg0,\_reg0,#4
lsr \_reg0,\_reg0,#24
cmp \_reg0,#0x35
bne l1_test_error
.endm
.macro cpus_tst_code_sub, _reg0,_reg1
mov \_reg0,pc
sub \_reg0,#4
ldr \_reg1,[\_reg0]
lsl \_reg1,\_reg1,#4
lsr \_reg1,\_reg1,#24
cmp \_reg1,#0x24
bne l1_test_error
.endm
.macro cpus_tst_code_ldr, _reg0,_reg1
mov \_reg0,pc
sub \_reg0,#0
ldr \_reg1,[\_reg0]
lsl \_reg1,\_reg1,#4
lsr \_reg1,\_reg1,#24
cmp \_reg1,#0x59
bne l1_test_error
.endm
.macro cpus_tst_code_bne, _reg0,_reg1
ldr \_reg0,[pc,#12]
lsr \_reg1,\_reg0,#28
lsl \_reg0,\_reg0,#4
lsr \_reg0,\_reg0,#24
cmp \_reg1,#0x1 //
bne l1_test_error
cmp \_reg0,#0xa0
bne l1_test_error
.endm
.macro test_cpus_l1_code_base
//r4 base
mov r5,#16
test_cpus_pc_jump r4,r3,r5
//add r4,#8
mov r6,r4
mov r8,#20
test_cpus_pc_jump r6,r7,r8
//add r4,#8
cpus_tst_code_lsl r5
cpus_tst_code_lsr r7
cpus_tst_code_cmp r9
cpus_tst_code_sub r11,r10,
cpus_tst_code_ldr r12,r8
cpus_tst_code_bne r6,r7
.endm
.macro test_cpus_l1_code_base_
mov r4,r4
mov r6,r6
mov r7,r7
mov r8,r8
mov r4,r4
mov r6,r6
mov r7,r7
mov r8,r8
mov r4,r4
mov r6,r6
mov r4,r4
mov r6,r6
mov r7,r7
mov r8,r8
mov r4,r4
mov r6,r6
mov r7,r7
mov r8,r8
mov r4,r4
mov r6,r6
mov r7,r7
mov r8,r8
mov r4,r4
mov r6,r6
mov r7,r7
.endm
.macro test_cpus_l1_loop_100
.endm
.macro test_cpus_l1_loop_500
#if 1
test_cpus_l1_code_base
test_cpus_l1_code_base
#else
test_cpus_l1_code_base_
test_cpus_l1_code_base_
test_cpus_l1_code_base_
test_cpus_l1_code_base_
test_cpus_l1_code_base_
test_cpus_l1_code_base_
#endif
.endm
.macro test_cpus_l1_loop_1_k
test_cpus_l1_loop_500
test_cpus_l1_loop_500
.endm
.macro test_cpus_l1_loop_4_k
test_cpus_l1_loop_1_k
test_cpus_l1_loop_1_k
test_cpus_l1_loop_1_k
test_cpus_l1_loop_1_k
test_cpus_l1_loop_500
.endm
.macro test_cpus_l1_loop_10_k
test_cpus_l1_loop_4_k
test_cpus_l1_loop_4_k
test_cpus_l1_loop_4_k
test_cpus_l1_loop_4_k
.endm
.macro test_cpus_l1_loop_50_k
test_cpus_l1_loop_10_k
test_cpus_l1_loop_10_k
test_cpus_l1_loop_10_k
test_cpus_l1_loop_10_k
test_cpus_l1_loop_10_k
.endm
.macro test_cpus_l1_loop_200_k
test_cpus_l1_loop_50_k
test_cpus_l1_loop_50_k
test_cpus_l1_loop_50_k
test_cpus_l1_loop_50_k
.endm

View File

@@ -0,0 +1,98 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include "cpu_test.h"
.text
//r0,array0
ENTRY(test_cpus_l0)
stmfd sp!, { r1 - r12, lr }
1: mov r0,r0
//b 1b
mov r4,r0
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
//test_cpus_l1_loop_200_k
//test_cpus_l1_loop_200_k
//test_cpus_l1_loop_200_k
1: mov r1,r1
//b 1b
ldmfd sp!, { r1 - r12, pc }
l1_test_error:
mov r1,r1
mov r1,r1
mov r1,r1
1: mov r1,r1
b 1b
ENDPROC(test_cpus_l0)
//r0 adr base,r1 end adr,r2 tst date
ENTRY(test_cpus_l2)
stmfd sp!, { r3 - r12, lr }
1: mov r0,r0
//b 1b
mov r4,r0
sub r5,r1,#4
l2_write:
str r2,[r4],#4
cmp r4,r5
bls l2_write
mov r4,r0
l2_check:
ldr r6,[r4],#4
cmp r6,r2
bne l2_test_error
mov r6,#0
cmp r4,r5
bhi l2_tst_end
ldr r7,[r4],#4
cmp r7,r2
bne l2_test_error
mov r7,#0
cmp r4,r5
bls l2_check
l2_tst_end:
3: mov r0,#0
//b 3b
ldmfd sp!, { r3 - r12, pc }
l2_test_error:
1: mov r0,#1
//b 1b
ldmfd sp!, { r3 - r12, pc }
ENDPROC(test_cpus_l2)
/***************while for dbg***************/
ENTRY(rk30_cpu_while_tst)
stmfd sp!, { r3 - r12, lr }
1: mov r3,r3
b 1b
ldmfd sp!, { r3 - r12, pc }
ENDPROC(rk30_cpu_while_tst)

View File

@@ -0,0 +1,44 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
//#include <asm/memory.h>
//#include <mach/io.h>
#include "cpu_test.h"
.text
//r0,array0
ENTRY(test_cpus_l1)
stmfd sp!, { r1 - r12, lr }
1: mov r0,r0
//b 1b
mov r4,r0
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
test_cpus_l1_loop_200_k
1: mov r1,r1
//b 1b
ldmfd sp!, { r1- r12, pc }
l1_test_error:
1: mov r1,r1
b 1b
ENDPROC(test_cpus_l1)

View File

@@ -0,0 +1,362 @@
/* arch/arm/mach-rk30/rk_pm_tests.c
*
* Copyright (C) 2010 ROCKCHIP, Inc.
*
* 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.
*
*/
/*************************************************************************/
/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED.*/
/*************************************************************************
FILE : rk_pm_tests.c
DESC : Power management in dynning state
AUTHOR : chenxing
DATE : 2012-7-2
NOTES :
$LOG: GPIO.C,V $
REVISION 0.01
#include <linux/clk.h>
#include <linux/kobject.h>
***************************************************************************/
#include <linux/string.h>
#include <linux/resume-trace.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/freezer.h>
#include <linux/dma-mapping.h>
#include <linux/regulator/machine.h>
#include <plat/dma-pl330.h>
#include <linux/mfd/wm831x/core.h>
#include <linux/sysfs.h>
#include <linux/err.h>
#include <linux/kthread.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/gpio.h>
//#include <mach/ddr.h>
#if 0
#include "rk_pm_tests.h"
#include "clk_rate.h"
#include "clk_volt.h"
#include "maxfreq.h"
#include "freq_limit.h"
#include "cpu_usage.h"
#include "rk_suspend_test.h"
#include "clk_auto_volt.h"
#include "delayline.h"
#endif
#define ft_printk(fmt, arg...) \
printk(KERN_EMERG fmt, ##arg)
//KERN_DEBUG
#define ft_printk_dbg(fmt, arg...) \
printk(KERN_EMERG fmt, ##arg)
//KERN_DEBUG
#define ft_printk_info(fmt, arg...) \
printk(KERN_EMERG fmt, ##arg)
static unsigned long arm_setup2_rate=1608*1000*1000;
//0-15 :test setup1
#define CPU_TST_L1 (1<<0)
#define CPU_TST_L2 (1<<1)
//16-31 :test setup2
#define CPU_TST_L1_STP2 (1<<16)
#define CPU_TST_L2_STP2 (1<<17)
static DEFINE_PER_CPU(int, cpu_tst_flags)=(CPU_TST_L1|CPU_TST_L2|CPU_TST_L1_STP2|CPU_TST_L2_STP2);
static struct clk *arm_clk;
#define FT_CLIENT_READY_PIN RK30_PIN3_PB3
#define FT_CLIENT_IDLE_PIN RK30_PIN0_PA3
static DEFINE_PER_CPU(wait_queue_head_t, wait_rate);
/************************************l1 tst***************************************/
void test_cpus_l1(u32 *data);
void test_cpus_l0(u32 *data);
static struct semaphore sem = __SEMAPHORE_INITIALIZER(sem, 0);
void ft_cpu_l1_test(u32 cnt)
{
u32 cpu = smp_processor_id();
int test_array[100];
int i;
ft_printk_dbg("l1_test cpu=%d start\n",cpu);
for(i=0;i<cnt;i++)
{
test_cpus_l1(&test_array[0]);
barrier();
}
for(i=0;i<cnt;i++)
{
test_cpus_l0(&test_array[0]);
barrier();
}
ft_printk_dbg("l1_test cpu=%d end\n",cpu);
}
/************************************l2 tst***************************************/
static struct semaphore sem_step2 = __SEMAPHORE_INITIALIZER(sem_step2, 0);
int test_cpus_l2(char *data_s,char *data_e,u32 data);
#define l1_DCACHE_SIZE (32*1024)
#define l1_DCACHE_SIZE_M (l1_DCACHE_SIZE*32)
#define BUF_SIZE (l1_DCACHE_SIZE_M*4)// tst buf size
static char memtest_buf0[BUF_SIZE] __attribute__((aligned(4096)));
#if (NR_CPUS>=2)
static char memtest_buf1[BUF_SIZE] __attribute__((aligned(4096)));
#if (NR_CPUS>=4)
static char memtest_buf2[BUF_SIZE] __attribute__((aligned(4096)));
static char memtest_buf3[BUF_SIZE] __attribute__((aligned(4096)));
#if (NR_CPUS>=8)
static char memtest_buf4[BUF_SIZE] __attribute__((aligned(4096)));
static char memtest_buf5[BUF_SIZE] __attribute__((aligned(4096)));
static char memtest_buf6[BUF_SIZE] __attribute__((aligned(4096)));
static char memtest_buf7[BUF_SIZE] __attribute__((aligned(4096)));
#endif
#endif
#endif
static char *l2_test_buf[NR_CPUS]=
{
memtest_buf0,
#if (NR_CPUS>=2)
memtest_buf1,
#if (NR_CPUS>=4)
memtest_buf2,
memtest_buf3,
#if (NR_CPUS>=8)
memtest_buf4,
memtest_buf5,
memtest_buf6,
memtest_buf7,
#endif
#endif
#endif
};
int ft_test_cpus_l2(char *data_s,u32 buf_size,u32 cnt)
{
int i,j;
int ret=0;
int test_size=l1_DCACHE_SIZE;
for(j=0;j<cnt;j++)
{
for(i=0;i<buf_size;)
{
ret=test_cpus_l2(data_s+i,data_s+i+test_size,0xffffffff);
if(ret)
return -1;
ret=test_cpus_l2(data_s+i,data_s+i+test_size,0);
if(ret)
return -1;
ret=test_cpus_l2(data_s+i,data_s+i+test_size,0xaaaaaaaa);
if(ret)
return -1;
i+=test_size;
if((i+test_size)>buf_size)
break;
}
}
return 0;
}
/*************************************816 tst case**************************************/
void ft_cpu_test_step1(void)
{
u32 temp=-1;
u32 cpu = smp_processor_id();
//arm rate init
ft_cpu_l1_test(10);
per_cpu(cpu_tst_flags, cpu)&=~CPU_TST_L1;
temp=ft_test_cpus_l2(l2_test_buf[cpu],sizeof(char)*BUF_SIZE,18);
if(!temp)
per_cpu(cpu_tst_flags, cpu)&=~CPU_TST_L2;
up(&sem);
}
/*************************************hight rate tst case**************************************/
void ft_cpu_test_step2(void)
{
u32 temp=-1;
u32 cpu = smp_processor_id();
//arm rate init
ft_cpu_l1_test(10*2);
per_cpu(cpu_tst_flags, cpu)&=~CPU_TST_L1_STP2;
temp=ft_test_cpus_l2(l2_test_buf[cpu],sizeof(char)*BUF_SIZE,20*2);
if(!temp)
per_cpu(cpu_tst_flags, cpu)&=~CPU_TST_L2_STP2;
up(&sem_step2);
}
// tst thread callback for per cpu
static int ft_cpu_test(void *data)
{
u32 cpu = smp_processor_id();
ft_cpu_test_step1();
//arm hight rate
wait_event_freezable(per_cpu(wait_rate, cpu), (clk_get_rate(arm_clk)==arm_setup2_rate)||kthread_should_stop());
ft_cpu_test_step2();
return 0;
}
static int __init rk_ft_tests_init(void)
{
int cpu, ret = 0;
struct sched_param param = { .sched_priority = 0 };
arm_clk=clk_get(NULL, "cpu");
if (IS_ERR(arm_clk))
arm_setup2_rate=0;
for (cpu = 0; cpu < NR_CPUS; cpu++) {
init_waitqueue_head(&per_cpu(wait_rate, cpu));
}
for (cpu = 0; cpu < NR_CPUS; cpu++) {
struct task_struct *task = kthread_create(ft_cpu_test, NULL, "ft_cpu_test%d", cpu);
sched_setscheduler_nocheck(task, SCHED_RR, &param);
get_task_struct(task);
kthread_bind(task, cpu);
wake_up_process(task);
}
return ret;
}
core_initcall(rk_ft_tests_init);
static int rk_ft_tests_over(void)
{
int cpu, ret = 0;
for (cpu = 0; cpu < NR_CPUS; cpu++)
down(&sem);
ft_printk_info("arm=%lu,ddr=%lu\n",clk_get_rate(arm_clk),clk_get_rate(clk_get(NULL, "ddr")));
ret=per_cpu(cpu_tst_flags, 0)|per_cpu(cpu_tst_flags, 1)|per_cpu(cpu_tst_flags, 2)|per_cpu(cpu_tst_flags, 3);
ret&=0xffff;// test setup1
ft_printk_dbg("per cpu setup1=%x\n",ret);
if(ret)
ft_printk("#R01KERNEL*\n");
else
ft_printk("#R00KERNEL*\n");
if(arm_setup2_rate)
{
ft_printk("#SHSPEED*\n");
#if 0
// send msg to ctr board to up the volt
gpio_direction_output(FT_CLIENT_READY_PIN, GPIO_HIGH);
gpio_direction_input(FT_CLIENT_IDLE_PIN);
// waiting for volt upping ok
while( 0 == gpio_get_value(FT_CLIENT_IDLE_PIN));
gpio_set_value(FT_CLIENT_READY_PIN, GPIO_LOW);
#endif
clk_set_rate(arm_clk,arm_setup2_rate);
for (cpu = 0; cpu < NR_CPUS; cpu++)
wake_up(&per_cpu(wait_rate, cpu));
for (cpu = 0; cpu < NR_CPUS; cpu++)
down(&sem_step2);
ft_printk_info("arm=%lu,ddr=%lu\n",clk_get_rate(arm_clk),clk_get_rate(clk_get(NULL, "ddr")));
ret=per_cpu(cpu_tst_flags, 0)|per_cpu(cpu_tst_flags, 1)|per_cpu(cpu_tst_flags, 2)|per_cpu(cpu_tst_flags, 3);
ret&=(0xffff<<16);// test setup1
ft_printk_dbg("per cpu setup2=%x\n",ret);
if(ret)
ft_printk("#R01HSPEED*\n");
else
ft_printk("#R00HSPEED*\n");
}
ft_printk("#END1F*\n");
while(1);
return ret;
}
late_initcall_sync(rk_ft_tests_over);