Subject: Re: sparse vs. dense pci space
To: Andrew Gallatin <gallatin@cs.duke.edu>
From: Chris G. Demetriou <cgd@pa.dec.com>
List: port-alpha
Date: 12/15/1997 10:22:24
[ As always, not the opinions of Digital, not necessarily meant to
  indicate current or future behaviour of firmware or systems,
  etc... ]

> I eventually turned on extent debugging in
> arch/alpha/pci/cia_swiz_bus_mem.c From the output of the debugging
> printfs in pci_swiz_bus_mem_chipdep.c, it looks like I'm getting back
> a handle for a sparse address.  The problem is that I need a
> dense-space address.  I came up with a gross workaround to force
> bus_space_map to give me back the sort of address I can use.  Doing
> what I'm doing right now strikes me as wrong; can somebody offer a
> suggestion as to how I should approach this?  Since there isn't a way
> to specify dense/sparse, I think I must be doing something wrong.

By default, use of dense vs. sparse is determined based on whether the
region is cacheable/prefetchable.  You can probably hack around this,
but you shouldn't.  I'll let you hang yourself; here are the
instructions:  8-)


> What I used to do:
> 
>     if (pci_mem_find(pa->pa_pc, pa->pa_tag, 0x10, &regbase, 
> 		     &regsize, &cacheable))
>       return;
>     if (bus_space_map(sc->myri_bustag, regbase, regsize, cacheable, 
> 		      &sc->myri_bushandle))
>       return;
> 
> 
> What I think I should be able to do:
> 
>    if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, 0, 
> 		       &sc->myri_bustag, &sc->myri_bushandle,
> 		       &regbase, &regsize)) {
> 	    printf(": can't map registers\n");
> 	    return;
>     }
> 
> What I'm doing right now:
> 
>     if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, 0x10, PCI_MAPREG_TYPE_MEM, 
> 			&regbase, &regsize, &cacheable))
> 	    return;
> 
>     if (bus_space_map(sc->myri_bustag, regbase, regsize, cacheable|BUS_SPACE_MAP_CACHEABLE, 
> 		      &sc->myri_bushandle))
>       return;

What you're not doing right now:

Using the fourth argument to pci_mapreg_map() to specify flags to be
passed to bus_space_map().  8-)

You should be able to do:

pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM,
    BUS_SPACE_MAP_CACHEABLE|BUS_SPACE_MAP_LINEAR, ...)

and have it do what you want, if necessary.  Note that if it _can't_
do what you want, it'll fail.  Note also that for CIA bus memory space
(and some other Alpha memory spaces), unless you specify "cacheable"
(which really means "dense space OK" in this context,
a.k.a. "prefetchable" 8-) you _can't_ do linear mapping.


What you want to do here is non-portable and arguably "wrong."

I say wrong because you should only use direct, linear access where
absolutely necessary.  (My favorite example is frame buffers, where
you need linear access for the raster console code to work.)  It
doesn't look like it's necessary here, but I don't have much of an example.

I say non-portable because direct linear access may not be supported
at all, either for the hardware you're accessing or on the
architecture you're using.  I seem to recall that there are alphas
which do not _implement_ dense space, and that there are alphas which
do not implement "overlapping" dense and sparse space (i.e. something
can either be accessed via dense space, or accessed via sparse space,
picked by the firmware based on the 'prefetchable' bit).  (The PCI
mapping code uses that bit to determine whether or not to add the
'cacheable' flag in, so if linear mapping were the right thing, you'd
already be getting it.)  Portable (between multiple architectures and
between different systems on a single architecture) drivers cannot
depend on linear mappings.



chris