Subject: Re: PCI configuration
To: Ben Harris <bjh21@netbsd.org>
From: Jason R Thorpe <thorpej@zembu.com>
List: tech-kern
Date: 02/02/2001 13:57:53
On Fri, Feb 02, 2001 at 04:30:05PM -0500, Allen Briggs wrote:

 > Thanks for reminding me of extent(9).  I haven't used it before.  I
 > probably should be using that, but I'm not sure how to.  I don't see
 > a way to allocate "the first aligned, N-byte segment" from an extent.
 > With extent(9), I need to specify where that region is.  Would it make
 > sense to specify an extent_find_region() and/or extent_find_region1()
 > to do a find the first region that matches the specified size & alignment?
 > It could then alloc and/or just return the base of the region.

There is a way to do it... you do:

	error = extent_alloc(ex, size, alignment,
	    boundary /* 0 if no boundary constraint */, flags, &result);

 > Thoughts?

...yes.  There are a few issues here.  And it's kinda complicated.

You want machdep code to present to you a list of regions in which
PCI devices can be mapped.  Machdep code could do this by passing in
an extent map that has all the space allocated except for the available
regions.

Then do:

	for each device on the bus {
		/*
		 * Devices always need a power-of-2 amount of space.
		 * If the device is a bridge, you have to recurse to
		 * find out how much space the "device" requires.
		 */
		figure out how much space the device needs;
	}
	for each device on the bus {
		assign space to the device;
		if device is a bridge {
			create extent map for bridge and
			    recurse, allowing the bridge
			    to assign addresses to its
			    devices;
		}
	}

When you encounter a PCI-something bridge, you have to recurse.  This
is why you have to do it in 2 loops -- if you do it in one loop,
the PCI bridge won't have it's space allocated to it when it needs to
assign addresses to the devices behind it... and you need to program
the mapping window in the bridge.

Anyway, it's possible for the extent code to give you the "first fit"
or the "best fit".  You probably want to use the "best fit" algorithm
(which is the default).

After all this is done, you can destroy the extent maps -- they're only
really needed during the "program the bus phase".  They're orthogonal
to the extent maps used by the bus_space implementation on some
platforms.

This does expose a deficiency in bus_space API, tho.  Really, we'd like
to claim all the space used by PCI devices, even if there is no driver
in the kernel, so that other things that allocate space don't get mapped
there by mistake.  This isn't really crucial to solving your problem, tho.

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