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

📄 com.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (ISSET(sc->sc_mcr, MCR_DTR)) {			if (!ISSET(sc->sc_mcr, MCR_RTS)) {				SET(sc->sc_mcr, MCR_RTS);				bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);			}		} else {			if (ISSET(sc->sc_mcr, MCR_RTS)) {				CLR(sc->sc_mcr, MCR_RTS);				bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);			}		}		sc->sc_dtr = MCR_DTR | MCR_RTS;	} else		sc->sc_dtr = MCR_DTR;	/* and copy to tty */	tp->t_ispeed = t->c_ispeed;	tp->t_ospeed = t->c_ospeed;	oldcflag = tp->t_cflag;	tp->t_cflag = t->c_cflag;	/*	 * If DCD is off and MDMBUF is changed, ask the tty layer if we should	 * stop the device.	 */	if (!ISSET(sc->sc_msr, MSR_DCD) &&	    !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&	    ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) &&	    (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {		CLR(sc->sc_mcr, sc->sc_dtr);		bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);	}	/* Just to be sure... */	splx(s);	comstart(tp);	return 0;}voidcomstart(tp)	struct tty *tp;{	struct com_softc *sc = com_cd.cd_devs[DEVUNIT(tp->t_dev)];	bus_space_tag_t iot = sc->sc_iot;	bus_space_handle_t ioh = sc->sc_ioh;	int s;	s = spltty();	if (ISSET(tp->t_state, TS_BUSY))		goto out;	if (ISSET(tp->t_state, TS_TIMEOUT | TS_TTSTOP) || sc->sc_halt > 0)		goto stopped;	if (ISSET(tp->t_cflag, CRTSCTS) && !ISSET(sc->sc_msr, MSR_CTS))		goto stopped;	if (tp->t_outq.c_cc <= tp->t_lowat) {		if (ISSET(tp->t_state, TS_ASLEEP)) {			CLR(tp->t_state, TS_ASLEEP);			wakeup(&tp->t_outq);		}		if (tp->t_outq.c_cc == 0)			goto stopped;		selwakeup(&tp->t_wsel);	}	SET(tp->t_state, TS_BUSY);	if (!ISSET(sc->sc_ier, IER_ETXRDY)) {		SET(sc->sc_ier, IER_ETXRDY);		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);	}	if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {		u_char buffer[64];	/* XXX: largest fifo */		u_char *cp = buffer;		int n = q_to_b(&tp->t_outq, cp, sc->sc_fifolen);		do {			bus_space_write_1(iot, ioh, com_data, *cp++);		} while (--n);	} else		bus_space_write_1(iot, ioh, com_data, getc(&tp->t_outq));out:	splx(s);	return;stopped:	if (ISSET(sc->sc_ier, IER_ETXRDY)) {		CLR(sc->sc_ier, IER_ETXRDY);		bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);	}	splx(s);}/* * Stop output on a line. */intcomstop(tp, flag)	struct tty *tp;	int flag;{	int s;	s = spltty();	if (ISSET(tp->t_state, TS_BUSY))		if (!ISSET(tp->t_state, TS_TTSTOP))			SET(tp->t_state, TS_FLUSH);	splx(s);	return 0;}voidcomdiag(arg)	void *arg;{	struct com_softc *sc = arg;	int overflows, floods;	int s;	s = spltty();	sc->sc_errors = 0;	overflows = sc->sc_overflows;	sc->sc_overflows = 0;	floods = sc->sc_floods;	sc->sc_floods = 0;	splx(s);	log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf overflow%s\n",	    sc->sc_dev.dv_xname,	    overflows, overflows == 1 ? "" : "s",	    floods, floods == 1 ? "" : "s");}voidcompoll(arg)	void *arg;{	int unit;	struct com_softc *sc;	struct tty *tp;	register u_char *ibufp;	u_char *ibufend;	register int c;	int s;	static int lsrmap[8] = {		0,      TTY_PE,		TTY_FE, TTY_PE|TTY_FE,		TTY_FE, TTY_PE|TTY_FE,		TTY_FE, TTY_PE|TTY_FE	};	s = spltty();	if (comevents == 0) {		splx(s);		goto out;	}	comevents = 0;	splx(s);	for (unit = 0; unit < com_cd.cd_ndevs; unit++) {		sc = com_cd.cd_devs[unit];		if (sc == 0 || sc->sc_ibufp == sc->sc_ibuf)			continue;		tp = sc->sc_tty;		s = spltty();		ibufp = sc->sc_ibuf;		ibufend = sc->sc_ibufp;		if (ibufp == ibufend) {			splx(s);			continue;		}		sc->sc_ibufp = sc->sc_ibuf = (ibufp == sc->sc_ibufs[0]) ?					     sc->sc_ibufs[1] : sc->sc_ibufs[0];		sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER;		sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE;		if (tp == 0 || !ISSET(tp->t_state, TS_ISOPEN)) {			splx(s);			continue;		}		if (ISSET(tp->t_cflag, CRTSCTS) &&		    !ISSET(sc->sc_mcr, MCR_RTS)) {			/* XXX */			SET(sc->sc_mcr, MCR_RTS);			bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr,			    sc->sc_mcr);		}		splx(s);		while (ibufp < ibufend) {			c = *ibufp++;			if (*ibufp & LSR_OE) {				sc->sc_overflows++;				if (sc->sc_errors++ == 0)					timeout(comdiag, sc, 60 * hz);			}			/* This is ugly, but fast. */			c |= lsrmap[(*ibufp++ & (LSR_BI|LSR_FE|LSR_PE)) >> 2];			(*linesw[tp->t_line].l_rint)(c, tp);		}	}out:	timeout(compoll, NULL, 1);}intcomintr(arg)	void *arg;{	struct com_softc *sc = arg;	bus_space_tag_t iot = sc->sc_iot;	bus_space_handle_t ioh = sc->sc_ioh;	struct tty *tp;	u_char lsr, data, msr, delta;#ifdef PPS_SYNC	struct timeval tv;	long usec;#endif /* PPS_SYNC */#ifdef COM_DEBUG	int n;	struct {		u_char iir, lsr, msr;	} iter[32];#endif	if (!sc->sc_tty)		return (0);		/* can't do squat. */#ifdef COM_DEBUG	n = 0;	if (ISSET(iter[n].iir = bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))		return (0);#else	if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))		return (0);#endif	tp = sc->sc_tty;	for (;;) {#ifdef COM_DEBUG		iter[n].lsr =#endif		lsr = bus_space_read_1(iot, ioh, com_lsr);		if (ISSET(lsr, LSR_RXRDY)) {			register u_char *p = sc->sc_ibufp;			comevents = 1;			do {				data = bus_space_read_1(iot, ioh, com_data);				if (ISSET(lsr, LSR_BI)) {#ifdef notdef					printf("break %02x %02x %02x %02x\n",					    sc->sc_msr, sc->sc_mcr, sc->sc_lcr,					    sc->sc_dtr);#endif#ifdef DDB					if (ISSET(sc->sc_hwflags,					    COM_HW_CONSOLE)) {						if (db_console)							Debugger();						goto next;					}#endif					data = 0;				}				if (p >= sc->sc_ibufend) {					sc->sc_floods++;					if (sc->sc_errors++ == 0)						timeout(comdiag, sc, 60 * hz);				} else {					*p++ = data;					*p++ = lsr;					if (p == sc->sc_ibufhigh &&					    ISSET(tp->t_cflag, CRTSCTS)) {						/* XXX */						CLR(sc->sc_mcr, MCR_RTS);						bus_space_write_1(iot, ioh, com_mcr,						    sc->sc_mcr);					}				}#ifdef DDB			next:#endif#ifdef COM_DEBUG				if (++n >= 32)					goto ohfudge;				iter[n].lsr =#endif				lsr = bus_space_read_1(iot, ioh, com_lsr);			} while (ISSET(lsr, LSR_RXRDY));			sc->sc_ibufp = p;		}#ifdef COM_DEBUG		else if (ISSET(lsr, LSR_BI|LSR_FE|LSR_PE|LSR_OE))			printf("weird lsr %02x\n", lsr);#endif#ifdef COM_DEBUG		iter[n].msr =#endif		msr = bus_space_read_1(iot, ioh, com_msr);		if (msr != sc->sc_msr) {			delta = msr ^ sc->sc_msr;			sc->sc_msr = msr;			if (ISSET(delta, MSR_DCD)) {#ifdef PPS_SYNC				if (ISSET(sc->sc_swflags, COM_SW_PPS)) {					if (ISSET(msr, MSR_DCD)) {						usec = time.tv_usec;						microtime(&tv);						usec = tv.tv_usec - usec;						if (usec < 0)							usec += 1000000;						hardpps(&tv, usec);					}				}				else#endif /* PPS_SYNC */				if (!ISSET(sc->sc_swflags, COM_SW_SOFTCAR) &&				    (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)) == 0) {					CLR(sc->sc_mcr, sc->sc_dtr);					bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);				}			}			if (ISSET(delta & msr, MSR_CTS) &&			    ISSET(tp->t_cflag, CRTSCTS)) {				/* the line is up and we want to do rts/cts flow control */				(*linesw[tp->t_line].l_start)(tp);			}		}		if (ISSET(lsr, LSR_TXRDY) && ISSET(tp->t_state, TS_BUSY)) {			CLR(tp->t_state, TS_BUSY | TS_FLUSH);			if (sc->sc_halt > 0)				wakeup(&tp->t_outq);			(*linesw[tp->t_line].l_start)(tp);		}#ifdef COM_DEBUG		if (++n >= 32)			goto ohfudge;		if (ISSET(iter[n].iir = bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))			return (1);#else		if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_NOPEND))			return (1);#endif	}#ifdef COM_DEBUGohfudge:	printf("comintr: too many iterations");	for (n = 0; n < 32; n++) {		if ((n % 4) == 0)			printf("\ncomintr: iter[%02d]", n);		printf("  %02x %02x %02x", iter[n].iir, iter[n].lsr, iter[n].msr);	}	printf("\n");	printf("comintr: msr %02x mcr %02x lcr %02x ier %02x\n",	    sc->sc_msr, sc->sc_mcr, sc->sc_lcr, sc->sc_ier);	printf("comintr: state %08x cc %d\n", sc->sc_tty->t_state,	    sc->sc_tty->t_outq.c_cc);#endif}/* * Following are all routines needed for COM to act as console */#include <dev/cons.h>#ifdef arc#undef CONADDR	extern int CONADDR;#endifvoidcomcnprobe(cp)	struct consdev *cp;{	/* XXX NEEDS TO BE FIXED XXX */#ifdef arc	bus_space_tag_t iot = &arc_bus_io;#else#ifdef powerpc	bus_space_tag_t iot = &p4e_isa_io;#else        bus_space_tag_t iot = 0;#endif   #endif	bus_space_handle_t ioh;	int found;	if(CONADDR == 0) {		cp->cn_pri = CN_DEAD;		return;	}	comconsiot = iot;	if (bus_space_map(iot, CONADDR, COM_NPORTS, 0, &ioh)) {		cp->cn_pri = CN_DEAD;		return;	}	found = comprobe1(iot, ioh);	bus_space_unmap(iot, ioh, COM_NPORTS);	if (!found) {		cp->cn_pri = CN_DEAD;		return;	}	/* locate the major number */	for (commajor = 0; commajor < nchrdev; commajor++)		if (cdevsw[commajor].d_open == comopen)			break;	/* initialize required fields */	cp->cn_dev = makedev(commajor, CONUNIT);#ifdef	COMCONSOLE	cp->cn_pri = CN_REMOTE;		/* Force a serial port console */#else	cp->cn_pri = CN_NORMAL;#endif}voidcomcninit(cp)	struct consdev *cp;{	if (bus_space_map(comconsiot, CONADDR, COM_NPORTS, 0, &comconsioh))		panic("comcninit: mapping failed");	cominit(comconsiot, comconsioh, comdefaultrate);	comconsaddr = CONADDR;	comconsinit = 0;}voidcominit(iot, ioh, rate)	bus_space_tag_t iot;	bus_space_handle_t ioh;	int rate;{	int s = splhigh();	u_char stat;	bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);	rate = comspeed(comdefaultrate);	bus_space_write_1(iot, ioh, com_dlbl, rate);	bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);	bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);	bus_space_write_1(iot, ioh, com_ier, IER_ERXRDY | IER_ETXRDY);	bus_space_write_1(iot, ioh, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_4);	stat = bus_space_read_1(iot, ioh, com_iir);	splx(s);}intcomcngetc(dev)	dev_t dev;{	int s = splhigh();	bus_space_tag_t iot = comconsiot;	bus_space_handle_t ioh = comconsioh;	u_char stat, c;	while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))		;	c = bus_space_read_1(iot, ioh, com_data);	stat = bus_space_read_1(iot, ioh, com_iir);	splx(s);	return c;}/* * Console kernel output character routine. */voidcomcnputc(dev, c)	dev_t dev;	int c;{	int s = splhigh();	bus_space_tag_t iot = comconsiot;	bus_space_handle_t ioh = comconsioh;	u_char stat;	register int timo;#ifdef KGDB	if (dev != kgdb_dev)#endif	if (comconsinit == 0) {		cominit(iot, ioh, comdefaultrate);		comconsinit = 1;	}	/* wait for any pending transmission to finish */	timo = 50000;	while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)		;	bus_space_write_1(iot, ioh, com_data, c);	/* wait for this transmission to complete */	timo = 1500000;	while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)		;#if 0 /* I don't think sooooo (pefo) */	/* clear any interrupts generated by this transmission */	stat = bus_space_read_1(iot, ioh, com_iir);#endif	splx(s);}voidcomcnpollc(dev, on)	dev_t dev;	int on;{}

⌨️ 快捷键说明

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