diff options
author | iedowse <iedowse@FreeBSD.org> | 2005-08-18 00:42:45 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2005-08-18 00:42:45 +0000 |
commit | 1161399eefe49cc63043fec5cc9e5ba8c9a2cb32 (patch) | |
tree | f77701998d64b645834b575ed4da156006e7fe4b /sys/boot | |
parent | 352b6c307b4abedd12512a605aaec6e8df2c96bd (diff) | |
download | FreeBSD-src-1161399eefe49cc63043fec5cc9e5ba8c9a2cb32.zip FreeBSD-src-1161399eefe49cc63043fec5cc9e5ba8c9a2cb32.tar.gz |
Add the ability to specify the boot2 serial console speed in
/boot.config or on the "boot:" prompt line via a "-S<speed>" flag,
e.g. "-h -S19200". This adds about 50 bytes to the size of boot2
and required a few other small changes to limit the size impact.
This changes only affects boot2; there are further loader changes
to follow.
Diffstat (limited to 'sys/boot')
-rw-r--r-- | sys/boot/i386/boot2/boot2.c | 41 | ||||
-rw-r--r-- | sys/boot/i386/boot2/lib.h | 2 | ||||
-rw-r--r-- | sys/boot/i386/boot2/sio.S | 7 | ||||
-rw-r--r-- | sys/boot/i386/gptboot/gptboot.c | 41 |
4 files changed, 59 insertions, 32 deletions
diff --git a/sys/boot/i386/boot2/boot2.c b/sys/boot/i386/boot2/boot2.c index d12ae47..0a4d056 100644 --- a/sys/boot/i386/boot2/boot2.c +++ b/sys/boot/i386/boot2/boot2.c @@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$"); #define RBX_NOINTR 0x1c /* -n */ /* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */ #define RBX_DUAL 0x1d /* -D */ -#define RBX_PROBEKBD 0x1e /* -P */ /* 0x1f is reserved for log2(RB_BOOTINFO). */ /* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */ @@ -91,7 +90,7 @@ __FBSDID("$FreeBSD$"); extern uint32_t _end; -static const char optstr[NOPT] = "DhaCgmnPprsv"; +static const char optstr[NOPT] = "DhaCgmnprsv"; /* Also 'P', 'S' */ static const unsigned char flags[NOPT] = { RBX_DUAL, RBX_SERIAL, @@ -100,7 +99,6 @@ static const unsigned char flags[NOPT] = { RBX_GDB, RBX_MUTE, RBX_NOINTR, - RBX_PROBEKBD, RBX_PAUSE, RBX_DFLTROOT, RBX_SINGLE, @@ -122,6 +120,7 @@ static struct dsk { static char cmd[512]; static char kname[1024]; static uint32_t opts; +static int comspeed = SIOSPD; static struct bootinfo bootinfo; static uint8_t ioctrl = IO_KEYBOARD; @@ -390,34 +389,48 @@ static int parse() { char *arg = cmd; - char *p, *q; + char *ep, *p, *q; + const char *cp; unsigned int drv; - int c, i; + int c, i, j; while ((c = *arg++)) { if (c == ' ' || c == '\t' || c == '\n') continue; for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; if (*p) *p++ = 0; if (c == '-') { while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* Fall through to error below ('S' not in optstr[]). */ + } for (i = 0; c != optstr[i]; i++) if (i == NOPT - 1) return -1; opts ^= 1 << flags[i]; } - 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; - opts &= ~(1 << RBX_PROBEKBD); - } ioctrl = opts & 1 << RBX_DUAL ? (IO_SERIAL|IO_KEYBOARD) : opts & 1 << RBX_SERIAL ? IO_SERIAL : IO_KEYBOARD; if (ioctrl & IO_SERIAL) - sio_init(); + sio_init(115200 / comspeed); } else { for (q = arg--; *q && *q != '('; q++); if (*q) { @@ -459,7 +472,7 @@ parse() ? DRV_HARD : 0) + drv; dsk_meta = 0; } - if ((i = p - arg - !*(p - 1))) { + if ((i = ep - arg)) { if ((size_t)i >= sizeof(kname)) return -1; memcpy(kname, arg, i + 1); diff --git a/sys/boot/i386/boot2/lib.h b/sys/boot/i386/boot2/lib.h index 4bb93cf..0459bc2 100644 --- a/sys/boot/i386/boot2/lib.h +++ b/sys/boot/i386/boot2/lib.h @@ -17,7 +17,7 @@ * $FreeBSD$ */ -void sio_init(void); +void sio_init(int); void sio_flush(void); void sio_putc(int); int sio_getc(void); diff --git a/sys/boot/i386/boot2/sio.S b/sys/boot/i386/boot2/sio.S index 3fc2963..7b8e9eb 100644 --- a/sys/boot/i386/boot2/sio.S +++ b/sys/boot/i386/boot2/sio.S @@ -17,7 +17,6 @@ .set SIO_PRT,SIOPRT # Base port .set SIO_FMT,SIOFMT # 8N1 - .set SIO_DIV,(115200/SIOSPD) # 115200 / SPD .globl sio_init .globl sio_flush @@ -25,14 +24,14 @@ .globl sio_getc .globl sio_ischar -/* void sio_init(void) */ +/* void sio_init(int div) */ 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 + movl 0x8(%esp),%eax # Set outw %ax,(%dx) # BPS popl %edx # Restore movb $SIO_FMT,%al # Clear @@ -41,6 +40,8 @@ sio_init: movw $SIO_PRT+0x3,%dx # Data format reg movb $0x3,%al # Set RTS, outb %al,(%dx) # DTR incl %edx # Line status reg + call sio_flush + ret $0x4 /* void sio_flush(void) */ diff --git a/sys/boot/i386/gptboot/gptboot.c b/sys/boot/i386/gptboot/gptboot.c index d12ae47..0a4d056 100644 --- a/sys/boot/i386/gptboot/gptboot.c +++ b/sys/boot/i386/gptboot/gptboot.c @@ -63,7 +63,6 @@ __FBSDID("$FreeBSD$"); #define RBX_NOINTR 0x1c /* -n */ /* 0x1d is reserved for log2(RB_MULTIPLE) and is just misnamed here. */ #define RBX_DUAL 0x1d /* -D */ -#define RBX_PROBEKBD 0x1e /* -P */ /* 0x1f is reserved for log2(RB_BOOTINFO). */ /* pass: -a, -s, -r, -d, -c, -v, -h, -C, -g, -m, -p, -D */ @@ -91,7 +90,7 @@ __FBSDID("$FreeBSD$"); extern uint32_t _end; -static const char optstr[NOPT] = "DhaCgmnPprsv"; +static const char optstr[NOPT] = "DhaCgmnprsv"; /* Also 'P', 'S' */ static const unsigned char flags[NOPT] = { RBX_DUAL, RBX_SERIAL, @@ -100,7 +99,6 @@ static const unsigned char flags[NOPT] = { RBX_GDB, RBX_MUTE, RBX_NOINTR, - RBX_PROBEKBD, RBX_PAUSE, RBX_DFLTROOT, RBX_SINGLE, @@ -122,6 +120,7 @@ static struct dsk { static char cmd[512]; static char kname[1024]; static uint32_t opts; +static int comspeed = SIOSPD; static struct bootinfo bootinfo; static uint8_t ioctrl = IO_KEYBOARD; @@ -390,34 +389,48 @@ static int parse() { char *arg = cmd; - char *p, *q; + char *ep, *p, *q; + const char *cp; unsigned int drv; - int c, i; + int c, i, j; while ((c = *arg++)) { if (c == ' ' || c == '\t' || c == '\n') continue; for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++); + ep = p; if (*p) *p++ = 0; if (c == '-') { while ((c = *arg++)) { + if (c == 'P') { + if (*(uint8_t *)PTOV(0x496) & 0x10) { + cp = "yes"; + } else { + opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; + cp = "no"; + } + printf("Keyboard: %s\n", cp); + continue; + } else if (c == 'S') { + j = 0; + while ((unsigned int)(i = *arg++ - '0') <= 9) + j = j * 10 + i; + if (j > 0 && i == -'0') { + comspeed = j; + break; + } + /* Fall through to error below ('S' not in optstr[]). */ + } for (i = 0; c != optstr[i]; i++) if (i == NOPT - 1) return -1; opts ^= 1 << flags[i]; } - 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; - opts &= ~(1 << RBX_PROBEKBD); - } ioctrl = opts & 1 << RBX_DUAL ? (IO_SERIAL|IO_KEYBOARD) : opts & 1 << RBX_SERIAL ? IO_SERIAL : IO_KEYBOARD; if (ioctrl & IO_SERIAL) - sio_init(); + sio_init(115200 / comspeed); } else { for (q = arg--; *q && *q != '('; q++); if (*q) { @@ -459,7 +472,7 @@ parse() ? DRV_HARD : 0) + drv; dsk_meta = 0; } - if ((i = p - arg - !*(p - 1))) { + if ((i = ep - arg)) { if ((size_t)i >= sizeof(kname)) return -1; memcpy(kname, arg, i + 1); |