Linux on Xilinx v2pro: OCM access?

P

Peter Monta

Guest
I'm having trouble accessing OCM peripherals from Linux.
The symptom is a machine check exception whenever the
OCM address space is read or written.

This code is run from a kernel module:

unsigned int* p = (unsigned int*)ioremap(0x40000000,0x1000);
printk("%08x\n",p[0]);

When the OCM address of 0x40000000 is replaced with, say,
the UART at 0xA0000000, things work as expected: can peek
and poke the UART registers with no problem. How is
the OCM different from a PLB peripheral from Linux's
point of view? The cacheability registers, DCCR and ICCR,
are correctly set by Linux to 0xf0000000, so only addresses
under 512 MByte are cacheable (currently occupied by DRAM),
and OCM is well outside this range. (We use only DSOCM.)

If the ioremap() address is replaced with something
nonexistent, such as 0x50000000, then the same type of
machine exception occurs. It's as if the OCM didn't exist.

But running in real mode works fine: a small test application
running from PLB block RAM can see all of the OCM resources.

This is a 2VP20, processor version number 0x200108a0.

I plan to open a Xilinx hotline case, but thought I'd ask
in the newsgroup for good measure.

Cheers,
Peter Monta
RGB Networks, Inc.
 
Peter,

here is some user code that let's you access the DOCM (8KB at address
0x40000000):

---
// mmaptest.c
// gcc -o mmaptest mmaptest.c
// su -c "mmaptest"

#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <assert.h>

int main(void)
{
int fd;
unsigned char *buf;
int i;

fd=open("/dev/mem", O_RDWR);
printf("fd: %d\n", fd);

buf = mmap (0x40000000, 8*1024, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, 0x40000000);
printf("buf: %x\n", buf);
assert(buf == 0x40000000); // virtual address must match physical address

for (i=0; i < 8; i++)
printf("buf[%d] = %x\n", i, buf);

return 0;
}
---

Please note that the OCM is virtually addressed and virtually accessed,
i.e. you must make sure that the virtual address returned by mmap() is
exactly the same as the physical address. For that, ioremap() will not
work as the virtual address and the physical address typically are
different.

Further, you have to enable the work-around for the OCM errata, i.e. set
some undocumented bit(s) in the CCR0 register. The PPC405 errata sheet
available from xilinx.com contains information which bit(s) these are
(see solution record 14052).

Next, the program must be run with enough rights to access /dev/mem,
i.e. run it as root. For a final implementation you will typically have
to write a device driver that accesses the OCM and abstracts these
accesses from the user code.


- Peter


Peter Monta wrote:
I'm having trouble accessing OCM peripherals from Linux.
The symptom is a machine check exception whenever the
OCM address space is read or written.

This code is run from a kernel module:

unsigned int* p = (unsigned int*)ioremap(0x40000000,0x1000);
printk("%08x\n",p[0]);

When the OCM address of 0x40000000 is replaced with, say,
the UART at 0xA0000000, things work as expected: can peek
and poke the UART registers with no problem. How is
the OCM different from a PLB peripheral from Linux's
point of view? The cacheability registers, DCCR and ICCR,
are correctly set by Linux to 0xf0000000, so only addresses
under 512 MByte are cacheable (currently occupied by DRAM),
and OCM is well outside this range. (We use only DSOCM.)

If the ioremap() address is replaced with something
nonexistent, such as 0x50000000, then the same type of
machine exception occurs. It's as if the OCM didn't exist.

But running in real mode works fine: a small test application
running from PLB block RAM can see all of the OCM resources.

This is a 2VP20, processor version number 0x200108a0.

I plan to open a Xilinx hotline case, but thought I'd ask
in the newsgroup for good measure.

Cheers,
Peter Monta
RGB Networks, Inc.
 
... Please note that the OCM is virtually addressed
Thank you *very much*. It works perfectly now.

I imagine the MMU is on the PLB-facing side of the PPC,
so that address translation is not active for cache-like
entities like OCM. But I would not have guessed this
without help.

Xilinx hotline support is pretty reasonable, but
Usenet can sometimes outperform it :).

Cheers,
Peter Monta
RGB Networks, Inc.
 

Welcome to EDABoard.com

Sponsor

Back
Top