Occurrence of a Data Abort exception in bare board application executing on i.MX6 based board

We have developed a bare board software on NXP’s i.MX6 based platform. The bare board software enables MMU after initializing a single ARM Cortex-A9 processor to execute a small application.

Initial State

All caches are disabled.

L1 prefetch disabled

Observation:

Case I:

When all the memory is mapped with ‘Strongly Ordered’ attribute, there is no exception and the application executes continuously.

Case II:

When all the memory (except the memory containing UART, Interrupt and Timer peripheral registers) is mapped with ‘Normal’ attribute, a Data Abort exception occurs randomly when the UART device is continuously accessed. Here, ‘randomly’ means that the number of times UART is accessed before the exception occurs is not constant.

Analysis Done:

The value in DFAR is an invalid memory address i.e., it is not mapped in the page tables and should not be accessed as per the application memory map.

The assembly code which caused exception is shown below( the address with blue underline is the PC generating exception):

This is really an embedded systems debugging problem, but I'll try to point you in the right direction as to what I think is going on.

I suspect that the processor is performing a speculative access into some area of normal memory and that this causing the exception.

This is why is doesn't happen when the memory is all marked as Strongly-Ordered.

The processor is free to perform speculative accesses into Normal memory architecturally, so this would tend to point to an oversight in the MMU settings.

The peripherals should be mapped as 'Device' memory, and additionally I'd consider setting the eXecute Never (XN) bit for these areas.

The RAM and ROM should be marked as 'Normal' memory, the processor can then perform speculative accesses ahead-of-time without any side affects; this will enable it to populate the I & D caches based on current and previous accesses.

Any other memory should be marked as 'No access' so a fault would be generated.