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

📄 si.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	for (i=0; i < NSI; i++) {		sc = &si_softc[i];		if ((caddr_t)sc->sc_paddr == (caddr_t)paddr) {			DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,				"si%d: iomem (%x) already configured to si%d\n",				id->id_unit, sc->sc_paddr, i));			return(0);		}	}	/* Is there anything out there? (0x17 is just an arbitrary number) */	*maddr = 0x17;	if (*maddr != 0x17) {		DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,			"si%d: 0x17 check fail at phys 0x%x\n",			id->id_unit, paddr));fail:		return(0);	}	/*	 * Let's look first for a JET ISA card, since that's pretty easy	 *	 * All jet hosts are supposed to have this string in the IDROM,	 * but it's not worth checking on self-IDing busses like PCI.	 */	{		unsigned char *jet_chk_str = "JET HOST BY KEV#";		for (i = 0; i < strlen(jet_chk_str); i++)			if (jet_chk_str[i] != *(maddr + SIJETIDSTR + 2 * i))				goto try_mk2;	}	DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,		"si%d: JET first check - 0x%x\n",		id->id_unit, (*(maddr+SIJETIDBASE))));	if (*(maddr+SIJETIDBASE) != (SISPLXID&0xff))		goto try_mk2;	DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,		"si%d: JET second check - 0x%x\n",		id->id_unit, (*(maddr+SIJETIDBASE+2))));	if (*(maddr+SIJETIDBASE+2) != ((SISPLXID&0xff00)>>8))		goto try_mk2;	/* It must be a Jet ISA or RIO card */	DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,		"si%d: JET id check - 0x%x\n",		id->id_unit, (*(maddr+SIUNIQID))));	if ((*(maddr+SIUNIQID) & 0xf0) !=0x20)		goto try_mk2;	/* It must be a Jet ISA SI/XIO card */	*(maddr + SIJETCONFIG) = 0;	type = SIJETISA;	ramsize = SIJET_RAMSIZE;	goto got_card;	/*	 * OK, now to see if whatever responded is really an SI card.	 * Try for a MK II next (SIHOST2)	 */try_mk2:	for (i = SIPLSIG; i < SIPLSIG + 8; i++)		if ((*(maddr+i) & 7) != (~(BYTE)i & 7))			goto try_mk1;	/* It must be an SIHOST2 */	*(maddr + SIPLRESET) = 0;	*(maddr + SIPLIRQCLR) = 0;	*(maddr + SIPLIRQSET) = 0x10;	type = SIHOST2;	ramsize = SIHOST2_RAMSIZE;	goto got_card;	/*	 * Its not a MK II, so try for a MK I (SIHOST)	 */try_mk1:	*(maddr+SIRESET) = 0x0;		/* reset the card */	*(maddr+SIINTCL) = 0x0;		/* clear int */	*(maddr+SIRAM) = 0x17;	if (*(maddr+SIRAM) != (BYTE)0x17)		goto fail;	*(maddr+0x7ff8) = 0x17;	if (*(maddr+0x7ff8) != (BYTE)0x17) {		DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,			"si%d: 0x17 check fail at phys 0x%x = 0x%x\n",			id->id_unit, paddr+0x77f8, *(maddr+0x77f8)));		goto fail;	}	/* It must be an SIHOST (maybe?) - there must be a better way XXX */	type = SIHOST;	ramsize = SIHOST_RAMSIZE;got_card:	DPRINT((0, DBG_AUTOBOOT, "si%d: found type %d card, try memory test\n",		id->id_unit, type));	/* Try the acid test */	ux = maddr + SIRAM;	for (i = 0; i < ramsize; i++, ux++)		*ux = (BYTE)(i&0xff);	ux = maddr + SIRAM;	for (i = 0; i < ramsize; i++, ux++) {		if ((was = *ux) != (BYTE)(i&0xff)) {			DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,				"si%d: match fail at phys 0x%x, was %x should be %x\n",				id->id_unit, paddr + i, was, i&0xff));			goto fail;		}	}	/* clear out the RAM */	ux = maddr + SIRAM;	for (i = 0; i < ramsize; i++)		*ux++ = 0;	ux = maddr + SIRAM;	for (i = 0; i < ramsize; i++) {		if ((was = *ux++) != 0) {			DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,				"si%d: clear fail at phys 0x%x, was %x\n",				id->id_unit, paddr + i, was));			goto fail;		}	}	/*	 * Success, we've found a valid board, now fill in	 * the adapter structure.	 */	switch (type) {	case SIHOST2:		if ((id->id_irq & (IRQ11|IRQ12|IRQ15)) == 0) {bad_irq:			DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,				"si%d: bad IRQ value - %d\n",				id->id_unit, id->id_irq));			return(0);		}		id->id_msize = SIHOST2_MEMSIZE;		break;	case SIHOST:		if ((id->id_irq & (IRQ11|IRQ12|IRQ15)) == 0) {			goto bad_irq;		}		id->id_msize = SIHOST_MEMSIZE;		break;	case SIJETISA:		if ((id->id_irq & (IRQ9|IRQ10|IRQ11|IRQ12|IRQ15)) == 0) {			goto bad_irq;		}		id->id_msize = SIJETISA_MEMSIZE;		break;	case SIMCA:		/* MCA */	default:		printf("si%d: %s not supported\n", id->id_unit, si_type[type]);		return(0);	}	id->id_intr = (inthand2_t *)si_intr; /* set here instead of config */	si_softc[id->id_unit].sc_type = type;	si_softc[id->id_unit].sc_typename = si_type[type];	return(-1);	/* -1 == found */}/* * We have to make an 8 bit version of bcopy, since some cards can't * deal with 32 bit I/O */#if 1static voidsi_bcopy(const void *src, void *dst, size_t len){	while (len--)		*(((u_char *)dst)++) = *(((u_char *)src)++);}#else#define si_bcopy bcopy#endif/* * Attach the device.  Initialize the card. * * This routine also gets called by the EISA and PCI attach routines. * It presumes that the softstate for the unit has had had its type field * and the EISA specific stuff filled in, as well as the kernel virtual * base address and the unit number of the isa_device struct. */static intsiattach(id)	struct isa_device *id;{	int unit = id->id_unit;	struct si_softc *sc = &si_softc[unit];	struct si_port *pp;	volatile struct si_channel *ccbp;	volatile struct si_reg *regp;	volatile caddr_t maddr;	struct si_module *modp;	struct tty *tp;	struct speedtab *spt;	int nmodule, nport, x, y;	int uart_type;	DPRINT((0, DBG_AUTOBOOT, "si%d: siattach\n", id->id_unit));	sc->sc_paddr = (caddr_t)vtophys(id->id_maddr);	sc->sc_maddr = id->id_maddr;	sc->sc_irq = id->id_irq;	DPRINT((0, DBG_AUTOBOOT, "si%d: type: %s paddr: %x maddr: %x\n", unit,		sc->sc_typename, sc->sc_paddr, sc->sc_maddr));	sc->sc_ports = NULL;			/* mark as uninitialised */	maddr = sc->sc_maddr;	/* Stop the CPU first so it won't stomp around while we load */	switch (sc->sc_type) {#if NEISA > 0		case SIEISA:			outb(sc->sc_eisa_iobase + 2, sc->sc_eisa_irq << 4);		break;#endif#if NPCI > 0		case SIPCI:			*(maddr+SIPCIRESET) = 0;		break;		case SIJETPCI: /* fall through to JET ISA */#endif		case SIJETISA:			*(maddr+SIJETCONFIG) = 0;		break;		case SIHOST2:			*(maddr+SIPLRESET) = 0;		break;		case SIHOST:			*(maddr+SIRESET) = 0;		break;		default: /* this should never happen */			printf("si%d: unsupported configuration\n", unit);			return 0;		break;	}	/* OK, now lets download the download code */	if (SI_ISJET(sc->sc_type)) {		DPRINT((0, DBG_DOWNLOAD, "si%d: jet_download: nbytes %d\n",			id->id_unit, si3_t225_dsize));		si_bcopy(si3_t225_download, maddr + si3_t225_downloadaddr,			si3_t225_dsize);		DPRINT((0, DBG_DOWNLOAD,			"si%d: jet_bootstrap: nbytes %d -> %x\n",			id->id_unit, si3_t225_bsize, si3_t225_bootloadaddr));		si_bcopy(si3_t225_bootstrap, maddr + si3_t225_bootloadaddr,			si3_t225_bsize);	} else {		DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n",			id->id_unit, si2_z280_dsize));		si_bcopy(si2_z280_download, maddr + si2_z280_downloadaddr,			si2_z280_dsize);	}	/* Now start the CPU */	switch (sc->sc_type) {#if NEISA > 0	case SIEISA:		/* modify the download code to tell it that it's on an EISA */		*(maddr + 0x42) = 1;		outb(sc->sc_eisa_iobase + 2, (sc->sc_eisa_irq << 4) | 4);		(void)inb(sc->sc_eisa_iobase + 3); /* reset interrupt */		break;#endif	case SIPCI:		/* modify the download code to tell it that it's on a PCI */		*(maddr+0x42) = 1;		*(maddr+SIPCIRESET) = 1;		*(maddr+SIPCIINTCL) = 0;		break;	case SIJETPCI:		*(maddr+SIJETRESET) = 0;		*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN;		break;	case SIJETISA:		*(maddr+SIJETRESET) = 0;		switch (sc->sc_irq) {		case IRQ9:			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0x90;			break;		case IRQ10:			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xa0;			break;		case IRQ11:			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xb0;			break;		case IRQ12:			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xc0;			break;		case IRQ15:			*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|0xf0;			break;		}		break;	case SIHOST:		*(maddr+SIRESET_CL) = 0;		*(maddr+SIINTCL_CL) = 0;		break;	case SIHOST2:		*(maddr+SIPLRESET) = 0x10;		switch (sc->sc_irq) {		case IRQ11:			*(maddr+SIPLIRQ11) = 0x10;			break;		case IRQ12:			*(maddr+SIPLIRQ12) = 0x10;			break;		case IRQ15:			*(maddr+SIPLIRQ15) = 0x10;			break;		}		*(maddr+SIPLIRQCLR) = 0x10;		break;	default: /* this should _REALLY_ never happen */		printf("si%d: Uh, it was supported a second ago...\n", unit);		return 0;	}	DELAY(1000000);			/* wait around for a second */	regp = (struct si_reg *)maddr;	y = 0;					/* wait max of 5 sec for init OK */	while (regp->initstat == 0 && y++ < 10) {		DELAY(500000);	}	switch (regp->initstat) {	case 0:		printf("si%d: startup timeout - aborting\n", unit);		sc->sc_type = SIEMPTY;		return 0;	case 1:		if (SI_ISJET(sc->sc_type)) {			/* set throttle to 100 times per second */			regp->int_count = JET_INT_COUNT;			/* rx_intr_count is a NOP in Jet */		} else {			/* set throttle to 125 times per second */			regp->int_count = INT_COUNT;			/* rx intr max of 25 times per second */			regp->rx_int_count = RXINT_COUNT;		}		regp->int_pending = 0;		/* no intr pending */		regp->int_scounter = 0;	/* reset counter */		break;	case 0xff:		/*		 * No modules found, so give up on this one.		 */		printf("si%d: %s - no ports found\n", unit,			si_type[sc->sc_type]);		return 0;	default:		printf("si%d: download code version error - initstat %x\n",			unit, regp->initstat);		return 0;	}	/*	 * First time around the ports just count them in order	 * to allocate some memory.	 */	nport = 0;	modp = (struct si_module *)(maddr + 0x80);	for (;;) {		DPRINT((0, DBG_DOWNLOAD, "si%d: ccb addr 0x%x\n", unit, modp));		switch (modp->sm_type) {		case TA4:			DPRINT((0, DBG_DOWNLOAD,				"si%d: Found old TA4 module, 4 ports\n",				unit));			x = 4;			break;		case TA8:			DPRINT((0, DBG_DOWNLOAD,				"si%d: Found old TA8 module, 8 ports\n",				unit));			x = 8;			break;		case TA4_ASIC:			DPRINT((0, DBG_DOWNLOAD,				"si%d: Found ASIC TA4 module, 4 ports\n",				unit));			x = 4;			break;		case TA8_ASIC:			DPRINT((0, DBG_DOWNLOAD,				"si%d: Found ASIC TA8 module, 8 ports\n",				unit));			x = 8;			break;		case MTA:			DPRINT((0, DBG_DOWNLOAD,				"si%d: Found CD1400 module, 8 ports\n",				unit));			x = 8;			break;		case SXDC:			DPRINT((0, DBG_DOWNLOAD,				"si%d: Found SXDC module, 8 ports\n",				unit));			x = 8;			break;		default:			printf("si%d: unknown module type %d\n",				unit, modp->sm_type);			goto try_next;		}		/* this was limited in firmware and is also a driver issue */		if ((nport + x) > SI_MAXPORTPERCARD) {			printf("si%d: extra ports ignored\n", unit);			goto try_next;		}		nport += x;		si_Nports += x;		si_Nmodules++;try_next:		if (modp->sm_next == 0)			break;		modp = (struct si_module *)			(maddr + (unsigned)(modp->sm_next & 0x7fff));	}	sc->sc_ports = (struct si_port *)malloc(sizeof(struct si_port) * nport,		M_DEVBUF, M_NOWAIT);	if (sc->sc_ports == 0) {mem_fail:		printf("si%d: fail to malloc memory for port structs\n",			unit);		return 0;	}	bzero(sc->sc_ports, sizeof(struct si_port) * nport);	sc->sc_nport = nport;	/*	 * allocate tty structures for ports	 */	tp = (struct tty *)malloc(sizeof(*tp) * nport, M_DEVBUF, M_NOWAIT);	if (tp == 0)		goto mem_fail;	bzero(tp, sizeof(*tp) * nport);	si_tty = tp;	/*	 * Scan round the ports again, this time initialising.	 */	pp = sc->sc_ports;	nmodule = 0;	modp = (struct si_module *)(maddr + 0x80);	uart_type = 1000;	/* arbitary, > uchar_max */	for (;;) {		switch (modp->sm_type) {		case TA4:			nport = 4;			break;		case TA8:			nport = 8;			break;		case TA4_ASIC:			nport = 4;			break;		case TA8_ASIC:			nport = 8;			break;		case MTA:			nport = 8;			break;		case SXDC:			nport = 8;			break;		default:			goto try_next2;		}		nmodule++;		ccbp = (struct si_channel *)((char *)modp + 0x100);		if (uart_type == 1000)			uart_type = ccbp->type;		else if (uart_type != ccbp->type)			printf("si%d: Warning: module %d mismatch! (%d%s != %d%s)\n",			    unit, nmodule,			    ccbp->type, si_modulename(sc->sc_type, ccbp->type),			    uart_type, si_modulename(sc->sc_type, uart_type));		for (x = 0; x < nport; x++, pp++, ccbp++) {			pp->sp_ccb = ccbp;	/* save the address */			pp->sp_tty = tp++;			pp->sp_pend = IDLE_CLOSE;			pp->sp_state = 0;	/* internal flag */			pp->sp_dtr_wait = 3 * hz;			pp->sp_iin.c_iflag = TTYDEF_IFLAG;			pp->sp_iin.c_oflag = TTYDEF_OFLAG;			pp->sp_iin.c_cflag = TTYDEF_CFLAG;			pp->sp_iin.c_lflag = TTYDEF_LFLAG;			termioschars(&pp->sp_iin);			pp->sp_iin.c_ispeed = pp->sp_iin.c_ospeed =				TTYDEF_SPEED;;			pp->sp_iout = pp->sp_iin;		}try_next2:		if (modp->sm_next == 0) {			printf("si%d: card: %s, ports: %d, modules: %d, type: %d%s\n",				unit,				sc->sc_typename,				sc->sc_nport,				nmodule,				uart_type,				si_modulename(sc->sc_type, uart_type));			break;		}		modp = (struct si_module *)			(maddr + (unsigned)(modp->sm_next & 0x7fff));	}	if (done_chartimes == 0) {		for (spt = chartimes ; spt->sp_speed != -1; spt++) {			if ((spt->sp_code /= hz) == 0)				spt->sp_code = 1;		}		done_chartimes = 1;	}#ifdef DEVFS/*	path	name	devsw		minor	type   uid gid perm*/	for ( x = 0; x < sc->sc_nport; x++ ) {		/* sync with the manuals that start at 1 */		y = x + 1 + id->id_unit * (1 << SI_CARDSHIFT);		sc->devfs_token[x].ttya = devfs_add_devswf(			&si_cdevsw, x,			DV_CHR, 0, 0, 0600, "ttyA%02d", y);		sc->devfs_token[x].cuaa = devfs_add_devswf(			&si_cdevsw, x + 0x00080,			DV_CHR, 0, 0, 0600, "cuaA%02d", y);		sc->devfs_token[x].ttyi = devfs_add_devswf(			&si_cdevsw, x + 0x10000,			DV_CHR, 0, 0, 0600, "ttyiA%02d", y);		sc->devfs_token[x].cuai = devfs_add_devswf(			&si_cdevsw, x + 0x10080,			DV_CHR, 0, 0, 0600, "cuaiA%02d", y);		sc->devfs_token[x].ttyl = devfs_add_devswf(			&si_cdevsw, x + 0x20000,

⌨️ 快捷键说明

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