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

📄 ixm1200pci.c

📁 vxworks的BSP开发配置文件
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* Assign Addresses */    for (i=0; i < nBars; i++) {        /* Assign bar[i] */        if (Bars[i]->address != 0xFFFFFFFF) {            /* Already Assigned */            continue;        }        /* Find first available addr */        addr = 0;        /* check for conflicts */        for (j=0; j < nBars; j++) {            if (Bars[j]->address == 0xFFFFFFFF)                continue;            /* Bars[j] has valid address */            if ((Bars[j]->address < addr + Bars[i]->size) &&                (addr < Bars[j]->address + Bars[j]->size)) {                /* conflict */                addr = Bars[j]->address + Bars[j]->size;                addr = (addr + Bars[i]->size - 1) & ~(Bars[i]->size - 1);                j = -1;                continue;            } /* end if conflict */        } /* end for j */        /* no conflict */        Bars[i]->address = addr;    } /* end for i */}/******************************************************************************** addPageEntries - Call sysMmuMapAdd to add page entries for specified range** This function takes a range of addresses containing a gap, and then calls* sysMmuMapAdd to add page table entries for the one or two memory ranges* specified.** RETURNS: N/A*/static voidaddPageEntries    (    UINT32 start,      /* Starting PCI address of range*/    UINT32 size,       /* Size of range */    UINT32 offset      /* Offset from PCI address to virtual address */    ){    UINT32 end = start + size;    if (size != 0) {        start = ROUND_DOWN(start, PAGE_SIZE);        end = ROUND_UP(end, PAGE_SIZE);        sysMmuMapAdd((void*)(offset + start), end-start,                     VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE,                     VM_STATE_VALID | VM_STATE_WRITABLE     | VM_STATE_CACHEABLE_NOT);    }}/******************************************************************************** sysPciAssignAddrs - Scan PCI bus and automatically assign PCI addresses** This function scans the PCI bus to see what other devices are there. It then* sorts the BARs that it finds and 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.** As a special case, it assigns its own SDRAM space to PCI address zero.** This funciton only has an effect if this processor is the PCI central function.** RETURNS: N/A*/voidsysPciAssignAddrs(void){    PciBar   *memBars[MAX_BARS];    PciBar   *ioBars[MAX_BARS];    int nMBars, nIOBars;    int bus, dev, func, i, j;    UINT16 data;    INT32 data32, tmp, size;#if !(defined(IXM1200))    int central_func;    central_func =        IXP1200_SA_CONTROL_PCF & *(UINT32 *)IXP1200_SA_CONTROL;    if (! central_func)        return;#endif    /* Assign first device to ourselves */    devices[0].bus = 0;    devices[0].device = 0;    devices[0].func = 0;    devices[0].vendor_id = sysRead16((void*)IXM1200_PCI_VENDOR_ID);    devices[0].device_id = sysRead16((void*)IXM1200_PCI_DEVICE_ID);    devices[0].error = FALSE;    devices[0].bar[CSR_BAR].size = IXM1200_PCI_MEM_BAR_SIZE; /* 1 Meg: CSR Mem Base */    devices[0].bar[CSR_BAR].address = *(UINT32 *)(IXM1200_PCI_MEM_BAR);       /* Mem addr */    devices[0].bar[IO_BAR].size = IXM1200_PCI_IO_BAR_SIZE;  /* 128: CSR I/O Base */    devices[0].bar[IO_BAR].address = *(UINT32 *)(IXM1200_PCI_IO_BAR);        /* I/O addr */    devices[0].bar[SD_BAR].size = LOCAL_MEM_SIZE_ACTUAL; /* SDRAM Mem Base */    devices[0].bar[SD_BAR].address = *(UINT32 *)(IXM1200_PCI_DRAM_BAR);      /* Mem addr */    devices[0].bar[NO_BAR].size = 0;    nDevices = 1;    nMBars = nIOBars = 0;    /* But SDRAM base first */    memBars[nMBars++] = &devices[0].bar[SD_BAR];    memBars[nMBars++] = &devices[0].bar[CSR_BAR];    ioBars[nIOBars++] = &devices[0].bar[IO_BAR];    func = 0;    for ( bus = 0; bus < PCI_MAX_BUS; bus++ ) {        for (dev = 0; dev < PCI_MAX_DEV; dev++ ) {            pciConfigInWord(bus, dev, func, 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 = func;            devices[nDevices].vendor_id = data;            pciConfigInWord(bus, dev, func, PCI_CFG_DEVICE_ID, &data);            devices[nDevices].device_id = data;            devices[nDevices].error = FALSE;            for (i=0; i<6; i++) {                pciConfigOutLong(bus, dev, func,                                 PCI_CFG_BASE_ADDRESS_0 + (4*i),                                 0xFFFFFFFF);                pciConfigInLong(bus, dev, func,                                PCI_CFG_BASE_ADDRESS_0 + (4*i),                                &data32);                if (data32 == 0)                    break;                devices[nDevices].bar[i].address = (data32 & 1);                if (data32 & 1) {                    /* IO space */                    tmp = data32 & ~0x00000003;                    size = ~(tmp-1);                    devices[nDevices].bar[i].size = size;                    devices[nDevices].bar[i].address = 0xFFFFFFFF;                    if (tmp != ~(size-1))                        devices[nDevices].error = TRUE;                    else {                        if (nIOBars < MAX_BARS)                            ioBars[nIOBars++] = &devices[nDevices].bar[i];                    }                } else {                    /* Mem space */                    tmp = data32 & ~0x0000000F;                    size = ~(tmp-1);                    devices[nDevices].bar[i].size = size;                    devices[nDevices].bar[i].address = 0xFFFFFFFF;                    if (tmp != ~(size-1))                        devices[nDevices].error = TRUE;                    else {                        if (nMBars < MAX_BARS)                            memBars[nMBars++] = &devices[nDevices].bar[i];                    }                }            } /* end for i */            devices[nDevices].bar[i].size = 0;            devices[nDevices].irq = (int)INT_VEC_PIL;            nDevices++;        } /* end for dev */    } /* end for bus */    /* Sort bars, Leave our SDRAM at Mem zero */    sortBars(memBars, nMBars);    sortBars(ioBars, nIOBars);    for (i=0; i < nIOBars; i++)        ioBars[i]->address |= 1;    data = INITIAL_PCI_CMD;    *(UINT32 *)(IXM1200_PCI_MEM_BAR)  = devices[0].bar[CSR_BAR].address;    *(UINT32 *)(IXM1200_PCI_IO_BAR)   = devices[0].bar[IO_BAR].address;    *(UINT32 *)(IXM1200_PCI_DRAM_BAR) = devices[0].bar[SD_BAR].address;    /* Fix C0/Hyannis PCI CSR bug */    *(volatile int*)(IXM1200_PCI_MEM_BAR);        for (i=1; i<nDevices; i++) {        if (devices[i].error)            continue;        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);            addPageEntries(devices[i].bar[j].address,                           devices[i].bar[j].size,                           ((devices[i].bar[j].address & 1) ?                            PCI_IO_BASE : PCI_MEM_BASE));        }        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,                         data);    } /* end for i */}/******************************************************************************** readBarsAddrs - Scan PCI bus and automatically reads the BARs addresses** This function scans the PCI bus and reads their addresses. It also adds* page entries to cover the range of PCI space used.** As a special case, it assigns its own SDRAM space to PCI address zero.** This funciton only has an effect if this processor is the PCI central function.** RETURNS: N/A*/voidreadBarsAddrs(void){    int bus, dev, func, i, j;    UINT16 data;    INT32 data32, tmp, size;#if !(defined(IXM1200))    int central_func;    central_func =        IXM1200_SA_CONTROL_PCF & *(UINT32 *)IXM1200_SA_CONTROL;    if (! central_func)        return;#endif    /* Assign first device to ourselves */    devices[0].bus = 0;    devices[0].device = 0;    devices[0].func = 0;    devices[0].vendor_id = sysRead16((void*)IXM1200_PCI_VENDOR_ID);    devices[0].device_id = sysRead16((void*)IXM1200_PCI_DEVICE_ID);    devices[0].error = FALSE;    devices[0].bar[CSR_BAR].size    = IXM1200_PCI_MEM_BAR_SIZE;          /* 1 Meg: CSR Mem Base */    devices[0].bar[CSR_BAR].address = *(UINT32 *)(IXM1200_PCI_MEM_BAR);  /* Mem addr */    devices[0].bar[IO_BAR].size     = IXM1200_PCI_IO_BAR_SIZE;           /* 128: CSR I/O Base */    devices[0].bar[IO_BAR].address  = *(UINT32 *)(IXM1200_PCI_IO_BAR);   /* I/O addr */    devices[0].bar[SD_BAR].size     = LOCAL_MEM_SIZE_ACTUAL;             /* SDRAM Mem Base */    devices[0].bar[SD_BAR].address  = *(UINT32 *)(IXM1200_PCI_DRAM_BAR); /* Mem addr */    devices[0].bar[NO_BAR].size = 0;    nDevices = 1;    func = 0;    for ( bus = 0; bus < PCI_MAX_BUS; bus++ ) {        for (dev = 0; dev < PCI_MAX_DEV; dev++ ) {            pciConfigInWord(bus, dev, func, 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 = func;            devices[nDevices].vendor_id = data;            pciConfigInWord(bus, dev, func, PCI_CFG_DEVICE_ID, &data);            devices[nDevices].device_id = data;            devices[nDevices].error = FALSE;            for (i=0; i<6; i++) {                                pciConfigInLong(bus, dev, func,                                                                PCI_CFG_BASE_ADDRESS_0 + (4*i),                                                                &devices[nDevices].bar[i].address);                pciConfigOutLong(bus, dev, func,                                 PCI_CFG_BASE_ADDRESS_0 + (4*i),                                 0xFFFFFFFF);                pciConfigInLong(bus, dev, func,                                PCI_CFG_BASE_ADDRESS_0 + (4*i),                                &data32);                pciConfigOutLong(bus, dev, func,                                PCI_CFG_BASE_ADDRESS_0 + (4*i),                                                                devices[nDevices].bar[i].address);                                if (data32 == 0)                    break;                devices[nDevices].bar[i].address = (data32 & 1);                tmp = data32 & ~0x0000000F;                size = ~(tmp-1);                devices[nDevices].bar[i].size = size;                if (tmp != ~(size-1))                    devices[nDevices].error = TRUE;          } /* end for i */            devices[nDevices].bar[i].size = 0;            nDevices++;        } /* end for dev */    } /* end for bus */        for (i=1; i<nDevices; i++) {        if (devices[i].error)            continue;        for (j=0; devices[i].bar[j].size; j++) {            addPageEntries(devices[i].bar[j].address,                           devices[i].bar[j].size,                           ((devices[i].bar[j].address & 1) ?                            PCI_IO_BASE : PCI_MEM_BASE));        }    } /* 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, j;    for (i=0; i<nDevices; i++) {        printf("bus %d  dev %d  irq 0x%02X error %d  id %04X %04X\n",               devices[i].bus,               devices[i].device,               devices[i].irq,               devices[i].error,               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]);}#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, 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 );    }#endif /* ifdef AUTO_PCI_CONFIG */

⌨️ 快捷键说明

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