📄 route.c
字号:
(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 + -