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

📄 pciinit.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
        return(FALSE);
    }

    *pMemSize += SecondaryMemSize;
    *pIoSize += SecondaryIoSize;

    return(TRUE);

}


BOOL
PciInitCheckBARs(
    ULONG Bus,
    ULONG Device,
    ULONG Function,
    ULONG NumberOfRegs,
    PULONG pMemSize,
    PULONG pIoSize
    )
{
    ULONG Offset;
    ULONG i;
    ULONG BaseAddress;
    ULONG Size;
    ULONG Type;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("InitCheckBars %d %d %d\r\n"), Bus, Device, Function));
    
    Offset = 0x10;
    for (i = 0; i < NumberOfRegs; i++) {

        PCIConfig_Write(Bus,Device,Function,Offset,0xFFFFFFFF);
        BaseAddress = PCIConfig_Read(Bus,Device,Function,Offset);

        DEBUGMSG(ZONE_INFO, (TEXT("ICB: Offset (0x%B) = 0x%X\r\n"), Offset, BaseAddress));
        if (BaseAddress & 1) {

            //
            // IO space
            //

            Size = ~(BaseAddress & 0xFFFFFFFC);
            Type = PCI_TYPE_IO;

        } else {

            //
            // memory space
            // BUGBUG - don't properly handle the MEM20 case
            //

            Size = ~(BaseAddress & 0xFFFFFFF0);
            Type = PCI_TYPE_MEM;

        }

        //
        // check that the register is valid format
        // should have consecutive high 1's and consecutive low 0's
        //

        if ((BaseAddress != 0) &&
            (BaseAddress != 0xFFFFFFFF) &&
            ((Size + 1) & Size) == 0) {

            //
            // Add to list so allocate space later
            //

            SpaceDesc[nSpaceDesc].Bus = Bus;
            SpaceDesc[nSpaceDesc].Device = Device;
            SpaceDesc[nSpaceDesc].Function = Function;
            SpaceDesc[nSpaceDesc].Offset = Offset;
            SpaceDesc[nSpaceDesc].Bridge = 0;
            SpaceDesc[nSpaceDesc].IoSize = 0;
            SpaceDesc[nSpaceDesc].MemSize = 0;

            if (Type == PCI_TYPE_IO) {
                *pIoSize += Size + 1;
                SpaceDesc[nSpaceDesc].IoSize = Size + 1;
            } else {
                *pMemSize += Size + 1;
                SpaceDesc[nSpaceDesc].MemSize = Size + 1;
            }
            
            DEBUGMSG(ZONE_INFO, (TEXT("BAR %d %d %d 0x%X %d 0x%X %s\r\n",
                               Bus,Device,Function,Offset,Type,
                               Size+1,(Type == PCI_TYPE_IO)? "IO":"MEM")));
            nSpaceDesc++;
            if (nSpaceDesc == MAX_SPACE) {
                RETAILMSG(1, (TEXT("ERROR: MAX_SPACE.\r\n")));
                return(FALSE);
            }
        }

        //
        // check for 64 bit device - BAR is twice as big
        //

        if ((BaseAddress & 0x7) == 0x4) {

            //
            // 64 bit device - BAR is twice as wide - zero out high part
            //

            Offset += 4;
            PCIConfig_Write(Bus,Device,Function,Offset,0x0);
        }
        Offset += 4;
    }


    return(TRUE);
}


BOOL
PciInitAllocateIoSpace(
    ULONG IoUpperBound,
    ULONG IoLowerBound,
    ULONG Bus
    )
{
    ULONG i;
    ULONG j;
    ULONG IoBase;
    PSPACE_DESC pSpace;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("AllocateIo %d %X %X\r\n"), Bus, IoUpperBound, IoLowerBound));
    //
    // Sort the space descriptors for a given bus by size
    //

    for (i = 31; i >= 1; i--) {

        for (j = 0; j < nSpaceDesc; j++) {

            pSpace = &SpaceDesc[j];
            if ((pSpace->Bus == Bus) && ((pSpace->IoSize) & (1 << i))) {

                if (pSpace->Bridge == 0) {

                    IoUpperBound -= pSpace->IoSize;
                    PCIConfig_Write(pSpace->Bus,
                                    pSpace->Device,
                                    pSpace->Function,
                                    pSpace->Offset,
                                    IoUpperBound);
                    pSpace->IoBase = IoUpperBound;
                    pSpace->SortOrder = SortOrder++;
                    DEBUGMSG(ZONE_INFO, (TEXT("AllocateIO %d %d %d %x %x (%X)\r\n"),
                                       pSpace->Bus, pSpace->Device, 
                                       pSpace->Function, pSpace->Offset, 
                                       IoUpperBound,pSpace->IoSize));

                } else {

                    if (!PciInitAllocateIoSpace(
                        IoUpperBound,
                        IoUpperBound - pSpace->IoSize,
                        pSpace->SecondaryBus)) {

                        return(FALSE);
                    }

                    //
                    // init I/O base and limit registers
                    //

                    IoBase = PCIConfig_Read(pSpace->Bus,
                                             pSpace->Device,
                                             pSpace->Function,
                                             PCIBRIDGE_IO);

                    ((PBRIDGE_IO)(&IoBase))->IoLimit.Address =
                        (BYTE)(((IoUpperBound - 1) & 0xF000) >> 12);
                    //((PBRIDGE_IO)(&IoBase))->IoLimit.DecodeType = Something;
                    IoUpperBound -= pSpace->IoSize;
                    ((PBRIDGE_IO)(&IoBase))->IoBase.Address =
                        (BYTE)(((IoUpperBound) & 0xF000) >> 12);
                    //((PBRIDGE_IO)(&IoBase))->IoBase.DecodeType = Something;
                    DEBUGMSG(ZONE_INFO, (TEXT("AllocateIOLimit %d %d %d %x %x (%X)\r\n"),
                                       pSpace->Bus, pSpace->Device, 
                                       pSpace->Function, pSpace->Offset, 
                                       IoBase,pSpace->IoSize));

                    PCIConfig_Write(pSpace->Bus,
                                    pSpace->Device,
                                    pSpace->Function,
                                    PCIBRIDGE_IO,
                                    IoBase);
                    
                    //
                    // Now enable the I/O and memory accesses...
                    //
                    PCIConfig_Write(pSpace->Bus,
                                    pSpace->Device,
                                    pSpace->Function,
                                    PCI_CONFIG_COMMAND_STATUS,
                                    0x7);
                    
                    pSpace->IoBase = IoBase;
                    pSpace->SortOrder = SortOrder++;
                }
            }

            if (IoUpperBound < IoLowerBound) {

                return(FALSE);
            }
        }
    }

    return(TRUE);
}


BOOL
PciInitAllocateMemSpace(
    ULONG MemUpperBound,
    ULONG MemLowerBound,
    ULONG Bus
    )
{
    ULONG i;
    ULONG j;
    ULONG MemBase;
    PSPACE_DESC pSpace;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("AllocateMem %d %X %X\r\n"), Bus, MemUpperBound,MemLowerBound));

    //
    // Sort the space descriptors for a given bus by size
    //

    for (i = 31; i >= 1; i--) {

        for (j = 0; j < nSpaceDesc; j++) {

            pSpace = &SpaceDesc[j];
            if ((pSpace->Bus == Bus) && ((pSpace->MemSize) & (1 << i))) {

                if (pSpace->Bridge == 0) {

                    MemUpperBound -= pSpace->MemSize;
                    PCIConfig_Write(pSpace->Bus,
                                    pSpace->Device,
                                    pSpace->Function,
                                    pSpace->Offset,
                                    MemUpperBound);
                    pSpace->MemBase = MemUpperBound;
                    pSpace->SortOrder = SortOrder++;
                    DEBUGMSG(ZONE_INFO, (TEXT("AllocateMem %d %d %d %x %x (%X)\r\n"),
                                       pSpace->Bus, pSpace->Device, 
                                       pSpace->Function, pSpace->Offset, 
                                       MemUpperBound,pSpace->MemSize));

                } else {

                    if (!PciInitAllocateMemSpace(
                        MemUpperBound,
                        MemUpperBound - pSpace->MemSize,
                        pSpace->SecondaryBus)) {

                        return(FALSE);
                    }

                    //
                    // Init mem base and limit registers
                    //

                    ((PBRIDGE_MEM)(&MemBase))->MemoryLimit.Address =
                        (WORD)(((MemUpperBound - 1) & 0xFFF00000) >> 20);
                    //((PBRIDGE_MEM)(&MemBase))->MemoryLimit.DecodeType = Something;
                    MemUpperBound -= pSpace->MemSize;
                    ((PBRIDGE_MEM)(&MemBase))->MemoryBase.Address =
                        (WORD)(((MemUpperBound) & 0xFFF00000) >> 20);
                    //((PBRIDGE_MEM)(&MemBase))->MemoryBase.DecodeType = Something;
                    DEBUGMSG(ZONE_INFO, (TEXT("AllocateMemLimit %d %d %d %x %x (%X)\r\n"),
                                       pSpace->Bus, pSpace->Device, 
                                       pSpace->Function, pSpace->Offset, 
                                       MemBase,pSpace->MemSize));

                    PCIConfig_Write(pSpace->Bus,
                                    pSpace->Device,
                                    pSpace->Function,
                                    PCIBRIDGE_MEMORY,
                                    MemBase);
                    pSpace->MemBase = MemBase;
                    pSpace->SortOrder = SortOrder++;

                }
            }

            if (MemUpperBound < MemLowerBound) {

                return(FALSE);
            }
        }
    }

    return(TRUE);
}


VOID
PciInitListDevices(
    )
{
    ULONG i,j;


    DEBUGMSG(ZONE_PCICNFG, (TEXT("\n\rList of Detected PCI Devices")));
    DEBUGMSG(ZONE_PCICNFG, (TEXT("\n\r-----------------------------------------------------------\n\r")));

    for (i = 0; i < nDev; i++) {

//        PrintVendorString(pDev[i].VendorID);
        DEBUGMSG(ZONE_PCICNFG, (TEXT("\r\n")));

        DEBUGMSG(ZONE_PCICNFG, (TEXT("  Bus:%d  Dev:%d  Funct:%d  Class:%X  IRQ:%X  "),
            pDev[i].Bus,
            pDev[i].Device,
            pDev[i].Function,
            PCIConfig_Read(pDev[i].Bus,
                           pDev[i].Device,
                           pDev[i].Function,
                           PCI_CONFIG_CLASS_REVISION),
            PCIConfig_Read(pDev[i].Bus,
                           pDev[i].Device,
                           pDev[i].Function,
                           PCI_CONFIG_INTERRUPT) & 0xff));

        DEBUGMSG(ZONE_PCICNFG, (TEXT("\r\n")));

        if ( PCIConfig_Read(pDev[i].Bus,
                            pDev[i].Device,
                            pDev[i].Function,
                            PCI_CONFIG_HEAD) & 0x00010000) {

            DEBUGMSG(ZONE_PCICNFG, (TEXT("BARs %X  %X  MemBase: %X  IoBase: %X"),
                    PCIConfig_Read(pDev[i].Bus,
                                   pDev[i].Device,
                                   pDev[i].Function,
                                   PCI_CONFIG_BASE0),
                    PCIConfig_Read(pDev[i].Bus,
                                   pDev[i].Device,
                                   pDev[i].Function,
                                   PCI_CONFIG_BASE1),
                    PCIConfig_Read(pDev[i].Bus,
                                   pDev[i].Device,
                                   pDev[i].Function,
                                   PCIBRIDGE_MEMORY),
                    PCIConfig_Read(pDev[i].Bus,
                                   pDev[i].Device,
                                   pDev[i].Function,
                                   PCIBRIDGE_IO)));
        } else {
            DEBUGMSG(ZONE_PCICNFG, (TEXT("BARs:")));
            for (j = PCI_CONFIG_BASE0; j <= PCI_CONFIG_BASE5; j += 4 ) {
                DEBUGMSG(ZONE_PCICNFG, (TEXT(" %X"),
                    PCIConfig_Read(pDev[i].Bus,
                                   pDev[i].Device,
                                   pDev[i].Function,
                                   j)));
            }
        }
        DEBUGMSG(ZONE_PCICNFG, (TEXT("\n\r\n\r")));

    }
    DEBUGMSG(ZONE_PCICNFG, (TEXT("Bus Dev Fnct Off   MemBase  MemSize  IoBase   IoSize\r\n")));
    for (i = 0; i < SortOrder; i++) {
        for (j = 0; j < nSpaceDesc; j++) {
            if (SpaceDesc[j].SortOrder == i) {
                DEBUGMSG(ZONE_PCICNFG, (TEXT("%B  %B  %B   %B   %X %X %X %X\r\n"),
                    SpaceDesc[j].Bus,
                    SpaceDesc[j].Device,
                    SpaceDesc[j].Function,
                    SpaceDesc[j].Offset,
                    SpaceDesc[j].MemBase,
                    SpaceDesc[j].MemSize,
                    SpaceDesc[j].IoBase,
                    SpaceDesc[j].IoSize));
            }
        }
    }
}


BOOL
PciInitSearchForDevice(
    ULONG VendorID,
    PULONG Bus,
    PULONG Device,
    PULONG Function
    )
{
    ULONG i;

    for (i = 0; i < nDev; i++) {
        if (pDev[i].VendorID == VendorID) {
            *Bus = pDev[i].Bus;
            *Device = pDev[i].Device;
            *Function = pDev[i].Function;
            return(TRUE);
        }
    }
    return(FALSE);
}


BOOL PCIInitListDevicesSummary(void)
{
    UCHAR nCount=0;
    PCI_DEVICE *p=NULL;


    DEBUGMSG(ZONE_PCICNFG, (TEXT("\r\nPCI Device List:\r\n")));
    DEBUGMSG(ZONE_PCICNFG, (TEXT("----------------------------------------------------------------------------\r\n")));
    DEBUGMSG(ZONE_PCICNFG, (TEXT(" VenId       DevId       (B:D:F)     BAR0           Stat/Cmd     Class/ID\r\n")));
    DEBUGMSG(ZONE_PCICNFG, (TEXT("----------------------------------------------------------------------------\r\n")));

    for(nCount=0 ; nCount < MAX_DEVICE ; nCount++)
    {
        p=&pDev[nCount];

        if(!p->VendorID)
            break;

    DEBUGMSG(ZONE_PCICNFG, (TEXT("%X    %X     (%d:%d:%d)  0x%X     0x%X    0x%X\r\n"),
	(p->VendorID&0xFFFF), (p->VendorID&0xFFFF0000)>>16,
	p->Bus, p->Device, p->Function, 
        PCIConfig_Read(p->Bus, p->Device, p->Function, 0x10),
        PCIConfig_Read(p->Bus, p->Device, p->Function, 0x04),
        PCIConfig_Read(p->Bus, p->Device, p->Function, 0x08)));
        
    }

    return(TRUE);
}

⌨️ 快捷键说明

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