/* Plx9054.c: Plx9054 PCI桥片驱动源文件*/
/* author: Wang.qi Jilin Univ. 2004512025*/
/*
PLX9054驱动程序从功能上可划分为以下模块:
初始化模块、PCI配置寄存器读写模块、本地寄存器读写模块、
本地空间读写模块、读写模块、控制与配置模块、DMA模块、
中断处理模块及测试维护模块。
各模块调用关系图
配置和
控制模块
PLX9054 PCI 配 PLX9054 本
置寄存器 地寄存器
读写模块 读写模块
PLX9054本地空间读写模块 DMA模块
*/
/*
modification history
------------------
2006-09-17
*/
#ifdef __cplusplus
extern "C" {
#endif
/* includes (header file) 头包含文件 */
#include "vxWorks.h"
#include "vme.h"
#include "memLib.h"
#include "sysLib.h"
#include "string.h"
#include "intLib.h"
#include "config.h"
#include "logLib.h"
#include "taskLib.h"
#include "vxLib.h"
#include "errnoLib.h"
#include "dosFsLib.h"
#include "stdio.h"
#include "cacheLib.h"
#include "private/vmLibP.h"
#include "arch/i86/pentiumLib.h"
#include "drv/pci/pciConfigLib.h"
#include "drv/pci/pciIntLib.h"
#include "plx9054.h"
/* define 宏定义 */
/* global */
PLX9054_DRVCTRL * pPlxDrvCtrl = NULL; /* 指向设备驱动结构体,驱动里通过这个指针操作设备*/
static PLX9054_DRVCTRL plxDrvCtrl;
static PLX9054_DEVICE plxDevCtrl[PLX9054_MAX_DEV];
/* local */
LOCAL PLX9054_BOARD_RESOURCES plx9054Brds [] =
{
{0, PLX_9054_VENDORID, PLX_9054_DEVICEID, 0},
};
LOCAL PLX9054_PCI_RESOURCES plx9054PciResrcs [] = /*默认分配给PLX 的PCI资源*/
{
{PLX9054_MEM_ADR0, PLX9054_IO_ADR0, PLX9054_INT_LVL0, PLX9054_INT_VEC0,
PCI_CFG_TYPE, 0, 0, 0},
{PLX9054_MEM_ADR1, PLX9054_IO_ADR1, PLX9054_INT_LVL1, PLX9054_INT_VEC1,
PCI_CFG_TYPE, 0, 0, 0},
{PLX9054_MEM_ADR2, PLX9054_IO_ADR2, PLX9054_INT_LVL2, PLX9054_INT_VEC2,
PCI_CFG_TYPE, 0, 0, 0},
{PLX9054_MEM_ADR3, PLX9054_IO_ADR3, PLX9054_INT_LVL3, PLX9054_INT_VEC3,
PCI_CFG_TYPE, 0, 0, 0}
};
static char line[256];
/* import */
IMPORT STATUS sysMmuMapAdd (void *, UINT, UINT, UINT);
IMPORT void sysWait(void);
#ifdef BOOT_COM_PRINT
IMPORT void com1BootPrint(char * buf);
#endif
IMPORT STATUS pciIntConnect();
IMPORT STATUS rebootHookAdd (FUNCPTR rebootHook);
/* function declarations*/
#if 0
STATUS PLX9054_GetSpaceInfo(int index, PLX9054_SPACE_INDEX spaceIndex, PLX9054_SPACE_DESC * pPlxSpace);
STATUS PLX9054_GetAllSpaceInfo(int index);
STATUS PLX9054_Local_Reg_Read( int index, int offset, UINT32 * pData);
STATUS PLX9054_Local_Reg_Write( int index, int offset, UINT32 data);
STATUS PLX9054_Pci_Reg_Read( int index, int offset, UINT32 * pData, DATA_WIDTH_MODE dataWidth);
STATUS PLX9054_Pci_Reg_Write( int index, int offset, UINT32 data, DATA_WIDTH_MODE dataWidth);
void PLX9054_IntEnable (int index);
void PLX9054_IntDisable (int index);
STATUS PLX9054_ReadByte (int index, PLX9054_SPACE_INDEX spaceIndex, UINT32 dwOffset, char * pData);
STATUS PLX9054_WriteByte (int index, PLX9054_SPACE_INDEX spaceIndex, UINT32 dwOffset, char data);
STATUS PLX9054_ReadWord (int index, PLX9054_SPACE_INDEX spaceIndex, UINT32 dwOffset, short * pData);
STATUS PLX9054_WriteWord (int index, PLX9054_SPACE_INDEX spaceIndex, UINT32 dwOffset, short data);
STATUS PLX9054_ReadDword (int index, PLX9054_SPACE_INDEX spaceIndex, UINT32 dwOffset, UINT32 * pData);
STATUS PLX9054_WriteDword (int index, PLX9054_SPACE_INDEX spaceIndex, UINT32 dwOffset, UINT32 data);
#endif
void PLX9054_EepromSendCommand(int index, UINT32 EepromCommand, UCHAR DataLengthInBits);
void PLX9054_EepromClock(int index);
void PLX9054_Int(int index);
STATUS sysPlx9054IntEnable(int level);
STATUS sysPlx9054IntDisable(int level);
/* function */
/*
sysPlx9054PciInit
在sysHwInit中调用,此时系统内核、MMU 等还未初始化
查找PLX9054扩展卡,读取PLX9054的PCI配置空间,以获取
BIOS分配给PLX9054扩展卡的资源
*/
STATUS sysPlx9054PciInit (void)
{
UINT32 membaseCsr;
UINT32 iobaseCsr;
UINT32 sp0MemBase; /* PCI9054 本地空间0 的PCI Memory 基地址*/
UINT32 sp1MemBase; /* PCI9054 本地空间1 的PCI Memory 基地址*/
UINT32 sp0Range; /* PCI9054 本地空间0 的大小*/
UINT32 sp1Range; /* PCI9054 本地空间1 的大小*/
char irq;
int pciBus;
int pciDevice;
int pciFunc;
int ix;
int unit;
int found = FALSE;
int plx9054Units = 0;
char buf[255];
PLX9054_DRVCTRL * pDrvCtrl = NULL;
PLX9054_DEVICE * pDevCtrl = NULL;
/* 为驱动结构体申请内存空间*/
#if 0
pDrvCtrl = (PLX9054_DRVCTRL *)malloc(sizeof(PLX9054_DRVCTRL));
if(NULL == pDrvCtrl)
{
printf("Malloc return NULL File:%s, Line:%d.\n", __FILE__, __LINE__);
return ERROR;
}
#endif
pDrvCtrl = &plxDrvCtrl;
PLX9054_SetDrvCtrl(pDrvCtrl); /* 设置全局设备驱动结构体指针*/
memset((void *)pDrvCtrl, 0, sizeof(PLX9054_DRVCTRL));
/* find all plx9054 cards */
for (unit = 0; unit < PLX9054_MAX_DEV; unit++)
{
for (ix=0; ix < NELEMENTS (plx9054Brds); ix++)
{
if (pciFindDevice (plx9054Brds [ix].vendorId, plx9054Brds [ix].deviceId,
unit, &pciBus, &pciDevice, &pciFunc) == OK)
{
/* board detected */
found = TRUE;
#if 0
/* 为设备结构体申请内存空间*/
pDevCtrl = (PLX9054_DEVICE *)malloc(sizeof(PLX9054_DEVICE));
if(NULL == pDevCtrl)
{
printf("Malloc return NULL File:%s, Line:%d.\n", __FILE__, __LINE__);
/* 释放已分配的内存空间*/
return ERROR;
}
memset((void *)pDevCtrl, 0, sizeof(PLX9054_DEVICE));
#endif
pDevCtrl = &(plxDevCtrl[unit]);
/* load up the PCI device table */
pDevCtrl->PlxPciRsrc = plx9054PciResrcs[unit];
pDevCtrl->PlxPciRsrc.pciBus = pciBus;
pDevCtrl->PlxPciRsrc.pciDevice = pciDevice;
pDevCtrl->PlxPciRsrc.pciFunc = pciFunc;
pDrvCtrl->pDevice[unit] = pDevCtrl;
plx9054Units++; /* number of units found */
break;
}
}
}
pDrvCtrl->plxCardNum = plx9054Units;
if ((found != TRUE) || (pciDevice > PCI_MAX_DEV))
{
#ifdef PLX_DEBUG_PRINT
#ifdef BOOT_COM_PRINT
com1BootPrint("No PLX Device Find\n\r");
#endif
#endif
return ((int)NULL);
}
sprintf(buf, "Driver Find %d PLX9054 Devices.\n\r", plx9054Units);
#ifdef BOOT_COM_PRINT
com1BootPrint(buf);
#endif
/* Now initialize all the units we found
由于BIOS已经分配好资源,这里只需要读取BIOS
分配给PLX9054的资源信息即可,无需配置*/
for (unit = 0; unit < plx9054Units; unit++)
{
/* Fill in the resource entry */
pDevCtrl = pDrvCtrl->pDevice[unit];
if (PCI_CFG_FORCE == pDevCtrl->PlxPciRsrc.configType)
{
/* write the iobase, membase, and irq */
pciConfigOutLong (pDevCtrl->PlxPciRsrc.pciBus,
pDevCtrl->PlxPciRsrc.pciDevice,
pDevCtrl->PlxPciRsrc.pciFunc,
PCI_CFG_BASE_ADDRESS_1,
pDevCtrl->PlxPciRsrc.iobaseCsr |
PCI_BASE_IO);
pciConfigOutLong (pDevCtrl->PlxPciRsrc.pciBus,
pDevCtrl->PlxPciRsrc.pciDevice,
pDevCtrl->PlxPciRsrc.pciFunc,
PCI_CFG_BASE_ADDRESS_0,
pDevCtrl->PlxPciRsrc.membaseCsr);
pciConfigOutByte (p