📄 tyspci.c
字号:
ULONG data /* data to write */
)
{
if ((busNo == 0) && (deviceNo == 12))
return (ERROR);
switch (width)
{
case 1: /* byte */
PCI_OUT_LONG (tyspciConfAddr,
pciConfigBdfPack (busNo, deviceNo, funcNo) |
(offset & 0xfc) | 0x80000000);
PCI_OUT_BYTE ((tyspciConfData + (offset & 0x3)), data);
break;
case 2: /* word */
PCI_OUT_LONG (tyspciConfAddr,
pciConfigBdfPack (busNo, deviceNo, funcNo) |
(offset & 0xfc) | 0x80000000);
PCI_OUT_WORD ((tyspciConfData + (offset & 0x2)), data);
break;
case 4: /* long */
PCI_OUT_LONG (tyspciConfAddr,
pciConfigBdfPack (busNo, deviceNo, funcNo) |
(offset & 0xfc) | 0x80000000);
PCI_OUT_LONG (tyspciConfData, data);
break;
default:
return (ERROR);
}
return (OK);
}
STATUS tysDeviceShow
(
int busNo /* bus number */
)
{
int deviceNo;
int devices;
ushort_t vendorId;
ushort_t deviceId;
union {
int classCode;
char array[4];
} u;
printf ("Scanning function 0 of each PCI device on bus %d\n", busNo);
printf ("bus device function vendorID deviceID class\n");
devices = 0x1f;
/*
pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_VENDOR_ID, &vendorId);
pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_DEVICE_ID, &deviceId);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_PROGRAMMING_IF,
&u.array[3]);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_SUBCLASS, &u.array[2]);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_CLASS, &u.array[1]);
u.array[0] = 0;
devices = 0x16;
pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_VENDOR_ID, &vendorId);
pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_DEVICE_ID, &deviceId);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_PROGRAMMING_IF,
&u.array[3]);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_SUBCLASS, &u.array[2]);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_CLASS, &u.array[1]);
u.array[0] = 0;
*/
for (deviceNo=0; deviceNo < devices; deviceNo++)
{
pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_VENDOR_ID, &vendorId);
pciConfigInWord (busNo, deviceNo, 0, PCI_CFG_DEVICE_ID, &deviceId);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_PROGRAMMING_IF,
&u.array[3]);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_SUBCLASS, &u.array[2]);
pciConfigInByte (busNo, deviceNo, 0, PCI_CFG_CLASS, &u.array[1]);
u.array[0] = 0;
/* There are two ways to find out an empty device.
* 1. check Master Abort bit after the access.
* 2. check whether the read value is 0xffff.
* Since I didn't see the Master Abort bit of the host/PCI bridge
* changing, I use the second method.
*/
if (vendorId != 0xffff)
printf ("%.8x %.8x %.8x %.8x %.8x %.8x\n",
busNo, deviceNo, 0, vendorId, deviceId, u.classCode);
}
return (OK);
}
STATUS tysAutoBusNumberSet
( PCI_LOC * pPciLoc, UINT primary, UINT secondary, UINT subordinate ) { UINT workvar = 0; /* Working variable */ workvar = (subordinate << 16) + (secondary << 8) + primary; /* longword write */ pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRIMARY_BUS, 0x00ffffff, workvar); return OK; }
LOCAL UCHAR tysAutoIntAssign
( PCI_SYSTEM * pSystem, /* PCI system info */ PCI_LOC * pFunc /* input: Pointer to PCI function structure */ ) { UCHAR retVal = 0xFF; UCHAR intPin; /* Interrupt "Pin" value */ pciConfigInByte (pFunc->bus, pFunc->device, pFunc->function, PCI_CFG_DEV_INT_PIN, &intPin); /* * if the bsp provides interrupt routing for all PCI devices, * then there's no need of any computation whatsoever */ if ((!(pSystem->autoIntRouting)) && (intPin != 0)) { if ((pSystem->intAssignRtn) != NULL ) { retVal = (pSystem->intAssignRtn) (pSystem, pFunc, intPin); return (retVal); } } /* default interrupt routing: let's find out the IRQ for this device */ switch (pFunc->bus) { case 0: if (((pSystem->intAssignRtn) != NULL) && (intPin != 0)) { retVal = (pSystem->intAssignRtn) (pSystem, pFunc, intPin); } /* * if this is a P2P Bridge, then populate its interrupt * routing table. This will be used later for all the devices * belonging to its every subourdinate bus */ if (((pFunc->attribute) & PCI_AUTO_ATTR_BUS_PCI) > 0) { int i = 0; for (i = 0; i < 4; i++) { if ((pSystem->intAssignRtn) != NULL ) { tysAutoIntRoutingTable [i] = (pSystem->intAssignRtn)
(pSystem, pFunc, (i+1)); } } } break; default: retVal = tysAutoIntRoutingTable [(((pFunc->device) + (intPin - 1)
+ (pFunc->offset)) % 4)]; break; } printf("pciAutoIntAssign: int for [%d,%d,%d] pin %d is [%d]\n",
pFunc->bus, pFunc->device, pFunc->function, intPin, retVal);
return retVal; }
LOCAL void tysAutoFuncEnable
( PCI_SYSTEM * pSystem, /* PCI system info */ PCI_LOC * pFunc /* input: Pointer to PCI function structure */ ) { short pciClass; /* PCI class/subclass contents */ UCHAR intLine = 0xff; /* Interrupt "Line" value */ if ((pFunc->attribute) & PCI_AUTO_ATTR_DEV_EXCLUDE) { return; } printf("pciAutoFuncConfig: enable device [%d,%d,%d,0x%02x]\n",
pFunc->bus,
pFunc->device,
pFunc->function,
pFunc->attribute);
/* Initialize the cache line size register */ pciConfigOutByte (pFunc->bus, pFunc->device, pFunc->function, PCI_CFG_CACHE_LINE_SIZE, pSystem->cacheSize); /* Initialize the latency timer */ pciConfigOutByte (pFunc->bus, pFunc->device, pFunc->function, PCI_CFG_LATENCY_TIMER, pSystem->maxLatency); /* Get the PCI class code */ pciConfigInWord (pFunc->bus, pFunc->device, pFunc->function, PCI_CFG_SUBCLASS, &pciClass); /* Enable Bus Mastering (preserve status bits) */ pciConfigModifyLong (pFunc->bus, pFunc->device, pFunc->function, PCI_CFG_COMMAND, (0xffff0000 | PCI_CMD_MASTER_ENABLE), PCI_CMD_MASTER_ENABLE); /* * If an interrupt assignment routine is registered, assign the * interrupt and record interrupt line in config header, else * write 0xff (default value) to the interrupt line reg */ intLine = tysAutoIntAssign (pSystem, pFunc);
pciConfigOutByte (pFunc->bus, pFunc->device, pFunc->function, PCI_CFG_DEV_INT_LINE, intLine); /* Reset all writeable status bits */ pciConfigOutWord (pFunc->bus, pFunc->device, pFunc->function, PCI_CFG_STATUS, (UINT16)0xFFFF); return; }
LOCAL void tysAutoBusConfig
( PCI_SYSTEM * pSystem, /* PCI system info */ PCI_LOC * pPciLoc, /* PCI address of this bridge */ PCI_LOC **ppPciList, /* Pointer to function list pointer */ UINT *nSize /* Number of remaining functions */ ) { UCHAR bus; /* Bus number for current bus */ UINT temp; UINT dev_vend; UINT32 debugTmp; UINT32 debugTmp2; UINT32 debugTmp3; /* If it exists, call the user-defined pre-config pass bridge init */ if ((pSystem->bridgePreConfigInit) != NULL ) { pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_VENDOR_ID, &dev_vend); (pSystem->bridgePreConfigInit) (pSystem, pPciLoc, dev_vend); } /* Clear the secondary status bits */ pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE, 0xffff0000, 0xffff0000); /* Disable prefetch */ pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_BASE, 0xfff0fff0, 0x0000fff0); pciConfigOutLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_LIMIT_U, 0); pciConfigOutLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_BASE_U, 0xffffffff); /* Check for Prefetch memory support */ pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_BASE, &debugTmp); /* PF Registers return 0 if PF is not implemented */ if (debugTmp != 0) { pPciLoc->attribute |= PCI_AUTO_ATTR_BUS_PREFETCH; printf("pciAutoBusConfig: Bridge supports prefetch\n");
/* Pre-configure 32-bit Prefetchable Memory Base Address */ if ((pSystem->pciMem32Size) > 0) { temp = (pSystem->pciMem32); (pSystem->pciMem32) = (((pSystem->pciMem32) & ~0xfffff) + 0x100000); (pSystem->pciMem32Size) -= ((pSystem->pciMem32) - temp); printf("PF Base orig[0x%08x] new[0x%08x] adj[0x%08x]\n",
temp, pSystem->pciMem32,
(pSystem->pciMem32) - temp
); /* 64-bit Prefetch memory not supported at this time */ pciConfigOutLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_BASE_U, 0); pciConfigModifyLong (pPciLoc->bus,pPciLoc->device,pPciLoc->function, PCI_CFG_PRE_MEM_BASE, 0x0000fff0, (pSystem->pciMem32 >> (20-4)) ); pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_BASE, &debugTmp2); debugTmp = ((debugTmp2 & 0x0000fff0) << 16); printf("pciAutoBusConfig: PF Mem Base [0x%08x]\n",
debugTmp);
} } /* Pre-configure 32-bit I/O Base Address */ if ((pSystem->pciIo16Size) > 0) { temp = (pSystem->pciIo16); (pSystem->pciIo16) = (((pSystem->pciIo16) & ~0xfff) + 0x1000); (pSystem->pciIo16Size) -= ((pSystem->pciIo16) - temp); printf("IO16 Base align: orig[0x%08x] new[0x%08x] adj[0x%08x]\n",
temp, pSystem->pciIo16,
(pSystem->pciIo16) - temp
); pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE, 0x000000f0, (pSystem->pciIo16 >> (12-4)) ); pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE_U, 0x0000ffff, (pSystem->pciIo16 >> 16) ); pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE, &debugTmp); pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE_U, &debugTmp2); debugTmp3 = (((debugTmp & (UINT32)0xf0) << (12-4)) & 0x0000ffff); debugTmp = debugTmp3 | ((debugTmp2 << 16) & 0xffff0000); printf("pciAutoBusConfig: IO16 Base Address [0x%08x]\n",
debugTmp);
} /* Pre-configure 32-bit Non-prefetchable Memory Base Address */ if ((pSystem->pciMemIo32Size) > 0) { temp = (pSystem->pciMemIo32); (pSystem->pciMemIo32) = (((pSystem->pciMemIo32) & ~0xfffff) + 0x100000); (pSystem->pciMemIo32Size) -= ((pSystem->pciMemIo32) - temp); printf("NPMem Base: orig[0x%08x] new[0x%08x] adj[0x%08x]\n",
temp, pSystem->pciMemIo32,
(pSystem->pciMemIo32)- temp
); pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_MEM_BASE, 0x0000fff0, (pSystem->pciMemIo32 >> (20-4)) ); pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_MEM_BASE, &debugTmp2); debugTmp = ((debugTmp2 & 0x0000fff0) << 16); printf("pciAutoBusConfig: Mem Base Address [0x%08x]\n",
debugTmp);
} /* Configure devices on the bus implemented by this bridge */ pciConfigInByte (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_SECONDARY_BUS, &bus); tysAutoDevConfig (pSystem, bus, ppPciList, nSize);
/* Post-configure 32-bit I/O Limit Address */ if ((pSystem->pciIo16Size) > 0) { temp = (pSystem->pciIo16); (pSystem->pciIo16) = (((pSystem->pciIo16) & ~0xfff) + 0x1000); (pSystem->pciIo16Size) -= ((pSystem->pciIo16) - temp); printf("IO16 Limit: orig[0x%08x] new[0x%08x] adj[0x%08x]\n",
temp, pSystem->pciIo16,
(pSystem->pciIo16) - temp );
pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE, 0x0000f000, (pSystem->pciIo16 - 1) ); pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE_U, 0xffff0000, (pSystem->pciIo16 - 1) ); pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE, &debugTmp); pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_IO_BASE_U, &debugTmp2); debugTmp3 = ((debugTmp & (UINT32)0xf000) & 0x0000ffff); debugTmp = debugTmp3 | (debugTmp2 & 0xffff0000); debugTmp |= 0x00000FFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -