Re: PCI vremap on ALPHA

Linus Torvalds (torvalds@transmeta.com)
21 Jul 1998 06:47:54 GMT


In article <19980720232206.A11011@dot.cygnus.com>,
Richard Henderson <rth@dot.cygnus.com> wrote:
>On Mon, Jul 20, 1998 at 05:11:14PM +0200, Robert Wilhelm wrote:
>> Does mmapping memory on PCI cards work on ALPHA?
>
>Yes. But you don't use readl/writel with ioremaped memory,
>you treat it as plain memory.

Wrong. If the alpha port has that logic these days, it's broken. On
many architectures you _cannot_ treat PCI memory as plain memory, not
before and not after a "ioremap()".

Richard, what _should_ happen is that ioremap() is always required,
because on certain architectures you can't fit all of the PCI memory in
the memory map at the same time, so "ioremap()" is the way to tell the
kernel to please map it to a kernel mappable address. Think of it as a
"swap in this region into the kernel IO address working set".

Then you use readl/writel on that ioremapped address (see
Documentation/IO-mapping.txt for an example of this).

In short, you have to use _both_ ioremap and readl/writel, because
otherwise it simply will not work on certain architectures.

Now, on Alpha's we can actually fit all of the PCI memory mapping into
the kernel mapping without having to do any work, so on alpha's the
"ioremap()" is a no-op (or should be), possibly just adding a magic base
to the address we passed. So what you _should_ have is something like

/*
* ioremap doesn't need to do anything special
*/
void * ioremap(unsigned long io_addr)
{
return (void *) (MAGIC_PCI_MEM_BASE + io_addr);
}

and then "readl()/writel()" could be just normal reads.

This is slightly complicated by the fact that a lot of old-time drivers
know that the special ISA memory map hole (from 640kB-1MB) is always
mapped, so they'll use "readl()" on that directly without having any
call to ioremap(). As such, you'd either have to fix all legacy drivers,
or your "readl()" needs to look something like

unsigned int readl(void * addr)
{
unsigned int result;

if ((unsigned long) addr < (1<<20))
addr += MAGIC_PCI_MEM_BASE;

result = (unsigned volatile int *) addr;
asm volatile("mb");
return result;
}

which is not pretty, but expecting all legacy drivers to do ioremap() is
currently fairly utopistic..

Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html