📄 rioinit.c
字号:
** Now we have checked all the slots, turn off the MCA slot selector */ outb(McaSlotSelect,0); rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber); return ret;}int RIOEISAinit( int Mode ){ static int EISADone = 0; uint Paddr; int PollIntMixMsgDone = 0; caddr_t Caddr; ushort Ident; uchar EisaSlot; uchar Ivec; int ret = 0; /* ** The only valid mode information for EISA hosts is fast or slow ** links. */ Mode = (Mode & FAST_LINKS) ? EISA_TP_FAST_LINKS : EISA_TP_SLOW_LINKS; if ( EISADone ) { rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit() - already done, return.\n"); return(0); } EISADone++; rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit()\n"); /* ** First check all cards to see if ANY are set for polled mode operation. ** If so, set ALL to polled. */ for ( EisaSlot=1; EisaSlot<=RIO_MAX_EISA_SLOTS; EisaSlot++ ) { Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) | INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO); if ( Ident == RIO_EISA_IDENT ) { rio_dprintk (RIO_DEBUG_INIT, "Found Specialix product\n"); if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE ) { rio_dprintk (RIO_DEBUG_INIT, "Not Specialix RIO - Product number %x\n", INBZ(EisaSlot, EISA_PRODUCT_NUMBER)); continue; /* next slot */ } /* ** Its a Specialix RIO! */ rio_dprintk (RIO_DEBUG_INIT, "RIO Revision %d\n", INBZ(EisaSlot, EISA_REVISION_NUMBER)); RIOMachineType |= (1<<RIO_EISA); /* ** Just check we haven't found too many wonderful objects */ if ( RIONumHosts >= RIO_HOSTS ) { Rprintf(RIOMesgTooManyCards); return 0; } /* ** Ensure that the enable bit is set! */ OUTBZ( EisaSlot, EISA_ENABLE, RIO_EISA_ENABLE_BIT ); /* ** EISA_INTERRUPT_VEC contains the interrupt vector. */ Ivec = INBZ(EisaSlot,EISA_INTERRUPT_VEC);#ifdef RIODEBUG switch ( Ivec & EISA_INTERRUPT_MASK ) { case EISA_IRQ_3: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 3\n"); break; case EISA_IRQ_4: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 4\n"); break; case EISA_IRQ_5: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 5\n"); break; case EISA_IRQ_6: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 6\n"); break; case EISA_IRQ_7: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 7\n"); break; case EISA_IRQ_9: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 9\n"); break; case EISA_IRQ_10: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 10\n"); break; case EISA_IRQ_11: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 11\n"); break; case EISA_IRQ_12: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 12\n"); break; case EISA_IRQ_14: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 14\n"); break; case EISA_IRQ_15: rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 15\n"); break; case EISA_POLLED: rio_dprintk (RIO_DEBUG_INIT, "EISA POLLED\n"); break; default: rio_dprintk (RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n"); Ivec &= EISA_CONTROL_MASK; }#endif if ( (Ivec & EISA_INTERRUPT_MASK) == EISA_POLLED ) { RIOWillPoll = 1; break; /* From EisaSlot loop */ } } } /* ** Do it all again now we know whether to change all cards to polled ** mode or not */ for ( EisaSlot=1; EisaSlot<=RIO_MAX_EISA_SLOTS; EisaSlot++ ) { Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) | INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO); if ( Ident == RIO_EISA_IDENT ) { if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE ) continue; /* next slot */ /* ** Its a Specialix RIO! */ /* ** Ensure that the enable bit is set! */ OUTBZ( EisaSlot, EISA_ENABLE, RIO_EISA_ENABLE_BIT ); /* ** EISA_INTERRUPT_VEC contains the interrupt vector. */ Ivec = INBZ(EisaSlot,EISA_INTERRUPT_VEC); if ( RIOWillPoll ) { /* ** If we are going to operate in polled mode, but this ** board is configured to be interrupt driven, display ** the message explaining the situation to the punter, ** assuming we haven't already done so. */ if ( !PollIntMixMsgDone && (Ivec & EISA_INTERRUPT_MASK) != EISA_POLLED ) { Rprintf(RIOMesgAllPolled); PollIntMixMsgDone = 1; } /* ** Ungraciously ignore whatever the board reports as its ** interrupt vector... */ Ivec &= ~EISA_INTERRUPT_MASK; /* ** ...and force it to dance to the poll tune. */ Ivec |= EISA_POLLED; } /* ** Convert the IRQ enable mask into something useful (0-15) */ Ivec = RIOEisaToIvec(Ivec); rio_dprintk (RIO_DEBUG_INIT, "EISA host in slot %d has Ivec 0x%x\n", EisaSlot, Ivec); /* ** Find the physical address */ Paddr = (INBZ(EisaSlot,EISA_MEMORY_BASE_HI)<<24) | (INBZ(EisaSlot,EISA_MEMORY_BASE_LO)<<16); rio_dprintk (RIO_DEBUG_INIT, "EISA card has Ivec %d Addr %x\n", Ivec, Paddr); if ( Paddr == 0 ) { rio_dprintk (RIO_DEBUG_INIT, "Board in slot %d configured for address zero!\n", EisaSlot); continue; } /* ** Tell the memory mapper that we want to talk to it */ rio_dprintk (RIO_DEBUG_INIT, "About to map EISA card \n"); if (RIOMapin( Paddr, RIO_EISA_MEM_SIZE, &Caddr) == -1) { rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n", RIO_EISA_MEM_SIZE,Paddr); continue; } rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr); /* ** And check that it is actually there! */ if ( RIOBoardTest( Paddr,Caddr,RIO_EISA,EisaSlot) == RIO_SUCCESS ) { rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n"); rio_dprintk (RIO_DEBUG_INIT, "Slot %d. Ivec %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", EisaSlot,Ivec,RIO_EISA,Paddr,Caddr,Mode); /* ** Board has passed its scrub test. Fill in all the ** transient stuff. */ p->RIOHosts[RIONumHosts].Slot = EisaSlot; p->RIOHosts[RIONumHosts].Ivec = Ivec; p->RIOHosts[RIONumHosts].Type = RIO_EISA; p->RIOHosts[RIONumHosts].Copy = bcopy; p->RIOHosts[RIONumHosts].PaddrP = Paddr; p->RIOHosts[RIONumHosts].Caddr = Caddr; p->RIOHosts[RIONumHosts].CardP = (struct DpRam *)Caddr; p->RIOHosts[RIONumHosts].Mode = Mode; /* ** because the EISA prom is mapped into IO space, we ** need to copy the unqiue number into the memory area ** that it would have occupied, so that the download ** code can determine its ID and card type. */ WBYTE(p->RIOHosts[RIONumHosts].Unique[0],INBZ(EisaSlot,EISA_UNIQUE_NUM_0)); WBYTE(p->RIOHosts[RIONumHosts].Unique[1],INBZ(EisaSlot,EISA_UNIQUE_NUM_1)); WBYTE(p->RIOHosts[RIONumHosts].Unique[2],INBZ(EisaSlot,EISA_UNIQUE_NUM_2)); WBYTE(p->RIOHosts[RIONumHosts].Unique[3],INBZ(EisaSlot,EISA_UNIQUE_NUM_3)); p->RIOHosts[RIONumHosts].UniqueNum = ((RBYTE(p->RIOHosts[RIONumHosts].Unique[0])&0xFF)<<0)| ((RBYTE(p->RIOHosts[RIONumHosts].Unique[1])&0xFF)<<8)| ((RBYTE(p->RIOHosts[RIONumHosts].Unique[2])&0xFF)<<16)| ((RBYTE(p->RIOHosts[RIONumHosts].Unique[3])&0xFF)<<24); INBZ(EisaSlot,EISA_INTERRUPT_RESET); RIONumHosts++; ret++; } else { /* ** It failed the test, so ignore it. */ rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n"); RIOMapout(Paddr, RIO_EISA_MEM_SIZE, Caddr ); } } } if (RIOMachineType & RIO_EISA) return ret+1; return ret;}#endif#ifndef linux#define CONFIG_ADDRESS 0xcf8#define CONFIG_DATA 0xcfc#define FORWARD_REG 0xcfastatic intread_config(int bus_number, int device_num, int r_number) { unsigned int cav; unsigned int val;/* Build config_address_value: 31 24 23 16 15 11 10 8 7 0 ------------------------------------------------------ |1| 0000000 | bus_number | device # | 000 | register | ------------------------------------------------------*/ cav = r_number & 0xff; cav |= ((device_num & 0x1f) << 11); cav |= ((bus_number & 0xff) << 16); cav |= 0x80000000; /* Enable bit */ outpd(CONFIG_ADDRESS,cav); val = inpd(CONFIG_DATA); outpd(CONFIG_ADDRESS,0); return val;}staticwrite_config(bus_number,device_num,r_number,val) { unsigned int cav;/* Build config_address_value: 31 24 23 16 15 11 10 8 7 0 ------------------------------------------------------ |1| 0000000 | bus_number | device # | 000 | register | ------------------------------------------------------*/ cav = r_number & 0xff; cav |= ((device_num & 0x1f) << 11); cav |= ((bus_number & 0xff) << 16); cav |= 0x80000000; /* Enable bit */ outpd(CONFIG_ADDRESS, cav); outpd(CONFIG_DATA, val); outpd(CONFIG_ADDRESS, 0); return val;}#else/* XXX Implement these... */static intread_config(int bus_number, int device_num, int r_number) { return 0;}static intwrite_config(int bus_number, int device_num, int r_number) { return 0;}#endifintRIOPCIinit(p, Mode)struct rio_info *p;int Mode;{ #define MAX_PCI_SLOT 32 #define RIO_PCI_JET_CARD 0x200011CB static int slot; /* count of machine's PCI slots searched so far */ caddr_t Caddr; /* Virtual address of the current PCI host card. */ unsigned char Ivec; /* interrupt vector for the current PCI host */ unsigned long Paddr; /* Physical address for the current PCI host */ int Handle; /* Handle to Virtual memory allocated for current PCI host */ rio_dprintk (RIO_DEBUG_INIT, "Search for a RIO PCI card - start at slot %d\n", slot); /* ** Initialise the search status */ p->RIOLastPCISearch = RIO_FAIL; while ( (slot < MAX_PCI_SLOT) & (p->RIOLastPCISearch != RIO_SUCCESS) ) { rio_dprintk (RIO_DEBUG_INIT, "Currently testing slot %d\n", slot); if (read_config(0,slot,0) == RIO_PCI_JET_CARD) { p->RIOHosts[p->RIONumHosts].Ivec = 0; Paddr = read_config(0,slot,0x18); Paddr = Paddr - (Paddr & 0x1); /* Mask off the io bit */ if ( (Paddr == 0) || ((Paddr & 0xffff0000) == 0xffff0000) ) { rio_dprintk (RIO_DEBUG_INIT, "Goofed up slot\n"); /* what! */ slot++; continue; } p->RIOHosts[p->RIONumHosts].PaddrP = Paddr; Ivec = (read_config(0,slot,0x3c) & 0xff); rio_dprintk (RIO_DEBUG_INIT, "PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec); Handle = RIOMapin( Paddr, RIO_PCI_MEM_SIZE, &Caddr ); if (Handle == -1) { rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr); slot++; continue; } p->RIOHosts[p->RIONumHosts].Ivec = Ivec + 32; p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec, (int (*)())rio_intr, (char *)p->RIONumHosts); if (RIOBoardTest( Paddr, Caddr, RIO_PCI, 0 ) == RIO_SUCCESS) { rio_dprintk (RIO_DEBUG_INIT, ("Board has passed test\n"); rio_dprintk (RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr, Mode); /* ** Board has passed its scrub test. Fill in all the ** transient stuff. */ p->RIOHosts[p->RIONumHosts].Slot = 0; p->RIOHosts[p->RIONumHosts].Ivec = Ivec + 32; p->RIOHosts[p->RIONumHosts].Type = RIO_PCI; p->RIOHosts[p->RIONumHosts].Copy = rio_pcicopy; p->RIOHosts[p->RIONumHosts].PaddrP = Paddr; p->RIOHosts[p->RIONumHosts].Caddr = Caddr; p->RIOHosts[p->RIONumHosts].CardP = (struct DpRam *)Caddr; p->RIOHosts[p->RIONumHosts].Mode = Mode;#if 0 WBYTE(p->RIOHosts[p->RIONumHosts].Control, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE ); WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt,0xff); WBYTE(p->RIOHosts[p->RIONumHosts].Control, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | p->RIOHosts[p->RIONumHosts].Mode | INTERRUPT_DISABLE ); WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt,0xff);#else WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);#endif p->RIOHosts[p->RIONumHosts].UniqueNum = ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0])&0xFF)<<0)| ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)| ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)| ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24); rio_dprintk (RIO_DEBUG_INIT, "Unique no 0x%x.\n", p->RIOHosts[p->RIONumHosts].UniqueNum); p->RIOLastPCISearch = RIO_SUCCESS; p->RIONumHosts++; } } slot++; } if ( slot >= MAX_PCI_SLOT ) { rio_dprintk (RIO_DEBUG_INIT, "All %d PCI slots have tested for RIO cards !!!\n", MAX_PCI_SLOT); } /* ** I don't think we want to do this anymore ** if (!p->RIOLastPCISearch == RIO_FAIL ) { p->RIOFailed++; } ** */}#ifdef FUTURE_RELEASEvoid riohalt( void ){ int host; for ( host=0; host<p->RIONumHosts; host++ ) { rio_dprintk (RIO_DEBUG_INIT, "Stop host %d\n", host); (void)RIOBoardTest( p->RIOHosts[host].PaddrP, p->RIOHosts[host].Caddr, p->RIOHosts[host].Type,p->RIOHosts[host].Slot ); }}#endif#endifstatic uchar val[] = {#ifdef VERY_LONG_TEST 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xa5, 0xff, 0x5a, 0x00, 0xff, 0xc9, 0x36, #endif 0xff, 0x00, 0x00 };#define TEST_END sizeof(val)/*** RAM test a board. ** Nothing too complicated, just enough to check it out.*/intRIOBoardTest(paddr, caddr, type, slot)paddr_t paddr;caddr_t caddr;uchar type;int slot;{ struct DpRam *DpRam = (struct DpRam *)caddr; char *ram[4]; int size[4]; int op, bank; int nbanks; rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n", type,(int)DpRam, slot); RIOHostReset(type, DpRam, slot); /* ** Scrub the memory. This comes in several banks: ** DPsram1 - 7000h bytes ** DPsram2 - 200h bytes ** DPsram3 - 7000h bytes ** scratch - 1000h bytes */ rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n"); size[0] = DP_SRAM1_SIZE; size[1] = DP_SRAM2_SIZE; size[2] = DP_SRAM3_SIZE; size[3] = DP_SCRATCH_SIZE; ram[0] = (char *)&DpRam->DpSram1[0]; ram[1] = (char *)&DpRam->DpSram2[0]; ram[2] = (char *)&DpRam->DpSram3[0]; nbanks = (type == RIO_PCI) ? 3 : 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -