Subject: Re: TC bba audio problem on DEC3000/300
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Jason R Thorpe <thorpej@zembu.com>
List: port-alpha
Date: 07/12/2000 22:36:39
On Tue, Jul 04, 2000 at 11:44:28PM +0900, Izumi Tsutsui wrote:

 > % cat myu.au > /dev/audio
 > panic: tc_mem_read_1 not implemented for sparse space
 > Stopped in tcsh at	cpu_Debugger+0x4:	ret	zero,(ra)
 > db>
 > ---
 > 
 > Is anyone working to update tc_bus_mem.c to fix this?
 > Anyway, bba configuration in TCWSCONS should be disabled for now...

Actually, this is a bug in the `bba' driver.  We really don't need or
want to be doing byte or word reads in sparse space.  I looked at what
is required to do it.  And it's not pretty.  Basically, it involves:

	- compute byte lane mask
	- block machine checks
	- set BYTE MASK register in bus controller
	- do access
	- restore BYTE MASK register in bus controller
	- unblock machine checks
	- extract and return byte

Thankfully, DEC hardware has a sleazy hack that allows you do avoid
this song-and-dance ... and the `zs' (and `scc') driver already does
it.

Alpha and DECstation are little-endian, and the bytes happen to be
padded out.  So, do 4-byte access with the byte you want in the least
significant 8-bits of the 4-byte longword.

The following patch should make it go:

Index: bba.c
===================================================================
RCS file: /cvsroot/syssrc/sys/dev/tc/bba.c,v
retrieving revision 1.8
diff -c -r1.8 bba.c
*** bba.c	2000/06/28 17:05:20	1.8
--- bba.c	2000/07/13 05:36:21
***************
*** 808,815 ****
  
  	DPRINTF(("bba_codec_dread(): sc=%p, reg=%d\n",sc,reg));
  
! 	val = bus_space_read_1(sc->sc_bst, sc->sc_codec_bsh,
! 		(reg<<BBA_REGISTER_SHIFT));
  
  	for (i=0; i<TIMETOWASTE; i++) {};
  
--- 808,815 ----
  
  	DPRINTF(("bba_codec_dread(): sc=%p, reg=%d\n",sc,reg));
  
! 	val = bus_space_read_4(sc->sc_bst, sc->sc_codec_bsh,
! 		(reg<<BBA_REGISTER_SHIFT)) & 0xff;
  
  	for (i=0; i<TIMETOWASTE; i++) {};
  
Note that bba_codec_dwrite() already used bus_space_write_4().

Anyway, I also noticed that there's a TIMETOWASTE constant in there
which looks like it was intended to implement a recovery delay.  It
doesn't work -- the compiler optimizes the loop right out.  If the
delay is really needed (which I would guess it is not, since it's
not actually there right now), it should be done with delay().

-- 
        -- Jason R. Thorpe <thorpej@zembu.com>