[parisc-linux-cvs] [PATCH] PCI MMIO mapping
Bjorn Helgaas
bjorn_helgaas@hp.com
Wed, 23 May 2001 17:14:26 -0600
Thanks for the detailed feedback!
> > @@ -884,7 +898,6 @@ iosapic_enable_irq(void *dev, int irq)
> >
> > /* data is initialized by fixup_irq */
> > ASSERT(0 < vi->vi_txn_irq);
> > - ASSERT(0UL != vi->vi_txn_addr);
> > ASSERT(0UL != vi->vi_txn_data);
>
> Why was the ASSERT removed?
> I thought txn_addr will always be non-zero for PA-RISC.
> Can txn_addr be zero?
txn_addr is zero for cell 0, cpu 0 on superdome.
> Me either. Sorry. I think the comment should read:
> /*
> ** Sign extend all BAR values on "legacy" platforms.
> ** "Sprockets" PDC (Forte/Allegro) initializes everything for
> ** for "legacy" 32-bit OS (HPUX 10.20).
> ** Upper 32-bits of 64-bit BAR will be zero too.
> */
>
> > - lba_dev->lmmio_base = 0xffffffff00000000UL;
> > + lba_dev->hba.mem_space_offset = 0xffffffff00000000UL;
> > +#else
> > + lba_dev->hba.mem_space_offset = 0UL;
> > #endif
I can parse it now, but I don't think it is quite correct yet. On 64-bit
"legacy" (non-PAT) boxes, we set the 32 high-order bits of lmmio_base,
then later do "res->start |= ldev->lmmio_base". This isn't sign-extension
because it doesn't depend on the value of a sign bit. Right?
> > @@ -1166,10 +1164,8 @@ lba_legacy_resources( struct hp_device *
> > r->name = "LBA PCI LMMIO";
> > r->flags = IORESOURCE_MEM;
> > /* Ignore "Range Enable" bit in the BASE register */
> > - r->start = ((long) READ_REG32(d->hpa + LBA_LMMIO_BASE)) & ~1UL;
> > -#ifdef __LP64__
> > - r->start |= 0xffffffff00000000UL; /* sign extend f-space */
> > -#endif
> > + r->start = PCI_HOST_ADDR(HBA_DATA(lba_dev),
> > + ((unsigned long) READ_REG32(d->hpa + LBA_LMMIO_BASE)) & ~1UL);
>
> This has me slightly nervous.
> Does this work on both C3000 and A500? (ie Sprockets and PAT PDCs)
> If so, does it work because the value is sign extended?
> Or because the READ_REG32() is cast to a 64-bit read and both PDCs
> write a 64-bit value into LMMIO_BASE?
I haven't tested on anything but Superdome yet, because I was ignorant of
what the important test cases were. I'll test C3000 and A500 before
checking in. I did not intend to be relying on any sign extension or
side-effects of casting.
As I understand it, the current behavior is:
32-bit boxes:
host address == PCI bus address always
64-bit legacy:
PCI bus addresses are of the form 0x00000000XXXXXXXX
host_addr = (0xffffffff << 32) | bus_addr
bus_addr = (host_addr & 0xffffffff)
64-bit PAT boxes:
PCI bus addresses are of the form 0x00000000XXXXXXXX
lmmio_base is of the form 0xXXXXXXXX00000000
host_addr = lmmio_base | bus_addr
bus_addr = (host_addr & 0xffffffff)
My reasoning was that since there's no overlap between bits set in
lmmio_base and bits set in PCI bus addresses, this should be equivalent to
host_addr = bus_addr + offset
bus_addr = host_addr - offset
where
32-bit boxes:
offset = 0
64-bit legacy:
offset = (0xffffffff << 32)
64-bit PAT boxes:
offset = lmmio_base_PA_VIEW - lmmio_base_IO_VIEW
(for non-Superdome boxes, lmmio_base_IO_VIEW is 0)
> > @@ -1181,7 +1177,7 @@ lba_legacy_resources( struct hp_device *
> > r->end = r->start + rsize - 1 ;
> >
> > /*
> > - ** XXX FIXME - ignore LBA_ELMMIO_BASE for now
> > + ** XXX FIXME - ignore LBA_LMMIO_BASE for now
>
> I meant ELMMIO_BASE.
>
> But I can't find "ELMMIO" in the Elroy ERS I have (rev 1.4, 08/23/99).
> Offset 0x250 is marked "reserved". I guess one has to have HPUX source
> code access to know about this. *sigh*.
The Mercury ERS describes ELMMIO and says Elroy has it too, but removed it
from the ERS. I'll leave the comment as it was except for correcting
"distrubuted". I had just thought ELMMIO itself was a typo.
> > @@ -744,6 +744,7 @@ dino_card_init(struct dino_device *dino_
> >
> > dino_dev->ioport_addr = 0x00001000; /* Make believe */
> > dino_dev->mmio_addr = 0xf0800000; /* FIXME: Make believe */
> > + dino_dev->hba.mem_space_offset = 0; /* CPU addrs == bus addrs */
>
> Here, mem_space_offset should be set to -1 since the mmio_addr
> is bogus too. Card-mode dino doesn't route MMIO transaction
> to the PCI bus. At least not until someone writes the code to figure
> out which MMIO ranges are available and programs IOADDR_EN in Dino.
> PDC does this for built-in dino but not for card-mode dino.
Why is -1 preferable to 0? I'm not interested in making card-mode dino
MMIO work either; the only reason I set mem_space_offset at all here was
so that if somebody *did* try to use PCI_{HOST,BUS}_ADDR with such a dino,
it wouldn't use an uninitialized offset.
> In fact, I'm wondering if pcibios_host_to_bus()even implements
> pcivtobus() correctly. IIRC, pcivtobus() is to convert *any* Host
> virtual address into and address which can be DMA'd to by the PCI
> device. This mess was replaced with Dynamic DMA mapping in 2.3 and
> it's just taking the drivers a while to catch up.
I think the driver uses pcivtobus() only for CSRs and script memory, not
or arbitrary host addresses. Since it doesn't appear in 2.4.4. at all,
we're in luck, because this was the only use for pcibios_host_to_bus(), so
we'll be able to just nuke the whole thing.
Bjorn