📄 i80312pcilib.c
字号:
* not handled at power up. ** RETURNS: N/A*/LOCAL void i80312PciSecondaryBusInit(void) { /* * Set Secondary Private I/O and memory space */ *BRIDGE_SIOBR = 0x00; /* We take from 0x#### on */ *BRIDGE_SIOLR = 0xf0; *BRIDGE_SMBR = 0x0000; /* From 0x######## up*s private */ *BRIDGE_SMLR = 0xfff0; /* modify if necessary */ *BRIDGE_SDER |= 0x04; /* SDER_PRIVATE_MEM_ENABLE; */ /* set database to point to first avail I/O adress */ /* * 0xF000 to 0xFFFF are mapped by the 21154 so * 0xE000 to 0xEFFF are available to the Secondary * bus */ i80312BusOut[1].ioCurrent = 0xFFFFF000; i80312BusOut[1].ioBase = 0xFFFF0000; /* set database to point to first avail Memory */ i80312BusOut[1].current = 0xFFE00000; i80312BusOut[1].base = 0xFC000000; /* Secondary ATU command register */ *ATU_SATUCMD = SCMD_MEM_ENABLE | SCMD_BUS_MASTER_ENABLE | SCMD_MWI_ENABLE | SCMD_SERR_ENABLE | SCMD_FAST_B_TO_B_ENABLE; /* enable secondary outbound direct address translation */ *ATU_ATUCR |= ATUCR_SEC_OUTBOUND_ENABLE; /* mask off SATU error ints */ *ATU_SATUIMR = SATUIMR_MASK | ATUIMR_TARGET_ABORT_ENABLE; }/****************************************************************************** i80312SecondaryAtuInit - initialize secondary ATU interface ** This routine initializes secondary ATU interface. Secondary ATU address* window is same as primary ATU address mapping by default.** RETURNS: N/A**/LOCAL void i80312SecondaryAtuInit(void) { UINT32 memSize; /* Get top of system memory pool. */ memSize = (UINT32)(sysPhysMemTop() - LOCAL_MEM_LOCAL_ADRS); /* program secondary ATU same as primary by default. */ *ATU_SIALR = ~(memSize - 1); /* limit reg; sets size */ *ATU_SIABAR = LOCAL_MEM_LOCAL_ADRS; /* value register. Set to local address for translation */ *ATU_SIATVR = LOCAL_MEM_LOCAL_ADRS; /* Private PCI Memory space starts at 0xFC000000 */ *ATU_SOMWVR = 0xFC000000; *ATU_SOIOWVR = 0xFFFF0000; /* We don't use Dual Address Cycle address' */ *ATU_SODWVR = 0; *ATU_SATUCMD = 0x146; /* enable secondary outbound transactions */ *ATU_ATUCR |= 0x4; }/******************************************************************* i80310SecondaryBridgeInit - Init the 21154 PCI bridge*/LOCAL STATUS i80310SecondaryBridgeInit() { UINT32 busNo; int deviceNo, tmp; PCI_CFG_ADDR cfgAddr; /* Select the Secondary Bus */ busNo = i80312PciChkBusNumbers(i80312_BusNumbers[SECONDARY_BUS_INDEX]); /* The bridge is device 7 */ deviceNo = 7; /* Build a config word */ cfgAddr.u.whole=CONFIG_WORD_PACK (PCI_CFG_TYP0,0, 0,deviceNo,busNo,PCI_UINT32_ACCESS); /* Make sure the bridge answers */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_HEADER_TYPE); if (i80312PciCfgRd((int)busNo,cfgAddr,(UINT32 *)&tmp) != OK) { while(1) { IQ80310_SEVEN_SEG_WRITE_MSB(L7SEG_E & L7SEG_Dot); IQ80310_SEVEN_SEG_WRITE_LSB(L7SEG_1 & L7SEG_Dot); } /* This is not good. */ } /* Make sure the bridge is disabled */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_COMMAND); i80312PciCfgWr(busNo, cfgAddr, 0xFFFF0000); /* Setup Bus Numbers*/ tmp = ( (0xff << 24) | ( (i80312_SubBusNumber & 0xFF) << 16) | ( (i80312_SubBusNumber & 0xFF) << 8) | ( (i80312_SecBusNumber & 0xFF)) ); CONFIG_REG_ADDR(cfgAddr,PCI_CFG_PRIMARY_BUS); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Set I/O base and limit */ tmp = 0xFFFF << 16; /* Clear Status bits */ tmp |= (0xF0 << 8); /* Limit to 0xFFFF */ tmp |= 0xF0; /* Base at 0xF000 */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_IO_BASE); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Set Memory base and limit */ tmp = (0xFFF0 << 16); /* Limit to 0xFFFFFFFF */ tmp |= 0xFFF0; /* Base to 0xFFF00000 */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_MEM_BASE); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Set Prefetchable Memory base and limit */ tmp = 0x0; /* Disable */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_PRE_MEM_BASE); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Set Upper Prefetchable Memory base and limit */ tmp = 0; /* We don't support 64 bits */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_PRE_MEM_BASE_U); i80312PciCfgWr(busNo, cfgAddr, tmp); CONFIG_REG_ADDR(cfgAddr,PCI_CFG_PRE_MEM_LIMIT_U); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Set Upper I/O base and limit */ tmp = 0xFFFFFFFF; /* I/O at the top of 32 bit I/O space */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_IO_BASE_U); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Enable 21154 Bridge */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_COMMAND); i80312PciCfgWr(busNo, cfgAddr, 0xFFFF0007); return(OK); }/******************************************************************* i80310EthInit - Init the 82559ER Ethernet chip*/LOCAL void i80310EthInit() { UINT32 busNo; int deviceNo, tmp; PCI_CFG_ADDR cfgAddr; /* Select the Secondary Bus */ busNo = i80312PciChkBusNumbers(i80312_BusNumbers[SECONDARY_BUS_INDEX + 1]); /* The 82559 is device 0 */ deviceNo = 0; /* Build a config word */ cfgAddr.u.whole=CONFIG_WORD_PACK (PCI_CFG_TYP1,0, 0,deviceNo,busNo,PCI_UINT32_ACCESS); /* Make sure the bridge answers */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_HEADER_TYPE); if (i80312PciCfgRd((int)busNo,cfgAddr,(UINT32 *)&tmp) != OK) { while(1) { IQ80310_SEVEN_SEG_WRITE_MSB(L7SEG_E & L7SEG_Dot); IQ80310_SEVEN_SEG_WRITE_LSB(L7SEG_2 & L7SEG_Dot); } /* This is not good. */ return; } /* Make sure the chip is disabled */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_COMMAND); i80312PciCfgWr(busNo, cfgAddr, 0xFFFF0000); /* Set Memory Space to 0xFFFFF000 */ tmp = 0xFFFFF000; CONFIG_REG_ADDR(cfgAddr,PCI_CFG_BASE_ADDRESS_0); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Set I/O Space to 0x0000FF00 */ tmp = 0xFFFFF001; CONFIG_REG_ADDR(cfgAddr,PCI_CFG_BASE_ADDRESS_1); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Set Flash Memory Space to 0xFFFDF000 */ tmp = 0xFFFDF000; CONFIG_REG_ADDR(cfgAddr,PCI_CFG_BASE_ADDRESS_2); i80312PciCfgWr(busNo, cfgAddr, tmp); /* Enable */ CONFIG_REG_ADDR(cfgAddr,PCI_CFG_COMMAND); i80312PciCfgWr(busNo, cfgAddr, 0xFFFF0007); }/******************************************************************* i80312PrivateDevInit - Detect and configure private Pci devices** This routine detects and configures PCI devices on the secondary* bus. The 21154 an 82559ER are statically configured prior to* calling this routine.** RETURNS: N/A**/LOCAL void i80312PrivateDevInit() { UINT32 busNo, ebusNo, command_word; int deviceNo, devices, k, request[5], response[5]; ushort_t vendorId, deviceId; int funcNo,maxFuncNum; PCI_CFG_ADDR cfgAddr; OUTBOUND_ADDRESS_TRAN *transPtr; char class, sub_class, *busName = "default"; UINT8 rotary = I80310_ROT_STAT_REG_RD(); devices = 0x1f; if (rotary != 0x7) /* rotary switch NOT in position 7 - stand-alone backplane */ { /* Start with the Primary Bus */ busNo = i80312PciChkBusNumbers(i80312_BusNumbers[PRIMARY_BUS_INDEX]); ebusNo = busNo + 1; } else { /* Start with the Secondary Bus */ busNo = i80312PciChkBusNumbers(i80312_BusNumbers[SECONDARY_BUS_INDEX]); ebusNo = busNo; } for(; busNo <= ebusNo; busNo++) { /* Get a pointer to Pci resources table */ transPtr = (busNo < i80312_BusNumbers[SECONDARY_BUS_INDEX]? &i80312BusOut[0] : &i80312BusOut[1]); if(busNo < i80312_BusNumbers[SECONDARY_BUS_INDEX]) busName = "Primary Bus"; else if(busNo == i80312_BusNumbers[SECONDARY_BUS_INDEX]) busName = "Secondary Bus"; else busName = "Ternary Bus"; for (deviceNo=0; deviceNo < devices; deviceNo++) { if(busNo <= i80312_BusNumbers[SECONDARY_BUS_INDEX]) cfgAddr.u.whole=CONFIG_WORD_PACK (PCI_CFG_TYP0,PCI_CFG_HEADER_TYPE, 0,deviceNo,busNo,PCI_BYTE_ACCESS); else cfgAddr.u.whole=CONFIG_WORD_PACK (PCI_CFG_TYP1,PCI_CFG_HEADER_TYPE, 0,deviceNo,busNo,PCI_BYTE_ACCESS); maxFuncNum = i80312PciDeviceProbe (busNo,cfgAddr); for (funcNo=0;funcNo<maxFuncNum;funcNo++) { if(pciConfigInWord(busNo,deviceNo,funcNo,PCI_CFG_VENDOR_ID, (short *)&vendorId) != 0) break; pciConfigInWord(busNo,deviceNo,funcNo,PCI_CFG_DEVICE_ID, (short *)&deviceId); pciConfigInByte(busNo,deviceNo,funcNo,PCI_CFG_CLASS, &class); pciConfigInByte(busNo,deviceNo,funcNo,PCI_CFG_SUBCLASS,&sub_class); pciCfg[cur_pciCfg].busNo = busNo; pciCfg[cur_pciCfg].deviceNo = deviceNo; pciCfg[cur_pciCfg].funcNo = funcNo; pciCfg[cur_pciCfg].vendorId = vendorId; pciCfg[cur_pciCfg].deviceId = deviceId; /* We don't do bridges ! */ if( class == CLASS_BRIDGE_DEV) { cur_pciCfg++; continue; } if (vendorId == 0xffff) break; command_word = 0; cfgAddr.u.bit.regPos = 0; cfgAddr.u.bit.funcNum = funcNo; cfgAddr.u.bit.regLen = PCI_UINT32_ACCESS; /* Disable device */ cfgAddr.u.bit.regNum = PCI_IDX_ST_CMD; i80312PciCfgWr(busNo, cfgAddr, 0xFFFF0000); bzero((char *)request, sizeof(request)); bzero((char *)response, sizeof(response)); /* We only configure memory and i/o space for now */ for( k = 0; k < 5; k++) { cfgAddr.u.bit.regNum = PCI_IDX_BAR_0 + k; pciConfigQuery(busNo, cfgAddr, (UINT32 *)&request[k]); /* unimplemented means last one. */ if (request[k] == 0) break; /* Find device's PCI space size */ if (request[k] & 1) /* I/O space */ { request[k] &= 0xFFFFFFFE; /* mask off address space indicator */ request[k] = ~request[k] + 1; /* change to size */ /* Round Up to 256 byte boundary */ request[k] = (request[k] + 0xff) & 0xFFFFFF00; request[k] |= 1; command_word |= CSR_IO_EN;; } else /* Memory space */ { /* PCI spec suggests rounding up to 4K for memory space */ request[k] &= 0xFFFFF000; request[k] = ~request[k] + 1; /* change to size */ command_word |= CSR_MEM_EN; } } for( k = 0; request[k] && k < 5; k++) { cfgAddr.u.bit.regNum = PCI_IDX_BAR_0 + k; if (request[k] & 1) /* I/O space */ { if ( ( transPtr->ioCurrent - request[k] ) < transPtr->ioBase ) { DRV_LOG("Pci I/O resource exhausted - bus %s\n" , busName , 0 , 0 , 0, 0, 0); request[k] = 0; break; } transPtr->ioCurrent -= (request[k] & 0xFFFFFFFE); i80312PciCfgWr(busNo, cfgAddr, (transPtr->ioCurrent | 1) ); pciCfg[cur_pciCfg].pci_addr[k] = (unsigned int)transPtr->ioCurrent; } else { if ( ( transPtr->current - request[k] ) < transPtr->base ) { DRV_LOG("Pci Memory resource exhausted - bus %s\n" , busName , 0 , 0 , 0, 0, 0); request[k] = 0; break; } transPtr->current -= request[k]; i80312PciCfgWr(busNo, cfgAddr, transPtr->current); pciCfg[cur_pciCfg].pci_addr[k] = (unsigned int)transPtr->current; } pciCfg[cur_pciCfg].pci_size[k] = (unsigned int)request[k]; } cur_pciCfg++; command_word |= (0xFFFF0000 + CSR_BM_EN); cfgAddr.u.bit.regNum = PCI_IDX_ST_CMD; i80312PciCfgWr(busNo, cfgAddr, command_word); } } }}/******************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -