Date: Fri, 17 Jan 1997 13:37:13 +1100 From: Bruce Evans <bde@zeta.org.au> To: bde@freebsd.org, root@red.jnx.com Cc: hackers@freebsd.org Subject: Re: do you mind if I apply this to 2.2 and 3.0? Message-ID: <199701170237.NAA29673@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>It turns out that when doing remote gdb, the damn console baud rate switching >code is pretty throughougly broken (yes, it's supposed to change the divisor, >no it doesn't do it right...) It changes the divisor, but the initial state is not set properly, so changing back to the previous state often gives a bad state. >i think the real culprit is that the siocnopen() code is incorrect. >I think that code should always poke both divisor bytes any time either >byte differs, but who really understands all the sio bugs out there. Poking both bytes might help fix a bug, but I don't know of any bugs in this area. >This patch definitely fixes remote gdb on devices != 115k and doesn't hurt >anything else (and it gets rid of more stupid magic numbers). Here's a more complete and conservative fix. Initializing the h/w in siocnopen() ensures that the state switches are null until the device is probed (or comdefaultrate is fiddled with). This early initialization is necessary for booting with -dg. Booting with -dh (or maybe with -dgh) works a bit better because the bootblocks usually agree about CONSPEED. Later, sioprobe() is careful not to change the speed for the console. I didn't change the magic 9600's because CONSPEED and comdefaultrate are only for the console and I'm not sure that the slop in the delays is sufficient at higher speeds. comdefaultrate is now declared volatile to ensure that gcc doesn't optimize it away. Bruce diff -c2 sio.c~ sio.c *** sio.c~ Fri Jan 17 13:05:08 1997 --- sio.c Fri Jan 17 13:06:26 1997 *************** *** 341,346 **** static int comconsole = -1; ! static speed_t comdefaultrate = CONSPEED; static u_int com_events; /* input chars + weighted output completions */ static int sio_timeout; static int sio_timeouts_until_log; --- 341,347 ---- static int comconsole = -1; ! static volatile speed_t comdefaultrate = CONSPEED; static u_int com_events; /* input chars + weighted output completions */ + static bool_t siointr1_looping; static int sio_timeout; static int sio_timeouts_until_log; *************** *** 582,590 **** * We don't want to to wait long enough to drain at 2 bps. */ ! outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS); ! outb(iobase + com_dlbl, COMBRD(9600) & 0xff); ! outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8); ! outb(iobase + com_cfcr, CFCR_8BITS); ! DELAY((16 + 1) * 1000000 / (9600 / 10)); /* --- 583,595 ---- * We don't want to to wait long enough to drain at 2 bps. */ ! if (dev->id_unit == comconsole) ! DELAY((16 + 1) * 1000000 / (comdefaultrate / 10)); ! else { ! outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS); ! outb(iobase + com_dlbl, COMBRD(9600) & 0xff); ! outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8); ! outb(iobase + com_cfcr, CFCR_8BITS); ! DELAY((16 + 1) * 1000000 / (9600 / 10)); ! } /* *************** *** 2566,2570 **** --- 2605,2620 ---- struct consdev *cp; { + int s; + struct siocnstate sp; + comconsole = DEV_TO_UNIT(cp->cn_dev); + + /* + * Minimise context switching of the device state by setting a + * good state to switch back to. + */ + s = spltty(); + siocnopen(&sp); + splx(s); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199701170237.NAA29673>