#include "u.h"#include "lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h" IOQ consiq;IOQ consoq; static int useuart; int debug = 0; voidkbdchar(int c){ c &= 0x7F; if(c == 0x10) warp86("\n^P\n", 0); if(c == 0x12) /* control-r? */ debug = !debug; consiq.putc(&consiq, c);} static intconsputc(void){ return consoq.getc(&consoq);} voidkbdinit(void){ i8042init(); qinit(&consiq);} voidconsinit(char* name){ char *p; int baud, port; if(name == nil || *name == 0 || cistrcmp(name, "cga") == 0) return; port = strtoul(name, &p, 0); if(port < 0 || port > 1) return; baud = 0; while(p = strchr(p, 'b')){ if(p > name && p[-1] != ' ' && p[-1] != '\t') continue; baud = strtoul(p + 1, &p, 0); break; } if(baud == 0) baud = 9600; qinit(&consoq); uartspecial(port, kbdchar, consputc, baud); useuart = 1; uartputs(&consoq, "\n", 1);} voidconsdrain(void){ if(useuart == 0) return; while(consoq.in != consoq.out){ if(uartdrain() == -1) break; uartputs(&consoq, 0, 0); }} voidconsputs(char* s, int n){ cgascreenputs(s, n); if(useuart) uartputs(&consoq, s, n);} voidwarp86(char* s, ulong){ if(s != nil) print(s); spllo(); consdrain(); i8042reset(); /* * Often the BIOS hangs during restart if a conventional 8042 * warm-boot sequence is tried. The following is Intel specific and * seems to perform a cold-boot, but at least it comes back. * And sometimes there is no keyboard... * * The reset register (0xcf9) is usually in one of the bridge * chips. The actual location and sequence could be extracted from * ACPI but why bother, this is the end of the line anyway. */ print("Takes a licking and keeps on ticking...\n"); *(ushort*)KADDR(0x472) = 0x1234; /* BIOS warm-boot flag */ outb(0xcf9, 0x02); outb(0xcf9, 0x06); for(;;) idle();} static intgetline(char *buf, int size, int timeout){ int c, i=0; ulong start; char echo; for (;;) { start = m->ticks; do{ /* timeout seconds to first char */ if(timeout && ((m->ticks - start) > timeout*HZ)) return -2; c = consiq.getc(&consiq); }while(c == -1); timeout = 0; if(c == '\r') c = '\n'; /* turn carriage return into newline */ if(c == '\177') c = '\010'; /* turn delete into backspace */ if(c == '\025') echo = '\n'; /* echo ^U as a newline */ else echo = c; consputs(&echo, 1); if(c == '\010'){ if(i > 0) i--; /* bs deletes last character */ continue; } /* a newline ends a line */ if (c == '\n') break; /* ^U wipes out the line */ if (c =='\025') return -1; if(i == size) return size; buf[i++] = c; } buf[i] = 0; return i;} intgetstr(char *prompt, char *buf, int size, char *def, int timeout){ int len, isdefault; char pbuf[PRINTSIZE]; buf[0] = 0; isdefault = (def && *def); if(isdefault == 0){ timeout = 0; sprint(pbuf, "%s: ", prompt); } else if(timeout) sprint(pbuf, "%s[default==%s (%ds timeout)]: ", prompt, def, timeout); else sprint(pbuf, "%s[default==%s]: ", prompt, def); for (;;) { print(pbuf); len = getline(buf, size, timeout); switch(len){ case 0: /* RETURN */ if(isdefault) break; continue; case -1: /* ^U typed */ continue; case -2: /* timeout, use default */ consputs("\n", 1); len = 0; break; default: break; } if(len >= size){ print("line too long\n"); continue; } if(strcmp(buf, "pcihinv") == 0){ pcihinv(nil); continue; } break; } if(len == 0 && isdefault) strcpy(buf, def); return 0;} 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); consputs(buf, n); return n;} voidpanic(char *fmt, ...){ int n; va_list arg; char buf[PRINTSIZE]; strcpy(buf, "panic: "); va_start(arg, fmt); n = vseprint(buf+7, buf+sizeof(buf), fmt, arg) - buf; va_end(arg); buf[n] = '\n'; consputs(buf, n+1); //floppymemwrite();//splhi(); for(;;);// if(etherdetach)// etherdetach();// if(sddetach)// sddetach(); consputs("\nPress almost any key to reset...", 32); spllo(); while(consiq.getc(&consiq) == -1) ; warp86(nil, 0);}
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
IOQ consiq;
IOQ consoq;
static int useuart;
int debug = 0;
void
kbdchar(int c)
{
c &= 0x7F;
if(c == 0x10)
warp86("\n^P\n", 0);
if(c == 0x12) /* control-r? */
debug = !debug;
consiq.putc(&consiq, c);
}
static int
consputc(void)
{
return consoq.getc(&consoq);
}
void
kbdinit(void)
{
i8042init();
qinit(&consiq);
}
void
consinit(char* name)
{
char *p;
int baud, port;
if(name == nil || *name == 0 || cistrcmp(name, "cga") == 0)
return;
port = strtoul(name, &p, 0);
if(port < 0 || port > 1)
return;
baud = 0;
while(p = strchr(p, 'b')){
if(p > name && p[-1] != ' ' && p[-1] != '\t')
continue;
baud = strtoul(p + 1, &p, 0);
break;
}
if(baud == 0)
baud = 9600;
qinit(&consoq);
uartspecial(port, kbdchar, consputc, baud);
useuart = 1;
uartputs(&consoq, "\n", 1);
}
void
consdrain(void)
{
if(useuart == 0)
return;
while(consoq.in != consoq.out){
if(uartdrain() == -1)
break;
uartputs(&consoq, 0, 0);
}
}
void
consputs(char* s, int n)
{
cgascreenputs(s, n);
if(useuart)
uartputs(&consoq, s, n);
}
void
warp86(char* s, ulong)
{
if(s != nil)
print(s);
spllo();
consdrain();
i8042reset();
/*
* Often the BIOS hangs during restart if a conventional 8042
* warm-boot sequence is tried. The following is Intel specific and
* seems to perform a cold-boot, but at least it comes back.
* And sometimes there is no keyboard...
*
* The reset register (0xcf9) is usually in one of the bridge
* chips. The actual location and sequence could be extracted from
* ACPI but why bother, this is the end of the line anyway.
*/
print("Takes a licking and keeps on ticking...\n");
*(ushort*)KADDR(0x472) = 0x1234; /* BIOS warm-boot flag */
outb(0xcf9, 0x02);
outb(0xcf9, 0x06);
for(;;)
idle();
}
static int
getline(char *buf, int size, int timeout)
{
int c, i=0;
ulong start;
char echo;
for (;;) {
start = m->ticks;
do{
/* timeout seconds to first char */
if(timeout && ((m->ticks - start) > timeout*HZ))
return -2;
c = consiq.getc(&consiq);
}while(c == -1);
timeout = 0;
if(c == '\r')
c = '\n'; /* turn carriage return into newline */
if(c == '\177')
c = '\010'; /* turn delete into backspace */
if(c == '\025')
echo = '\n'; /* echo ^U as a newline */
else
echo = c;
consputs(&echo, 1);
if(c == '\010'){
if(i > 0)
i--; /* bs deletes last character */
continue;
}
/* a newline ends a line */
if (c == '\n')
break;
/* ^U wipes out the line */
if (c =='\025')
return -1;
if(i == size)
return size;
buf[i++] = c;
}
buf[i] = 0;
return i;
}
int
getstr(char *prompt, char *buf, int size, char *def, int timeout)
{
int len, isdefault;
char pbuf[PRINTSIZE];
buf[0] = 0;
isdefault = (def && *def);
if(isdefault == 0){
timeout = 0;
sprint(pbuf, "%s: ", prompt);
}
else if(timeout)
sprint(pbuf, "%s[default==%s (%ds timeout)]: ", prompt, def, timeout);
else
sprint(pbuf, "%s[default==%s]: ", prompt, def);
for (;;) {
print(pbuf);
len = getline(buf, size, timeout);
switch(len){
case 0:
/* RETURN */
if(isdefault)
break;
continue;
case -1:
/* ^U typed */
continue;
case -2:
/* timeout, use default */
consputs("\n", 1);
len = 0;
break;
default:
break;
}
if(len >= size){
print("line too long\n");
continue;
}
if(strcmp(buf, "pcihinv") == 0){
pcihinv(nil);
continue;
}
break;
}
if(len == 0 && isdefault)
strcpy(buf, def);
return 0;
}
int
print(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);
consputs(buf, n);
return n;
}
void
panic(char *fmt, ...)
{
int n;
va_list arg;
char buf[PRINTSIZE];
strcpy(buf, "panic: ");
va_start(arg, fmt);
n = vseprint(buf+7, buf+sizeof(buf), fmt, arg) - buf;
va_end(arg);
buf[n] = '\n';
consputs(buf, n+1);
//floppymemwrite();
//splhi(); for(;;);
// if(etherdetach)
// etherdetach();
// if(sddetach)
// sddetach();
consputs("\nPress almost any key to reset...", 32);
spllo();
while(consiq.getc(&consiq) == -1)
;
warp86(nil, 0);
}