summaryrefslogtreecommitdiff
path: root/sys/src/boot
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-02-18 01:22:29 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2013-02-18 01:22:29 +0100
commitc9c06dd8ba2a5ce322a0a25b08c17a892bd75a4f (patch)
treeed87cb34cb8b9c517843ceff8b13502052f79c13 /sys/src/boot
parent364f1f78d4a7893da440e6eb68b905b6d9b9418c (diff)
9boot: serial console support
Diffstat (limited to 'sys/src/boot')
-rw-r--r--sys/src/boot/pc/fns.h13
-rw-r--r--sys/src/boot/pc/l.s22
-rw-r--r--sys/src/boot/pc/mkfile2
-rw-r--r--sys/src/boot/pc/sub.c62
-rw-r--r--sys/src/boot/pc/uart.s35
5 files changed, 103 insertions, 31 deletions
diff --git a/sys/src/boot/pc/fns.h b/sys/src/boot/pc/fns.h
index 760a51250..8409fc421 100644
--- a/sys/src/boot/pc/fns.h
+++ b/sys/src/boot/pc/fns.h
@@ -5,9 +5,8 @@ extern char bootname[];
/* l.s */
void start(void *sp);
-int getc(void);
-int gotc(void);
-void putc(int c);
+void cgaputc(int c);
+int kbdgetc(void);
void usleep(int t);
void halt(void);
void jump(void *pc);
@@ -17,6 +16,9 @@ int readn(void *f, void *data, int len);
void close(void *f);
void unload(void);
+int getc(void);
+void putc(int c);
+
void memset(void *p, int v, int n);
void memmove(void *dst, void *src, int n);
int memcmp(void *src, void *dst, int n);
@@ -36,3 +38,8 @@ ulong e820(ulong bx, void *p);
/* apm.s */
void apm(int id);
+
+/* uart.s */
+void uartinit(int p, int c);
+void uartputc(int p, int c);
+int uartgetc(int p);
diff --git a/sys/src/boot/pc/l.s b/sys/src/boot/pc/l.s
index 3ba560a6e..b7f925ae9 100644
--- a/sys/src/boot/pc/l.s
+++ b/sys/src/boot/pc/l.s
@@ -121,26 +121,20 @@ TEXT halt(SB), $0
_halt:
JMP _halt
-TEXT getc(SB), $0
- CALL rmode16(SB)
- STI
- MOVB $0x00, AH
- BIOSCALL(0x16)
-_getcret:
- CALL16(pmode32(SB))
- ANDL $0xFF, AX
- RET
-
-TEXT gotc(SB), $0
+TEXT kbdgetc(SB), $0
CALL rmode16(SB)
STI
MOVB $0x01, AH
BIOSCALL(0x16)
- JNZ _getcret
+ JNZ _gotkey
+ CLR(rAX)
+ JMP _pret32
+_gotkey:
CLR(rAX)
- JMP _getcret
+ BIOSCALL(0x16)
+ JMP _pret32
-TEXT putc(SB), $0
+TEXT cgaputc(SB), $0
MOVL 4(SP),AX
CALL rmode16(SB)
STI
diff --git a/sys/src/boot/pc/mkfile b/sys/src/boot/pc/mkfile
index 3ef82e159..1fbc90223 100644
--- a/sys/src/boot/pc/mkfile
+++ b/sys/src/boot/pc/mkfile
@@ -36,7 +36,7 @@ pbs: pbs.$O
$LD -o $target -H3 -T0x0800 -l $prereq
ls -l $target
-9boot&: l%.$O %.$O sub.$O apm.$O e820.$O a20.$O
+9boot&: l%.$O %.$O sub.$O apm.$O e820.$O a20.$O uart.$O
$LD -o $target -H3 -T0x7c00 -l $prereq
ls -l $target
diff --git a/sys/src/boot/pc/sub.c b/sys/src/boot/pc/sub.c
index 2fda72da8..f1b931cc2 100644
--- a/sys/src/boot/pc/sub.c
+++ b/sys/src/boot/pc/sub.c
@@ -3,6 +3,37 @@
#include "fns.h"
#include "mem.h"
+int uart = -1;
+
+void
+putc(int c)
+{
+ cgaputc(c);
+ if(uart != -1)
+ uartputc(uart, c);
+}
+
+void
+print(char *s)
+{
+ while(*s != 0){
+ if(*s == '\n')
+ putc('\r');
+ putc(*s++);
+ }
+}
+
+int
+getc(void)
+{
+ int c;
+
+ c = kbdgetc();
+ if(c == 0 && uart != -1)
+ c = uartgetc(uart);
+ return c & 0x7f;
+}
+
void
memset(void *dst, int v, int n)
{
@@ -68,16 +99,6 @@ strchr(char *s, int c)
return nil;
}
-void
-print(char *s)
-{
- while(*s != 0){
- if(*s == '\n')
- putc('\r');
- putc(*s++);
- }
-}
-
int
readn(void *f, void *data, int len)
{
@@ -112,7 +133,9 @@ readline(void *f, char buf[64])
putc('>');
for(;;){
if(f == nil){
- putc(*p = getc());
+ while((*p = getc()) == 0)
+ ;
+ putc(*p);
if(*p == '\r')
putc('\n');
else if(*p == '\b' && p > buf){
@@ -147,7 +170,7 @@ static int
timeout(int ms)
{
while(ms > 0){
- if(gotc())
+ if(getc() != 0)
return 1;
usleep(100000);
ms -= 100;
@@ -164,6 +187,7 @@ char *confend;
static void apmconf(int);
static void e820conf(void);
+static void uartconf(char*);
static char*
getconf(char *s, char *buf)
@@ -261,9 +285,11 @@ Loop:
*p++ = 0;
delconf(line);
if(memcmp("apm", line, 3) == 0){
- apmconf('0' - line[3]);
+ apmconf(line[3] - '0');
continue;
}
+ if(memcmp("console", line, 8) == 0)
+ uartconf(p);
s = confend;
memmove(confend, line, n = strlen(line)); confend += n;
@@ -392,6 +418,16 @@ e820conf(void)
print(s);
}
+static void
+uartconf(char *s)
+{
+ if(*s >= '0' && *s <= '3'){
+ uart = *s - '0';
+ uartinit(uart, (7<<5) | 3); /* b9660 l8 s1 */
+ } else
+ uart = -1;
+}
+
static ulong
beswal(ulong l)
{
diff --git a/sys/src/boot/pc/uart.s b/sys/src/boot/pc/uart.s
new file mode 100644
index 000000000..ac69b0add
--- /dev/null
+++ b/sys/src/boot/pc/uart.s
@@ -0,0 +1,35 @@
+#include "x16.h"
+
+TEXT uartinit(SB), $0
+ MOVL c+8(SP), AX
+ MOVB $0x00, AH
+ JMP _uartbios
+
+TEXT uartputc(SB), $0
+ MOVL c+8(SP), AX
+ MOVB $0x01, AH
+ JMP _uartbios
+
+TEXT uartgetc(SB), $0
+ MOVL p+4(SP), DX
+ CALL rmode16(SB)
+ STI
+ MOVB $0x03, AH
+ BIOSCALL(0x14)
+ CALL16(pmode32(SB))
+ ANDL $0x8100, AX
+ MOVL $0x0100, BX
+ CMPL BX, AX
+ JE _uartread
+ XORL AX, AX
+ RET
+_uartread:
+ MOVB $0x02, AH
+_uartbios:
+ MOVL p+4(SP), DX
+ CALL rmode16(SB)
+ STI
+ BIOSCALL(0x14)
+ CALL16(pmode32(SB))
+ ANDL $0xFF, AX
+ RET