Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Right Semantics for ioremap, remap_page_range

42 views
Skip to first unread message

Alexander Ehlert

unread,
Jul 18, 2001, 7:50:07 AM7/18/01
to
Hi,

I'm currently trying to write a linux kernel driver for an experimental
graphics board we're developing at our institute. It's fitted
with an plx9054 and got some sdram on board connected to the plx.
Now I come this far, that I actually detect the board, set some modes
and do an ioremap on pci_resource_start(pdev,2) which is the
base for 64Mb Ram Onboard. After ioremap() I actually like
to do remap_page_range through fileops/mmap call. I just copied
that code from drivers/char/mem.c, but just using the ioremapped
address as offset in remap_page_range, doesn't seem to work, instead
I think I just mmap some totally different area... Now, what do I have to
use for that offset? What I currently do in the init function is
something like that:

...
priv.pcibar2 = (char*)ioremap(pci_resource_start(pdev,2),
pci_resource_len(pdev,2));
...

and later on in the mmap method I do:

static int mmap_plx9054(file, vma) {
unsigned long pcibase = (unsigned long)priv.pcibar2;
...
remap_page_range(vma->vma_start, pcibase, len, vma->vm_page_prot);
...
}

I just use pcibase as offset, anything wrong here?

Cheers, Alex

PS: Is there someone who knows about the plx9054?

--

Small things make base men proud.
-- William Shakespeare, "Henry VI"


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Richard B. Johnson

unread,
Jul 18, 2001, 8:50:05 AM7/18/01
to
On Wed, 18 Jul 2001, Alexander Ehlert wrote:

> Hi,
>
> I'm currently trying to write a linux kernel driver for an experimental
> graphics board we're developing at our institute. It's fitted
> with an plx9054 and got some sdram on board connected to the plx.
> Now I come this far, that I actually detect the board, set some modes
> and do an ioremap on pci_resource_start(pdev,2) which is the
> base for 64Mb Ram Onboard. After ioremap() I actually like
> to do remap_page_range through fileops/mmap call. I just copied
> that code from drivers/char/mem.c, but just using the ioremapped
> address as offset in remap_page_range, doesn't seem to work, instead
> I think I just mmap some totally different area... Now, what do I have to
> use for that offset? What I currently do in the init function is
> something like that:
>
> ...
> priv.pcibar2 = (char*)ioremap(pci_resource_start(pdev,2),
> pci_resource_len(pdev,2));
> ...

This is becoming a FAQ. The return value from ioremap() and friends
is not a pointer. It is actually something that from time-to-time
will be poisoned to detect its use as a pointer. It is a 'cookie'
designed to be used with readl() readw() readb(), writel(), etc.
For large arrays, you use copy/to/from_io(). It is possible to
determine the actual virtual address with a runtime code snippit
so you could access your remapped address conventionally, i.e.,
as a pointer, perhaps to a structure, etc., but cheating like
that is frowned upon and makes your driver more non-portable
than it probably already is. The assumption seems to be that
when Apple comes out with a 256 bit machine with 128 bit PCI
and 32, 40 GHz CPUs, you just recompile everything and it will run );

If your driver is never going to be used for anything but
a private experiment, the value of a pointer to the remapped
area is (usually) the (address_you_asked_for) | PAGE_OFFSET.

You have to save the returned cookie anyway because you use
it to release the remapped area when your module exits.

Cheers,
Dick Johnson

Penguin : Linux version 2.4.1 on an i686 machine (799.53 BogoMips).

I was going to compile a list of innovations that could be
attributed to Microsoft. Once I realized that Ctrl-Alt-Del
was handled in the BIOS, I found that there aren't any.

Alexander Ehlert

unread,
Jul 18, 2001, 9:00:08 AM7/18/01
to
Hi,

in the meantime I got it running, just some board setup issues,
I had to introduce some udelays() at the right spot :)

> designed to be used with readl() readw() readb(), writel(), etc.
> For large arrays, you use copy/to/from_io(). It is possible to

Thats what I do anyway.

> than it probably already is. The assumption seems to be that
> when Apple comes out with a 256 bit machine with 128 bit PCI
> and 32, 40 GHz CPUs, you just recompile everything and it will run );

Yeah, there are only about 5 boards at the present time :)

> If your driver is never going to be used for anything but
> a private experiment, the value of a pointer to the remapped
> area is (usually) the (address_you_asked_for) | PAGE_OFFSET.

What I now do is ioremap_nocache and do writel's, readl's on it.
For the mmap stuff, I just call remap_page_range with the physical
address that I get from pci_resource_start(). Is that alright?
I mean it's working for me now, thats most important :)

Cheers, Alex

--

When I was younger, I could remember anything, whether it had happened
or not; but my faculties are decaying now and soon I shall be so I
cannot remember any but the things that never happened. It is sad to
go to pieces like this but we all have to do it.
-- Mark Twain

Martin Frey

unread,
Jul 18, 2001, 10:40:08 AM7/18/01
to
Hi,

>What I now do is ioremap_nocache and do writel's, readl's on it.
>For the mmap stuff, I just call remap_page_range with the physical
>address that I get from pci_resource_start(). Is that alright?
>I mean it's working for me now, thats most important :)
>

That does not work on an Alpha. The Alpha (at leat my DS20 and
ES40) is happy with result of ioremap feeded into remap_page_range,
or the real CPU physical address (pci_resource_start + 0x80000000000
on Tsunami chipset).
There is an io_remap_page_range, which does a
remap_page_range(virt_to_phys(ioremap(pci_resource_start()))) on
Alpha, but this does not work either.

There must be a portable way to export PCI memory space to user space,
since e.g. the X servers are using that.

Any hints?

Thanks & regards,

Martin

Pete Zaitcev

unread,
Jul 18, 2001, 3:30:09 PM7/18/01
to
> base for 64Mb Ram Onboard. After ioremap() I actually like
> to do remap_page_range through fileops/mmap call.

Bad idea. The remap_page_range can remap actual memory only,
located on the CPU side of the I/O bridge.
What ioremap returns is useful in readb/writeb only, and
not to be fed into other functions.

Instead, use io_remap_page_range, lift the example from
drivers/video/fbmem.c.

-- Pete

Pete Zaitcev

unread,
Jul 18, 2001, 3:30:08 PM7/18/01
to
> There is an io_remap_page_range, which does a
> remap_page_range(virt_to_phys(ioremap(pci_resource_start()))) on
> Alpha, but this does not work either.

Kick the Alpha maintainer.

0 new messages