move to a new process-based console that's much friendlier to multiprocessors. additionally, fill out sys->machptr[0]. Reference: /n/atom/patch/applied2013/fsmpcons Date: Tue Aug 27 16:07:52 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/fs/pc/pc.c Tue Aug 27 16:06:43 2013 +++ /sys/src/fs/pc/pc.c Tue Aug 27 16:06:43 2013 @@ -337,11 +337,8 @@ ready(p); } -static int useuart; -static void (*intrputs)(char*, int); - -static int -pcgetc(void) +int +consgetc(void) { int c; @@ -349,44 +346,56 @@ return c; if(c = cecgetc()) return c; - if(useuart) - return uartgetc(); - return 0; + return uartgetc(); } -static void -pcputc(int c) +void +consputs(char* s, int n) { - if(predawn) - cgaputc(c); - if(useuart) - uartputc(c); + cgaputs(s, n); + cecputs(s, n); + uartputs(s, n); } -static void -pcputs(char* s, int n) +/* remove this crunchy junk */ +void +wave(int c) +{ + outb(0x3F8+0, c); + while((inb(0x3F8+5) & 1<<5) == 0) + ; +} + +void +waveprint(char *fmt, ...) { - if(!predawn){ - cgaputs(s, n); - cecputs(s, n); + int i; + static Lock lk; + + va_list arg; + char buf[PRINTSIZE]; + + va_start(arg, fmt); + vseprint(buf, buf+sizeof buf, fmt, arg); + va_end(arg); + + ilock(&lk); + for(i = 0; buf[i] != 0; i++){ + wave(buf[i]); + cgaputc(buf[i]); + microdelay(100); } - if(intrputs) - (*intrputs)(s, n); + iunlock(&lk); } void -consinit(void (*puts)(char*, int)) +consinit(void) { char *p; int baud, port; kbdinit(); - consgetc = pcgetc; - consputc = pcputc; - consputs = pcputs; - intrputs = puts; - if((p = getconf("console")) == 0 || cistrcmp(p, "cga") == 0) return; @@ -398,8 +407,8 @@ if(*p != 'b' || (baud = strtoul(p+1, 0, 0)) == 0) baud = 9600; - uartspecial(port, kbdchar, conschar, baud); - useuart = 1; + uartspecial(port, kbdchar, nil, baud); + conf.useuart = 1; } void @@ -508,3 +517,8 @@ return a / b; } */ + +void +archmach0init(Mach*) +{ +} --- /sys/src/fs/pc/8250.c Tue Aug 27 16:06:44 2013 +++ /sys/src/fs/pc/8250.c Tue Aug 27 16:06:45 2013 @@ -314,12 +314,12 @@ } void -uartputs(char *s) +uartputs(char *s, int n) { - int c; + int i; - while(c = *s++) - uartputc(c); + for(i = 0; i < n; i++) + uartputc(s[i]); } void --- /sys/src/fs/pc/fns.h Tue Aug 27 16:06:46 2013 +++ /sys/src/fs/pc/fns.h Tue Aug 27 16:06:46 2013 @@ -59,9 +59,10 @@ void trapinit(void); int uartgetc(void); void uartputc(int); -void uartputs(char*); +void uartputs(char*, int); void uartspecial(int, void (*)(int), int (*)(void), int); void* vmap(ulong, int); +void waveprint(char*, ...); void wrmsr(int, vlong); #define PTR2UINT(p) ((uintptr)(p)) --- /sys/src/fs/port/portfns.h Tue Aug 27 16:06:47 2013 +++ /sys/src/fs/port/portfns.h Tue Aug 27 16:06:48 2013 @@ -2,6 +2,7 @@ void addfree(Device*, Off, Superb*); void arpstart(void); void apcinit(void); +void archmach0init(Mach*); void arginit(void); void _assert(char*); void atexit(void (*)(void*), void*); @@ -45,13 +46,11 @@ void devcopyproc(void); Device* devstr(char*); void dotrace(int); -int conschar(void); -void consinit(void (*)(char*, int)); +void consinit(void); void consreset(void); void consstart(int); -int (*consgetc)(void); -void (*consputc)(int); -void (*consputs)(char*, int); +int consgetc(void); +void consputs(char*, int); void consserve(void); int conslock(void); int con_attach(int, char*, char*); --- /sys/src/fs/port/portdat.h Tue Aug 27 16:06:49 2013 +++ /sys/src/fs/port/portdat.h Tue Aug 27 16:06:50 2013 @@ -529,6 +529,7 @@ uchar idedma; /* flag: use DMA on IDE disks? */ uchar fastworm; /* flag: don't cache cw reads in c device */ uint uartonly; /* botch? work around soekris with no vga. */ + uint useuart; }; /* --- /sys/src/fs/port/main.c Tue Aug 27 16:06:51 2013 +++ /sys/src/fs/port/main.c Tue Aug 27 16:06:52 2013 @@ -18,6 +18,9 @@ active.exiting = 0; active.machs = 1; + + sys->machptr[m->machno] = m; + archmach0init(m); } static void @@ -58,6 +61,7 @@ { int i; + memset(edata, 0, end - edata); echo = 1; predawn = 1; lockinit(); @@ -66,10 +70,9 @@ cpuidentify(); vecinit(); confinit(); - if(conf.uartonly) - uartspecial(0, kbdchar, conschar, conf.uartonly); - printinit(); procinit(); + consinit(); + printinit(); clockinit(); print("Plan 9 fileserver\n"); --- /sys/src/fs/port/devcons.c Tue Aug 27 16:06:52 2013 +++ /sys/src/fs/port/devcons.c Tue Aug 27 16:06:53 2013 @@ -7,10 +7,11 @@ struct { Lock; - uchar buf[4000]; - uchar *in; - uchar *out; - int printing; + Rendez; + uchar buf[2000]; + uint n; + uint seq; + uint init; } printq; static @@ -24,112 +25,77 @@ int reading; } readq; -int (*consgetc)(void); -void (*consputc)(int); -void (*consputs)(char*, int); +static int early = 1; -/* - * Put a string on the console. - * n bytes of s are guaranteed to fit in the buffer and is ready to print. - * Must be called splhi() and with printq locked. - * If early in booting (predawn) poll output. - * This is the interrupt driven routine used for non- screen-based systems. - */ -static void -puts(char *s, int n) +int +printable(void*) { + return printq.n != 0; +} - if(predawn) { - while(n > 0) { - (*consputc)(*s++ & 0xFF); - delay(5); - n--; - } - return; - } - if(!printq.printing){ - printq.printing = 1; - consstart(*s++ & 0xFF); - n--; - } - memmove(printq.in, s, n); - printq.in += n; - if(printq.in >= printq.buf+sizeof(printq.buf)) - printq.in = printq.buf; +void +printproc(void) +{ + char buf[sizeof printq.buf]; + int n; + +loop: + sleep(&printq, printable, 0); + + ilock(&printq); + n = printq.n; + memmove(buf, printq.buf, n); + printq.n = 0; + iunlock(&printq); + + if(n > 0) + consputs(buf, n); + + ilock(&printq); + printq.seq++; + iunlock(&printq); + + goto loop; } void printinit(void) { - lock(&printq); /* allocate lock */ - printq.in = printq.buf; - printq.out = printq.buf; - unlock(&printq); + ilock(&printq); /* allocate lock */ + iunlock(&printq); lock(&readq); /* allocate lock */ readq.in = readq.buf; readq.out = readq.buf; unlock(&readq); - consinit(puts); + userinit(printproc, nil, "print"); + early = 0; } /* - * Print a string on the console. This is the high level routine - * with a queue to the interrupt handler. BUG: There is no check against - * overflow. + * Print a string on the console. */ void -putstrn(char *str, int n) +putstrn(char *s, int n) { - int s, m; - char *t; + uint t; - s = splhi(); - lock(&printq); - while(n > 0){ - if(*str == '\n') - (*consputs)("\r", 1); - m = printq.buf+sizeof(printq.buf) - printq.in; - if(n < m) - m = n; - t = memchr(str+1, '\n', m-1); - if(t) - if(t-str < m) - m = t - str; - (*consputs)(str, m); - n -= m; - str += m; + if(early || predawn){ + waveprint("%.*s", n, s); + return; } - unlock(&printq); - splx(s); -} -/* - * get character to print at interrupt time - * always called splhi from proc 0 - */ -int -conschar(void) -{ - uchar *p; - int c, s; - - s = splhi(); - lock(&printq); - p = printq.out; - if(p == printq.in) { - printq.printing = 0; - c = -1; - } else { - c = *p++; - if(p >= printq.buf+sizeof(printq.buf)) - p = printq.buf; - printq.out = p; + ilock(&printq); + for(t = printq.n; t != nelem(printq.buf); t++){ + if(n-- == 0) + break; + printq.buf[t] = *s++; } - unlock(&printq); - splx(s); - return c; + printq.n = t; + iunlock(&printq); + + wakeup(&printq); } /* @@ -142,7 +108,6 @@ void kbdchar(int c) { - int s; uchar *p; uchar ch; @@ -159,8 +124,7 @@ return; } - s = splhi(); - lock(&readq); + ilock(&readq); if(readq.reading) goto out; if(c == Ctl('U')){ @@ -184,15 +148,14 @@ wakeup(&readq); } out: - unlock(&readq); - splx(s); + iunlock(&readq); } int rawchar(int seconds) { int c; - ulong s; + Mpl s; if(seconds != 0) seconds += toytime(); @@ -201,16 +164,14 @@ c = consgetc(); if(c) { if(c == '\r') - c = '\n'; - if(c == '\n') { - consputc('\r'); + continue; + if(c == '\n') delay(10); - } - consputc(c); + putstrn((char*)&c, 1); return c; } if(seconds) { - /* Allow MACHP(0)->ticks to run */ + /* Allow Ticks to run */ s = spllo(); if(toytime() > seconds) { splx(s); @@ -238,20 +199,18 @@ int getc(void) { - int c, s; + int c; uchar *p; c = 0; loop: sleep(&readq, reading, 0); - s = splhi(); - lock(&readq); + ilock(&readq); p = readq.out; if(readq.in == p) { readq.reading = 0; - unlock(&readq); - splx(s); + iunlock(&readq); goto loop; } if(readq.in != p) { @@ -260,8 +219,7 @@ p = readq.buf; readq.out = p; } - unlock(&readq); - splx(s); + iunlock(&readq); return c; } @@ -275,11 +233,8 @@ va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); - if(predawn && conf.uartonly){ - for(int i = 0; i < n; i++) - uartputc(buf[i]); - }else - putstrn(buf, n); + + putstrn(buf, n); /* consputs() doesn't hang */ return n; } @@ -291,9 +246,6 @@ char buf[PRINTSIZE]; lights(Lpanic, 1); - /* if the only console is vga, conserve it */ - if(uartcons) - dumpstack(u); strcpy(buf, "panic: "); va_start(arg, fmt); n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf; @@ -304,19 +256,28 @@ spllo(); prflush(); } + /* if the only console is vga, conserve it */ + if(uartcons) + dumpstack(u); exit(); } void prflush(void) { - int i; + int i, lo; - if(predawn || !uartcons) + if(predawn) return; - for(i=0; i<50; i++) { - if(!printq.printing) - break; - delay(100); - } + + ilock(&printq); + i = printq.seq; + iunlock(&printq); + + lo = islo(); + while(printq.n != 0 && i == printq.seq) + if(lo) + sched(); + else + delay(100); /* dangerous */ }