ref: ef1061c6c6123570d90899426953b850d7167758
parent: b6edae9552d2c802fbb1d9b9a6af0de2ee6bf1f9
author: 9ferno <gophone2015@gmail.com>
date: Sun Aug 8 14:23:04 EDT 2021
working uart after import from 9front
--- a/os/pc/uarti8250.c
+++ b/os/pc/uarti8250.c
@@ -158,7 +158,7 @@
uchar ier, lcr, mcr, msr;
ctlr = uart->regs;
- p = malloc(READSTR);
+ p = smalloc(READSTR);
mcr = ctlr->sticky[Mcr];
msr = csr8r(ctlr, Msr);
ier = ctlr->sticky[Ier];
@@ -435,25 +435,28 @@
static void
i8250kick(Uart* uart)
{
- int i;
+ int i, n;
Ctlr *ctlr;
- if(uart->cts == 0 || uart->blocked)
+ if(uart->cts == 0 || uart->blocked )
return;
/*
- * 128 here is an arbitrary limit to make sure
+ * Stagesize here imposes 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
+ * chip's output queue is longer than Stagesize, too
+ * bad, performance will be slower.
+ * Stagesize = 1024
*/
ctlr = uart->regs;
- for(i = 0; i < 128; i++){
+ if(!(csr8r(ctlr, Lsr) & Thre))
+ return;
+ for(n = uartstageoutput(uart); n > 0; n--, uart->op++){
if(!(csr8r(ctlr, Lsr) & Thre))
break;
- if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
+ if(uart->op >= uart->oe)
break;
- outb(ctlr->io+Thr, *(uart->op++));
+ outb(ctlr->io+Thr, *uart->op);
}
}
@@ -542,8 +545,8 @@
csr8w(ctlr, Ier, ctlr->sticky[Ier]);
if(ctlr->iena != 0){
- if(intrdisable(ctlr->irq, i8250interrupt, uart, ctlr->tbdf, uart->name) == 0)
- ctlr->iena = 0;
+ ctlr->iena = 0;
+ intrdisable(ctlr->irq, i8250interrupt, uart, ctlr->tbdf, uart->name);
}
}
@@ -563,7 +566,7 @@
* the transmitter is really empty.
* Also, reading the Iir outwith i8250interrupt()
* can be dangerous, but this should only happen
- * once, before interrupts are enabled.
+ * once before interrupts are enabled.
*/
ilock(ctlr);
if(!ctlr->checkfifo){
@@ -621,12 +624,14 @@
{
Ctlr *ctlr;
- if((ctlr = malloc(sizeof(Ctlr))) != nil){
- ctlr->io = io;
- ctlr->irq = irq;
- ctlr->tbdf = tbdf;
+ ctlr = malloc(sizeof(Ctlr));
+ if(ctlr == nil){
+ print("i8250alloc: no memory for Ctlr\n");
+ return nil;
}
-
+ ctlr->io = io;
+ ctlr->irq = irq;
+ ctlr->tbdf = tbdf;
return ctlr;
}
@@ -691,18 +696,9 @@
if((p = getconf("console")) == nil)
return;
n = strtoul(p, &cmd, 0);
- if(p == cmd)
+ if(p == cmd || n < 0 || n >= nelem(i8250uart))
return;
- switch(n){
- default:
- return;
- case 0:
- uart = &i8250uart[0];
- break;
- case 1:
- uart = &i8250uart[1];
- break;
- }
+ uart = &i8250uart[n];
(*uart->phys->enable)(uart, 0);
uartctl(uart, "b9600 l8 pn s1");
@@ -712,29 +708,3 @@
consuart = uart;
uart->console = 1;
}
-/* TODO these are not in 9front
-void
-i8250mouse(char* which, int (*putc)(Queue*, int), int setb1200)
-{
- char *p;
- int port;
-
- port = strtol(which, &p, 0);
- if(p == which || port < 0 || port > 1)
- error(Ebadarg);
- uartmouse(&i8250uart[port], putc, setb1200);
-}
-
-void
-i8250setmouseputc(char* which, int (*putc)(Queue*, int))
-{
- char *p;
- int port;
-
- port = strtol(which, &p, 0);
- if(p == which || port < 0 || port > 1)
- error(Ebadarg);
- uartsetmouseputc(&i8250uart[port], putc);
-
-}
-*/
--- a/os/port/devuart.c
+++ b/os/port/devuart.c
@@ -628,9 +628,12 @@
{
int n;
+ if(p->op < p->oe)
+ return p->oe - p->op;
n = qconsume(p->oq, p->ostage, Stagesize);
- if(n <= 0)
+ if(n <= 0){
return 0;
+ }
p->op = p->ostage;
p->oe = p->ostage + n;
return n;