MPU not effective for disabling caching

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
elagil
Posts: 94
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

MPU not effective for disabling caching

Post by elagil »

Hello,

I want to use DMA memcpy from one external SDRAM region to another.

I know, I have to invalidate cache or disable caching with MPU, in order to have transparent transfers with the DMA. I chose to use the MPU like this:

Code: Select all

#define SDRAM_DEVICE_ADDR 0xC0000000UL   
   /*
   * Configure memory protection region with disabled cache in SDRAM
   * This ensures that DMA access is not hidden behind unchanged caches
   *
   * Assumes 32 MiB SDRAM.
   */
   mpuConfigureRegion(
      MPU_REGION_6,
      SDRAM_DEVICE_ADDR,
      MPU_RASR_ATTR_AP_RW_RW |
      MPU_RASR_ATTR_NON_CACHEABLE |
      MPU_RASR_SIZE_32M |
      MPU_RASR_ENABLE);


However, this is not effective. In the following code, "MEM" is a memory region on SDRAM, starting at "0xC0000000UL". The data that I can examine in MEM[20] is only correct, if I use the manual buffer invalidation before!

Code: Select all

   MEM[0] = 18;
   
   // cacheBufferInvalidate(MEM, 8); <= With this line, it works!

   dmaStartMemCopy(INT_MEM_DMA_STREAM,
      STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_BYTE |
                        STM32_DMA_CR_MSIZE_BYTE,
      &MEM[0], &MEM[20], 8);


Is there some configuration error in the MPU?

Thanks in advance,
Adrian
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: MPU not effective for disabling caching

Post by Giovanni »

Hi,

A while ago I tried this and it appeared to work:

Code: Select all

  /* The SRAM2 bank can optionally made a non cache-able area for use by
     DMA engines.*/
  mpuConfigureRegion(MPU_REGION_7,
                     SRAM2_BASE,
                     MPU_RASR_ATTR_AP_RW_RW |
                     MPU_RASR_ATTR_NON_CACHEABLE |
                     MPU_RASR_SIZE_16K |
                     MPU_RASR_ENABLE);
  mpuEnable(MPU_CTRL_PRIVDEFENA);

  /* Invalidating data cache to make sure that the MPU settings are taken
     immediately.*/
  SCB_CleanInvalidateDCache();


Giovanni
elagil
Posts: 94
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

Re: MPU not effective for disabling caching

Post by elagil »

Thanks, I actually used the same configuration already.

The problem seems to be fixed by changing the base address. I initially used 0xC0000000, now 0x60000000 with a protected size of 512 MB. This way, my memory region is surely covered. Since I use bank 1 for my SDRAM, why should I not be able to use the 0xC0000000 base address for the MPU? Do you have any idea? I use 0xC0000000 as the address of a custom memory region, also in the linker file:

Code: Select all

    ram7    : org = 0xC0000000, len = 32M       /* SDRAM space for Ethernet pools and user memory */


Edit: SWP_FMC would cause this behaviour, I assume. It says in an ST manual:
The SWP_FMC bit in the System Configuration Remap register allows remapping the FMC controller’s SDRAM banks 1 and 2 to the NOR/RAM bank base address, which allows changing the SDRAM memory’s attributes. When FMC bank swap is enabled, the NOR/RAM bank is remapped to the SDRAM bank 1 address.


However, it is not enabled, as I can see in the register view.

screen.png


Best regards
elagil
Posts: 94
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

Re: MPU not effective for disabling caching

Post by elagil »

My last assumption is not correct, it does not work with different memory base address. What can be the problem? This is the complete initialization at the moment:

Code: Select all

   mpuConfigureRegion(
      MPU_REGION_6,
      0xc0000000,
      MPU_RASR_ATTR_AP_RW_RW |
      MPU_RASR_ATTR_NON_CACHEABLE |
      MPU_RASR_SIZE_32M |
      MPU_RASR_ENABLE);
     
   mpuEnable(MPU_CTRL_PRIVDEFENA);

   SCB_CleanInvalidateDCache();
     


I now copy with this instruction:

Code: Select all

   dmaStartMemCopy(INT_MEM_DMA_STREAM, STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD, source, destination, N);
   dmaWaitCompletion(INT_MEM_DMA_STREAM);
   


It works for arrays that I initialize locally, but not on SDRAM.
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: MPU not effective for disabling caching

Post by Giovanni »

Not sure why, you should try asking on the ST forum.

Giovanni
elagil
Posts: 94
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

Re: MPU not effective for disabling caching

Post by elagil »

Actually, as I found out, there is no need to use the MPU. It says in the STM32F7 system architecture document (AN4667):

The two default regions of SDRAM banks are not cacheable. So even if the cache is enabled, the data or instructions will not go through the cache. To benefit from the cache acceleration, the SDRAM banks can be remapped from 0xC000 0000 and 0xD000 0000 to 0x6000 0000 and 0x7000 0000 respectively, which are, by default, cacheable regions.


In this case, I do not understand why the DMA does not work. Maybe, my SDRAM is not working properly.
elagil
Posts: 94
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

Re: MPU not effective for disabling caching

Post by elagil »

Further investigations of the MPU and SDRAM lead to more information about modes in which memory is used. There are three memory modes in STM32F7 (See programming manual PM0253):

Normal
The processor can re-order transactions for efficiency, or perform speculative reads.

Device and Strongly-ordered
The processor preserves transaction order relative to other transactions to Device or Strongly-ordered memory.

The different ordering requirements for Device and Strongly-ordered memory mean that the memory system can buffer a write to Device memory, but must not buffer a write to Strongly-ordered memory.


If using SDRAM without any MPU enabled in the SDRAM region, the memory is used in "Device" type mode. In this mode, only word-aligned access is allowed, which is a problem for many applications. For example, I placed Lwip buffers on SDRAM and this crashed due to the limitation of word-aligned access only.

If the MPU is enabled for the SDRAM, so that the region is in "Normal" type mode, byte, half-word, and word accesses are possible. This enabled me to use Lwip buffers on SDRAM without any problems. However, the DMA-inconsistencies, as described here, showed up.

Then, I switched to strongly-ordered mode. This ensures that CPU and DMA always see the same state of the memory and all accesses are performed in the order in which they are programmed to happen. Finally, this solved the problem. It seems like the CPU read the data before the DMA was finished writing.
Post Reply