Date: Tue, 25 Oct 2005 22:19:19 -0500 From: "Yong Ma" <mayong@mail.com> To: freebsd-drivers@freebsd.org Subject: Cryptography Driver (Help !!!!) Message-ID: <20051026031920.11BC983C03@ws1-1.us4.outblaze.com>
index | next in thread | raw e-mail
Dear colleagues,
Cry for help!!!!
The cryptography card driver (polling mode, not interrupt mode) works well
under linux-2.4, but not working under FreeBSD-5.4. The DMA buffer just
keep intact under FreeBSD-5.4 after the Random value generation command
has been issued.
Every thing is compared, but it still not working.
Thanks alot
Following is the Linux and FreeBSD files:
The cryptography card driver under Linux 2.4:
/////////////////////////////////////////////////////////////
#include <linux/config.h>
#include <linux/module.h>
#include <asm/io.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <linux/serial.h>
#include <linux/fcntl.h>
#include <linux/major.h>
#include <linux/delay.h>
#include <linux/tqueue.h>
#include <linux/version.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <linux/spinlock.h>
#include "sjy22bdrv.h"
/* lilin changed*/
u_char *dma_buffer;
struct pci_dev *pdev = NULL;
dma_addr_t dma_addr;
/* time out vars and function */// lilin adding
volatile unsigned long isdmatimeout=0;
volatile unsigned long iscardtimeout=0;
struct timer_list timer_dma,timer_card;
void dma_timeout(unsigned long ptr);
void card_timeout(unsigned long ptr);
/* */
#define WORD unsigned short int
#define HInD(port) inl(card_base[card_no]+port)
#define HOutD(port,val) outl( val,card_base[card_no]+port)
#define YhOutW(port,val) outw( val,port)
#define YhOutB(port,val) outb( val,port)
WORD basePort=0,dataPort,addrPort;
static int jmkmajor;
//lilin adding
#define DMA_BUFFER_SIZE 4*1024
void * card_clea[CARD_NUM];
ulong card_stat[CARD_NUM];
ulong card_use[CARD_NUM];/*added */
ulong card_base[CARD_NUM];
ulong card_addr[CARD_NUM];
ulong card_data[CARD_NUM];
int leftPort[CARD_NUM];
int rightPort[CARD_NUM];
spinlock_t sjy22_lock;
int DMAOpen( int card_no );
//================================
/******* hhw changed 2000 12 28 ************/
/******* lilin changed 2002 5 *************/
int close_jmk(struct inode *inode , struct file *file)
{
return 0;
}
int open_jmk(struct inode *inode, struct file *file)
{
return 0;
}
void SendCmdToF206( PARAM_INFO *MI,int card_no )
{
int i1;
memcpy(dma_buffer+4, (char *)MI->inp, MI->inlen );
for (i1 = 0; i1 < MI->inlen + 14; i1 ++)
printk("%x ", (unsigned char )*((unsigned char *)dma_buffer + i1));
printk("\n");
HOutD( 0x08c, MI->inlen+4);
//sent data
HOutD( 0x090, 0 );
i1 = HInD(0xA8);
HOutD( 0x0A8, i1 | (1<<0) );
HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
i1 = 0;
while(i1 == 0)
{
i1 = HInD(0xA8) & (1<<4);
}
writel ( 0, card_clea[0]);
return;
}
int RcvDataFromF206( PARAM_INFO *MI,int card_no)
{
int i1;
char *chp;
chp=(char *)MI->outp;
HOutD( 0x08c, MI->outlen+4);
HOutD( 0x090, (1<<3) );
i1 = HInD(0xA8);
HOutD( 0x0A8, i1 | (1<<0) );
HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
/* init_timer(&timer_dma);//init timer struct
timer_dma.function = dma_timeout;
timer_dma.expires = jiffies+120*HZ;//120 seconds
add_timer(&timer_dma); */
i1 = 0;
while(i1 == 0)
{
if (isdmatimeout ==0)//if timeout ,del timer and return
i1 = HInD(0xA8) & (1<<4);
/* else
{
del_timer(&timer_dma);
card_use[card_no] = CARD_READY;
isdmatimeout = 0;
chp[0]=0x29;
chp[1]=0;
chp[2]=0;
chp[3]=0;
return -1;
}*/
}
// del_timer(&timer_dma);
/* for (i1 = 0; i1 < 16; i1++)
printk("%x ", *((unsigned char *)dma_buffer + 4 +i1));*/
memcpy((char *)MI->outp, dma_buffer+4 ,MI->outlen );
return 0;
}
int F206Function(PARAM_INFO *MI ,int card_no)
{
unsigned long RegValue;
unsigned long lock_flag;
int i;
char *chp;
chp=(char *)MI->outp;
spin_lock_irqsave(&sjy22_lock,lock_flag);
if( card_use[card_no] == CARD_BUSY)
{
spin_unlock_irqrestore(&sjy22_lock,lock_flag);
chp[0] = 0x2A;
chp[1] = 0;
chp[2] = 0;
chp[2] = 0;
return -EBUSY;
}
card_use[card_no] = CARD_BUSY;
spin_unlock_irqrestore(&sjy22_lock,lock_flag);
SendCmdToF206(MI, card_no);
// init_timer(&timer_card);//init timer struct
// timer_card.function = card_timeout;
// timer_card.expires = jiffies+120*HZ;//120 second:s
// add_timer(&timer_card);
RegValue = 0x3;
while( RegValue != 0)
{
if (iscardtimeout ==0)
RegValue = readl ( card_clea[0] ) & 0x3;
/* else
{
del_timer(&timer_card);
iscardtimeout = 0;
card_use[card_no] = CARD_READY;
chp[0]=0x29;
chp[1]=0;
chp[2]=0;
chp[3]=0;
return -1;
}*/
}
printk("request RegValue = %x\n", RegValue);
// del_timer(&timer_card);
RegValue = 0x3;
while(RegValue != 0)
{
RegValue = readl(card_clea[0]) & 0x3;
}
RegValue = readl( card_clea[0]);
/* It's neccessary! Two read(0x1000 0000) operation needed.*/
printk("RegValue = %x\n", RegValue);
i=RcvDataFromF206( MI, card_no );
if (i == -1)
{
card_use[0] = CARD_READY;
return -1;
}
if(card_no==0) card_use[0]=CARD_READY;
return 0;
}
int ioctl_jmk(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
int card_no = 0;
int ioadd;
unsigned long ii1;
PARAM_INFO MMI;
switch( cmd )
{
case Ioctl_F206_Reset:
ioadd = card_base[card_no] + 0x6c;
ii1 = inl( ioadd );
ii1 |= ( 1 << 30 );
outl( ii1, ioadd );
ii1 &= ~( 1 << 30 );
outl( ii1, ioadd );
HOutD(0x00, 0xfffe0000 );
HOutD(0xf0, 0xfffe0000 );
DMAOpen( card_no );
return 0;
break;
case Ioctl_F206_Function:
copy_from_user(&MMI,(PARAM_INFO *)arg,sizeof(MMI) );
F206Function( &MMI,card_no);
copy_to_user((PARAM_INFO *)arg,&MMI,sizeof(MMI) );
return 0;
default:
break;
}
return 0;
}
struct file_operations jmk_fops = {
ioctl: ioctl_jmk,
open: open_jmk,
release: close_jmk,
};
int init_sjy22b(void)
{
unsigned long k;
int card_no;
card_no = 0;
if (pci_present()) {
u32 pio_start, pio_end, pio_flags, pio_len;
unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
void *map_addr;
pdev = pci_find_device (0x10b5, 0x5406,pdev);
if (!pdev) return 1;
pci_write_config_word(pdev, PCI_COMMAND, 7);
pio_start = pci_resource_start (pdev, 1);
pio_end = pci_resource_end (pdev, 1);
pio_flags = pci_resource_flags (pdev, 1);
pio_len = pci_resource_len (pdev, 1);
mmio_start = pci_resource_start (pdev, 3);
mmio_end = pci_resource_end (pdev, 3);
mmio_flags = pci_resource_flags (pdev, 3);
mmio_len = pci_resource_len (pdev, 3);
if(pci_request_regions (pdev, "sjy22bdrv")){
printk("<1>%s: region resource error, aborting\n",pdev->slot_name);
return 1;
}
/* enable PCI bus-mastering */
// pci_set_master (pdev);
card_base[0] = pio_start ;
k = inl( card_base[0]+0x04 );
printk("Base_address[04] = %lxH\n",k);
k = inl( card_base[0]+0x0f4 );
printk("Base_address[f4] = %lxH\n",k);
HOutD(0x00, 0xfffe0000 );
HOutD(0xf0, 0xfffe0000 );
outl( 0x20000000, card_base[0]+0x04 );
outl( 0x10000000, (card_base[0]+0x0f4) );
/* ioremap MMIO region */
map_addr = ioremap (mmio_start, mmio_len);
if (map_addr == NULL) {
printk("%s: cannot remao mmiom,aborting\n",pdev->slot_name);
return 1;
}
(void *)card_clea[0] = map_addr;
// dma_buffer = pci_alloc_consistent(pdev,DMA_BUFFER_SIZE,&dma_addr);
dma_buffer = kmalloc(4096,GFP_KERNEL);
dma_addr = dma_buffer - 0xc0000000;
if(dma_buffer == NULL) {
printk("allock dma buffer error\n");
return 1;
}
card_stat[0]=CARD_READY;
card_use[0]=CARD_READY;
card_stat[1]=CARD_BUSY;
card_use[1]=CARD_BUSY;
k = inl(card_base[0] + 0x0c);
k &= 0xffffff00;
outl(k, card_base[0] + 0x0c);
DMAOpen( 0 );
spin_lock_init(&sjy22_lock);
printk("(C)Copyright Duanxuejiang, 2002, Beijing(V1.42.1).\n");
printk("Welcome to use BOCO SJY22 PCI CARD!\n");
jmkmajor=register_chrdev(0,"jmk",&jmk_fops);
printk("PCI Major=%d.\n",jmkmajor);
printk("SJY22 is Ok\n");
return 0;
}
printk("No SJY22 device!");
return 1;
}
int init_jmk(void)
{
int temp;
temp = init_sjy22b();
return temp;
}
/*-------------------------------------------------------------*/
#ifdef MODULE
int init_module(void)
{
int temp;
temp = init_sjy22b();
return temp;
}
void cleanup_module(void)
{
unregister_chrdev(jmkmajor,"jmk");
pci_free_consistent(pdev,DMA_BUFFER_SIZE,dma_buffer,dma_addr);
iounmap ((void *)card_addr[0]);
/* it's ok to call this even if we have no regions to free */
pci_release_regions (pdev);
printk("clean up!\n");
}
#endif
int DMAOpen( int card_no )
{
unsigned long RegValue;
HOutD(0x004, 0x20000001 );
HOutD(0x0f4, 0x10000001 );
RegValue = HInD(0x008);
RegValue &= ~(1 << 20);
RegValue |= (1 << 19);
HOutD(0x008, RegValue );
RegValue = HInD(0x0B0);
HOutD(0x0B0, (RegValue & 0xffff0000));
HOutD(0x080, 0x0001c3 );
RegValue = HInD(0x068);
RegValue &= ~(1 << 18);
RegValue &= ~(1 << 8);
HOutD(0x068, RegValue );
//dma_buffer2 = virt_to_phys(dma_buffer);
RegValue = dma_addr;
HOutD(0x084, RegValue );
RegValue = 0x20000000;
HOutD( 0x088, RegValue );
HOutD( 0x08c, 16 );
//sent data
HOutD( 0x090, (1<<3) );
HOutD( 0x0B4, 0 );
HOutD( 0x0A8, (1<<0) );
return 0;
}
void dma_timeout(unsigned long ptr)
{
isdmatimeout=1;
}
void card_timeout(unsigned long ptr)
{
iscardtimeout=1;
}
/////////////////////////////////////////////////////////////////////
Device Driver under FreeBSD-5.4
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/*
Ma Yong, Zhouyi Zhou
Infrastructure Software Center
Institute of Software
Chinese Academy of Sciences
*/
//#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#include <sys/param.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/conf.h>
#include <sys/uio.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include "sjy22bdrv.h"
#define WORD unsigned short int
#define DWORD unsigned long
#define BYTE unsigned char
#define HInD(port) inl(card_base[0]+port)
#define HOutD(port,val) outl( val,card_base[0]+port)
#define Debug 0
#define YhOutW(port,val) outw( val,port)
#define YhOutB(port,val) outb( val,port)
typedef struct {
volatile unsigned long lock;
volatile unsigned int babble;
const char *module;
} spinlock_t;
#define save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
#define restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
#define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
#define LOCK_SECTION_NAME \
".text.lock.sjy22bdrv"
#define LOCK_SECTION_START(extra) \
".subsection 1\n\t" \
extra \
".ifndef " LOCK_SECTION_NAME "\n\t" \
LOCK_SECTION_NAME ":\n\t" \
".endif\n\t"
#define LOCK_SECTION_END \
".previous\n\t"
#define spin_lock_string \
"\n1:\t" \
"lock ; decb %0\n\t" \
"js 2f\n" \
LOCK_SECTION_START("") \
"2:\t" \
"cmpb $0,%0\n\t" \
"rep;nop\n\t" \
"jle 2b\n\t" \
"jmp 1b\n" \
LOCK_SECTION_END
static inline void spin_lock(spinlock_t *lock)
{
__asm__ __volatile__(
spin_lock_string
:"=m" (lock->lock) : : "memory");
}
#define spin_lock_irqsave(lock, flags) do { local_irq_save(flags); spin_lock(lock); } while (0)
#define spin_unlock_string \
"movb $1,%0" \
:"=m" (lock->lock) : : "memory"
static inline void spin_unlock(spinlock_t *lock)
{
__asm__ __volatile__(
spin_unlock_string
);
}
#define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
#define local_irq_restore(x) __restore_flags(x)
#define spin_unlock_irqrestore(lock, flags) do { spin_unlock(lock); local_irq_restore(flags); } while (0)
spinlock_t sjy22_lock;
typedef struct
{
BYTE Code;
BYTE Unused;
WORD Length;
BYTE *Data;
} DSP_CMD_INFO, *pDSP_CMD_INFO;
typedef struct
{
DSP_CMD_INFO info;
BYTE Buffer[1024*16];
} DSP_CMD, *PDSP_CMD;
#define DSP_CMD_SELECT_KEY 0x62
#define DSP_CMD_SELECT_KW_GET_KS 0x3B
#define DSP_CMD_SELECT_KW_SET_KS 0x3C
#define DSP_CMD_BCA 0x63
#define DSP_CMD_HASH 0x64
#define DSP_CMD_GET_HASH 0x65
#define DSP_CMD_BCA_HASH 0x66
#define DSP_CMD_BCA_HASH_EN 0x67
#define DSP_CMD_BCA_HASH_DE 0x68
#define DSP_CMD_ENCRYPT_BLOCK 0x95
#define DSP_CMD_ENCRYPT_HASH 0x96
#define DSP_CMD_HASH_BLOCK 0x97
#define DSP_CMD_IPSEC_ENCRYPT 0x98
#define DSP_CMD_IPSEC_DECRYPT 0x99
// 纡�#define DSP_CMD_GEN_RANDOM 0x80
DSP_CMD inPara,outPara;
void SendDspCmd(DWORD , DSP_CMD *,DSP_CMD *);
WORD dspReadRandom( BYTE *);
#define SPINLOCK_MAGIC_INIT
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }
#define spin_lock_init(x) do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
int DMAOpen( int );
int self_lock=0; /*added for pci*/
int self_lock_myself=0;
#define MAJOR 199
#define MAXMSGLEN 128
#define Nmypci CARD_NUM
#define DMA_BUFFER_SIZE 4*1024
bus_space_tag_t card_clea[CARD_NUM];
bus_space_tag_t card_stat[CARD_NUM];
bus_space_tag_t card_use[CARD_NUM];/*added */
bus_space_tag_t card_base[CARD_NUM];
bus_space_tag_t card_addr[CARD_NUM];
bus_space_tag_t card_data[CARD_NUM];
bus_space_tag_t card_irq[CARD_NUM];
u_char *dma_buffer;
unsigned dma_addr;
int leftPort[CARD_NUM];
int rightPort[CARD_NUM];
//int * test = 3;
struct mypci_softc
{
bus_space_tag_t bst;
bus_space_handle_t bsh;
device_t sc_dev;
u_int32_t open_mask;
u_int32_t read_mask;
struct resource *res0,*res1;
struct resource *rl_irq;
void *rl_intrhand;
int rid;
bus_dma_tag_t rl_tag;
struct cdev *dev;
};
static inline unsigned long m_sleep(unsigned long time)
{
int mm_i1;
int mm_i2;
if( time != 1)
{
self_lock_myself=1;
self_lock=0;
}
mm_i1 = 0;
mm_i2 = 0;
while(self_lock!=1)
{
__asm __volatile("sti" : : : "memory");
// __asm __volatile("sti");
{
int loop_i,counter=0;
for(loop_i=0;loop_i<10;loop_i++)
{counter++;}
}
__asm __volatile("cli" : : : "memory");
// cli();
mm_i1++;
if(mm_i1>50000000){
mm_i2 = 1;
break;
}
}//end while
return mm_i2;
}
void SendCmdToF206( PARAM_INFO *,int );
int RcvDataFromF206( PARAM_INFO *,int );
int F206Function(PARAM_INFO * ,int );
void SendCmdToF206( PARAM_INFO *MI,int card_no )
{
int i1;
// memcpy(dma_buffer+4, (char *)MI->inp, MI->inlen );
*((unsigned char *) dma_buffer + 0) = 0x73;
*((unsigned char *) dma_buffer + 1) = 0x6a;
*((unsigned char *) dma_buffer + 2) = 0x79;
*((unsigned char *) dma_buffer + 3) = 0x32;
*((unsigned char *) dma_buffer + 4) = 0x80;
*((unsigned char *) dma_buffer + 5) = 0x0;
*((unsigned char *) dma_buffer + 6) = 0x1;
*((unsigned char *) dma_buffer + 7) = 0x0;
*((unsigned char *) dma_buffer + 8) = 0x3c;
*((unsigned char *) dma_buffer + 9) = 0xb7;
*((unsigned char *) dma_buffer + 10) = 0xff;
*((unsigned char *) dma_buffer + 11) = 0xbf;
*((unsigned char *) dma_buffer + 12) = 0x8;
*((unsigned char *) dma_buffer + 13) = 0x0;
i1 = readl(card_clea[0]);
HOutD( 0x08c, MI->inlen+4);
//sent data
HOutD( 0x090, 0 );
i1 = HInD(0xA8);
HOutD( 0x0A8, i1 | (1<<0) );
HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
i1 = 0;
while(i1 == 0)
{
i1 = HInD(0xA8) & (1<<4);
}
writel (card_clea[0],0);
return;
}
int RcvDataFromF206( PARAM_INFO *MI,int card_no)
{
int i1;
char *chp;
chp=(char *)MI->outp;
HOutD( 0x08c, MI->outlen+4);
HOutD( 0x090, (1<<3) );
i1 = HInD(0xA8);
HOutD( 0x0A8, i1 | (1<<0) );
HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
/* init_timer(&timer_dma);//init timer struct
timer_dma.function = dma_timeout;
timer_dma.expires = jiffies+120*HZ;//120 seconds
add_timer(&timer_dma);*/
i1 = 0;
while(i1 == 0)
{
// if (isdmatimeout ==0)//if timeout ,del timer and return
i1 = HInD(0xA8) & (1<<4);
/* else
{
del_timer(&timer_dma);
card_use[card_no] = CARD_READY;
isdmatimeout = 0;
chp[0]=0x29;
chp[1]=0;
chp[2]=0;
chp[3]=0;
return -1;
}*/
}
// del_timer(&timer_dma);
printf("Zhouyi Zhou After:\n");
for (int i = 0; i < 16 + 10; i++)
printf("%x ", *((unsigned char *) dma_buffer + 4 +i));
memcpy((char *)MI->outp, dma_buffer+4 ,MI->outlen );
return 0;
}
/*---------------------------------------------------------------------*/
/* §ga碛塄F206¼¯¯û� /
/ 脍: 潆«¡� /
/ 鲒: 0=·k�Ò× /
/----------------------------------------------------------------------*/
int F206Function(PARAM_INFO *MI ,int card_no)
{
unsigned long RegValue;
unsigned long lock_flag;
int i;
char *chp;
chp=(char *)MI->outp;
spin_lock_irqsave(&sjy22_lock,lock_flag);
if( card_use[card_no] == CARD_BUSY)
{
spin_unlock_irqrestore(&sjy22_lock,lock_flag);
chp[0] = 0x2A;
chp[1] = 0;
chp[2] = 0;
chp[2] = 0;
return -EBUSY;
}
card_use[card_no] = CARD_BUSY;
spin_unlock_irqrestore(&sjy22_lock,lock_flag);
SendCmdToF206(MI, card_no);
// init_timer(&timer_card);//init timer struct
//timer_card.function = card_timeout;
//timer_card.expires = jiffies+120*HZ;//120 second:s
//add_timer(&timer_card);
RegValue = 0x3;
while( RegValue != 0)
{
// if (iscardtimeout ==0)
RegValue = readl ( card_clea[0] ) & 0x3;
/* else
{
del_timer(&timer_card);
iscardtimeout = 0;
card_use[card_no] = CARD_READY;
chp[0]=0x29;
chp[1]=0;
chp[2]=0;
chp[3]=0;
return -1;
}*/
}
// del_timer(&timer_card);
RegValue = 0x3;
while(RegValue != 0)
{
RegValue = readl(card_clea[0]) & 0x3;
}
RegValue = readl( card_clea[0]);
/* It's neccessary! Two read(0x1000 0000) operation needed.*/
printf("RegValue = %x\n", RegValue);
i=RcvDataFromF206( MI, card_no );
if (i == -1)
{
card_use[0] = CARD_READY;
return -1;
}
if(card_no==0) card_use[0]=CARD_READY;
return 0;
}
/* Function prototypes */
static d_open_t mypci_open;
static d_close_t mypci_close;
static d_read_t mypci_read;
static d_write_t mypci_write;
static d_ioctl_t mypci_ioctl;
static struct cdevsw mypci_cdevsw = {
.d_version= D_VERSION,
.d_open = mypci_open,
.d_close = mypci_close,
.d_ioctl = mypci_ioctl,
.d_read = mypci_read,
.d_write = mypci_write,
.d_name = "mypci",
};
//static dev_t sdev;
static devclass_t mypci_devclass;
static int
mypci_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
{
return 0;
}
static int
mypci_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
{
/* int i1;
int ioadd;
int card_no = 0;
ioadd = card_base[card_no] + 0x3a;
YhOutW( ioadd, 0x0);
ioadd = card_base[card_no] + 0x38;
YhOutW( ioadd, 0x0);
ioadd = card_base[card_no] + 0x10;
i1 = inw( ioadd );*/
return 0;
}
char teststr[128];
static int
mypci_read(struct cdev *dev, struct uio *uio, int ioflag)
{
printf("Read\n");
int resid = MAXMSGLEN;
int error = 0;
do {
if (uio->uio_resid < resid)
resid = uio->uio_resid;
error = uiomove(teststr, resid, uio);
} while (resid > 0 && error == 0);
printf("mypci reads!\n");
printf("mypci read!\n");
return (error);
}
static int
mypci_write(struct cdev *dev, struct uio *uio, int ioflag)
{
printf("write\n");
int resid = MAXMSGLEN;
int error = 0;
do {
if (uio->uio_resid < resid)
resid = uio->uio_resid;
error = uiomove(teststr, resid, uio);
} while (resid > 0 && error == 0);
printf("mypci writed!\n");
return (error);
}
static int
mypci_probe(device_t dev)
{
device_printf(dev, "MyPCI Probe\nVendor ID : 0x%x\nDevice ID : 0x%x\n",
pci_get_vendor(dev), pci_get_device(dev));
if (pci_get_vendor(dev) == 0x10b5) {
printf("We've got the Cryptgraphic Card!\n");
return (0);
}
return (ENXIO);
}
static int
mypci_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
// mypci_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg )
{
int card_no = 0;
int ioadd;
unsigned long ii1;
//PARAM_INFO MMI;
cmd -= 0x20000000;
BYTE outStr[16];
switch( cmd )
{
case 2: /*Ioctl_F206_Reset:*/
ioadd = card_base[0] + 0x6c;
ii1 = inl( ioadd );
ii1 |= ( 1 << 30 );
outl( ii1, ioadd );
ii1 &= ~( 1 << 30 );
outl( ii1, ioadd );
HOutD(0x00, 0xfffe0000 );
HOutD(0xf0, 0xfffe0000 );
DMAOpen( card_no );
printf("mypci ioctl got called, F206 reset!\n");
break;
case 3: //Ioctl_F206_Function:
// copy_from_user((char *)&MMI,(char *)arg,sizeof(MMI) );
// F206Function( &MMI,card_no);
break;
case 4:
dspReadRandom(outStr);
break;
default:
break;
}
return 0;
}
static void sjy_interrupt(void * args)
{
int i1, ioadd;
int card_no = 0;
unsigned long reg;
i1 = 0;
ioadd = card_base[0] + 0x68;
// *test = 5;
reg = inl( ioadd );
if((reg & (1<<8)) == 0)
{
reg = inl( ioadd );
if((reg & (1<<8)) == 0){
return;
}
}
printf("my pci0 interrupt got called!\n");
if(reg & 0x00e0e000)
{
outl((reg & ~(1<<8)), card_base[0] + 0x68);
reg = inl( card_base[card_no] + 0x68);
if(reg & (1 << 15))
{
HOutD(0xA8,0x8);
if(self_lock_myself==1)
{
self_lock=1;
self_lock_myself=0;
}
}
if(reg & (1 << 21)) {
HOutD(0x068, 0x0B00);
if(self_lock_myself==1)
{
self_lock=1;
self_lock_myself=0;
}
readl(card_clea[0]);
}
return;
}
reg = inl( card_base[0] + 0x30);
if( reg & ( 1<<3) )
{
outl((reg & ~(1<<8)), card_base[0] + 0x68);
}
}
int DMAOpen( int card_no )
{
unsigned long RegValue;
HOutD(0x004, 0x20000001 );
HOutD(0x0f4, 0x10000001 );
RegValue = HInD(0x008);
RegValue &= ~(1 << 20);
RegValue |= (1 << 19);
HOutD(0x008, RegValue );
RegValue = HInD(0x0B0);
HOutD(0x0B0, (RegValue & 0xffff0000));
HOutD(0x080, 0x0001c3 );
RegValue = HInD(0x068);
RegValue &= ~(1 << 18);
RegValue &= ~(1 << 8);
HOutD(0x068, RegValue );
//dma_buffer2 = virt_to_phys(dma_buffer);
RegValue = pmap_kextract((unsigned long)dma_buffer);
HOutD(0x084, RegValue );
RegValue = 0x20000000;
HOutD( 0x088, RegValue );
HOutD( 0x08c, 16 );
//sent data
HOutD( 0x090, (1<<3) );
HOutD( 0x0B4, 0 );
HOutD( 0x0A8, (1<<0) );
return 0;
}
struct mypci_softc *sc;
int rid;
static int
mypci_attach(device_t dev)
{
unsigned long k;
int error = 0;
printf("Mypci device loading...");
rid=0x14;
struct resource *res;
unsigned map_addr;
u_long mmio_flags, mmio_len;
u_int32_t cmd;
sc = (struct mypci_softc *) device_get_softc(dev);
bzero(sc, sizeof (*sc));
sc->sc_dev = dev;
pci_enable_busmaster(dev);
// pci_set_powerstate(dev, 0);
cmd = pci_read_config(dev,PCIR_COMMAND,4);
cmd |= PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN|PCIM_CMD_PORTEN;
// pci_write_config(dev,PCIR_COMMAND,cmd,4);
sc->rid = rid;
res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
card_base[0]= rman_get_bushandle(res);
sc->res0 = res;
rid = 28;
res = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid,RF_ACTIVE);
sc->res1 = res;
mmio_flags = rman_get_flags(res);
map_addr = rman_get_bushandle(res);
mmio_len = bus_get_resource_count(dev, SYS_RES_MEMORY, rid);
card_clea[0] = (unsigned )map_addr;
//dma_buffer = contigmalloc(4096, M_DEVBUF, 1, 0, 0xffffffff, 4096, 0);
dma_buffer = malloc(4096, M_DEVBUF,M_NOWAIT|M_ZERO);
card_stat[0]=CARD_READY;
card_use[0]=CARD_READY;
card_stat[1]=CARD_BUSY;
card_use[1]=CARD_BUSY;
k = inl( card_base[0]+0x04 );
k = inl (card_base[0]+0x0f4);
outl(0xfffe0000, card_base[0] + 0x00);
outl(0xfffe0000, card_base[0] + 0x04);
outl( 0x20000000, card_base[0]+0x04 );
outl( 0x10000000, (card_base[0]+0x0f4) );
k = inl(card_base[0] + 0x0c);
k &= 0xffffff00;
outl(k, card_base[0] + 0x0c);
self_lock=0;
self_lock_myself=0;
DMAOpen( 0 );
spin_lock_init(&sjy22_lock);
sc->dev = make_dev(&mypci_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "mypci0");
/////////////////////////////////////////////////////
printf("Attach successfully!\n");
return (0);
}
static int
mypci_detach(device_t dev)
{
bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->res1);
bus_release_resource(dev, SYS_RES_IOPORT, 0x14, sc->res0);
destroy_dev(sc->dev);
free(dma_buffer, M_DEVBUF);
free(sc, M_DEVBUF);
return (0);
}
static int
mypci_shutdown(device_t dev)
{
return 0;
}
static int
mypci_suspend(device_t dev)
{
printf("Mypci suspend!\n");
return (0);
}
static int
mypci_resume(device_t dev)
{
printf("Mypci resume!\n");
return (0);
}
static device_method_t mypci_methods[] = {
DEVMETHOD(device_probe, mypci_probe),
DEVMETHOD(device_attach, mypci_attach),
DEVMETHOD(device_detach, mypci_detach),
DEVMETHOD(device_shutdown, mypci_shutdown),
DEVMETHOD(device_suspend, mypci_suspend),
DEVMETHOD(device_resume, mypci_resume),
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
{ 0, 0 }
};
static driver_t mypci_driver = {
"mypci",
mypci_methods,
//0,
sizeof(struct mypci_softc),
};
void SendDspCmd(DWORD CardID, DSP_CMD *pInPara,DSP_CMD *pOutPara)
{
PARAM_INFO param;
pInPara->info.Length /= 2;
pInPara->info.Data = pInPara->Buffer;
pOutPara->info.Length /=2;
pOutPara->info.Data = pOutPara->Buffer;
param.inp = (char *)pInPara;
param.inlen = sizeof(DSP_CMD_INFO) + pInPara->info.Length*2;
param.outp = (char *)pOutPara;
param.outlen = sizeof(DSP_CMD_INFO) + pOutPara->info.Length*2;
F206Function(¶m,CardID);
}
WORD dspReadRandom( BYTE *outStr)
{
// DWORD CardID = 0;
WORD len = 8;
int i;
inPara.info.Code = DSP_CMD_GEN_RANDOM;
inPara.info.Length = 2;
outPara.info.Length = 16;
memcpy(inPara.Buffer,&len,2);
SendDspCmd(0, &inPara,&outPara);
printf("\n");
for (i = 0; i < 16; i++)
printf("%x ",*((char *)outPara.Buffer + i));
printf("\n");
// memcpy(outStr,outPara.Buffer,16);
return outPara.info.Code;
}
DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);
--
___________________________________________________
Play 100s of games for FREE! http://games.mail.com/
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051026031920.11BC983C03>
