📄 syspci.c
字号:
/* sysPci.c - Motorola 5200 PCI support *//* includes */#include "vxWorks.h"#include "logLib.h"#include "taskLib.h"#include "config.h"#include "capi/bestcomm_api.h"#ifdef INCLUDE_PCI/* typedefs *//* local */#if defined(IS_ICECUBE) || defined (IS_ICECUBE_OLD)|| defined(IS_LITE5200B)LOCAL void *vectorTbl[] = { IV_IRQ0, IV_IRQ1, IV_IRQ2, IV_IRQ3 };#elif defined(IS_CP2)LOCAL void *vectorTbl[] = { IV_IRQ0, IV_IRQ1, IV_IRQ2, IV_IRQ3 };#else# error#endif/* include source file */#include "drv/pci/pciConfigLib.h"#include "pci/pciConfigLib.c" /* PCI config space access */#include "pci/pciConfigShow.c" /* display of PCI config space */#if 0#ifdef INCLUDE_SHOW_ROUTINES#include "pci/pciConfigShow.c" /* display of PCI config space */#endif /* INCLUDE_SHOW_ROUTINES */#endif/* defines */#define PCI_DEBUG 1 #undef PCI_DEBUG#define PCICDR ((volatile UINT32 *)(CPU_PCI_IO_ADRS))TaskSetupParamSet_t TaskRxPciParam;TaskId TaskRxPciId;TaskSetupParamSet_t TaskTxPciParam;TaskId TaskTxPciId;SEMAPHORE wrsyncSem;SEMAPHORE rdsyncSem;/* forward declarations */LOCAL STATUS sysPciSpecialCycle (int busNo, UINT32 message);LOCAL STATUS sysPciConfigRead (int busNo, int deviceNo, int funcNo, int offset, int width, void * pData);LOCAL STATUS sysPciConfigWrite (int busNo, int deviceNo, int funcNo, int offset, int width, ULONG data);STATUS PciBestcommRead(int *pSrcBuf, int *pDstBuf, int iLen);STATUS PciBestcommWrite(int *pSrcBuf, int *pDstBuf, int iLen);STATUS sysPciInit (void);void pciIntrIrq0();void pciIntrIrq1();void pciIntrIrq2();void pciIntrIrq3();void pciTxBestcommIntr();void pciRxBestcommIntr();VOIDFUNCPTR pciIntrIrqA = NULL;VOIDFUNCPTR pciIntrIrqB = NULL;VOIDFUNCPTR pciIntrIrqC = NULL;VOIDFUNCPTR pciIntrIrqD = NULL;/************************************************************************* sysPciSpecialCycle - generate a special cycle with a message** This routine generates a special cycle with a message.** NOMANUAL** RETURNS: OK*/LOCAL STATUS sysPciSpecialCycle ( int busNo, UINT32 message ) { int deviceNo = 0x0000001f; int funcNo = 0x00000007; if (busNo != 0) return ERROR; *PCICAR = pciConfigBdfPack (busNo, deviceNo, funcNo) | 0x80000000; EIEIO; PCI_OUT_LONG (PCICDR, message); EIEIO; *PCICAR = 0; return (OK); }/************************************************************************* sysPciIntAck - generate an interrupt acknowlege ** This routine generates an interrupt acknowledge ** NOMANUAL** RETURNS: OK*/int sysPciIntAck ( int busNo ) { int deviceNo = 0x0000001f; int funcNo = 0x00000007; int result; if (busNo != 0) return ERROR; *PCICAR = pciConfigBdfPack (busNo, deviceNo, funcNo) | 0x80000000; EIEIO; result = PCI_IN_LONG (PCICDR); EIEIO; *PCICAR = 0; return (result); }/************************************************************************* sysPciConfigRead - read from the PCI configuration space** This routine reads either a byte, word or a long word specified by* the argument <width>, from the PCI configuration space* This routine works around a problem in the hardware which hangs* PCI bus if device no 12 is accessed from the PCI configuration space.** RETURNS: OK, or ERROR if this library is not initialized** SEE ALSO: sysPciConfigWrite()*/LOCAL STATUS sysPciConfigRead ( int busNo, /* bus number */ int deviceNo, /* device number */ int funcNo, /* function number */ int offset, /* offset into the configuration space */ int width, /* width to be read */ void * pData /* data read from the offset */ ) { UINT8 retValByte = 0; UINT16 retValWord = 0; UINT32 retValLong = 0; STATUS retStat = ERROR;#if 0 int status; int key; int oldMask;#endif switch (width) { case 1: /* byte */#if 0 oldMask = *PCIICR; *PCIICR &= ~PCIICR_IAE;#endif *PCICAR = pciConfigBdfPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000; EIEIO; retValByte = PCI_IN_BYTE (PCICDR + (offset & 0x3)); EIEIO; *PCICAR = 0; #if 0 status = *PCIISR; *PCIISR = PCIISR_IA; /* clear */ *PCIICR = oldMask;#endif *((UINT8 *)pData) = retValByte;#if 0 retStat = ((status & PCIISR_IA) ? ERROR : OK);#endif retStat = OK; break; case 2: /* word */#if 0 oldMask = *PCIICR; *PCIICR &= ~PCIICR_IAE; #endif *PCICAR = pciConfigBdfPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000; EIEIO; retValWord = PCI_IN_WORD (PCICDR + (offset & 0x2)); EIEIO; *PCICAR = 0;#if 0 status = *PCIISR; *PCIISR = PCIISR_IA; /* clear */ *PCIICR = oldMask;#endif *((UINT16 *)pData) = retValWord;#if 0 retStat = ((status & PCIISR_IA) ? ERROR : OK);#endif retStat = OK; break; case 4: /* long */#if 0 oldMask = *PCIICR; *PCIICR &= ~PCIICR_IAE; #endif *PCICAR = pciConfigBdfPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000; EIEIO; retValLong = PCI_IN_LONG (PCICDR); EIEIO; *PCICAR = 0;#if 0 status = *PCIISR; *PCIISR = PCIISR_IA; /* clear */ *PCIICR = oldMask;#endif *((UINT32 *)pData) = retValLong;#if 0 retStat = ((status & PCIISR_IA) ? ERROR : OK);#endif retStat = OK; break; default: retStat = ERROR; break; } return retStat; }/************************************************************************* sysPciConfigWrite - write to the PCI configuration space** This routine writes either a byte, word or a long word specified by* the argument <width>, to the PCI configuration space* This routine works around a problem in the hardware which hangs* PCI bus if device no 12 is accessed from the PCI configuration space.** RETURNS: OK, or ERROR if this library is not initialized** SEE ALSO: sysPciConfigRead()*/LOCAL STATUS sysPciConfigWrite ( int busNo, /* bus number */ int deviceNo, /* device number */ int funcNo, /* function number */ int offset, /* offset into the configuration space */ int width, /* width to write */ ULONG data /* data to write */ ) {#if 0 UINT32 status = OK; int key; int oldMask;#endif if ((busNo == 0) && (deviceNo == 12)) return (ERROR); switch (width) { case 1: /* byte */#if 0 oldMask = *PCIICR; *PCIICR &= ~PCIICR_IAE; #endif *PCICAR = pciConfigBdfPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000; EIEIO; PCI_OUT_BYTE ((PCICDR + (offset & 0x3)), data); EIEIO; *PCICAR = 0;#if 0 status = *PCIISR; *PCIISR = PCIISR_IA; /* clear */ *PCIICR = oldMask;#endif break; case 2: /* word */#if 0 oldMask = *PCIICR; *PCIICR &= ~PCIICR_IAE; #endif *PCICAR = pciConfigBdfPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000; EIEIO; PCI_OUT_WORD ((PCICDR + (offset & 0x2)), data); EIEIO; *PCICAR = 0;#if 0 status = *PCIISR; *PCIISR = PCIISR_IA; /* clear */ *PCIICR = oldMask;#endif break; case 4: /* long */#if 0 oldMask = *PCIICR; *PCIICR &= ~PCIICR_IAE; #endif *PCICAR = pciConfigBdfPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000; EIEIO; PCI_OUT_LONG (PCICDR, data); EIEIO; *PCICAR = 0;#if 0 status = *PCIISR; *PCIISR = PCIISR_IA; /* clear */ *PCIICR = oldMask;#endif break; default: return (ERROR); }#if 0 return ((status & PCIISR_IA) ? ERROR : OK);#endif return (OK); }void setInitiatorWindow (int nr, UINT32 cpuBase, UINT32 busBase, UINT32 size, UINT8 mode){ UINT32 cpu, bus, mask, btarValue; if ((cpuBase & 0x00ffffff) != 0) return; if ((busBase & 0x00ffffff) != 0) return; cpu = cpuBase >> 24; bus = busBase >> 24; mask = (size >> 24) - 1; btarValue = cpu<<24|mask<<16|bus<<8; switch (nr) { case 0: *PCIIW0BTAR = btarValue; EIEIO; *PCIIWCR &= 0xf0ffffff; *PCIIWCR |= mode<<24; EIEIO; break; case 1: *PCIIW1BTAR = btarValue; EIEIO; *PCIIWCR &= 0xfff0ffff; *PCIIWCR |= mode<<16; EIEIO; break; case 2: *PCIIW2BTAR = btarValue; EIEIO; *PCIIWCR &= 0xfffff0ff; *PCIIWCR |= mode<<8; EIEIO; break; default: return; }} /************************************************************************* sysPciInit - PCI Configuration Library Initialization* * This routine initialize the PCI configuration library.** RETURNS: None*/STATUS sysPciInit ( void ) { STATUS retVal; int i; /* set GPIO correctly -> enable PCI */ *GPIO_STD_PORTCFG &= ~GPIO_STD_PC_PCI_MASK; /* MPC5200 is the PCI bus master */ *PCISCR |= PCISCR_B|PCI_COMMAND_MEMORY|PCISCR_S|PCISCR_P; *PCITCBR|= 0x01000000; /* latrule disable */ /* Set latency timer (minimum time the bus master can keep the bus after starting a transaction */ *PCICR1 &= ~PCICR1_LAT_MASK; *PCICR1 |= PCI_LAT_TIMER<<PCICR1_LAT_SHIFT; /* Set cache line size */ *PCICR1 = (*PCICR1 & ~0xff) | (PCI_CLINE_SZ / 4); EIEIO; /* m5200 as target */#if (BUS_PCI_SLV_MEM_LOCAL_A & 0x0003FFFF)# error#endif#if (BUS_PCI_SLV_MEM_LOCAL_A & 0x3FFFFFF)# error#endif#if (CPU_PCI_SLV_MEM_LOCAL_A & 0x0003FFFF)# error#endif#if (CPU_PCI_SLV_MEM_LOCAL_B & 0x3FFFFFFF)# error#endif *PCIBAR0 = BUS_PCI_SLV_MEM_LOCAL_A; *PCIBAR1 = BUS_PCI_SLV_MEM_LOCAL_B| (1 << 3); *PCITBATR0 = CPU_PCI_SLV_MEM_LOCAL_A | 1; /* set address and enable */ *PCITBATR1 = CPU_PCI_SLV_MEM_LOCAL_B | 1; /* set address and enable */ /* Park XLB on PCI */ *XLB_CR &= ~((7 << 8) | (3 << 5)); *XLB_CR |= (3 << 8) | (3 << 5); *XLB_MPR|=0x00000001; /* PCI Bestcomm XLB Priority */ #if 0 *BESTCOMM_PTD &= ~(1 << 15); /* iniator priority */ *BESTCOMM_IPR0 = 0x00000005; /* PCI FEC ATA lowest */ *BESTCOMM_IPR4 = 0x05030387; *BESTCOMM_IPR8 = 0x87000000; #endif /* Disable interrupts from PCI controller */ *PCIGSCR &= ~(7 << 12); *PCIICR &= ~(7 << 24); *PCIICR &= 0xffffff00; *PCITER = 0; *PCIRER = 0; *PCITTCR = 0x07000000; *PCIRTCR = 0x0C001000; /* RX receiver control */ /* Disable initiator windows */ *PCIIWCR = 0; /* m5200 as master */ /* Initiator 0 for 32 bit prefetch memory */ setInitiatorWindow (0, CPU_PCI_MEM_ADRS, BUS_PCI_MEM_ADRS, PCI_MEM_SIZE, PCIIWCR_ENABLE|PCIIWCR_MEM|PCIIWCR_READ_SINGLE); /* Initiator 1 for IO */ setInitiatorWindow (1, CPU_PCI_IO_ADRS, BUS_PCI_IO_ADRS, PCI_IO_SIZE, PCIIWCR_ENABLE|PCIIWCR_IO|PCIIWCR_READ_SINGLE); /* Initiator 2 for 32 bit non-prefetch memory */ setInitiatorWindow (2, CPU_PCI_NO_PRE_MEM_ADRS, BUS_PCI_NO_PRE_MEM_ADRS, PCI_NO_PRE_MEM_SIZE, PCIIWCR_ENABLE|PCIIWCR_MEM|PCIIWCR_READ_SINGLE); /* clear any pending int */ *PCIGSCR = PCIGSCR_BM|PCIGSCR_PE|PCIGSCR_SE; *PCIISR = PCIISR_RE|PCIISR_IA|PCIISR_TA; *PCITSR = 0x01ff0000; *PCITFSR = 0x007f0000; *PCIRSR = 0x01ff0000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -