⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixdp2400pci.c

📁 ixp2400 bsp for vxworks
💻 C
📖 第 1 页 / 共 3 页
字号:
{    return (void*)(~(*(UINT32 *)IXP2400_PCI_DRAM_BAR & ~0xF) & ((UINT32)PciAddr));}/******************************************************************************** sysPhysToPci - translate a physical address to a Pci address** This function converts a physical address to a Pci address. This only works* for PCI Memory space.** RETURNS: the Pci adddress*/void * sysPhysToPci(void *PhysAddr){    return (void*)((*(UINT32 *)IXP2400_PCI_DRAM_BAR & ~0xF) | ((UINT32)PhysAddr));}#ifdef AUTO_PCI_CONFIG/******************************************************************************** sysPciAssignAddrs - Scan PCI bus and automatically assign PCI addresses** This function scans the PCI bus to see what other devices are there. Then* it assigns them addresses. It also adds page entries to cover the range of* PCI space used. It enables PCI transactions as defined by INITIAL_PCI_CMD,* which defaults to enabling IO transactions.* It also does the transparent bridge init.** This funciton only has an effect if this processor is the PCI central function.** RETURNS: N/A*/voidsysPciAssignAddrs(void){	UINT32 ioStartAddr = 0;	UINT32 memStartAddr = 0;    int bus;	int dev;	int i;	int j;    UINT16 data;    INT32 data32;	INT32 size;	UINT32 bridgeIoStart = 0;	UINT32 bridgeIoLimit = 0;	UINT32 bridgeMemStart = 0;	UINT32 bridgeMemLimit = 0;	int memAddrExt = 0;	int ioAddrExt = 0;	/* if this is slave npu then return */	if(!(strapOptionsVal & CFG_PCI_BOOT_HOST))        return;    nDevices = 0;    for(bus = 0; bus < PCI_MAX_BUS; bus++)	{        for(dev = 0; dev < PCI_MAX_DEV; dev++)		{            pciConfigInWord(bus, dev, 0, PCI_CFG_VENDOR_ID, &data);            if (data == 0xFFFF)                continue;            if (nDevices == MAX_DEVICES)                break;            devices[nDevices].bus = bus;            devices[nDevices].device = dev;            devices[nDevices].func = 0;            devices[nDevices].vendor_id = data;            pciConfigInWord(bus, dev, 0, PCI_CFG_DEVICE_ID, &data);            devices[nDevices].device_id = data;            for (i = 0; i < 6; i++)			{                pciConfigOutLong(bus, dev, 0,                                 PCI_CFG_BASE_ADDRESS_0 + (4*i),                                 0xFFFFFFFF);                pciConfigInLong(bus, dev, 0,                                PCI_CFG_BASE_ADDRESS_0 + (4*i),                                &data32);                if (data32 == 0)				{					devices[nDevices].bar[i].size = 0;                    break;				}                devices[nDevices].bar[i].address = (data32 & 1);                if (data32 & 1)				{                    /* IO space */                    size = ~((data32 & ~0x3) - 1);                    devices[nDevices].bar[i].size = size;					if((ioStartAddr + devices[nDevices].bar[i].size) < 0x2000000)					{						/* assign address */						ioStartAddr = ROUND_UP(ioStartAddr, devices[nDevices].bar[i].size);						devices[nDevices].bar[i].address |= ioStartAddr;						ioStartAddr += devices[nDevices].bar[i].size;					}					else					{						if(ioAddrExt < 0xFFFF)						{							ioAddrExt++;							devices[nDevices].bar[i].address = ioAddrExt << 16;						}					}                }				else				{                    /* Mem space */                    size = ~((data32 & ~0xF) - 1);                    devices[nDevices].bar[i].size = size;					if(((memStartAddr + devices[nDevices].bar[i].size) < 0x20000000)						&& (size < SZ_128M))					{						/* assign address */						memStartAddr = ROUND_UP(memStartAddr, devices[nDevices].bar[i].size);						devices[nDevices].bar[i].address |= memStartAddr;						memStartAddr += devices[nDevices].bar[i].size;					}					else					{						if(memAddrExt < 7)						{							memAddrExt++;							devices[nDevices].bar[i].address = memAddrExt << 29;						}					}                }            } /* end for i */            devices[nDevices].irq = (int)INT_VEC_PIL;            nDevices++;        } /* end for dev */		/* For bridges, the memory window must start and end on a 1M		boundary and the I/O window must start and end on a 4K	    boundary. We round up the mem and I/O allocation bases	    to appropriate boundaries before configuring the devices on secondary bus */		if(bus == 0)		{			/* round up start of PCI memory space to a 1M boundary */			memStartAddr = ROUND_UP(memStartAddr, SZ_1M);			/* round up start of PCI I/O space to a 4 Kbyte start address */			ioStartAddr = ROUND_UP(ioStartAddr, SZ_4K);			/* save the starting offset for bus 1 */			bridgeIoStart = ioStartAddr;			bridgeMemStart = memStartAddr;		}    } /* end for bus */	/* check if we used any IO space */	if(ioStartAddr > bridgeIoStart)	{		ioStartAddr = ROUND_UP(ioStartAddr, SZ_4K);		bridgeIoLimit = ioStartAddr - 0x1000;		/* configure bridge registers accordingly */		pciConfigOutWord(tbBusNo, tbDeviceNo, tbFuncNo, PCI_CFG_IO_BASE_U,			(bridgeIoStart >> 16));		pciConfigOutWord(tbBusNo, tbDeviceNo, tbFuncNo, PCI_CFG_IO_LIMIT_U,			(bridgeIoLimit >> 16));		pciConfigOutByte(tbBusNo, tbDeviceNo, tbFuncNo, PCI_CFG_IO_BASE,			((bridgeIoStart & 0xf000) >> 8));		pciConfigOutByte(tbBusNo, tbDeviceNo, tbFuncNo, PCI_CFG_IO_LIMIT,			((bridgeIoLimit & 0xf000) >> 8));	}	/* check if we used any Mem space */	if(memStartAddr > bridgeMemStart)	{		memStartAddr = ROUND_UP(memStartAddr, SZ_1M);		bridgeMemLimit = memStartAddr - 0x100000;		/* configure bridge registers accordingly */		pciConfigOutWord(tbBusNo, tbDeviceNo, tbFuncNo, PCI_CFG_MEM_BASE,			((bridgeMemStart >> 16) & 0xfff0));		pciConfigOutWord(tbBusNo, tbDeviceNo, tbFuncNo, PCI_CFG_MEM_LIMIT,			((bridgeMemLimit >> 16) & 0xfff0));		pciConfigOutWord(tbBusNo, tbDeviceNo, tbFuncNo, PCI_CFG_PRE_MEM_LIMIT, 0);		pciConfigOutWord(tbBusNo, tbDeviceNo, tbFuncNo, PCI_CFG_PRE_MEM_BASE, 0xfff0);	}    for(i = 0; i < nDevices; i++)	{        for (j = 0; devices[i].bar[j].size; j++)		{            pciConfigOutLong(devices[i].bus,                             devices[i].device,                             devices[i].func,                             PCI_CFG_BASE_ADDRESS_0 + (4*j),                             devices[i].bar[j].address);        }         pciConfigOutLong(devices[i].bus,                         devices[i].device,                         devices[i].func,                         PCI_CFG_DEV_INT_LINE,                         INT_VEC_PIL);        pciConfigOutWord(devices[i].bus,                         devices[i].device,                         devices[i].func,                         PCI_CFG_COMMAND,                          PCI_CMD_STAT_VAL);    } /* end for i */}#ifdef INCLUDE_AUTO_PCI_CONFIG_SHOW_ROUTINE/******************************************************************************** pciAddrShow - Shows PCI address assignments** This function prints the PCI address assignments automatically generated. * It prints a table giving for each device the bus number, device number,* a flag indicating whether there was an error for that device, and the* vendor/device ID. Then it lists the BARs for that device, giving the* size of the region and its address. If the low-order bit of the address* is "1", then the address corresponds to I/O space, otherwise it is in* memory space.** RETURNS: N/A*/void pciAddrShow(void){    int i;	int j;    for(i = 0; i < nDevices; i++)	{        printf("bus %d  dev %d  irq 0x%02X id %04X %04X\n",               devices[i].bus,               devices[i].device,               devices[i].irq,               devices[i].vendor_id,               devices[i].device_id);        for (j=0; devices[i].bar[j].size; j++)		{            printf("  size %08X  addr %08X\n",                   devices[i].bar[j].size,                   devices[i].bar[j].address);        }    } /* end for i */}/******************************************************************************** pciInfoGet - Retrieves PCI device information** This function retrieves the PCI assignments of the specified device. * It returns a pointer to a PciDevice structure containing the bus number,* device number, a flag indicating whether there was an error for that* device, the vendor/device ID and a lists the BARs indicating the size of* the region and its address for that device. A NULL pointer will be* returned if the specified device is not within range of the configured* devices.** RETURNS: Pointer to PCI device information, or NULL*/PciDevice *pciInfoGet(UINT16 device){    if(device >= nDevices)		return(NULL);	return(&devices[device]);}/******************************************************************************** pciInfoSearch - Retrieves PCI device information** This function returns a pointer to the n'th instance of a specified device.* If the entry is not found, NULL is returned.** RETURNS: Pointer to PCI device information, or NULL*/PciDevice *pciInfoSearch(int bus, int device, int func, int count){    int ix;	int cnt = 0;    for ( ix = 0; ix < MAX_DEVICES; ix++)	{        if(devices[ix].bus == bus &&            devices[ix].device == device &&            devices[ix].func == func)		{            if(cnt == count)				return (&devices[ix]);            else                cnt++;		}	}    return((PciDevice *)NULL);}#endif /* ifdef #ifdef INCLUDE_AUTO_PCI_CONFIG_SHOW_ROUTINE *//******************************************************************************** pciDeviceGet - Retrieves PCI device information** This function returns a pointer to the n'th instance of a specified device.* If the entry is not found, NULL is returned.** RETURNS: Pointer to PCI device information, or NULL*/PciDevice *pciDeviceGet(int vendor_id, int device_id, int count){    int ix;	int cnt = 0;    for(ix = 0; ix < MAX_DEVICES; ix++)	{        if(devices[ix].vendor_id == vendor_id &&            devices[ix].device_id == device_id)		{            if(cnt == count)				return (&devices[ix]);            else                cnt++;		}	}    return( (PciDevice *)NULL );}/********************************************************************************* pciDeviceShow - print information about PCI devices** This routine prints information about PCI devices* There are two ways to find out an empty device.*   - check Master Abort bit after the access.*   - check whether the read value is 0xffff.* It uses the second method, since I didn't see the Master Abort bit of* the host/PCI bridge changing.** RETURNS:* OK, or ERROR if the library is not initialized.*/STATUS pciDeviceShow(void)    {    int deviceNo;    if (pciLibInitStatus != OK)			/* sanity check */        return (ERROR);    printf ("bus       device    function  vendorID  deviceID\n");    for (deviceNo=0; deviceNo < nDevices; deviceNo++)	{	    printf ("%.8x  %.8x  %.8x  %.8x  %.8x\n",		    devices[deviceNo].bus, devices[deviceNo].device, devices[deviceNo].func, devices[deviceNo].vendor_id, devices[deviceNo].device_id);	}    return (OK);    }#endif /* ifdef AUTO_PCI_CONFIG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -