Subject: PCI Physical Address allocation (i386)
To: None <tech-kern@netbsd.org>
From: Michael Richardson <mcr@solidum.com>
List: tech-kern
Date: 01/18/2000 21:26:53
  This may sound a bit strange at first.

  I want allocate a bunch of physical addresses on a PCI bus.

  Why?
  So I can program them into a BAR on a PCI device. Why didn't the POST/PCI
Bios do it? Well, because the device is an FPGA with a hard PCI core, and the
BARs don't get initialized until the FPGA is programmed. (The programming
interface is via PCI configuration space).

  [If the PCI core was soft, i.e. implemented by the FPGA, then nothing would
exist until you program the FPGA, so you would have to program it via another 
means. Since the PCI core is hard, you can reprogram the rest of the chip
from the PCI bus, which makes hardware development much easier...]

  Long term, we put a EEPROM on board and load the BARs from it, but short
term, we need to bring things up to the point where we can load the
EEPROM... (bootstrap problem).
  
  As I understand it, the PCI BIOS is in charge of scanning all of the
devices on the PCI bus and allocating physical address for them. No surprise
here. The PCI BIOS, of course, knows about things like the chipset on the
motherboard, how much ram there is, and what kinds of devices might already
be claiming physical address space from the 4Gb whole.

  The question is, how can I, as a NetBSD driver writer, find out what this
physical address map looks like? Or better yet, just have the PCI BIOS
allocate me a chunk of address space.

  I suspect that this can't be an isolated problem, since cardbus and
hot-swap PCI will need this. I was reading through the pccbb.c and cardbus/*,
and from I can see, if a card inserted has an invalid BAR, ifndef rbus, then
we use addresses 0x8300. Otherwise, we go through (*cf->cardbus_space_alloc),
which is probably pccbb_rbus_cb_space_alloc, but I don't know where
rbus_space_alloc is, or whether or not rbus is defined. From looking at
related code, pccbb_pcmcia_mem_alloc, it just calls bus_space_alloc.

  My problem with bus_space_alloc, is that this is allocating physical
addresses which have drivers attached to them. I.e. two drivers can't
allocate the same physical address space. It doesn't say anything about which 
physical device actually will decode it.

  I want an address which is currently not *decoded* by any physical device.
Maybe the map maintained by bus_space_alloc() is good enough for this, but as 
there isn't a "find me some" function, just a "can I have this?" function,
I'd have to add a new interface.

  Advice?

  I have read through the PCI Bios 2.1 spec (of 1994). It mentions
configuration space access, and interrupt routing assignment, and determining 
how many buses exist, but no mention of finding out what physical addresses
are in use by the system.

   :!mcr!:            |  Solidum Systems Corporation, http://www.solidum.com
   Michael Richardson |For a better connected world,where data flows faster<tm>
 Personal: http://www.sandelman.ottawa.on.ca/People/Michael_Richardson/Bio.html
	mailto:mcr@sandelman.ottawa.on.ca	mailto:mcr@solidum.com