//------------------------------------------------------------------------------ // // Function: InitKitlNIC // // Finds a supported PCI NIC, matching against g_NicSupported // If nothing is found it will return attempt to use dwDfltType with the input params, dwIrq and dwIoBase. // If that failes too, it will return NULL // PCKITL_NIC_INFO InitKitlNIC( DWORD dwIrq, DWORD dwIoBase, DWORD dwDfltType ) { PCI_COMMON_CONFIG pciConfig; int funcType, bus, device, function; PCSUPPORTED_NIC pNicFound; int length = 0; enum { FIND_BY_VENDOR, // 0 FIND_BY_TYPE // 1 }; // InitKitlNIC returns a pointer to this static KTIL_NIC_INFO KitlNic; KITLOutputDebugString("InitKitlNIC: Searching for PCI Ethernet NIC (dwIrq = %x, dwIoBase = %x, dwDfltType = %x) ...\r\n", dwIrq, dwIoBase, dwDfltType); // Pass 1: iterate searching for vendor (this is the best match) // Pass 2: iterate searching for matching type for (funcType = FIND_BY_VENDOR; funcType <= FIND_BY_TYPE; funcType++) { // iterate through buses for (bus = 0; bus < PCI_MAX_BUS; bus++) { // iterate through devices for (device = 0; device < PCI_MAX_DEVICES; device++) { // iterate through functions for (function = 0; function < PCI_MAX_FUNCTION; function++) { // read PCI config data OAL_PCI_LOCATION pciLoc; pciLoc.logicalLoc = bus << 16 | device << 8 | function; length = OALPCICfgRead(0, pciLoc, 0, (sizeof(pciConfig) - sizeof(pciConfig.DeviceSpecific)), &pciConfig); if (length == 0 || (pciConfig.VendorID == 0xFFFF)) break; // network controller or USB? if ( ( (pciConfig.BaseClass == PCI_CLASS_NETWORK_CTLR) && (pciConfig.SubClass == PCI_SUBCLASS_NET_ETHERNET_CTLR)) // Network device. || ( (pciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV) && (pciConfig.SubClass == PCI_SUBCLASS_BR_OTHER))) { // Other Unknown Special Devices DWORD dwFoundBase = pciConfig.u.type0.BaseAddresses[0] & 0xFFFFFFFC; DWORD dwFoundIrq = pciConfig.u.type0.InterruptLine; if (dwFoundIrq && dwFoundBase) { if ( (!dwIrq && !dwIoBase) // IRQ && IoBase not specified -- use 1st found || (dwIrq == OAL_KITL_IRQ_INVALID) // Undefined IRQ = Poll mode -- use first found || (!dwIoBase && (dwIrq == dwFoundIrq)) // IRQ match, no IO base specified || (dwIoBase == dwFoundBase)) // IOBase match { if(funcType == FIND_BY_VENDOR) { pNicFound = FindNICByVendor (&pciConfig); } else if(funcType == FIND_BY_TYPE) { pNicFound = FindNICByType ((UCHAR) dwDfltType); } if (pNicFound) { // found NIC card KitlNic.dwIoBase = dwFoundBase; KitlNic.dwIrq = dwFoundIrq; KitlNic.dwBus = bus; KitlNic.dwDevice = device; KitlNic.dwFunction = function; KitlNic.pDriver = pNicFound->pDriver; KitlNic.dwType = pNicFound->Type; memcpy (&KitlNic.pciConfig, &pciConfig, sizeof(pciConfig)); KITLOutputDebugString ("InitKitlNIC: Found PCI Ethernet NIC (type = %x, IRQ=%d, IOBase=0x%x).\r\n", pNicFound->Type, dwFoundIrq, dwFoundBase); return &KitlNic; } else { KITLOutputDebugString ("InitKitlNIC: skipping unknown PCI Ethernet NIC: (subclass=%x, Vendor=%x, Device=%x)\r\n", pciConfig.SubClass, pciConfig.VendorID, pciConfig.DeviceID); } } else { // found a NIC, but it didn't match what the bootloader was using KITLOutputDebugString ("InitKitlNIC: skipping PCI Ethernet NIC: (subclass = %x, IRQ=%d, IOBase=0x%x).\r\n", pciConfig.SubClass, dwFoundIrq, dwFoundBase); } } } if (function == 0 && !(pciConfig.HeaderType & 0x80)) break; } if (length == 0) break; } if (length == 0 && device == 0) break; } } // can't find it on PCI bus, if IRQ and IoBase are specified, use it if (dwIrq && dwIoBase && (pNicFound = FindNICByType ((UCHAR) dwDfltType))) { KitlNic.dwIoBase = dwIoBase; KitlNic.dwIrq = dwIrq; KitlNic.pDriver = pNicFound->pDriver; KitlNic.dwType = dwDfltType; // Signal that we're using a device but it's not on the PCI bus memset(&KitlNic.pciConfig, LEGACY_KITL_DEVICE_BYTEPATTERN, sizeof(pciConfig)); KITLOutputDebugString ("InitKitlNIC: Can't find PCI Ethernet NIC, use specified data (type = %x, IRQ=%d, IOBase=0x%x).\r\n", pNicFound->Type, dwIrq, dwIoBase); return &KitlNic; } return NULL; }
//------------------------------------------------------------------------------ // // Function: OALPCIInit // BOOL OALPCIInit() { VRC5477_REGS *pVRC5477Regs = OALPAtoUA(VRC5477_REG_PA); M1535_CFG_REGS *pM1535Regs = OALPAtoUA(BSP_REG_PA_M1535_CFG); OAL_PCI_LOCATION pciLoc; UINT32 u32; //---------------------------------------------------------------------- // External PCI //---------------------------------------------------------------------- // Cold reset OUTREG32(&pVRC5477Regs->PCICTL0H, PCI_CTRL_CRST); OALStall(100000); OUTREG32(&pVRC5477Regs->PCICTL0H, 0); OALStall(100000); // Setup windows OUTREG32(&pVRC5477Regs->PCIINIT00, BSP_PCI_INIT00); OUTREG32(&pVRC5477Regs->PCIW0, BSP_PCI_W0); OUTREG32(&pVRC5477Regs->PCIINIT10, BSP_PCI_INIT10); OUTREG32(&pVRC5477Regs->PCIW1, BSP_PCI_W1); // Setup control & arbiter registers OUTREG32(&pVRC5477Regs->PCICTL0L, BSP_PCI_CTL0L); OUTREG32(&pVRC5477Regs->PCICTL0H, BSP_PCI_CTL0H); OUTREG32(&pVRC5477Regs->PCIARB0L, BSP_PCI_ARB0L); OUTREG32(&pVRC5477Regs->PCIARB0H, BSP_PCI_ARB0H); // Setup configuration space OUTREG16(&pVRC5477Regs->PCICMD0, BSP_PCI_CMD0); OUTREG8(&pVRC5477Regs->MLTIM0, BSP_PCI_MLTIM0); OUTREG32(&pVRC5477Regs->BARC0, BSP_PCI_BARC0); OUTREG32(&pVRC5477Regs->BARM010, BSP_PCI_BARM010); OUTREG32(&pVRC5477Regs->BARM230, BSP_PCI_BARM230); OUTREG32(&pVRC5477Regs->BAR00, BSP_PCI_BAR00); OUTREG32(&pVRC5477Regs->BAR10, BSP_PCI_BAR10); OUTREG32(&pVRC5477Regs->BAR20, BSP_PCI_BAR20); OUTREG32(&pVRC5477Regs->BARB0, BSP_PCI_BARB0); OUTREG32(&pVRC5477Regs->BARP00, BSP_PCI_BARP00); OUTREG32(&pVRC5477Regs->BARP10, BSP_PCI_BARP10); //---------------------------------------------------------------------- // Internal PCI //---------------------------------------------------------------------- OUTREG32(&pVRC5477Regs->PCICTL1H, PCI_CTRL_CRST); OALStall(100000); OUTREG32(&pVRC5477Regs->PCICTL1H, 0); OALStall(100000); // Setup internal PCI windows OUTREG32(&pVRC5477Regs->PCIINIT01, BSP_PCI_INIT01); OUTREG32(&pVRC5477Regs->IOPCIW0, BSP_IOPCI_W0); OUTREG32(&pVRC5477Regs->PCIINIT11, BSP_PCI_INIT11); OUTREG32(&pVRC5477Regs->IOPCIW1, BSP_IOPCI_W1); // Setup control & arbiter registers OUTREG32(&pVRC5477Regs->PCICTL1L, BSP_PCI_CTL1L); OUTREG32(&pVRC5477Regs->PCICTL1H, BSP_PCI_CTL1H); OUTREG32(&pVRC5477Regs->PCIARB1L, BSP_PCI_ARB1L); OUTREG32(&pVRC5477Regs->PCIARB1H, BSP_PCI_ARB1H); // Setup configuration space OUTREG16(&pVRC5477Regs->PCICMD1, BSP_PCI_CMD1); OUTREG8(&pVRC5477Regs->MLTIM1, BSP_PCI_MLTIM1); OUTREG32(&pVRC5477Regs->BARC1, BSP_PCI_BARC1); OUTREG32(&pVRC5477Regs->BARM011, BSP_PCI_BARM011); OUTREG32(&pVRC5477Regs->BARM231, BSP_PCI_BARM231); OUTREG32(&pVRC5477Regs->BAR01, BSP_PCI_BAR01); OUTREG32(&pVRC5477Regs->BAR11, BSP_PCI_BAR11); OUTREG32(&pVRC5477Regs->BAR21, BSP_PCI_BAR21); OUTREG32(&pVRC5477Regs->BARB1, BSP_PCI_BARB1); OUTREG32(&pVRC5477Regs->BARP01, BSP_PCI_BARP01); OUTREG32(&pVRC5477Regs->BARP11, BSP_PCI_BARP11); OALStall(10000); //---------------------------------------------------------------------- // ALI M1535+ South Bridge //---------------------------------------------------------------------- // Is there ALI M1535+ bridge = CPU board is inserted to SG2 mother board, // in such case we must do some initialization --- default config address // lines for some ALI M1535+ internal devices colide with PCI slot config // address lines. pciLoc.bus = 0; pciLoc.dev = 8; pciLoc.fnc = 0; OALPCICfgRead(0, pciLoc, 0, sizeof(u32), &u32); if (u32 != 0x153310B9) goto cleanUp; //---------------------------------------------------------------------- // PCI-ISA bridge initialize //---------------------------------------------------------------------- OALLog(L"INFO: OALPCIInit: ALI M1535+ Bridge detected\r\n"); u32 = 0x0000C119; // I/O control, select PS2 keyboad/mouse OALPCICfgWrite(0, pciLoc, 0x40, sizeof(u32), &u32); u32 = 0x0000025D; // Primary IDE IRQ14 OALPCICfgWrite(0, pciLoc, 0x44, sizeof(u32), &u32); u32 = 0x70000009; // Audio->IRQ6, PCI INTC->IRQ11 OALPCICfgWrite(0, pciLoc, 0x48, sizeof(u32), &u32); u32 = 0x00000000; // USB1 enable OALPCICfgWrite(0, pciLoc, 0x50, sizeof(u32), &u32); u32 = 0x00000000; // PCSJ OALPCICfgWrite(0, pciLoc, 0x54, sizeof(u32), &u32); u32 = 0x0000007C; // IDE IDSEL(AD15), INTR OALPCICfgWrite(0, pciLoc, 0x58, sizeof(u32), &u32); u32 = 0x00004000; // Document recommend??? OALPCICfgWrite(0, pciLoc, 0x6C, sizeof(u32), &u32); u32 = 0x002600D2; // PMU IDSEL(AD14), USB IDSEL(AD13) OALPCICfgWrite(0, pciLoc, 0x70, sizeof(u32), &u32); u32 = 0x40801F01; // No modem, USB INTR(IRQ09), 2nd IDE IRQ15, AC97 IDSEL(AD17) OALPCICfgWrite(0, pciLoc, 0x74, sizeof(u32), &u32); u32 = 0x00000000; // USB2 disable OALPCICfgWrite(0, pciLoc, 0x7C, sizeof(u32), &u32); //--------------------------- // Configure super I/O chip //--------------------------- OUTPORT8(&pM1535Regs->config, 0x51); // Enter config mode OUTPORT8(&pM1535Regs->config, 0x23); // Enable parallel port OUTPORT8(&pM1535Regs->index, 0x07); OUTPORT8(&pM1535Regs->data, 0x03); // Select logical device 3 OUTPORT8(&pM1535Regs->index, 0x30); OUTPORT8(&pM1535Regs->data, 0x01); // Enable device OUTPORT8(&pM1535Regs->index, 0x60); OUTPORT8(&pM1535Regs->data, 0x03); // I/O address: 378h OUTPORT8(&pM1535Regs->index, 0x61); OUTPORT8(&pM1535Regs->data, 0x78); // I/O address: 378h OUTPORT8(&pM1535Regs->index, 0x70); OUTPORT8(&pM1535Regs->data, 0x07); // Irq: 7 // Enable UART1 OUTPORT8(&pM1535Regs->index, 0x07); OUTPORT8(&pM1535Regs->data, 0x04); // Select logical device 4 OUTPORT8(&pM1535Regs->index, 0x30); OUTPORT8(&pM1535Regs->data, 0x01); // Enable device OUTPORT8(&pM1535Regs->index, 0x60); OUTPORT8(&pM1535Regs->data, 0x03); // I/O address: 3F8h OUTPORT8(&pM1535Regs->index, 0x61); OUTPORT8(&pM1535Regs->data, 0xF8); // I/O address: 3F8h OUTPORT8(&pM1535Regs->index, 0x70); OUTPORT8(&pM1535Regs->data, 0x04); // Irq: 4 // Enable UART2/INFRA OUTPORT8(&pM1535Regs->index, 0x07); OUTPORT8(&pM1535Regs->data, 0x05); // Select logical device 5 OUTPORT8(&pM1535Regs->index, 0x30); OUTPORT8(&pM1535Regs->data, 0x01); // Enable device OUTPORT8(&pM1535Regs->index, 0x60); OUTPORT8(&pM1535Regs->data, 0x03); // I/O address: 3E8h OUTPORT8(&pM1535Regs->index, 0x61); OUTPORT8(&pM1535Regs->data, 0xE8); // I/O address: 3E8h OUTPORT8(&pM1535Regs->index, 0x70); OUTPORT8(&pM1535Regs->data, 0x05); // Irq: 5 // Enable PS/2 controller OUTPORT8(&pM1535Regs->index, 0x07); OUTPORT8(&pM1535Regs->data, 0x07); // Select logical device 7. OUTPORT8(&pM1535Regs->index, 0x30); OUTPORT8(&pM1535Regs->data, 0x01); // Enable device OUTPORT8(&pM1535Regs->index, 0x70); OUTPORT8(&pM1535Regs->data, 0x01); // Irq: 1 - keyboard OUTPORT8(&pM1535Regs->index, 0x72); OUTPORT8(&pM1535Regs->data, 0x0C); // Irq: 12 - mouse // Enable UART3 OUTPORT8(&pM1535Regs->index, 0x07); OUTPORT8(&pM1535Regs->data, 0x0B); // Select logical device 11 OUTPORT8(&pM1535Regs->index, 0x30); OUTPORT8(&pM1535Regs->data, 0x01); // Enable device OUTPORT8(&pM1535Regs->index, 0x60); OUTPORT8(&pM1535Regs->data, 0x02); // I/O address: 2F8h OUTPORT8(&pM1535Regs->index, 0x61); OUTPORT8(&pM1535Regs->data, 0xF8); // I/O address: 2F8h OUTPORT8(&pM1535Regs->index, 0x70); OUTPORT8(&pM1535Regs->data, 0x03); // Irq: 3 // Exit config mode OUTPORT8(&pM1535Regs->config, 0xBB); cleanUp: return TRUE; }