Exemple #1
0
static Uart*
i8250pnp(void)
{
	int i;
	Ctlr *ctlr;
	Uart *head, *uart;

	head = i8250uart;
	for(i = 0; i < nelem(i8250uart); i++){
		/*
		 * Does it exist?
		 * Should be able to write/read the Scratch Pad
		 * and reserve the I/O space.
		 */
		uart = &i8250uart[i];
		ctlr = uart->regs;
		csr8o(ctlr, Scr, 0x55);
		if(csr8r(ctlr, Scr) == 0x55)
			continue;
		if(ioalloc(ctlr->io, 8, 0, uart->name) < 0)
			continue;
		if(uart == head)
			head = uart->next;
		else
			(uart-1)->next = uart->next;
	}

	return head;
}
Exemple #2
0
static int
i8250baud(Uart* uart, int baud)
{
#ifdef notdef				/* don't change the speed */
	ulong bgc;
	Ctlr *ctlr;
	extern int i8250freq;	/* In the config file */

	/*
	 * Set the Baud rate by calculating and setting the Baud rate
	 * Generator Constant. This will work with fairly non-standard
	 * Baud rates.
	 */
	if(i8250freq == 0 || baud <= 0)
		return -1;
	bgc = (i8250freq+8*baud-1)/(16*baud);

	ctlr = uart->regs;
	while(csr8r(ctlr, Usr) & Busy)
		delay(1);
	csr8w(ctlr, Lcr, Dlab);		/* begin kludge */
	csr8o(ctlr, Dlm, bgc>>8);
	csr8o(ctlr, Dll, bgc);
	csr8w(ctlr, Lcr, 0);
#endif
	uart->baud = baud;
	return 0;
}
Exemple #3
0
static int
i8250baud(Uart* uart, int baud)
{
	ulong bgc;
	Ctlr *ctlr;

	/*
	 * Set the Baud rate by calculating and setting the Baud rate
	 * Generator Constant. This will work with fairly non-standard
	 * Baud rates.
	 */
	if(uart->freq == 0 || baud <= 0)
		return -1;
	bgc = (uart->freq+8*baud-1)/(16*baud);

	ctlr = uart->regs;
	csr8w(ctlr, Lcr, Dlab);
	csr8o(ctlr, Dlm, bgc>>8);
	csr8o(ctlr, Dll, bgc);
	csr8w(ctlr, Lcr, 0);

	uart->baud = baud;

	return 0;
}
Exemple #4
0
void
putc(int c)
{
	int i;

	for(i = 0; !(csr8r(Lsr) & Thre) && i < 1000000; i++)
		;
	csr8o(Thr, (uchar)c);
	for(i = 0; !(csr8r(Lsr) & Thre) && i < 1000000; i++)
		;
}
Exemple #5
0
Uart*
i8250console(char* cfg)
{
	int i;
	Uart *uart;
	Ctlr *ctlr;
	char *cmd, *p;

	/*
	 * Before i8250pnp() is run can only set the console
	 * to 0 or 1 because those are the only uart structs which
	 * will be the same before and after that.
	 */
	if((p = getconf("console")) == nil && (p = cfg) == nil)
		return nil;
	i = strtoul(p, &cmd, 0);
	if(p == cmd)
		return nil;
	if((uart = uartconsole(i, cmd)) != nil){
		consuart = uart;
		return uart;
	}
	switch(i){
	default:
		return nil;
	case 0:
		uart = &i8250uart[0];
		break;
	case 1:
		uart = &i8250uart[1];
		break;	
	}

	/*
	 * Does it exist?
	 * Should be able to write/read
	 * the Scratch Pad.
	 */
	ctlr = uart->regs;
	csr8o(ctlr, Scr, 0x55);
	if(csr8r(ctlr, Scr) != 0x55)
		return nil;

	(*uart->phys->enable)(uart, 0);
	uartctl(uart, "b9600 l8 pn s1 i1");
	if(*cmd != '\0')
		uartctl(uart, cmd);

	consuart = uart;
	uart->console = 1;

	return uart;
}
Exemple #6
0
static void
i8250putc(Uart* uart, int c)
{
	int i;
	Ctlr *ctlr;

	ctlr = uart->regs;
	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
		delay(1);
	csr8o(ctlr, Thr, c);
	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
		delay(1);
}
Exemple #7
0
static void
i8250kick(Uart* uart)
{
	int i;
	Ctlr *ctlr;

	if(/* uart->cts == 0 || */ uart->blocked)
		return;

	if(!normalprint) {			/* early */
		if (uart->op < uart->oe)
			emptyoutstage(uart, uart->oe - uart->op);
		while ((i = uartstageoutput(uart)) > 0)
			emptyoutstage(uart, i);
		return;
	}

	/* nothing more to send? then disable xmit intr */
	ctlr = uart->regs;
	if (uart->op >= uart->oe && qlen(uart->oq) == 0 &&
	    csr8r(ctlr, Lsr) & Temt) {
		ctlr->sticky[Ier] &= ~Ethre;
		csr8w(ctlr, Ier, 0);
		return;
	}

	/*
	 *  128 here is an arbitrary limit to make sure
	 *  we don't stay in this loop too long.  If the
	 *  chip's output queue is longer than 128, too
	 *  bad -- presotto
	 */
	for(i = 0; i < 128; i++){
		if(!(csr8r(ctlr, Lsr) & Thre))
			break;
		if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
			break;
		csr8o(ctlr, Thr, *uart->op++);		/* start tx */
		ctlr->sticky[Ier] |= Ethre;
		csr8w(ctlr, Ier, 0);			/* intr when done */
	}
}
Exemple #8
0
static void
i8250putc(Uart* uart, int c)
{
	int i;
	Ctlr *ctlr;

	if (!normalprint) {		/* too early; use brute force */
		int s = splhi();

		while (!(((ulong *)PHYSCONS)[Lsr] & Thre))
			;
		((ulong *)PHYSCONS)[Thr] = c;
		coherence();
		splx(s);
		return;
	}

	ctlr = uart->regs;
	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
		delay(1);
	csr8o(ctlr, Thr, (uchar)c);
	for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
		delay(1);
}
Exemple #9
0
static void
i8250kick(Uart* uart)
{
	int i;
	Ctlr *ctlr;

	if(uart->cts == 0 || uart->blocked)
		return;

	/*
	 *  128 here is an arbitrary limit to make sure
	 *  we don't stay in this loop too long.  If the
	 *  chip's output queue is longer than 128, too
	 *  bad -- presotto
	 */
	ctlr = uart->regs;
	for(i = 0; i < 128; i++){
		if(!(csr8r(ctlr, Lsr) & Thre))
			break;
		if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
			break;
		csr8o(ctlr, Thr, *(uart->op++));
	}
}
Exemple #10
0
static void
i8250enable(Uart* uart, int ie)
{
	int mode;
	Ctlr *ctlr;

	if (up == nil)
		return;				/* too soon */

	ctlr = uart->regs;

	/* omap only: set uart/irda/cir mode to uart */
	mode = csr8r(ctlr, Mdr);
	csr8o(ctlr, Mdr, (mode & ~Modemask) | Modeuart);

	ctlr->sticky[Lcr] = Wls8;		/* no parity */
	csr8w(ctlr, Lcr, 0);

	/*
	 * Check if there is a FIFO.
	 * Changing the FIFOena bit in Fcr flushes data
	 * from both receive and transmit FIFOs; there's
	 * no easy way to guarantee not losing data on
	 * the receive side, but it's possible to wait until
	 * the transmitter is really empty.
	 * Also, reading the Iir outwith i8250interrupt()
	 * can be dangerous, but this should only happen
	 * once, before interrupts are enabled.
	 */
	ilock(ctlr);
	if(!ctlr->checkfifo){
		/*
		 * Wait until the transmitter is really empty.
		 */
		while(!(csr8r(ctlr, Lsr) & Temt))
			;
		csr8w(ctlr, Fcr, FIFOena);
		if(csr8r(ctlr, Iir) & Ifena)
			ctlr->hasfifo = 1;
		csr8w(ctlr, Fcr, 0);
		ctlr->checkfifo = 1;
	}
	iunlock(ctlr);

	/*
	 * Enable interrupts and turn on DTR and RTS.
	 * Be careful if this is called to set up a polled serial line
	 * early on not to try to enable interrupts as interrupt-
	 * -enabling mechanisms might not be set up yet.
	 */
	if(ie){
		if(ctlr->iena == 0 && !ctlr->poll){
			irqenable(ctlr->irq, i8250interrupt, uart, uart->name);
			ctlr->iena = 1;
		}
		ctlr->sticky[Ier] = Erda;
//		ctlr->sticky[Mcr] |= Ie;		/* not on omap */
		ctlr->sticky[Mcr] = 0;
	}
	else{
		ctlr->sticky[Ier] = 0;
		ctlr->sticky[Mcr] = 0;
	}
	csr8w(ctlr, Ier, 0);
	csr8w(ctlr, Mcr, 0);

	(*uart->phys->dtr)(uart, 1);
	(*uart->phys->rts)(uart, 1);

	/*
	 * During startup, the i8259 interrupt controller is reset.
	 * This may result in a lost interrupt from the i8250 uart.
	 * The i8250 thinks the interrupt is still outstanding and does not
	 * generate any further interrupts. The workaround is to call the
	 * interrupt handler to clear any pending interrupt events.
	 * Note: this must be done after setting Ier.
	 */
	if(ie)
		i8250interrupt(nil, uart);
}