Subject: Re: access to external proms for PCI
To: Garrett D'Amore <>
From: Garrett D'Amore <>
List: tech-kern
Date: 12/12/2005 18:48:43
Actually I'm leaning at this point (writing the code) so that there is a
new routine:

boolean_t pci_rom_copy(
    pci_chipset_tag_t, pcitag_t, uint32_t *dest, int cnt);

This routine copies an expansion ROM (BAR at 0x30) to the named
destination.  The reason for doing it this way is that it makes it
simple to set up and tear down wired mappings, and I can reuse the same
virtual addresses for all PROMs, minimizing both impact to the code and
to the physical address space.

I believe this style of function is general enough to be straightforward
to implement on any platform that supports PIO access to PCI memory.

    -- Garrett

Garrett D'Amore wrote:

>I am trying to write a radeon framebuffer driver (ala machfb) -- yes I
>have ATI's documentation, and yes the driver will be given back to
>NetBSD.  The target for this driver is a MIPS processor.
>However, it turns out that I really need to be able to access the
>external PROM in order to extract some values from it for memory timing.
>The question is how best to achieve this, especially given my MIPS
>platform where I have to create an MMU entry to access the PCI memory bus.
>The PCI configuration code doesn't treat this like an ordinary BAR
>because for some devices external PROM access interferes with normal
>device usage.  (Not a problem in the specific case of the radeon.)
>I can see ways to do this, but I can't figure out which is the most
>desirable, and am interested in hearing opinions, or better ideas if
>anyone has any:
>    1) Create a special PCI routine that does the work --
>pci_map_extprom() or some such.  This would have to be supplied by the
>port's PCI layer, and would do the appropriate MMU work to establish the
>mapping(s).  There should also be a tear-down routine to release the
>    2) Create special pci_extprom_read() routine that works like
>pci_conf_read only without endian swapping.  This is cleanest for my
>platform, because I can reuse the same wired MMU entry that I'm using
>for PCI configuration space.  Drawback is that it is slower, and you
>can't use linear accesses (unless you copy into a scratch buffer first),
>but does anyone care about that?  Second drawback is adding the code for
>the other platforms.  I'm not interested in adding/testing this across a
>zillion different ports.
>    3) Same as number 2, but don't make it a MI interface, instead just
>leave the mapping logic in a MD header.  This means radeonfb has to
>#ifdef the usage.
>    4) Modify my port's boot loader (aka BIOS) to export some
>"properties" for the device.  This involves the least change to NetBSD,
>but is not likely to be very reusable by anyone else.  It probably means
>the radeon FB driver is not reusable  very easily, except on OpenBOOT
>systems which already do this.
>    5) Add port-specific logic to the radeonfb driver I'm writing that
>does the MMU translations itself.  Surrounded by #ifdef's of course, 
>And let someone else worry about porting it.  (The necessary mapping
>code would be easy to write for i386, and for OBP systems you can just
>grab properties out of OBP.)
>My gut says that #2 is the best option, but it means adding a new PCI
>interface.  I don't have enough experience with NetBSD to know how much
>resistance there is likely to be to this, especially since it would
>probably be a non-implemented API on most ports.

Garrett D'Amore                
Sr. Staff Engineer          Extending the Power of 64-bit UNIX Computing
Tadpole Computer, Inc.                             Phone: (951) 325-2134