Subject: 64-bit bus_addr_t (Re: sparc/dev/sbus.c rev 1.43 problem)
To: Juergen Hannken-Illjes <hannken@eis.cs.tu-bs.de>
From: Valeriy E. Ushakov <uwe@ptc.spbu.ru>
List: port-sparc
Date: 12/29/2001 17:04:01
On Sat, Dec 29, 2001 at 14:06:37 +0100, Juergen Hannken-Illjes wrote:

> > > All my kernels with rev 1.43 of sys/arch/sparc/dev/sbus.c get:
> > > 
> > > 	cpu0: NMI: system interrupts: 40000000<VME=0,SBUS=0,ME>
> > > 	trap type 0x29: pc=0xa1594 npc=0xa1598 psr=4000084<S>
> > > 	trap type 0x29: pc=0xf0008410 npc=0xf0008414 psr=44000c0<S,PS>
> > > 	kernel: trap trap
> > > 	Stopped in pid 212 (Xsun) at Lbcopy_doubles: ldd [%o0 + %g0], %o4
> > 
> > Did Xsun worked with previous revision of the file?  (I think Xsun has
> > been broken since bus_space_mmap changed signature as it was not
> > really converted, the method was stubbed out just to get the kernel
> > compiling).
> 
> A -current kernel works fine if I use rev 1.42.

Ah, I think I know what's the problem is.  See below


> > > 	cgthree0 at sbus0 slot 0 offset 0x0 level 9: SUNW,501-1718, 1152 x 900
> > > 
> > > Tracing sbus_bus_mmap I get (args and result):
> > > 
> > > before t=0xf0508f60 baddr=30000000 off=8fd000 prot=2 flags=2 => 308fd004
> > > after  t=0xf0275ba8 baddr=60000000 off=8fd000 prot=2 flags=2 => 608fd004
> > 
> > Sorry?  Before and after what?
> 
> before your change sparc/sparc/machdep.c::sbus_bus_mmap was called as:

You mean machdep.c::sparc_bus_mmap I think.


> 	sbus_bus_mmap(t=0xf0508f60 baddr=30000000 off=8fd000 prot=2 flags=2)
> 
> and returned 308fd004.
> 
> 
> Now sparc/dev/sbus.c::sbus_bus_mmap gets called with the same arguments:
> 
> 	sbus_bus_mmap(t=0xf0508f60 baddr=30000000 off=8fd000 prot=2 flags=2)
> 
> sets paddr to 60000000 and calls sparc/sparc/machdep.c::sbus_bus_mmap as:
> 
> 	sbus_bus_mmap(t=0xf0275ba8 baddr=60000000 off=8fd000 prot=2 flags=2)
> 
> and returns 608fd004.
> 
> > Hmm, baddr 3000.0000 looks right for slot 0 offset 0.  Leading '6'
> > would be slot 3.  Can you please give me more details?

bus_addr_t on sparc was changed to be a 64-bit int to encode in a
single number what sparc used two numbers for, bus_type_t and
bus_addr_t (32-bit).  This is necessary to be able to use MI drivers
that don't know about sparc's secret bus_type_t (e.g com at ebus
attachment on sparc needs this since it's bus_type_t would be 1 and we
just have no way to pass that secret '1' to MI com driver, we can only
pass bus_addr_t and need to encode all the information there).

New sbus_bus_mmap expects new 64-bit bus_addr_t, that you would get
from BUS_ADDR(slot, offset) - with slot in upper 32-bits and offset in
lower 32-bits.  It then translates that (via "ranges") to address in
parent's address space (i.e. physical address) and pass it to
sparc_bus_mmap.

But cgthree uses sbus_bus_addr to compute its sc_paddr that
"precomputes" sbus -> physical translation and when cg3 driver passes
that address to sbus_bus_mmap it gets translated to physical address
one more time (hence you get 6000.0000 since the address is translated
to 3000.0000 (slot 0) once by sbus_bus_addr and once by sbus_bus_mmap).

I haven't checked all the implications, but it seems that for sparc
sbus_bus_addr should be g/c'ed and in sys/dev/sbus/* all its uses
should be converted from sbus_bus_addr(tag, slot, offset) to
BUS_ADDR(slot, offset).

I'm not sure about sparc64, but from a quick glance it does
pre-translation in sbus_bus_addr and then just forwards sbus mmap to
physical mmap (since address is already pretranslated).  So any fix in
this area should be coordinated with sparc64 (hi, eeh).

This is probably a matter of a protocol, i.e. a choice between:

    bus_space_mmap(sbustag, sbus_bus_addr(bustag, slot, offset), ...)
vs
    bus_space_mmap(sbustag, BUS_ADDR(slot, offset), ...)

I'd say that the latter is more natural as it uses a generic macro
instead of bus-specific call (Occam's razor).


PS: All sparc drivers should probably be audited for new 64-bit
bus_addr_t usage.

SY, Uwe
-- 
uwe@ptc.spbu.ru                         |       Zu Grunde kommen
http://www.ptc.spbu.ru/~uwe/            |       Ist zu Grunde gehen