📄 pciiomaplib.c
字号:
semTake (&pciMuteSem, WAIT_FOREVER); /* mutual execlusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | (address & 0xfc) | 0x80000000); retval = PCI_IN_WORD (pciConfigAddr1 + (address & 0x2)); break; case PCI_MECHANISM_2: PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1)); PCI_OUT_BYTE (pciConfigAddr1, busNo); retval = PCI_IN_LONG (pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (address & 0xfc)); PCI_OUT_BYTE (pciConfigAddr0, 0); retval >>= (address & 0x02) * 8; break; default: break; } semGive (&pciMuteSem); /* mutual execlusion stop */ *pData = retval; return (OK); }/********************************************************************************* pciConfigInLong - read one longword from the PCI configuration space** This routine reads one longword from the PCI configuration space** RETURNS:* OK, or ERROR if this library is not initialized.**/STATUS pciConfigInLong ( int busNo, /* bus number */ int deviceNo, /* device number */ int funcNo, /* function number */ int address, /* address of the configuration space */ int * pData /* data read from the address */ ) { int retval = 0; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); semTake (&pciMuteSem, WAIT_FOREVER); /* mutual execlusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | (address & 0xfc) | 0x80000000); retval = PCI_IN_LONG (pciConfigAddr1); break; case PCI_MECHANISM_2: PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1)); PCI_OUT_BYTE (pciConfigAddr1, busNo); retval = PCI_IN_LONG (pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (address & 0xfc)); PCI_OUT_BYTE (pciConfigAddr0, 0); break; default: break; } semGive (&pciMuteSem); /* mutual execlusion stop */ *pData = retval; return (OK); }/********************************************************************************* pciConfigOutByte - write one byte to the PCI configuration space** This routine writes one byte to the PCI configuration space.** RETURNS:* OK, or ERROR if this library is not initialized.**/STATUS pciConfigOutByte ( int busNo, /* bus number */ int deviceNo, /* device number */ int funcNo, /* function number */ int address, /* address of the configuration space */ char data /* data written to the address */ ) { int retval; int mask = 0x000000ff; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); semTake (&pciMuteSem, WAIT_FOREVER); /* mutual execlusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | (address & 0xfc) | 0x80000000); PCI_OUT_BYTE ((pciConfigAddr1 + (address & 0x3)), data); break; case PCI_MECHANISM_2: PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1)); PCI_OUT_BYTE (pciConfigAddr1, busNo); retval = PCI_IN_LONG (pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (address & 0xfc)); data = (data & mask) << ((address & 0x03) * 8); mask <<= (address & 0x03) * 8; retval = (retval & ~mask) | data; PCI_OUT_LONG ((pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (address & 0xfc)), retval); PCI_OUT_BYTE (pciConfigAddr0, 0); break; default: break; } semGive (&pciMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pciConfigOutWord - write one word to the PCI configuration space** This routine writes one word to the PCI configuration space.** RETURNS:* OK, or ERROR if this library is not initialized.**/STATUS pciConfigOutWord ( int busNo, /* bus number */ int deviceNo, /* device number */ int funcNo, /* function number */ int address, /* address of the configuration space */ short data /* data written to the address */ ) { int retval; int mask = 0x0000ffff; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); semTake (&pciMuteSem, WAIT_FOREVER); /* mutual execlusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | (address & 0xfc) | 0x80000000); PCI_OUT_WORD ((pciConfigAddr1 + (address & 0x2)), data); break; case PCI_MECHANISM_2: PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1)); PCI_OUT_BYTE (pciConfigAddr1, busNo); retval = PCI_IN_LONG (pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (address & 0xfc)); data = (data & mask) << ((address & 0x02) * 8); mask <<= (address & 0x02) * 8; retval = (retval & ~mask) | data; PCI_OUT_LONG ((pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (address & 0xfc)), retval); PCI_OUT_BYTE (pciConfigAddr0, 0); break; default: break; } semGive (&pciMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pciConfigOutLong - write one longword to the PCI configuration space** This routine writes one longword to the PCI configuration space.** RETURNS:* OK, or ERROR if this library is not initialized.**/STATUS pciConfigOutLong ( int busNo, /* bus number */ int deviceNo, /* device number */ int funcNo, /* function number */ int address, /* address of the configuration space */ int data /* data written to the address */ ) { if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); semTake (&pciMuteSem, WAIT_FOREVER); /* mutual execlusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | (address & 0xfc) | 0x80000000); PCI_OUT_LONG (pciConfigAddr1, data); break; case PCI_MECHANISM_2: PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1)); PCI_OUT_BYTE (pciConfigAddr1, busNo); PCI_OUT_LONG ((pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (address & 0xfc)), data); PCI_OUT_BYTE (pciConfigAddr0, 0); break; default: break; } semGive (&pciMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pciSpecialCycle - generate a special cycle with a message** This routine generates a special cycle with a message.** RETURNS:* OK, or ERROR if this library is not initialized.**/STATUS pciSpecialCycle ( int busNo, /* bus number */ int message /* data on AD[31:0] during the special cycle */ ) { int deviceNo = 0x0000001f; int funcNo = 0x00000007; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); semTake (&pciMuteSem, WAIT_FOREVER); /* mutual execlusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | 0x80000000); PCI_OUT_LONG (pciConfigAddr1, message); break; case PCI_MECHANISM_2: PCI_OUT_BYTE (pciConfigAddr0, 0xff); PCI_OUT_BYTE (pciConfigAddr1, 0x00); PCI_OUT_LONG ((pciConfigAddr2 | ((deviceNo & 0x000f) << 8)), message); PCI_OUT_BYTE (pciConfigAddr0, 0); break; default: break; } semGive (&pciMuteSem); /* mutual execlusion stop */ return (OK); }/********************************************************************************* pciInt - interrupt handler for shared PCI interrupt.** This routine executes multiple interrupt handlers for a PCI interrupt.* Each interrupt handler must check the device dependent interrupt status bit* to determine the source of the interrupt, since it simply execute all* interrupt handlers in the link list.** RETURNS: N/A**/VOID pciInt ( int irq /* IRQ associated to the PCI interrupt */ ) { PCI_INT_RTN *pRtn; for (pRtn = (PCI_INT_RTN *)DLL_FIRST (&pciIntList[irq]); pRtn != NULL; pRtn = (PCI_INT_RTN *)DLL_NEXT (&pRtn->node)) (* pRtn->routine) (pRtn->parameter); }/********************************************************************************* pciIntConnect - connect the interrupt handler to the PCI interrupt.** This routine connects an interrupt handler to the PCI interrupt line(A - D).* Link list is created if multiple handlers are assigned to the single PCI* interrupt.** RETURNS:* OK, or ERROR if the interrupt handler cannot be built.**/STATUS pciIntConnect ( VOIDFUNCPTR *vector, /* interrupt vector to attach to */ VOIDFUNCPTR routine, /* routine to be called */ int parameter /* parameter to be passed to routine */ ) { int irq = IVEC_TO_INUM ((int)vector) - INT_NUM_IRQ0; PCI_INT_RTN *pRtn; int oldLevel; if (pciLibInitStatus != OK) return (ERROR); pRtn = (PCI_INT_RTN *)malloc (sizeof (PCI_INT_RTN)); if (pRtn == NULL) return (ERROR); pRtn->routine = routine; pRtn->parameter = parameter; oldLevel = intLock (); /* LOCK INTERRUPT */ dllAdd (&pciIntList[irq], &pRtn->node); intUnlock (oldLevel); /* UNLOCK INTERRUPT */ return (OK); }/********************************************************************************* pciIntDisconnect - disconnect the interrupt handler from the PCI interrupt.** This routine disconnects the interrupt handler from the PCI interrupt line.** RETURNS:* OK, or ERROR if the interrupt handler cannot be removed.**/STATUS pciIntDisconnect ( VOIDFUNCPTR *vector, /* interrupt vector to attach to */ VOIDFUNCPTR routine /* routine to be called */ ) { int irq = IVEC_TO_INUM ((int)vector) - INT_NUM_IRQ0; PCI_INT_RTN *pRtn; int oldLevel; if (pciLibInitStatus != OK) return (ERROR); for (pRtn = (PCI_INT_RTN *)DLL_FIRST (&pciIntList[irq]); pRtn != NULL; pRtn = (PCI_INT_RTN *)DLL_NEXT (&pRtn->node)) { if (pRtn->routine == routine) { oldLevel = intLock (); /* LOCK INTERRUPT */ dllRemove (&pciIntList[irq], &pRtn->node); intUnlock (oldLevel); /* UNLOCK INTERRUPT */ free ((char *)pRtn); return (OK); } } return (ERROR); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -