Enabling D-cache for OneNAND bufferram

Joakim Tjernlund joakim.tjernlund at transmode.se
Thu Mar 25 07:23:18 EDT 2010

> Joakim Tjernlund wrote:
> >> Hello!
> >>
> >> I am currently writing a piece of software that takes advantage of the
> >> fact that OneNAND supports read-while-loading. What I am doing is trying
> >> to achieve higher efficiency when decoding data from the OneNAND by
> >> decoding data that is available in the OneNAND bufferram directly
> >> instead of copying it to normal RAM and decoding there. So far, I have
> >> gotten quite poor results due to the fact that the bufferrams are not
> >> cached (for good reason since it is Device memory). My software will be
> >> used on ARM devices of different types, with my testrigs being a Nokia
> >> N810 and a N900.
> >>
> >> I have exclusive access to the OneNAND chip, and as such know exactly
> >> what information is stored in the bufferrams at all times. If I could
> >> only enable the D-cache for the bufferrams, I could therefore make sure
> >> to invalidate the cache whenever I reprogram the OneNAND chip.
> >>
> >>  From what I have read so far, it seems that the only way to enable
> >> cacheing of the bufferrams would be to somehow change how the memory
> >> attributes for the memory region in the MMU. I have however not found
> >> any easy way of doing this. Any tips? I dont really have very much
> >> experience when it comes to how the MMU works.
> >>
> >
> > Have a look at ioremap_cached(). Seems to be availabe on ARM
> > Basically you need to create a second virtual address mapping of the devices
> > RAM which is cached.
> >
> >     Jocke
> >
> >
> Thanks for the suggestion, but I am having some trouble getting it to
> work. This is how I tried to use ioremap_cached, along with the problems
> I got:
> Given a pointer to the first byte in the bufferram, I did:
> unsigned long int phys_addr = virt_to_phys(bufaddr);
> void *rmap = ioremap_cached(phys_addr, 2048);
> /* Read from rmap */
> iounmap(rmap);
> This would not compile however since L_PTE_CACHEABLE was not defined.
> After scanning through the kernel source, I found that L_PTE_CACHEABLE
> was usually defined as (1 << 3) for arm. With this defined,
> ioremap_cached returned a new virtual address, but gave a segmentation
> fault along with "Unhandled fault: external abort on non-linefetch
> (0x008) at 0xc8accc00" in /proc/kmsg when trying to do a read. Am I
> using ioremap correctly? Does ioremap change the old mapping, or simply
> add a second one? If it creates a second one without changing the first,
> this is illegal on ARM IIRC since two mappings cannot have differing
> memory attributes...
> Any other ideas?

ioremap returns a *second* mapping to the same RAM so you first original mapping
should be fine.

I have used ioremap in 2.4 to access NOR flash in cached mode and it worked
fine. one just have to rember to invalidate the cache when needed. This was on
PPC and I knonw nothing about ARM.

I can think of two things:
 1) check that virt_to_phys(bufaddr) returns
    the correct physical address for your NAND.
 2) have a look at __ioremap instead of ioremap_cached

Perhaps you need to talk to the ARM people, it may very well be
a bug in ARM arch code.


More information about the linux-mtd mailing list