summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2005-08-18 00:42:45 +0000
committeriedowse <iedowse@FreeBSD.org>2005-08-18 00:42:45 +0000
commit1161399eefe49cc63043fec5cc9e5ba8c9a2cb32 (patch)
treef77701998d64b645834b575ed4da156006e7fe4b /sys/boot
parent352b6c307b4abedd12512a605aaec6e8df2c96bd (diff)
downloadFreeBSD-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.c41
-rw-r--r--sys/boot/i386/boot2/lib.h2
-rw-r--r--sys/boot/i386/boot2/sio.S7
-rw-r--r--sys/boot/i386/gptboot/gptboot.c41
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);
OpenPOWER on IntegriCloud