📄 pciconfiglib.c
字号:
break; default: break; } intUnlock (key); /* mutual exclusion stop */ *pData = retval; return (retStat); }/********************************************************************************* pciConfigInWord - read one word from the PCI configuration space** This routine reads one word from the PCI configuration space** RETURNS: OK, or ERROR if this library is not initialized*/STATUS pciConfigInWord ( int busNo, /* bus number */ int deviceNo, /* device number */ int funcNo, /* function number */ int offset, /* offset into the configuration space */ UINT16 * pData /* data read from the offset */ ) { STATUS retStat = ERROR; UINT16 retval = 0; UINT32 retvallong = 0; int key; /* check for library initialization or unaligned access */#ifdef PCI_CONFIG_OFFSET_NOCHECK if (pciLibInitStatus != OK) { return (retStat); }#else if ((pciLibInitStatus != OK) || ((offset & (int)0x1) > 0) ) { return (retStat); }#endif key = intLock (); /* mutual exclusion start */ switch (pciConfigMech) { case PCI_MECHANISM_0: if (pciConfigRead (busNo, deviceNo, funcNo, offset, 2, (void *)&retval) == ERROR) { retval = 0xffff; } else { retStat = OK; } break; case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciConfigBdfPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000); retval = PCI_IN_WORD (pciConfigAddr1 + (offset & 0x2)); retStat = OK; break; case PCI_MECHANISM_2: PCI_OUT_BYTE (pciConfigAddr0, 0xf0 | (funcNo << 1)); PCI_OUT_BYTE (pciConfigAddr1, busNo); retvallong = PCI_IN_LONG (pciConfigAddr2 | \ ((deviceNo & 0x000f) << 8) | (offset & 0xfc)); PCI_OUT_BYTE (pciConfigAddr0, 0); retvallong >>= (offset & 0x02) * 8; retval = (UINT16)(retvallong & 0xffff); retStat = OK; break; default: break; } intUnlock (key); /* mutual exclusion stop */ *pData = retval; return (retStat); }/********************************************************************************* 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 offset, /* offset into the configuration space */ UINT32 * pData /* data read from the offset */ ) { int key; STATUS retStat = ERROR; UINT32 retval = 0; /* check for library initialization or unaligned access */#ifdef PCI_CONFIG_OFFSET_NOCHECK if (pciLibInitStatus != OK) { return (retStat); }#else if ((pciLibInitStatus != OK) || ((offset & (int)0x3) > 0) ) { return (retStat); }#endif key = intLock (); /* mutual exclusion start */ switch (pciConfigMech) { case PCI_MECHANISM_0: if (pciConfigRead (busNo, deviceNo, funcNo, offset, 4, (void *)&retval) == ERROR) { retval = 0xffffffff; } else { retStat = OK; } break; case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciConfigBdfPack (busNo, deviceNo, funcNo) | (offset & 0xfc) | 0x80000000); retval = PCI_IN_LONG (pciConfigAddr1); retStat = OK; 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)); PCI_OUT_BYTE (pciConfigAddr0, 0); retStat = OK; break; default: break; } intUnlock (key); /* mutual exclusion stop */ *pData = retval; return (retStat); }/********************************************************************************* 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 offset, /* offset into the configuration space */ UINT8 data /* data written to the offset */ ) { UINT32 retval; int mask = 0x000000ff; int key; if (pciLibInitStatus != OK) /* sanity check */ return (ERROR); key = intLock (); /* mutual exclusion start */ switch (pciConfigMech) { case PCI_MECHANISM_0: pciConfigWrite (busNo, deviceNo, funcNo, offset, 1, data); break; case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciConfigBdfPack (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; 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 */ UINT16 data /* data written to the offset */ ) { UINT32 retval; int mask = 0x0000ffff; int key; /* check for library initialization or unaligned access */#ifdef PCI_CONFIG_OFFSET_NOCHECK if (pciLibInitStatus != OK) { return (ERROR); }#else if ((pciLibInitStatus != OK) || ((offset & (int)0x1) > 0) ) { return (ERROR); }#endif key = intLock (); /* mutual exclusion start */ switch (pciConfigMech) { case PCI_MECHANISM_0: pciConfigWrite (busNo, deviceNo, funcNo, offset, 2, data); break; case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciConfigBdfPack (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; 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 */ UINT32 data /* data written to the offset */ ) { int key; /* check for library initialization or unaligned access */#ifdef PCI_CONFIG_OFFSET_NOCHECK if (pciLibInitStatus != OK) { return (ERROR); }#else if ((pciLibInitStatus != OK) || ((offset & (int)0x3) > 0) ) { return (ERROR); }#endif key = intLock (); /* mutual exclusion start */ switch (pciConfigMech) { case PCI_MECHANISM_0: pciConfigWrite (busNo, deviceNo, funcNo, offset, 4, data); break; case PCI_MECHANISM_1: PCI_OUT_LONG (pciConfigAddr0, pciConfigBdfPack (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; default: break; } intUnlock (key); /* mutual exclusion stop */ return (OK); }/******************************************************************************* pciConfigModifyLong - Perform a masked longword register update** This function writes a field into a PCI configuration header without* altering any bits not present in the field. It does this by first* doing a PCI configuration read (into a temporary location) of the PCI* configuration header word which contains the field to be altered.* It then alters the bits in the temporary location to match the desired* value of the field. It then writes back the temporary location with* a configuration write. All configuration accesses are long and the* field to alter is specified by the "1" bits in the 'bitMask' parameter.** Be careful to using pciConfigModifyLong for updating the Command and* status register. The status bits must be written back as zeroes, else* they will be cleared. Proper use involves including the status bits in* the mask value, but setting their value to zero in the data value.** The following example will set the PCI_CMD_IO_ENABLE bit without clearing any* status bits. The macro PCI_CMD_MASK includes all the status bits as* part of the mask. The fact that PCI_CMD_MASTER doesn't include these bits,* causes them to be written back as zeroes, therefore they aren't cleared.** .CS* pciConfigModifyLong (b,d,f,PCI_CFG_COMMAND,* (PCI_CMD_MASK | PCI_CMD_IO_ENABLE), PCI_CMD_IO_ENABLE);* .CE** Use of explicit longword read and write operations for dealing with any* register containing "write 1 to clear" bits is sound policy.** RETURNS: OK if operation succeeds, ERROR if operation fails.*/STATUS pciConfigModifyLong (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -