Why do we map PCI IO space so late ?
benh at kernel.crashing.org
Fri Oct 1 17:21:04 EST 2004
On Fri, 2004-10-01 at 01:45, John Rose wrote:
> Hi Ben-
> Good questions :) First let me clear something up, and forgive me if
> I'm telling you stuff you already know. The ioremap()'s that we do at
> boot are _exclusively_ done for PHBs. This creates mappings that span
> the ranges for their children buses. Why do we do this when drivers can
> themselves use ioremap()? Because some drivers still use inb()/outb(),
> etc, without remapping their own space.
Yah, that at least is obvious :)
> The short answer to your questions is that I/O DLPAR required these PHB
> ioremap()'s to be moved to a later chronological point during boot, so
> that imalloc records would be kept.
Okay, that makes more sense to me now.
> Here's the long answer. To dynamically remove a bus (EADS or PHB), we
> need to iounmap() the range associated with it. The iounmap() function
> is prototyped in generic code to take one argument, the virtual address
> in question. In order to know the size of the region to unmap, we need
> to keep some records of what was ioremap()'ed originally. The imalloc
> subsystem exists to keep these records.
> The ppc64 ioremap() implementation has the limitation that if one calls
> it before mem_init_done, no imalloc records are left behind. If we
> remap the PHBs early in boot, we have no way to unmap them (or their
> children) at DLPAR remove time. Does this make sense?
> As a side note, we didn't similarly defer the remap for ISA, b/c we
> assumed that we'd never want to unmap this range. I wrote the function
> that remaps for ISA, and it's a hack, you're right :) Suggestions are
> welcome. I would ask why your ISA node doesn't have a ranges property,
> b/c I thought it was mandatory from some spec.
The OF tree of this board is still a work in progress. It has to be
mapped early anyway for other reasons, like the console serial driver
which will be initialized before we do the real mapping.
> You asked about ioremap_explicit(). This is used in two ways. First
> during boot, to remap the necessary regions for PHBs after
> mem_init_done. We've saved off the "physical" range info from the ofdt
> early in boot, and now we explicitly remap starting at virtual addr
> PHBS_IO_BASE. Second, we use it to remap the range of a newly
> DLPAR-added bus. You can imagine that in the case of adding an EADS
> slot, we need the mappings to exist at exact virtual addresses relative
> to its parent PHB, etc. Hence the creation of ioremap_explicit().
> Suggestions on improvements are welcome. Hope this helps, it's before
> lunch and I'm being wordy. :)
Thanks, it's enough for now, I need to think of alternative (read: simpler)
ways to deal with that in the future, but for now, it's fine.
More information about the Linuxppc64-dev