Enabling D-cache for OneNAND bufferram

Leo Barnes leo.barnes at algotrim.com
Thu Mar 25 06:57:10 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?

Best regards,
//Leo



More information about the linux-mtd mailing list