📄 devcons.c
字号:
#include "all.h"/* from ../pc/8250.c */extern int uartcons;staticstruct{ Lock; uchar buf[4000]; uchar *in; uchar *out; int printing;} printq;staticstruct{ Lock; Rendez; uchar buf[500]; uchar *in; uchar *out; int reading;} readq;int (*consgetc)(void);void (*consputc)(int);void (*consputs)(char*, int);/* * 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 voidputs(char *s, int n){ 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;}voidprintinit(void){ lock(&printq); /* allocate lock */ printq.in = printq.buf; printq.out = printq.buf; unlock(&printq); lock(&readq); /* allocate lock */ readq.in = readq.buf; readq.out = readq.buf; unlock(&readq); consinit(puts);}/* * 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. */voidputstrn(char *str, int n){ int s, m; char *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; } unlock(&printq); splx(s);}/* * get character to print at interrupt time * always called splhi from proc 0 */intconschar(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; } unlock(&printq); splx(s); return c;}#define ctl(c) ((c) & 037)/* * dispose of input character at interrupt time * always called splhi from proc 0 */voidkbdchar(int c){ int s; uchar *p; uchar ch; char uparrow[2]; if(c == ctl('t')) dotrace(0); s = splhi(); lock(&readq); if(readq.reading) goto out; if(c == ctl('u')) { if(echo) putstrn("^U\n", 3); /* echo */ readq.in = readq.out; goto out; } if(c == '\r') c = '\n'; ch = c; if(echo) /* * cga mode (for example) does a poor job of showing control * chars, so echo them as ^X. this will mess up subsequent * backspace erasures, alas. it also doesn't cope with utf. */ if (ch >= ' ' || ch == '\n' || ch == '\t' || ch == '\b') putstrn((char*)&ch, 1); /* echo */ else { uparrow[0] = '^'; uparrow[1] = ch + '@'; /* ctrl -> upper case */ putstrn(uparrow, 2); } p = readq.in; *p++ = c; if(p >= readq.buf+sizeof(readq.buf)) p = readq.buf; readq.in = p; if(c == '\n' || c == ctl('d')) { readq.reading = 1; wakeup(&readq); }out: unlock(&readq); splx(s);}intrawchar(int seconds){ int c; ulong s; if(seconds != 0) seconds += toytime(); for(;;) { c = (*consgetc)(); if(c) { if(c == '\r') c = '\n'; /* ugh! yet another place that does echoing */ if(c == '\n') { (*consputc)('\r'); delay(10); } (*consputc)(c); return c; } if(seconds) { /* Allow MACHP(0)->ticks to run */ s = spllo(); if(toytime() > seconds) { splx(s); break; } splx(s); } delay(1); } return 0;}intreading(void*){ return readq.reading;}/* * get a character from the console * this is the high level routine with * a queue to the interrupt handler */intgetc(void){ int c, s; uchar *p; c = 0;loop: sleep(&readq, reading, 0); s = splhi(); lock(&readq); p = readq.out; if(readq.in == p) { readq.reading = 0; unlock(&readq); splx(s); goto loop; } if(readq.in != p) { c = *p++; if(p == readq.buf+sizeof(readq.buf)) p = readq.buf; readq.out = p; } unlock(&readq); splx(s); return c;}intprint(char *fmt, ...){ int n; va_list arg; char buf[PRINTSIZE]; va_start(arg, fmt); n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); putstrn(buf, n); return n;}voidpanic(char *fmt, ...){ int n; va_list arg; 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; va_end(arg); buf[n] = '\n'; putstrn(buf, n+1); if(!predawn){ spllo(); prflush(); } exit();}voidprflush(void){ int i; if(predawn || !uartcons) return; for(i=0; i<50; i++) { if(!printq.printing) break; delay(100); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -