Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Aug 2005 02:43:01 +0100
From:      Ian Dowse <iedowse@iedowse.com>
To:        current@freebsd.org
Subject:   Loader serial baud rate control
Message-ID:  <200508140243.aa50444@nowhere.iedowse.com>

next in thread | raw e-mail | index | archive | help

Currently the baud rate used by the i386/amd64 loader for a serial
console is hard-coded as 9600 baud and you need to recompile the
loader to change it. Below is a patch that adds a "comconsole_speed"
loader environment variable so that the speed can be changed from
loader.conf or manually from the loader prompt. It doesn't quite
do what you want though, since the loader has already printed a
number of things by the time it reads loader.conf. Any comments?

Ian

Index: i386/libi386/comconsole.c
===================================================================
RCS file: /dump/FreeBSD-CVS/src/sys/boot/i386/libi386/comconsole.c,v
retrieving revision 1.10
diff -u -r1.10 comconsole.c
--- i386/libi386/comconsole.c	16 Sep 2003 11:24:23 -0000	1.10
+++ i386/libi386/comconsole.c	14 Aug 2005 01:12:52 -0000
@@ -48,8 +48,13 @@
 static void	comc_putchar(int c);
 static int	comc_getchar(void);
 static int	comc_ischar(void);
+static int	comc_parsespeed(const char *string);
+static void	comc_setup(int speed);
+static int	comc_speed_set(struct env_var *ev, int flags,
+		    const void *value);
 
 static int	comc_started;
+static int	comc_curspeed;
 
 struct console comconsole = {
     "comconsole",
@@ -72,19 +77,29 @@
 static int
 comc_init(int arg)
 {
+    char speedbuf[16];
+    char *speedenv;
+    int speed;
+
     if (comc_started && arg == 0)
 	return 0;
-    comc_started = 1;
+    if (!comc_started) {
+	comc_curspeed = COMSPEED;
+	speedenv = getenv("comconsole_speed");
+	if (speedenv != NULL) {
+	    speed = comc_parsespeed(speedenv);
+	    if (speed > 0)
+		comc_curspeed = speed;
+	}
 
-    outb(COMPORT + com_cfcr, CFCR_DLAB | COMC_FMT);
-    outb(COMPORT + com_dlbl, COMC_BPS(COMSPEED) & 0xff);
-    outb(COMPORT + com_dlbh, COMC_BPS(COMSPEED) >> 8);
-    outb(COMPORT + com_cfcr, COMC_FMT);
-    outb(COMPORT + com_mcr, MCR_RTS | MCR_DTR);
+	sprintf(speedbuf, "%d", comc_curspeed);
+	unsetenv("comconsole_speed");
+	env_setenv("comconsole_speed", EV_VOLATILE, speedbuf, comc_speed_set,
+	    env_nounset);
+    }
+    comc_started = 1;
 
-    do
-        inb(COMPORT + com_data);
-    while (inb(COMPORT + com_lsr) & LSR_RXRDY);
+    comc_setup(comc_curspeed);
 
     return(0);
 }
@@ -112,3 +127,51 @@
 {
     return(inb(COMPORT + com_lsr) & LSR_RXRDY);
 }
+
+static int
+comc_speed_set(struct env_var *ev, int flags, const void *value)
+{
+    int speed;
+
+    if (value == NULL || (speed = comc_parsespeed(value)) <= 0) {
+	printf("Invalid speed\n");
+	return (CMD_ERROR);
+    }
+
+    if (comc_curspeed != speed)
+	comc_setup(speed);
+
+    env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+
+    return (CMD_OK);
+}
+
+static void
+comc_setup(int speed)
+{
+
+    comc_curspeed = speed;
+
+    outb(COMPORT + com_cfcr, CFCR_DLAB | COMC_FMT);
+    outb(COMPORT + com_dlbl, COMC_BPS(speed) & 0xff);
+    outb(COMPORT + com_dlbh, COMC_BPS(speed) >> 8);
+    outb(COMPORT + com_cfcr, COMC_FMT);
+    outb(COMPORT + com_mcr, MCR_RTS | MCR_DTR);
+
+    do
+        inb(COMPORT + com_data);
+    while (inb(COMPORT + com_lsr) & LSR_RXRDY);
+}
+
+static int
+comc_parsespeed(const char *speedstr)
+{
+    char *p;
+    int speed;
+
+    speed = strtol(speedstr, &p, 0);
+    if (p == speedstr || *p != '\0' || speed <= 0)
+	return (-1);
+
+    return (speed);
+}




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508140243.aa50444>