Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Sep 1996 02:04:44 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, julian@whistle.com
Cc:        hackers@FreeBSD.org, pst@shockwave.com
Subject:   Re: gdb remote
Message-ID:  <199608311604.CAA27835@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> I skip writing to the divisor registers if the divisor is already correct,
>> but it doesn't seem to make any difference for gdb.
>> 
>OK bruce, here is a patch for sio.c that solves my part of the
>problem...
>the cnxxx code doesn't initialise the registers unless the port is
>open, (except the first time) though you may want to modify the patch.
>I'd like to commit this unless you have a better version :)

Yes, I have a much better version :-).  First try only the CFCR_8BITS
change out of it.  Writing the speed to the same value should by harmless.
(Make sure that the port is set to the default speed by stty'ing it in
the usual way if necessary.  The defaults are 9600 for everything.)

I think I understand the problem now.  Sio console output is unbuffered
except for fifos in the hardware, so input is guaranteed to be lost if
>= sizeof(hardware fifo) characters are transmitted before checking for
input.  I'm using a 16450 on the remote, so the fifo size is only 2.
This rarely works.  Going the other way seems to never work (I guess
because the bursts of output are longer going that way).  I'm surprised
that a fifo size of 16 works for anyone.  The remote stub uses buffers
of size 400.  I'm writing some buffering routines now.

Bruce

*** sio.c~	Thu Jul 18 12:38:10 1996
--- sio.c	Sun Sep  1 01:10:52 1996
***************
*** 2398,2407 ****
  	siocntxwait();
  	sp->cfcr = inb(iobase + com_cfcr);
! 	outb(iobase + com_cfcr, CFCR_DLAB);
  	sp->dlbl = inb(iobase + com_dlbl);
  	sp->dlbh = inb(iobase + com_dlbh);
  	divisor = ttspeedtab(comdefaultrate, comspeedtab);
! 	outb(iobase + com_dlbl, divisor & 0xFF);
! 	outb(iobase + com_dlbh, (u_int) divisor >> 8);
  	outb(iobase + com_cfcr, CFCR_8BITS);
  	sp->mcr = inb(iobase + com_mcr);
--- 2459,2477 ----
  	siocntxwait();
  	sp->cfcr = inb(iobase + com_cfcr);
! 	outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
  	sp->dlbl = inb(iobase + com_dlbl);
  	sp->dlbh = inb(iobase + com_dlbh);
  	divisor = ttspeedtab(comdefaultrate, comspeedtab);
! 	/*
! 	 * Only set the divisor registers if they would change, since
! 	 * setting them clears the data input register on some 16550
! 	 * incompatibles.  Worse, on other or the same 16550 incompatibles
! 	 * (UMC8611?), setting while input is arriving them loses sync
! 	 * until data stops arriving.  Sigh.
! 	 */
! 	if (sp->dlbl != divisor & 0xFF)
! 		outb(iobase + com_dlbl, divisor & 0xFF);
! 	if (sp->dlbh != (u_int) divisor >> 8)
! 		outb(iobase + com_dlbh, (u_int) divisor >> 8);
  	outb(iobase + com_cfcr, CFCR_8BITS);
  	sp->mcr = inb(iobase + com_mcr);
***************
*** 2423,2431 ****
  	 * Restore the device control registers.
  	 */
  	siocntxwait();
  	iobase = siocniobase;
  	outb(iobase + com_cfcr, CFCR_DLAB);
! 	outb(iobase + com_dlbl, sp->dlbl);
! 	outb(iobase + com_dlbh, sp->dlbh);
  	outb(iobase + com_cfcr, sp->cfcr);
  	/*
--- 2493,2503 ----
  	 * Restore the device control registers.
  	 */
  	siocntxwait();
  	iobase = siocniobase;
  	outb(iobase + com_cfcr, CFCR_DLAB);
! 	if (sp->dlbl != inb(iobase + com_dlbl))
! 		outb(iobase + com_dlbl, sp->dlbl);
! 	if (sp->dlbh != inb(iobase + com_dlbh))
! 		outb(iobase + com_dlbh, sp->dlbh);
  	outb(iobase + com_cfcr, sp->cfcr);
  	/*



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