0

I am ARM Cortex A9 CPU with 2 cores. But I just use 1 core and the other is just in a busy loop. I setup the MMU table using section (1MB per entry) like this:

0x00000000-0x14ffffff => 0x00000000-0x14ffffff (non-cachable, non-bufferable)
0x15000000-0x24ffffff => 0x15000000-0x24ffffff (cachable, bufferable)
0x25000000-0x94ffffff => 0x25000000-0x94ffffff (non-cachable, non-bufferable)
0x15000000-0x24ffffff => 0x95000000-0xa4ffffff (non-cachable, non-bufferable)
0xa5000000-0xffffffff => 0xa5000000-0xffffffff (non-cachable, non-bufferable)

It is rather simple. I just want to have a mirror of 256MB memory for non-cachable access. However, when I do several write to the the non-cachable memory section at 0x95000000-0xa4ffffff. I find the write is not actually written until I explicitly give a cache flush.

Am I doing something wrong or this kind of mapping is not valid? If that is the case, I don't understand how Linux's ioremap will be working on ARM. It will be good if anyone can give some explanation to me. Thanks very much.

artless noise
  • 21,212
  • 6
  • 68
  • 105
sing lam
  • 131
  • 1
  • 10
  • you have 0x15000000 mapped to two different places? How did you manage that? – old_timer Nov 20 '13 at 03:03
  • @dwelch: I'm guessing left-hand side is physical addresses. – unixsmurf Nov 20 '13 at 07:06
  • How do you know the write doesn't happen before a cache flush? I'm going to take a stab in the dark but are you writing to `0x95000000` but reading from `0x15000000` (which may have stale data in the cache)? – tangrs Nov 20 '13 at 07:28
  • Am I doing something wrong? You need to show us what you did, post code or mmu table settings, etc. The problem may or may not be obvious from those details. – old_timer Nov 20 '13 at 14:23
  • *I find the write is not actually written until I explicitly give a cache flush.* - How do you determine this? By reading at 0x15000000-0x24ffffff? This area maybe read-cached. The cache is VIVT, it has no way of knowing about your aliasing. Linux `ioremap()` will only allocate non-cacheable/non-bufferable, it doesn't map two sections/pages. – artless noise Nov 20 '13 at 20:29
  • Sorry for confusion, left side is physical and right side is virtual. I am doing this because I have a device which will take an address of a data structure to start DMA the memory content to another device. Before the DMA is ticked start, I need to read and write to specify member of the structure. I find it is very inefficient to do cache invalidate and flush whenever I need to access 4 bytes of a structure. This is the reason why I want to have a uncached and unbuffer copy of memory. If this is not a proper to do this, is there any alternative? – sing lam Nov 22 '13 at 00:19

1 Answers1

1

First of all: the Cortex-A9 is an ARMv7-A processor. The terms non-cacheable/non-bufferable/cacheable/bufferable are no longer correct descriptions of the mappings. The actual mapping type is determined by TEX[2:0], C and B bits.

So I am actually having to guess a bit here as to what your mappings actually are. And my guess is that you have the majority of your mappings set as Strongly-ordered, and the mirrored region as Normal Write-Back cacheable.

Having multiple virtual mappings with different memory types pointing to the same physical location is generally not a good idea in the ARM architecture. It used to be explicitly banned, but the latest version of the ARMv7-AR Architecture reference manual (DDI 0406C.b) has a (fairly long) section dedicated to the implications of "Mismatched memory attributes".

I would recommend finding a different way of achieving your goal.

Simply changing the mapping of the uncached regions to Normal Non-cacheable would be a good start. There is no valid reason for using Strongly-ordered mappings for RAM.

unixsmurf
  • 5,852
  • 1
  • 33
  • 40