📄 pciiomaplib.c
字号:
* 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 offset, /* offset into the configuration space */ char data /* data written to the offset */ ) { UINT32 retval; int mask = 0x000000ff; int key; int n; UINT32 addr; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); key = intLock (); /* mutual exclusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000); PCI_OUT_BYTE ((pciConfigAddr1 + (offset & 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) | (offset & 0xfc)); data = (data & mask) << ((offset & 0x03) * 8); mask <<= (offset & 0x03) * 8; retval = (retval & ~mask) | data; PCI_OUT_LONG ((pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (offset & 0xfc)), retval); PCI_OUT_BYTE (pciConfigAddr0, 0); break; case PCI_MECHANISM_3: n = offset % 4; IDSEL(busNo, deviceNo); /* Setup IDSEL Lines */ addr = ((busNo == 0) ? pciConfigAddr0 : pciConfigAddr1) | MAKE_CFG_ADDR(busNo, deviceNo, funcNo, (offset & ~3)); retval = PCI_IN_LONG (addr); retval &= ~(0xFF << (n*8)); retval |= (data << (n*8)); PCI_OUT_LONG (addr, retval); CLR_IDSEL; /* Clear IDSEL Lines */ break; default: break; } intUnlock (key); /* mutual exclusion stop */ return (OK); }/********************************************************************************* pciConfigOutWord - write one 16-bit word to the PCI configuration space** This routine writes one 16-bit 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 offset, /* offset into the configuration space */ short data /* data written to the offset */ ) { UINT32 retval; int mask = 0x0000ffff; int key; int n; UINT32 addr; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); key = intLock (); /* mutual exclusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000); PCI_OUT_WORD ((pciConfigAddr1 + (offset & 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) | (offset & 0xfc)); data = (data & mask) << ((offset & 0x02) * 8); mask <<= (offset & 0x02) * 8; retval = (retval & ~mask) | data; PCI_OUT_LONG ((pciConfigAddr2 | ((deviceNo & 0x000f) << 8) | (offset & 0xfc)), retval); PCI_OUT_BYTE (pciConfigAddr0, 0); break; case PCI_MECHANISM_3: n = offset % 4; IDSEL(busNo, deviceNo); /* Setup IDSEL Lines */ addr = ((busNo == 0) ? pciConfigAddr0 : pciConfigAddr1) | MAKE_CFG_ADDR(busNo, deviceNo, funcNo, (offset & ~3)); retval = PCI_IN_LONG (addr); retval &= ~(0xFFFF << (n*8)); retval |= (data << n*8); PCI_OUT_LONG (addr, retval); CLR_IDSEL; /* Clear IDSEL Lines */ break; default: break; } intUnlock (key); /* mutual exclusion 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 offset, /* offset into the configuration space */ int data /* data written to the offset */ ) { int key; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); key = intLock (); /* mutual exclusion start */ switch (pciConfigMech) { case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciPack (busNo, deviceNo, funcNo) | (offset & 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) | (offset & 0xfc)), data); PCI_OUT_BYTE (pciConfigAddr0, 0); break; case PCI_MECHANISM_3: IDSEL(busNo, deviceNo); /* Setup IDSEL Lines */ PCI_OUT_LONG (((busNo == 0) ? pciConfigAddr0 : pciConfigAddr1) | MAKE_CFG_ADDR(busNo, deviceNo, funcNo, offset), data); CLR_IDSEL; /* Clear IDSEL Lines */ break; default: break; } intUnlock (key); /* mutual exclusion 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; int key; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); key = intLock (); /* mutual exclusion 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; } intUnlock (key); /* mutual exclusion 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); }#endif /* defined(INCLUDE_PCI) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -