⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pciiomaplib.c

📁 vxworks的BSP开发配置文件
💻 C
📖 第 1 页 / 共 3 页
字号:
/* pciIomapLib.c - Support for PCI drivers *//* Copyright 1984-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01m,24nov97,jpd  made conditional on INCLUDE_PCI.01l,27oct97,kkk  took out "EOF" line at end of file.01k,26sep97,jpd  make all config accesses 32-bit. Add Type 1 config addresses.01j,02sep97,jpd  added support for non-PC/PowerPC configuration.01i,25apr97,mas  tweaked DELAY loop for long read; no loop for long write.01h,22apr97,mas  added include of dllLib.h; added pciDevConfig; converted		 semaphore-based exclusion to intLock-based exclusion; fixed		 pciFindXxxx to skip nonexistant devices; limited bus scanning		 to PCI_MAX_BUS, PCI_MAX_DEV and PCI_MAX_FUNC (SPR 8226).01g,12jan97,hdn  changed variable name "vender" to "vendor".01f,12jan97,hdn  changed variable name "class" to "classCodeReg".01e,03dec96,hdn  added single/multi function check.01d,16sep96,dat  made pciConfigMech global (for pciIomapShow).01c,06aug96,hdn  added pciInt(), pciIntConnect() and pciIntDisconnect().01b,14mar96,hdn  re-written.  changed parameters of the functions.		 removed BIOS dependent codes.01a,25feb95,bcs  written*//*DESCRIPTIONThis library is PCI Revision 2.1 compliant.This module contains routines to support PCI bus mapped on IO address spacefor x86 and PowerPC architecture.  Functions in this library should not becalled from the interrupt level, except pciInt(), since it uses a mutualexclusion semaphore for consecutive register access.  The functions addressed here include:  - Initialize the library.  - Locate the device by deviceID and vendorID.  - Locate the device by classCode.  - Generate the special cycle.  - Access its configuration registers.  - Connect a shared interrupt handler.  - Disconnect a shared interrupt handler.  - Master shared interrupt handler.There are functions to access the IO address space.  In x86 architecture,they are sysInXXX() and sysOutXXX().  Macro PCI_IN_XXX() and PCI_OUT_XXX()are provided to use other IO address space functions.Shared PCI interrupt are supported by three functions: pciInt(),pciIntConnect(), pciIntDisconnect().  pciIntConnect() adds the specifiedinterrupt handler to the link list and pciIntDisconnect() removes it fromthe link list.  Master interrupt handler pciInt() executes these interrupthandlers in the link list for a PCI interrupt.  Each interrupt handler mustcheck the device dependent interrupt status bit to determine the source ofthe interrupt, since it simply execute all interrupt handlers in the linklist.  pciInt() should be attached by intConnect() function in the BSP initialization with its parameter. The parameter is an IRQ associated to the PCI interrupt.The maximum number of Type-1 Configuration Space buses supported in the 2.1Specifications is 256 (0x00 - 0xFF), far greater than most systems currentlysupport.  Most buses are numbered sequentially from 0.  An optional definecalled PCI_MAX_BUS may be declared in config.h to override the defaultdefinition of 256.  Similarly, the default number of devices and functionsmay be overriden by defining PCI_MAX_DEV and/or PCI_MAX_FUNC.  Note thatthe number of devices applies only to bus zero, all others being restrictedto 16 by the 2.1 spec.*/#if defined(INCLUDE_PCI)#include "vxWorks.h"#include "config.h"#include "dllLib.h"#include "sysLib.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "intLib.h"/* * We currently wish to include this from locally rather than from * there as that version is out-dated. However, as it has been included * in sysLib.c already, this will do no harm. */#include "drv/pci/pciIomapLib.h"/* defines */#ifndef	PCI_IN_BYTE#define PCI_IN_BYTE(x)		sysInByte (x)#endif#ifndef	PCI_IN_WORD#define PCI_IN_WORD(x)		sysInWord (x)#endif#ifndef	PCI_IN_LONG#define PCI_IN_LONG(x)		sysInLong (x)#endif#ifndef	PCI_OUT_BYTE#define PCI_OUT_BYTE(x,y)	sysOutByte (x,y)#endif#ifndef	PCI_OUT_WORD#define PCI_OUT_WORD(x,y)	sysOutWord (x,y)#endif#ifndef	PCI_OUT_LONG#define PCI_OUT_LONG(x,y)	sysOutLong (x,y)#endif/* * The following defines specify, by default, the maximum number of busses, * devices and functions allowed by the PCI 2.1 Specification. * * Any or all may be overriden by defining them in config.h. */#ifndef PCI_MAX_BUS#  define PCI_MAX_BUS	256#endif  /* PCI_MAX_BUS */#ifndef PCI_MAX_DEV#  define PCI_MAX_DEV	21#endif  /* PCI_MAX_DEV */#ifndef PCI_MAX_FUNC#  define PCI_MAX_FUNC	8#endif  /* PCI_MAX_FUNC */#define PCI_DELAY       500   /* XXXmas *//* * The following macro should be defined if IDSEL selection is not done using * the bits AD[31:11], but is done via access to a separate register. If it has * not been defined, then define it as a null macro doing nothing. */#ifndef IDSEL#define IDSEL(bus, device)#endif#ifndef CLR_IDSEL#define CLR_IDSEL#endif/* globals */STATUS	pciLibInitStatus = NONE;	/* initialization done */DL_LIST	pciIntList[PCI_IRQ_LINES];	/* link list of int handlers */int	pciConfigMech = NONE;		/* 1=mechanism-1, 2=mechanism-2 *//* locals */LOCAL int pciConfigAddr0;		/* config-addr-reg, CSE-reg*/LOCAL int pciConfigAddr1;		/* config-data-reg, forward-reg */LOCAL int pciConfigAddr2;		/* not-used, base-addr *//********************************************************************************* pciIomapLibInit - initialize the configuration access-method and addresses** This routine initializes the configuration access-method and addresses.** Configuration mechanism one utilizes two 32-bit IO ports located at addresses* 0x0cf8 and 0x0cfc. These two ports are:*   - 32-bit configuration address port, at 0x0cf8*   - 32-bit configuration data port, at 0x0cfc* Accessing a PCI function's configuration port is two step process.*   - Write the bus number, physical device number, function number and *     register number to the configuration address port.*   - Perform an IO read from or an write to the configuration data port.** Configuration mechanism two uses following two single-byte IO ports.*   - Configuration space enable, or CSE, register, at 0x0cf8*   - Forward register, at 0x0cfa* To generate a PCI configuration transaction, the following actions are* performed.*   - Write the target bus number into the forward register.*   - Write a one byte value to the CSE register at 0x0cf8.  The bit*     pattern written to this register has three effects: disables the*     generation of special cycles; enables the generation of configuration*     transactions; specifies the target PCI functional device.*   - Perform a one, two or four byte IO read or write transaction within*     the IO range 0xc000 through 0xcfff.** Configuration mechanism three is for non-PC/PowerPC environments* where an area of address space produces PCI configuration* transactions. No support for special cycles is included.** RETURNS:* OK, or ERROR if a mechanism is not 1, 2 or 3.**/STATUS pciIomapLibInit    (    int mechanism,	/* configuration mechanism: 1, 2 or 3 */    int addr0,		/* config-addr-reg / CSE-reg */    int addr1,		/* config-data-reg / Forward-reg */    int addr2		/* none            / Base-address */    )    {    int ix;    if (pciLibInitStatus != NONE)	return (pciLibInitStatus);    switch (mechanism)	{	case PCI_MECHANISM_1:	case PCI_MECHANISM_2:	case PCI_MECHANISM_3:	    pciConfigMech	= mechanism;	    pciConfigAddr0	= addr0;	    pciConfigAddr1	= addr1;	    pciConfigAddr2	= addr2;	    pciLibInitStatus	= OK;	    break;	default:    	    pciLibInitStatus	= ERROR;	    break;	}    for (ix = 0; ix < PCI_IRQ_LINES; ix++)        dllInit (&pciIntList[ix]);    return (pciLibInitStatus);    }/********************************************************************************* pciFindDevice - find the nth device with the given device & vendor ID** This routine finds the nth device with the given device & vendor ID.** RETURNS:* OK, or ERROR if the deviceId and vendorId didn't match.**/STATUS pciFindDevice    (    int    vendorId,	/* vendor ID */    int    deviceId,	/* device ID */    int    index,	/* desired instance of device */    int *  pBusNo,	/* bus number */    int *  pDeviceNo,	/* device number */    int *  pFuncNo	/* function number */    )    {    STATUS status = ERROR;    BOOL   cont   = TRUE;    int    busNo;    int    deviceNo;    int    funcNo;    UINT32 device;    UINT32 vendor;    char   header;    if (pciLibInitStatus != OK)			/* sanity check */        cont = FALSE;    for (busNo = 0; cont == TRUE && busNo < PCI_MAX_BUS; busNo++)        for (deviceNo = 0;	     cont == TRUE && deviceNo < ((busNo == 0) ? PCI_MAX_DEV : 16);	     ++deviceNo)            for (funcNo = 0; cont == TRUE && funcNo < PCI_MAX_FUNC; funcNo++)		{#if (PCI_MAX_DEV > 31) && (PCI_MAX_FUNC > 7)		/* avoid a special bus cycle */		if ((deviceNo == 0x1f) && (funcNo == 0x07))		    continue;#endif		pciConfigInLong (busNo, deviceNo, funcNo, PCI_CFG_VENDOR_ID,				 &vendor);		/* If nonexistent device, skip to next */		if ((vendor == 0xFFFFFFFF) && (funcNo == 0))		    break;		device  = vendor >> 16;		device &= 0x0000FFFF;		vendor &= 0x0000FFFF;		if ((vendor == (UINT32)vendorId) &&		    (device == (UINT32)deviceId) &&		    (index-- == 0))		    {		    *pBusNo	= busNo;		    *pDeviceNo	= deviceNo;		    *pFuncNo	= funcNo;		    status	= OK;		    cont	= FALSE;	/* terminate all loops */		    continue;		    }		/* goto next if current device is single function */		pciConfigInByte (busNo, deviceNo, funcNo, PCI_CFG_HEADER_TYPE, 				 &header);		if ((header & PCI_HEADER_MULTI_FUNC) != PCI_HEADER_MULTI_FUNC &&		    funcNo == 0)		    break;		}    return (status);    }/********************************************************************************* pciFindClass - find the nth occurence of a device by PCI class code.** This routine finds the nth device with the given 24-bit PCI class code* (class subclass prog_if).** RETURNS:* OK, or ERROR if the class didn't match.**/STATUS pciFindClass    (    int    classCode,	/* 24-bit class code */    int	   index,	/* desired instance of device */    int *  pBusNo,	/* bus number */    int *  pDeviceNo,	/* device number */    int *  pFuncNo	/* function number */    )    {    STATUS status = ERROR;    BOOL   cont   = TRUE;    int    busNo;    int    deviceNo;    int    funcNo;    int    classCodeReg;    char   header;    if (pciLibInitStatus != OK)			/* sanity check */        cont = FALSE;    for (busNo = 0; cont == TRUE && busNo < PCI_MAX_BUS; busNo++)        for (deviceNo = 0;	     cont == TRUE && deviceNo < ((busNo == 0) ? PCI_MAX_DEV : 16);	     ++deviceNo)            for (funcNo = 0; cont == TRUE && funcNo < PCI_MAX_FUNC; funcNo++)		{#if (PCI_MAX_DEV > 31) && (PCI_MAX_FUNC > 7)		/* avoid a special bus cycle */		if ((deviceNo == 0x1f) && (funcNo == 0x07))		    continue;#endif		pciConfigInLong (busNo, deviceNo, funcNo, PCI_CFG_REVISION,				 &classCodeReg);		/* If nonexistent device, skip to next */		if (((UINT32)classCodeReg == 0xFFFFFFFF) && (funcNo == 0))		    break;		if ((((classCodeReg >> 8) & 0x00ffffff) == classCode) &&		    (index-- == 0))		    {		    *pBusNo	= busNo;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -