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

📄 route.c

📁 威盛 wince5.0 bsp 包 for x86 系统, 支持 VT8601 等北桥
💻 C
📖 第 1 页 / 共 2 页
字号:
            (pDevLoc->BusNumber & 0xff) * 0x100 +  // Bus Number
            ((pDevLoc->LogicalLoc >> 5) & 0xF8) +  // Device Number
            ((pDevLoc->LogicalLoc ) & 7 );  //Function Number.
        DEBUGMSG(1,(L"BiosMapIqr(EAX=%x,EBX=%x,ECX=%x)\r\n",mReg32.RegEax,mReg32.RegEbx,mReg32.RegEcx));
        bRet=CallBios32(&mReg32,pBiosAddr);
        DEBUGMSG(1,(L"BiosMapIqr return %d and EAX=%x\r\n",bRet,mReg32.RegEax));
        return bRet;
    }
    return FALSE;
}
void ScanConfiguredIrq(IRQRountingOptionsBuffer *pBuffer,WORD wExClusive);

BOOL GetRoutingOption(IRQRountingOptionsBuffer * pBuffer,PVOID phPciBiosAddr)
{
    Reg32 mReg32;
    PCI_ROUTING_TABLE * pPCIRoutingTable=NULL;
    DEBUGMSG(1,(L"+GetRoutingOption\r\n"));
    if (pBiosVirtAddr!=NULL && search_pci_routing(&pPCIRoutingTable) && pPCIRoutingTable) {
        DWORD dwCurPos=sizeof(PCI_ROUTING_TABLE);
        RoutingOptionTable * curTable=(RoutingOptionTable *)(pPCIRoutingTable+1);
        DWORD dwIndex=0;
        pBuffer->BufferSize=0;
        pBuffer->pDataBuffer = (PBYTE)(pBuffer->routingOptionTable);
        DEBUGMSG(1,(L"GetRoutingOption, found ROM version for Routing table.\r\n"));
        while (dwCurPos + sizeof(RoutingOptionTable)<=pPCIRoutingTable->Table_Size && dwIndex < MAX_DEVICE ) {
            memcpy(pBuffer->routingOptionTable+dwIndex,curTable,sizeof(RoutingOptionTable));
            dwIndex++;
            curTable++;
            dwCurPos +=sizeof(RoutingOptionTable);
            pBuffer->BufferSize +=sizeof(RoutingOptionTable);
        }
        DEBUGMSG(1,(L"GetRoutingOption return SUCCESS .AH=%x \r\n",pPCIRoutingTable->ExclusiveIrqs));
        ScanConfiguredIrq(pBuffer,(WORD)pPCIRoutingTable->ExclusiveIrqs);
        return TRUE;
    }
    else
    if (pBuffer && phPciBiosAddr) {
        pBuffer->BufferSize = sizeof(pBuffer->routingOptionTable);
        pBuffer->pDataBuffer = (PBYTE)(pBuffer->routingOptionTable);
        pBuffer->DS=GetDS();
        DEBUGMSG(1,(L"GetRoutingOption with buffer Size %d bytes buffer DS%x:addr =%x \r\n",pBuffer->BufferSize,pBuffer->DS,pBuffer->pDataBuffer));
        mReg32.RegEax=PCI_FUNCTION_ID*0x100 + GET_IRQ_ROUTING_OPTIONS;
        mReg32.RegEbx=0;
        mReg32.RegEdi=(DWORD)pBuffer;
        if (CallBios32(&mReg32,(PVOID) phPciBiosAddr)) { 
            // Success
            DEBUGMSG(1,(L"GetRoutingOption return SUCCESS .AH=%x \r\n",(mReg32.RegEax & 0xff00)>>8));
            ScanConfiguredIrq(pBuffer,(WORD)mReg32.RegEbx);
            return TRUE;
        }
        else {
            pBuffer->pDataBuffer = NULL;// Routing does not exist.
            DEBUGMSG(1,(L"GetRoutingOption return FAILS error code AH=%x \r\n",(mReg32.RegEax & 0xff00)>>8));
        }
    }
    return FALSE;
}
void GetPciRoutingIrqTable()
{
    ULONG phBiosOffset=0;
    // Initial the talbe.
    memset(&irqRoutingOptionBuffer,0,sizeof(irqRoutingOptionBuffer));
    pBiosAddr=NULL;
    // Maping BIOS address 
    if (!pBiosVirtAddr)
        pBiosVirtAddr=(PBYTE)NKCreateStaticMapping((DWORD)BIOS_START>>8,BIOS_LENGTH);// 64k From E0000-FFFFF
   DEBUGMSG(1,(L"PCIBIOS:: BIOS Address static map to addr=%x\r\n",pBiosVirtAddr));
    if (!pBiosVirtAddr)
        return;
    DEBUGMSG(1,(L"GetPicRoutingIrqTable: Start\n"));
    if (search_pci_bios(pBiosVirtAddr,&phBiosOffset) && phBiosOffset!=0) {
        // Find out the address off $PCI service.
        ULONG phPciServiceAddr=0;
        Reg32 mReg32;
        mReg32.RegEax=0x49435024;//"$PCI"
        mReg32.RegEbx=0;
        CallBios32(&mReg32,pBiosVirtAddr+phBiosOffset);
        DEBUGMSG(1,(L"Return from First BIOS EAX=%x EBX=%x,ECX=%x EDX=%x\n",
                mReg32.RegEax,mReg32.RegEbx,mReg32.RegEcx,mReg32.RegEdx));
        if ((mReg32.RegEax & 0xff)==0) { // Success to load and PCI calls
            phBiosOffset=mReg32.RegEbx+mReg32.RegEdx-BIOS_START;
            DEBUGMSG(1,(L"32 PCI BIOS offset located.addr=%x\n",phBiosOffset));
            mReg32.RegEax=PCI_FUNCTION_ID*0x100+PCI_BIOS_PRESENT;
            if (CallBios32(&mReg32,pBiosVirtAddr+phBiosOffset) &&  (mReg32.RegEbx & 0xffff)>=0x210 ) { // IF PCI 2.10 exist.
                DWORD dwNumOfBus=mReg32.RegEcx & 0xff;
                DEBUGMSG(1,(L"32 PCI BIOS Present EDX=%x,EAX=%x EBX=%x,ECX=%x\n",
                    mReg32.RegEdx,mReg32.RegEax,mReg32.RegEbx,mReg32.RegEcx));
                pBiosAddr=pBiosVirtAddr+phBiosOffset;
                GetRoutingOption(&irqRoutingOptionBuffer,pBiosAddr);
                return;
            }
        }
        
    }
    
    DEBUGMSG(1,(L"GetPicRoutingIrqTable: FAILS!!!\n"));
}
void ScanConfiguredIrq(IRQRountingOptionsBuffer *pBuffer,WORD wExClusive)
{
    DEBUGMSG(1,(L"canConfiguredIrq with PCI Exclusive Irq Bit (wExClusive)  =%x \r\n",wExClusive));
    memset(bIrqLinked,0,sizeof(bIrqLinked));
    wBestPCIIrq=wExClusive;
    
    if (pBuffer) {
        RoutingOptionTable * pRoute;
        DWORD dwCurPos=0;
        DEBUGMSG(1,(L"ScanConfigureIrq: BufferSize = %d @ address %x \r\n", pBuffer->BufferSize,pBuffer->pDataBuffer));
        pRoute =(RoutingOptionTable * )(pBuffer->pDataBuffer);
        while (pRoute && dwCurPos + sizeof(RoutingOptionTable)<=pBuffer->BufferSize) {
            DWORD dwFunc;
            DEBUGMSG(1,(L"ScanConfigureIrq: for Bus=%d ,Device=%d SlotNumber=%d\r\n",
                pRoute->PCIBusNumber,(pRoute->PCIDeviceNumber)>>3,pRoute->SlotNumber));
            DEBUGMSG(1,(L"     INTA_LinkValue=%x,INTA_IrqBitMap=%x\r\n",pRoute->INTA_LinkValue,pRoute->INTA_IrqBitMap));
            DEBUGMSG(1,(L"     INTB_LinkValue=%x,INTB_IrqBitMap=%x\r\n",pRoute->INTB_LinkValue,pRoute->INTB_IrqBitMap));
            DEBUGMSG(1,(L"     INTC_LinkValue=%x,INTC_IrqBitMap=%x\r\n",pRoute->INTC_LinkValue,pRoute->INTC_IrqBitMap));
            DEBUGMSG(1,(L"     INTD_LinkValue=%x,INTC_IrqBitMap=%x\r\n",pRoute->INTD_LinkValue,pRoute->INTD_IrqBitMap));
            for (dwFunc=0;dwFunc<8;dwFunc++) {
                PCI_COMMON_CONFIG pciConfig;
                DWORD dwLength;
                pciConfig.VendorID = 0xFFFF;
                pciConfig.HeaderType = 0;
                dwLength=PCIReadBusData(pRoute->PCIBusNumber,(pRoute->PCIDeviceNumber)>>3,dwFunc,
                          &pciConfig,0,sizeof(pciConfig) - sizeof(pciConfig.DeviceSpecific));
                if (dwLength != (sizeof(pciConfig) - sizeof(pciConfig.DeviceSpecific)) ||
                        (pciConfig.DeviceID == PCI_INVALID_DEVICEID) || (pciConfig.VendorID == PCI_INVALID_VENDORID) || (pciConfig.VendorID == 0)) {
                    if (dwFunc != 0) {
                        // If a multi-function device, continue to next function
                        continue;
                    } else {
                        // If not a multi-function device, continue to next device
                        break;
                    }
                }

                // If device not already placed, configure interrupt
                //if ((pciConfig.Command & (PCI_ENABLE_IO_SPACE | PCI_ENABLE_MEMORY_SPACE))) 
                {
                    DWORD Irq=(DWORD)-1;
                    DWORD Pin=0;
                    switch( pciConfig.HeaderType & ~PCI_MULTIFUNCTION) {
                        case PCI_DEVICE_TYPE: // Devices
                            Irq = pciConfig.u.type0.InterruptLine;
                            Pin = pciConfig.u.type0.InterruptPin;
                            break;
                        case PCI_BRIDGE_TYPE: // PCI-PCI bridge
                            Irq = pciConfig.u.type1.InterruptLine;
                            Pin = pciConfig.u.type1.InterruptPin;
                            break;

                        case PCI_CARDBUS_TYPE: // PCI-Cardbus bridge
                            Irq = pciConfig.u.type2.InterruptLine;
                            Pin = pciConfig.u.type2.InterruptPin;
                            break;
                    }
                    if (Irq<=0xf) {
                        BYTE bLinkNumber=0;
                        switch (Pin) {
                            case 1:
                                bLinkNumber=pRoute->INTA_LinkValue;
                                break;
                            case 2:
                                bLinkNumber=pRoute->INTB_LinkValue;
                                break;
                            case 4:
                                bLinkNumber=pRoute->INTC_LinkValue;
                                break;
                            case 8:
                                bLinkNumber=pRoute->INTD_LinkValue;
                                break;
                        }
                        if (bLinkNumber!=0) {
                            if (bIrqLinked [Irq]!=0 && bIrqLinked [Irq]!= bLinkNumber)
                                DEBUGMSG(1,(L"!!!ERROR:::curLinkNumber=%d not same as previous %d\r\n",bLinkNumber,bIrqLinked [Irq]));
                            bIrqLinked[Irq]=bLinkNumber;
                            DEBUGMSG(1,(L"ScanConfigureIrq:    LinkNumber=%d associated with irq=%d\r\n",bLinkNumber,Irq));
                        }
                    }
                }
                if ((pciConfig.HeaderType & PCI_MULTIFUNCTION)==0) { // Not multi-function card.
                    break;
                }                
            }
            dwCurPos +=sizeof(RoutingOptionTable);
            pRoute ++;
        }

    }
}

BOOL OALIntrRequestIrqs(PDEVICE_LOCATION pDevLoc, UINT32 *pCount, UINT32 *pIrq)
{
    int Bus = pDevLoc->BusNumber;
    int Device = (pDevLoc->LogicalLoc >> 8) & 0xFF;

    // Figure out the Link number in routing table
    RoutingOptionTable * pRoute=(RoutingOptionTable * )irqRoutingOptionBuffer.pDataBuffer;

    DEBUGMSG(1,(L"OEMGetInterrupt:(Bus=%d,Device=%d,Pin=%d)\r\n",Bus,Device,pDevLoc->Pin));
    // This shouldn't happen
    if (*pCount < 1) return FALSE;
    if (pRoute) {
        // serch table.
        DWORD dwCurPos=0;
        while (dwCurPos + sizeof(RoutingOptionTable)<=irqRoutingOptionBuffer.BufferSize) {            
            DEBUGMSG(1,(L"OEMGetInterrupt: for Bus=%d ,Device=%d SlotNumber=%d\r\n",
                pRoute->PCIBusNumber,(pRoute->PCIDeviceNumber)>>3,pRoute->SlotNumber));
            DEBUGMSG(1,(L"     INTA_LinkValue=%x,INTA_IrqBitMap=%x\r\n",pRoute->INTA_LinkValue,pRoute->INTA_IrqBitMap));
            DEBUGMSG(1,(L"     INTB_LinkValue=%x,INTB_IrqBitMap=%x\r\n",pRoute->INTB_LinkValue,pRoute->INTB_IrqBitMap));
            DEBUGMSG(1,(L"     INTC_LinkValue=%x,INTC_IrqBitMap=%x\r\n",pRoute->INTC_LinkValue,pRoute->INTC_IrqBitMap));
            DEBUGMSG(1,(L"     INTD_LinkValue=%x,INTC_IrqBitMap=%x\r\n",pRoute->INTD_LinkValue,pRoute->INTD_IrqBitMap));
            if (pRoute->PCIBusNumber== Bus && ((pRoute->PCIDeviceNumber)>>3)==Device) { // found
                BYTE bLinkNumber=0;
                WORD wIntPossibleBit=0;
                switch (pDevLoc->Pin) {
                case 1:
                    bLinkNumber=pRoute->INTA_LinkValue;
                    wIntPossibleBit=pRoute->INTA_IrqBitMap;
                    break;
                case 2:
                    bLinkNumber=pRoute->INTB_LinkValue;
                    wIntPossibleBit=pRoute->INTB_IrqBitMap;
                    break;
                case 4:
                    bLinkNumber=pRoute->INTC_LinkValue;
                    wIntPossibleBit=pRoute->INTC_IrqBitMap;
                    break;
                case 8:
                    bLinkNumber=pRoute->INTD_LinkValue;
                    wIntPossibleBit=pRoute->INTD_IrqBitMap;
                    break;
                }
                if (bLinkNumber!=0) {
                    DWORD dwIndex;
                    BYTE  bIrq=(BYTE)-1;
                    WORD wIntrBit;
                    int iIndex;
                    for (dwIndex=0;dwIndex<0x10;dwIndex++) {
                        if (bIrqLinked[dwIndex]==bLinkNumber) { // Found a used interrupt linke
                            if (pIrq) *pIrq=dwIndex;
                            if (pCount) *pCount = 1;
                            DEBUGMSG(1,(L"-OEMGetInterrupt:Find existing IRQ return IRQ=%d\r\n",dwIndex));
                            return TRUE;
                        }
                    }
                    // Search Useful Interrupt
                    wIntrBit=0x8000;
                    for (iIndex=0xf;iIndex>=0;iIndex--) {
                        if ((wBestPCIIrq & wIntrBit)!=0 && bIrqLinked[iIndex]==0 ) { // Best interurpt is can be mapped but not mapped yet
                            bIrq=(BYTE)iIndex;
                            DEBUGMSG(1,(L"OEMGetInterrupt: Mapping New IRQ(%d) to this device\r\n",bIrq));
                            if (bIrq<=0xf && BiosMapIqr(pDevLoc,bIrq)) { // Mapped.
                                bIrqLinked[bIrq]=bLinkNumber;
                                if (pIrq) *pIrq=(DWORD)bIrq;
                                if (pCount) *pCount = 1;
                                DEBUGMSG(1,(L"-OEMGetInterrupt: Mapped New IRQ return IRQ=%d\r\n",bIrq));
                                return TRUE;
                            }
                        }
                        wIntrBit>>=1;
                    }
                    wIntrBit=0x8000;
                    for (iIndex=0xf;iIndex>=0;iIndex--) {
                        if ((wIntPossibleBit & wIntrBit)!=0 && bIrqLinked[iIndex]==0 ) { // Best interurpt is can be mapped but not mapped yet
                            bIrq=(BYTE)iIndex;
                            DEBUGMSG(1,(L"OEMGetInterrupt: Mapping New IRQ(%d) to this device\r\n",bIrq));
                            if (bIrq<=0xf && BiosMapIqr(pDevLoc,bIrq)) { // Mapped.
                                bIrqLinked[bIrq]=bLinkNumber;
                                if (pIrq) *pIrq=(DWORD)bIrq;
                                if (pCount) *pCount = 1;
                                DEBUGMSG(1,(L"-OEMGetInterrupt: Mapped New IRQ return IRQ=%d\r\n",bIrq));
                                return TRUE;
                            }
                        }
                        wIntrBit>>=1;
                    }
                }
                break;// False
                
            }
            dwCurPos +=sizeof(RoutingOptionTable);
            pRoute ++;
        }
    }
    return FALSE;
}

// stub for OALIoTransBusAddress, not supported in x86
BOOL OALIoTransBusAddress (INTERFACE_TYPE ifcType, UINT32 busNumber, UINT64 busAddress, UINT32 * pAddressSpace, UINT64 * pSystemAddress)
{
    return FALSE;
}


BOOL RegisterBINFS_NAND (PX86BootInfo pX86Info)
{
    if (pX86Info && pX86Info->NANDBootFlags) {
        PCI_SLOT_NUMBER SlotNumber;
        PCI_REG_INFO NANDPCIRegInfo ;
        PCI_COMMON_CONFIG Cfg;
        DWORD dwBus = pX86Info->NANDBusNumber;
        SlotNumber.u.AsULONG = pX86Info->NANDSlotNumber;
        PCIGetBusDataByOffset(dwBus, SlotNumber.u.AsULONG, &Cfg, 0, sizeof(PCI_COMMON_CONFIG));
        PCIInitInfo(L"Drivers\\BuiltIn\\PCI\\Instance\\NAND_Flash",
                dwBus, SlotNumber.u.bits.DeviceNumber, SlotNumber.u.bits.FunctionNumber, 0, &Cfg, &NANDPCIRegInfo);
        PCIReadBARs(&NANDPCIRegInfo);
        DEBUGMSG(1,(L"Num=%d,iobase=%x,ioLen=%x\r\n",NANDPCIRegInfo.IoBase.Num, NANDPCIRegInfo.IoBase.Reg[0], NANDPCIRegInfo.IoLen.Reg[0]));
        return PCIReg(&NANDPCIRegInfo);
    }
    return FALSE;
}

BOOL PCIInitConfigMechanism (UCHAR ucConfigMechanism);

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID PCIInitBusInfo (void)
{
    if (PCIInitConfigMechanism (g_pX86Info->ucPCIConfigType & 0x03)) {
        GetPciRoutingIrqTable ();
    } else {
        RETAILMSG(1, (TEXT("No PCI bus\r\n")));
    }
}

⌨️ 快捷键说明

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