Add serial, dual, and probe-keyboard support.

This commit is contained in:
rnordier 1998-10-15 20:04:21 +00:00
parent a0e096d460
commit 0b71e4f0b7
7 changed files with 338 additions and 50 deletions

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.4 1998/10/14 00:24:16 rnordier Exp $
# $Id: Makefile,v 1.5 1998/10/14 01:53:56 rnordier Exp $
PROG= boot2
NOMAN=
@ -6,7 +6,8 @@ STRIP=
BINDIR?= /boot
BINMODE= 444
CLEANFILES+= boot1 boot1.out boot1.o \
boot2.ldr boot2.bin boot2.ld boot2.out boot2.o
boot2.ldr boot2.bin boot2.ld boot2.out boot2.o \
sio.o
M4?= m4
@ -52,9 +53,12 @@ boot2.ldr:
boot2.bin: boot2.out
objcopy -S -O binary boot2.out ${.TARGET}
boot2.out: boot2.o
boot2.out: boot2.o sio.o
${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} \
${BTX}/lib/crt0.o boot2.o
${BTX}/lib/crt0.o boot2.o sio.o
sio.o: sio.s
${AS} ${AFLAGS} -o ${.TARGET} sio.s
install:
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \

View File

@ -14,7 +14,7 @@
*/
/*
* $Id: boot2.c,v 1.5 1998/10/13 23:00:47 rnordier Exp $
* $Id: boot2.c,v 1.6 1998/10/13 23:43:38 rnordier Exp $
*/
#include <sys/param.h>
@ -34,14 +34,21 @@
#include <btxv86.h>
#include "lib.h"
#define RBX_ASKNAME 0x0 /* -a */
#define RBX_SINGLE 0x1 /* -s */
#define RBX_DFLTROOT 0x5 /* -r */
#define RBX_KDB 0x6 /* -d */
#define RBX_CONFIG 0xa /* -c */
#define RBX_VERBOSE 0xb /* -v */
#define RBX_SERIAL 0xc /* -h */
#define RBX_CDROM 0xd /* -C */
#define RBX_GDB 0xf /* -g */
#define RBX_DUAL 0x1d /* -D */
#define RBX_PROBEKBD 0x1e /* -P */
#define RBX_MASK 0xffff
#define PATH_CONFIG "/boot.config"
#define PATH_BOOT3 "/boot/loader"
@ -49,7 +56,8 @@
#define PATH_HELP "boot.help"
#define ARGS 0x800
#define NOPT 8
#define NOPT 11
#define XOPT 2
#define BSIZEMAX 8192
#define NDEV 5
#define MEM_BASE 0x12
@ -67,13 +75,16 @@
extern uint32_t _end;
static const char optstr[NOPT] = "aCcdgrsv";
static const char optstr[NOPT] = "DhaCcdgPrsv";
static const unsigned char flags[NOPT] = {
RBX_DUAL,
RBX_SERIAL,
RBX_ASKNAME,
RBX_CDROM,
RBX_CONFIG,
RBX_KDB,
RBX_GDB,
RBX_PROBEKBD,
RBX_DFLTROOT,
RBX_SINGLE,
RBX_VERBOSE
@ -98,6 +109,7 @@ static uint32_t opts;
static struct bootinfo bootinfo;
static int ls;
static uint32_t fs_off;
static uint8_t ioctrl = 0x1;
void exit(int);
static void load(const char *);
@ -119,8 +131,10 @@ static uint32_t memsize(int);
static uint32_t drvinfo(int);
static int drvread(void *, unsigned, unsigned);
static int keyhit(unsigned);
static int putch(int);
static int getch(void);
static int xputc(int);
static int xgetc(int);
static void putc(int);
static int getc(int);
int
main(void)
@ -163,6 +177,8 @@ main(void)
"boot: ",
dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
'a' + dsk.part, kname, helpon ? help : "");
if (ioctrl & 0x2)
sio_flush();
if (!autoboot || keyhit(0x5a))
getstr(cmd, sizeof(cmd));
autoboot = helpon = 0;
@ -279,7 +295,7 @@ load(const char *fname)
bootinfo.bi_esymtab = VTOP(p);
printf("]\nentry=0x%x\n", addr);
bootinfo.bi_kernelname = VTOP(fname);
__exec((caddr_t)addr, RB_BOOTINFO | opts,
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
MAKEBOOTDEV(dsk.type, 0, dsk.slice, dsk.unit, dsk.part),
0, 0, 0, VTOP(&bootinfo));
}
@ -296,14 +312,27 @@ parse(char *arg)
for (p = arg; *p && *p != '\n' && *p != ' '; p++);
if (*p)
*p++ = 0;
if (c == '-')
if (c == '-') {
while ((c = *arg++)) {
for (i = 0; c != optstr[i]; i++)
if (i == NOPT - 1)
return -1;
opts |= 1 << flags[i];
if (i < XOPT)
opts ^= 1 << flags[i];
else
opts |= 1 << flags[i];
}
else {
if (opts & 1 << RBX_PROBEKBD) {
i = *(uint8_t *)PTOV(0x496) & 0x10;
printf("Keyboard: %s\n", i ? "yes" : "no");
if (!i)
opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL;
}
ioctrl = opts & 1 << RBX_DUAL ? 0x3 :
opts & 1 << RBX_SERIAL ? 0x2 : 0x1;
if (ioctrl & 0x2)
sio_init();
} else {
for (q = arg--; *q && *q != '('; q++);
if (*q) {
drv = -1;
@ -634,8 +663,8 @@ static int
putchar(int c)
{
if (c == '\n')
putch('\r');
return putch(c);
xputc('\r');
return xputc(c);
}
static int
@ -643,7 +672,7 @@ getchar(void)
{
int c;
c = getch();
c = xgetc(0);
if (c == '\r')
c = '\n';
return c;
@ -731,10 +760,7 @@ keyhit(unsigned ticks)
t0 = 0;
for (;;) {
v86.addr = 0x16;
v86.eax = 0x100;
v86int();
if (!V86_ZR(v86.efl))
if (xgetc(1))
return 1;
t1 = *(uint32_t *)PTOV(0x46c);
if (!t0)
@ -745,20 +771,42 @@ keyhit(unsigned ticks)
}
static int
putch(int c)
xputc(int c)
{
if (ioctrl & 0x1)
putc(c);
if (ioctrl & 0x2)
sio_putc(c);
return c;
}
static int
xgetc(int fn)
{
for (;;) {
if (ioctrl & 0x1 && getc(1))
return fn ? 1 : getc(0);
if (ioctrl & 0x2 && sio_ischar())
return fn ? 1 : sio_getc();
if (fn)
return 0;
}
}
static void
putc(int c)
{
v86.addr = 0x10;
v86.eax = 0xe00 | (c & 0xff);
v86.ebx = 0x7;
v86int();
return c;
}
static int
getch(void)
getc(int fn)
{
v86.addr = 0x16;
v86.eax = 0;
v86.eax = fn << 8;
v86int();
return v86.eax & 0xff;
return fn == 0 ? v86.eax & 0xff : !V86_ZR(v86.efl);
}

24
sys/boot/i386/boot2/lib.h Normal file
View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 1998 Robert Nordier
* All rights reserved.
*
* Redistribution and use in source and binary forms are freely
* permitted provided that the above copyright notice and this
* paragraph and the following disclaimer are duplicated in all
* such forms.
*
* This software is provided "AS IS" and without any express or
* implied warranties, including, without limitation, the implied
* warranties of merchantability and fitness for a particular
* purpose.
*/
/*
* $Id:$
*/
void sio_init(void);
void sio_flush(void);
void sio_putc(int);
int sio_getc(void);
int sio_ischar(void);

80
sys/boot/i386/boot2/sio.S Normal file
View File

@ -0,0 +1,80 @@
#
# Copyright (c) 1998 Robert Nordier
# All rights reserved.
#
# Redistribution and use in source and binary forms are freely
# permitted provided that the above copyright notice and this
# paragraph and the following disclaimer are duplicated in all
# such forms.
#
# This software is provided "AS IS" and without any express or
# implied warranties, including, without limitation, the implied
# warranties of merchantability and fitness for a particular
# purpose.
#
# $Id:$
.set SIO_PRT,0x3f8 # Base port
.set SIO_FMT,0x3 # 8N1
.set SIO_DIV,0xc # 115200 / 9600
.globl sio_init
.globl sio_flush
.globl sio_putc
.globl sio_getc
.globl sio_ischar
# void sio_init(void)
sio_init: movw $SIO_PRT+0x3,%dx # Data format reg
movb $SIO_FMT|0x80,%al # Set format
outb %al,(%dx) # and DLAB
pushl %edx # Save
subb $0x3,%dl # Divisor latch reg
movw $SIO_DIV,%ax # Set
outw %ax,(%dx) # BPS
popl %edx # Restore
movb $SIO_FMT,%al # Clear
outb %al,(%dx) # DLAB
incl %edx # Modem control reg
movb $0x3,%al # Set RTS,
outb %al,(%dx) # DTR
incl %edx # Line status reg
# void sio_flush(void)
sio_flush.0: call sio_getc.1 # Get character
sio_flush: call sio_ischar # Check for character
jnz sio_flush.0 # Till none
ret # To caller
# void sio_putc(int c)
sio_putc: movw $SIO_PRT+0x5,%dx # Line status reg
xor %ecx,%ecx # Timeout
movb $0x40,%ch # counter
sio_putc.1: inb (%dx),%al # Transmitter
testb $0x20,%al # buffer empty?
loopz sio_putc.1 # No
jz sio_putc.2 # If timeout
movb 0x4(%esp,1),%al # Get character
subb $0x5,%dl # Transmitter hold reg
outb %al,(%dx) # Write character
sio_putc.2: ret $0x4 # To caller
# int sio_getc(void)
sio_getc: call sio_ischar # Character available?
jz sio_getc # No
sio_getc.1: subb $0x5,%dl # Receiver buffer reg
inb (%dx),%al # Read character
ret # To caller
# int sio_ischar(void)
sio_ischar: movw $SIO_PRT+0x5,%dx # Line status register
xorl %eax,%eax # Zero
inb (%dx),%al # Received data
andb $0x1,%al # ready?
ret # To caller

80
sys/boot/i386/boot2/sio.s Normal file
View File

@ -0,0 +1,80 @@
#
# Copyright (c) 1998 Robert Nordier
# All rights reserved.
#
# Redistribution and use in source and binary forms are freely
# permitted provided that the above copyright notice and this
# paragraph and the following disclaimer are duplicated in all
# such forms.
#
# This software is provided "AS IS" and without any express or
# implied warranties, including, without limitation, the implied
# warranties of merchantability and fitness for a particular
# purpose.
#
# $Id:$
.set SIO_PRT,0x3f8 # Base port
.set SIO_FMT,0x3 # 8N1
.set SIO_DIV,0xc # 115200 / 9600
.globl sio_init
.globl sio_flush
.globl sio_putc
.globl sio_getc
.globl sio_ischar
# void sio_init(void)
sio_init: movw $SIO_PRT+0x3,%dx # Data format reg
movb $SIO_FMT|0x80,%al # Set format
outb %al,(%dx) # and DLAB
pushl %edx # Save
subb $0x3,%dl # Divisor latch reg
movw $SIO_DIV,%ax # Set
outw %ax,(%dx) # BPS
popl %edx # Restore
movb $SIO_FMT,%al # Clear
outb %al,(%dx) # DLAB
incl %edx # Modem control reg
movb $0x3,%al # Set RTS,
outb %al,(%dx) # DTR
incl %edx # Line status reg
# void sio_flush(void)
sio_flush.0: call sio_getc.1 # Get character
sio_flush: call sio_ischar # Check for character
jnz sio_flush.0 # Till none
ret # To caller
# void sio_putc(int c)
sio_putc: movw $SIO_PRT+0x5,%dx # Line status reg
xor %ecx,%ecx # Timeout
movb $0x40,%ch # counter
sio_putc.1: inb (%dx),%al # Transmitter
testb $0x20,%al # buffer empty?
loopz sio_putc.1 # No
jz sio_putc.2 # If timeout
movb 0x4(%esp,1),%al # Get character
subb $0x5,%dl # Transmitter hold reg
outb %al,(%dx) # Write character
sio_putc.2: ret $0x4 # To caller
# int sio_getc(void)
sio_getc: call sio_ischar # Character available?
jz sio_getc # No
sio_getc.1: subb $0x5,%dl # Receiver buffer reg
inb (%dx),%al # Read character
ret # To caller
# int sio_ischar(void)
sio_ischar: movw $SIO_PRT+0x5,%dx # Line status register
xorl %eax,%eax # Zero
inb (%dx),%al # Received data
andb $0x1,%al # ready?
ret # To caller

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.4 1998/10/14 00:24:16 rnordier Exp $
# $Id: Makefile,v 1.5 1998/10/14 01:53:56 rnordier Exp $
PROG= boot2
NOMAN=
@ -6,7 +6,8 @@ STRIP=
BINDIR?= /boot
BINMODE= 444
CLEANFILES+= boot1 boot1.out boot1.o \
boot2.ldr boot2.bin boot2.ld boot2.out boot2.o
boot2.ldr boot2.bin boot2.ld boot2.out boot2.o \
sio.o
M4?= m4
@ -52,9 +53,12 @@ boot2.ldr:
boot2.bin: boot2.out
objcopy -S -O binary boot2.out ${.TARGET}
boot2.out: boot2.o
boot2.out: boot2.o sio.o
${LD} ${LDFLAGS} -Ttext ${ORG2} -o ${.TARGET} \
${BTX}/lib/crt0.o boot2.o
${BTX}/lib/crt0.o boot2.o sio.o
sio.o: sio.s
${AS} ${AFLAGS} -o ${.TARGET} sio.s
install:
${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \

View File

@ -14,7 +14,7 @@
*/
/*
* $Id: boot2.c,v 1.5 1998/10/13 23:00:47 rnordier Exp $
* $Id: boot2.c,v 1.6 1998/10/13 23:43:38 rnordier Exp $
*/
#include <sys/param.h>
@ -34,14 +34,21 @@
#include <btxv86.h>
#include "lib.h"
#define RBX_ASKNAME 0x0 /* -a */
#define RBX_SINGLE 0x1 /* -s */
#define RBX_DFLTROOT 0x5 /* -r */
#define RBX_KDB 0x6 /* -d */
#define RBX_CONFIG 0xa /* -c */
#define RBX_VERBOSE 0xb /* -v */
#define RBX_SERIAL 0xc /* -h */
#define RBX_CDROM 0xd /* -C */
#define RBX_GDB 0xf /* -g */
#define RBX_DUAL 0x1d /* -D */
#define RBX_PROBEKBD 0x1e /* -P */
#define RBX_MASK 0xffff
#define PATH_CONFIG "/boot.config"
#define PATH_BOOT3 "/boot/loader"
@ -49,7 +56,8 @@
#define PATH_HELP "boot.help"
#define ARGS 0x800
#define NOPT 8
#define NOPT 11
#define XOPT 2
#define BSIZEMAX 8192
#define NDEV 5
#define MEM_BASE 0x12
@ -67,13 +75,16 @@
extern uint32_t _end;
static const char optstr[NOPT] = "aCcdgrsv";
static const char optstr[NOPT] = "DhaCcdgPrsv";
static const unsigned char flags[NOPT] = {
RBX_DUAL,
RBX_SERIAL,
RBX_ASKNAME,
RBX_CDROM,
RBX_CONFIG,
RBX_KDB,
RBX_GDB,
RBX_PROBEKBD,
RBX_DFLTROOT,
RBX_SINGLE,
RBX_VERBOSE
@ -98,6 +109,7 @@ static uint32_t opts;
static struct bootinfo bootinfo;
static int ls;
static uint32_t fs_off;
static uint8_t ioctrl = 0x1;
void exit(int);
static void load(const char *);
@ -119,8 +131,10 @@ static uint32_t memsize(int);
static uint32_t drvinfo(int);
static int drvread(void *, unsigned, unsigned);
static int keyhit(unsigned);
static int putch(int);
static int getch(void);
static int xputc(int);
static int xgetc(int);
static void putc(int);
static int getc(int);
int
main(void)
@ -163,6 +177,8 @@ main(void)
"boot: ",
dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
'a' + dsk.part, kname, helpon ? help : "");
if (ioctrl & 0x2)
sio_flush();
if (!autoboot || keyhit(0x5a))
getstr(cmd, sizeof(cmd));
autoboot = helpon = 0;
@ -279,7 +295,7 @@ load(const char *fname)
bootinfo.bi_esymtab = VTOP(p);
printf("]\nentry=0x%x\n", addr);
bootinfo.bi_kernelname = VTOP(fname);
__exec((caddr_t)addr, RB_BOOTINFO | opts,
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
MAKEBOOTDEV(dsk.type, 0, dsk.slice, dsk.unit, dsk.part),
0, 0, 0, VTOP(&bootinfo));
}
@ -296,14 +312,27 @@ parse(char *arg)
for (p = arg; *p && *p != '\n' && *p != ' '; p++);
if (*p)
*p++ = 0;
if (c == '-')
if (c == '-') {
while ((c = *arg++)) {
for (i = 0; c != optstr[i]; i++)
if (i == NOPT - 1)
return -1;
opts |= 1 << flags[i];
if (i < XOPT)
opts ^= 1 << flags[i];
else
opts |= 1 << flags[i];
}
else {
if (opts & 1 << RBX_PROBEKBD) {
i = *(uint8_t *)PTOV(0x496) & 0x10;
printf("Keyboard: %s\n", i ? "yes" : "no");
if (!i)
opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL;
}
ioctrl = opts & 1 << RBX_DUAL ? 0x3 :
opts & 1 << RBX_SERIAL ? 0x2 : 0x1;
if (ioctrl & 0x2)
sio_init();
} else {
for (q = arg--; *q && *q != '('; q++);
if (*q) {
drv = -1;
@ -634,8 +663,8 @@ static int
putchar(int c)
{
if (c == '\n')
putch('\r');
return putch(c);
xputc('\r');
return xputc(c);
}
static int
@ -643,7 +672,7 @@ getchar(void)
{
int c;
c = getch();
c = xgetc(0);
if (c == '\r')
c = '\n';
return c;
@ -731,10 +760,7 @@ keyhit(unsigned ticks)
t0 = 0;
for (;;) {
v86.addr = 0x16;
v86.eax = 0x100;
v86int();
if (!V86_ZR(v86.efl))
if (xgetc(1))
return 1;
t1 = *(uint32_t *)PTOV(0x46c);
if (!t0)
@ -745,20 +771,42 @@ keyhit(unsigned ticks)
}
static int
putch(int c)
xputc(int c)
{
if (ioctrl & 0x1)
putc(c);
if (ioctrl & 0x2)
sio_putc(c);
return c;
}
static int
xgetc(int fn)
{
for (;;) {
if (ioctrl & 0x1 && getc(1))
return fn ? 1 : getc(0);
if (ioctrl & 0x2 && sio_ischar())
return fn ? 1 : sio_getc();
if (fn)
return 0;
}
}
static void
putc(int c)
{
v86.addr = 0x10;
v86.eax = 0xe00 | (c & 0xff);
v86.ebx = 0x7;
v86int();
return c;
}
static int
getch(void)
getc(int fn)
{
v86.addr = 0x16;
v86.eax = 0;
v86.eax = fn << 8;
v86int();
return v86.eax & 0xff;
return fn == 0 ? v86.eax & 0xff : !V86_ZR(v86.efl);
}