- 论坛徽章:
- 0
|
错误信息如下:
Unable to handle kernel NULL pointer dereference at virtual address 00000403
pgd = c1250000
[00000403] *pgd=32a16031, *pte=00000000, *ppte=00000000
Internal error: Oops: 817 [#1]
Modules linked in: s3c2440_iocon
CPU: 0
PC is at memcpy+0xb0/0x480
LR is at __kfifo_put+0x54/0x78
pc : [<c0117ef0>] lr : [<c004c658>] Not tainted
sp : c314fecc ip : c314fef8 fp : c314fef4
r10: c02c64e8 r9 : 0002aba4 r8 : c314ffb0
r7 : c314ff1b r6 : c3d95f40 r5 : 00000001 r4 : 00000001
r3 : 00000001 r2 : 00000001 r1 : c314ff1c r0 : 00000403
Flags: Nzcv IRQs off FIQs on Mode SVC_32 Segment user
Control: C000717F Table: 31250000 DAC: 00000015
Process landtop (pid: 792, stack limit = 0xc314e194)
Stack: (0xc314fecc to 0xc3150000)
fec0: 00000403 00000001 00000001 c3d95f40 c314ff1b
fee0: c314ffb0 0002aba4 c314ff14 c314fef8 c004c658 c0117e50 00000013 00000002
ff00: 00000004 c02dc0e4 c314ff38 c314ff18 c013680c c004c614 0102aba4 c3c43f40
ff20: 00000000 00000000 00000031 c314ff5c c314ff3c c0022af0 c01367b0 c02c6edc
ff40: 00000031 c3c43f40 c314ffb0 c314ffb0 c314ff7c c314ff60 c0022c4c c0022ab4
ff60: ffffffff c314ffec 00000000 c0278ffc c314ffac c314ff80 c0022dd4 c0022bac
ff80: c314e04c 00000001 ffffffff c314ffec 00000000 c0278ffc 0002ab48 400eb118
ffa0: 00000000 c314ffb0 c0021bf0 c0022d94 0002bf68 00000000 00000000 0000021c
ffc0: 400dae40 000322d0 bdfff0f8 00000005 0002ab48 0002aba4 400eb118 0002aba8
ffe0: 00000063 bdffefd4 0002bf6b 40096c04 80000010 ffffffff 00000014 00000000
Backtrace:
[<c0117e40>] (memcpy+0x0/0x480) from [<c004c658>] (__kfifo_put+0x54/0x7
r9 = 0002ABA4 r8 = C314FFB0 r7 = C314FF1B r6 = C3D95F40
r5 = 00000001 r4 = 00000001 r0 = 00000403
[<c004c604>] (__kfifo_put+0x0/0x7 from [<c013680c>] (s3c2440_fpga_irq_rx+0x6c/0x90)
r7 = C02DC0E4 r6 = 00000004 r5 = 00000002 r4 = 00000013
[<c01367a0>] (s3c2440_fpga_irq_rx+0x0/0x90) from [<c0022af0>] (__do_irq+0x4c/0x8
r7 = 00000031 r6 = 00000000 r5 = 00000000 r4 = C3C43F40
[<c0022aa4>] (__do_irq+0x0/0x8 from [<c0022c4c>] (do_edge_IRQ+0xb0/0x12c)
r8 = C314FFB0 r7 = C314FFB0 r6 = C3C43F40 r5 = 00000031
r4 = C02C6EDC
[<c0022b9c>] (do_edge_IRQ+0x0/0x12c) from [<c0022dd4>] (asm_do_IRQ+0x50/0x13
r7 = C0278FFC r6 = 00000000 r5 = C314FFEC r4 = FFFFFFFF
[<c0022d84>] (asm_do_IRQ+0x0/0x13 from [<c0021bf0>] (__irq_usr+0x30/0x160)
Code: e3520002 e4d13001 a4d14001 c4d15001 (e4c03001)
<0>Kernel panic - not syncing: Aiee, killing interrupt handler!
请高手发表点见解,驱动源代码如下
#define DEVICE_NAME "fpga"
#define FPGA_MAJOR 246
#define NR_CHANNEL 8 //fpga通道数
#define BUF_SIZE 2048 //buf大小
//#define READ_SIZE 1024 //读取字节数
struct kfifo *read_fifo[NR_CHANNEL];
static spinlock_t read_lock[NR_CHANNEL];//= {SPIN_LOCK_UNLOCKED,SPIN_LOCK_UNLOCKED,SPIN_LOCK_UNLOCKED,SPIN_LOCK_UNLOCKED,};
spinlock_t s3c2440_fpga_lock=SPIN_LOCK_UNLOCKED;
typedef struct {
void *s3c2440_Rx_Addr[8];
void *s3c2440_Conf_Addr[8];
void *s3c2440_Stat_Addr[8];
void *s3c2440_Txrdy_Addr;
void *s3c2440_Rxrdy_Addr;
void *s3c2440_Version_Addr[2];
}read_addr;
read_addr s3c2440_fpgaread;
void s3c2440_fpga_ioremap_init (void)
{
unsigned char i;
for(i=0;i<8;i++)
{
s3c2440_fpgaread.s3c2440_Rx_Addr=ioremap_nocache((0x10000020+4*i),4);
s3c2440_fpgaread.s3c2440_Stat_Addr=ioremap_nocache((0x100000a0+4*i),4);
}
s3c2440_fpgaread.s3c2440_Txrdy_Addr=ioremap_nocache(0x100000c0,4);
s3c2440_fpgaread.s3c2440_Rxrdy_Addr=ioremap_nocache(0x100000c4,4);
for(i=0;i<2;i++){
s3c2440_fpgaread.s3c2440_Version_Addr=ioremap_nocache(0x100000cc+4*i,4);}
}
/*
unsigned int kfifo_put(struct kfifo *fifo,unsigned char *buffer,unsigned int len)
{
spin_lock(fifo->lock);
len=__kfifo_put(fifo,buffer,len);
spin_unlock(fifo->lock);
return len;
}
unsigned int kfifo_get(struct kfifo *fifo,unsigned char *buffer,unsigned int len)
{
spin_lock(fifo->lock);
len=__kfifo_get(fifo,buffer,len);
spin_unlock(fifo->lock);
return len;
}
*/
/*
***************************************************************************
** func name : s3c2440_fpga_irq_rx
** description : 中断接收服务程序
**
****************************************************************************
*/
static irqreturn_t s3c2440_fpga_irq_rx(int irq,void *dev_id,struct pt_regs *regs)
{
unsigned char tmp=0;
unsigned char read_data=0;
unsigned char i=0;
if((tmp=readb(s3c2440_fpgaread.s3c2440_Rxrdy_Addr)))//read rxsts reg
{
for(i=0;i<8;i++)
{
if((tmp>>i)&0x01)
{
// printk("intu %x \n",tmp);
read_data=readb(s3c2440_fpgaread.s3c2440_Rx_Addr);//read from fpga
//printk("iiiiiiiiiiiiiiiiiiiiiii\n" ;
kfifo_put(read_fifo,&read_data,1);//copy data to fifo
}
}
}
return IRQ_HANDLED;
}
/*
*********************************************************************************
* s3c2440_fpga_open
*
* 申请中断,分配fifo 资源
* date :
*********************************************************************************
*/
static int s3c2440_fpga_open(struct inode *inode,struct file *file )
{
unsigned int i=0;
spin_lock(&s3c2440_fpga_lock);
for(i=0;i<NR_CHANNEL;i++)
{
read_lock=SPIN_LOCK_UNLOCKED;
if((read_fifo=kfifo_alloc(BUF_SIZE,GFP_KERNEL,&read_lock)))
memset(read_fifo->buffer,0,BUF_SIZE);
else
printk("kmalloc buf failed \n" ;
}
spin_unlock(&s3c2440_fpga_lock);
return 0;
}
/*
***************************************************************************************
** function name : s3c2440_fpga_read
**
**description : addr 指定了读取数组通道号,和读取的size,read 函数读取的
** 是FPGA 的通道数据 不能,读取FPGA寄存器状态
** date :
****************************************************************************************
*/
#define READ_CHANNEL(x) (((x)>>12)&0x0F)
#define READ_SIZE(x) ((x)&0x0fff)
spinlock_t s3c2440_fpga_readlock;
static int s3c2440_fpga_read( struct file *filp,char __user *buf, size_t addr,loff_t *f_pos)
{
unsigned char *temp=NULL;
spin_lock(&s3c2440_fpga_readlock);
if((temp=kmalloc(READ_SIZE(addr),GFP_KERNEL)))// alloc buf
{
memset(temp,0,READ_SIZE(addr));
kfifo_get(read_fifo[READ_CHANNEL(addr)],temp,READ_SIZE(addr));//get data from fifo ,to buf
if(0!=copy_to_user(buf,temp,READ_SIZE(addr)))//copy data to user buf , copy success return value is 0
{
printk("copy readbuf = falied \n" ;
return -EFAULT;
}
}
else
{
printk("kmalloc failed \n" ;
return -EFAULT;
}
kfree(temp);
spin_unlock(&s3c2440_fpga_readlock);
return 0;
}
/*
***************************************************************************************
** function name : s3c2440_fpga_write
**
**description :
**
** date :
****************************************************************************************
*/
#define WRITE_CHANNEL(x) (((x)>>13)&0x07) //1110 0000 0000 0000
#define WRITE_BASE(x) (((x)>>11)&0x03)*0x40 //0001 1000 0000 0000
#define WRITE_SIZE(x) ((x)&0x07ff) //0000 0111 1111 1111 2k
#define WRITE_ADDR(x) (WRITE_CHANNEL(x)*4+WRITE_BASE(x))
// Write func addr =VA+CHANNEL*4+BASE
spinlock_t s3c2440_fpga_writelock;
static int s3c2440_fpga_write( struct file *file,char __user *buf,size_t addr,loff_t *f_pos)
{
unsigned int i;
unsigned int cnt=65500;
unsigned char * temp=NULL;
unsigned char *tbuf=NULL;
spin_lock(&s3c2440_fpga_writelock);
if((temp=kmalloc(WRITE_SIZE(addr),GFP_KERNEL)))//alloc buf
{
memset(temp,0,WRITE_SIZE(addr));
copy_from_user(temp,buf,WRITE_SIZE(addr));//copy data from user_room to kernel_room
tbuf=temp;
}
else
{
printk("kmalloc write buf failed \n" ;
return -EFAULT;
}
for(i=0;i<WRITE_SIZE(addr);i++)
{
while(!((readb(s3c2440_fpgaread.s3c2440_Txrdy_Addr)>>WRITE_CHANNEL(addr))&0x01) && cnt--)
{
cnt=cnt;
}
//printk("cnt=%d \n", cnt);
if(cnt)
{
writeb(*tbuf,S3C2440_FPGA_ADDR(WRITE_ADDR(addr)));
tbuf++;
cnt=65500;
}
else
{
printk("wait fpga timeout cnt =0 \n" ;
kfree(temp);
spin_unlock(&s3c2440_fpga_writelock);
return -EFAULT;
}
}
/* for(i=0;i<WRITE_SIZE(addr);i++)
*(temp+i)=i;
*/
kfree(temp);
spin_unlock(&s3c2440_fpga_writelock);
return 0;
}
//
static int s3c2440_fpga_release(struct inode *inode,struct file *file )
{
unsigned int i=0;
for(i=0;i<NR_CHANNEL;i++)
kfifo_free(read_fifo);
// printk("release ...............\n" ;
return 0;
}
static struct file_operations s3c2440_fpga_fops = {
.owner = THIS_MODULE,
.open = s3c2440_fpga_open,
.read = s3c2440_fpga_read,
.write = s3c2440_fpga_write,
.release = s3c2440_fpga_release,
};
/*
************************************************************************************************
* func : s3c2440_fpga_init
*
* desc : 注册fpga驱动,初始化接口
*
* date : 2010.5.25
*
**************************************************************************************************
*/
static int __init s3c2440_fpga_init(void)
{
int ret;
ret = register_chrdev(FPGA_MAJOR, DEVICE_NAME, &s3c2440_fpga_fops);
if (ret < 0) {
printk(DEVICE_NAME " can't register major number\n" ;
return ret;
}
//init cfg_region
__raw_writel((__raw_readl(S3C2410_BWSCON) | (0x0c<< ) & (~(0x03)<< ,S3C2410_BWSCON);//DW2=00 8bit
__raw_writel(0x2f70,S3C2410_BANKCON2);
//s3c2410_gpio_cfgpin(S3C2410_GPF5,S3C2410_GPF5_INP);
s3c2440_fpga_ioremap_init();
devfs_mk_cdev(MKDEV(FPGA_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);
printk(DEVICE_NAME " initialized succesfull !!!\n" ;
set_irq_type(IRQ_EINT5,IRQT_HIGH);
if(0 != request_irq(IRQ_EINT5,s3c2440_fpga_irq_rx,0,"fpga_irq",(void*)NULL))//request irq
{
printk("request irq failed!!!\n" ;
return -EAGAIN;
}
// s3c2410_gpio_pullup(S3C2410_GPF5, 0);// set io value
s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_EINT5);//set gpio
return 0;
}
//
static void __exit s3c2440_fpga_exit(void)
{
devfs_remove(DEVICE_NAME);
unregister_chrdev(FPGA_MAJOR, DEVICE_NAME);
} |
|