From owner-freebsd-current@FreeBSD.ORG Sun Aug 14 01:43:03 2005 Return-Path: X-Original-To: current@freebsd.org Delivered-To: freebsd-current@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 72EC916A41F for ; Sun, 14 Aug 2005 01:43:03 +0000 (GMT) (envelope-from iedowse@iedowse.com) Received: from nowhere.iedowse.com (nowhere.iedowse.com [82.195.144.75]) by mx1.FreeBSD.org (Postfix) with SMTP id CA59D43D45 for ; Sun, 14 Aug 2005 01:43:02 +0000 (GMT) (envelope-from iedowse@iedowse.com) Received: from localhost ([127.0.0.1] helo=iedowse.com) by nowhere.iedowse.com via local-iedowse id ; 14 Aug 2005 02:43:01 +0100 (IST) To: current@freebsd.org Date: Sun, 14 Aug 2005 02:43:01 +0100 From: Ian Dowse Message-ID: <200508140243.aa50444@nowhere.iedowse.com> Cc: Subject: Loader serial baud rate control X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 14 Aug 2005 01:43:03 -0000 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); +}