This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

External Data abort when executing LDREX/STREX on Beagleboard

Hello,

I am booting a microkernel on the Beagleboard RevD. Executing: 

"ldrex r1, [r3]"

Causes data abort with DFSR=0x8 meaning Synchronous External Abort and DFAR = address pointed by R3. RVD debugger reports this as an AXI decode error.

This happens after enabling virtual memory, ldrex/strex execute OK before MMU is enabled. However, the virtual address in R3 is valid and can be accessed without problems using an LDR or STR instruction.

Normally the kernel supports SMP Cortex-A9 and boots fine on a Versatile Express Cortex-A9 platform from ARM.

Any pointers to why this may be happening? Maybe we are missing a virtual memory setting on the OMAP35x?

Thanks,

Bahadir Balban

  • I have exactly the same issue. My software runs fine in QEMU but runs into issues on HW when running the strex instructions after the MMU has been enabled. Did you figure out what was wrong? If you did, I would really appreciate some help :)

     

    /Mattias

  • We haven't resolved it yet. Are you initializing the MMU by your own code? We have our own environment (a hypervisor) and I suspect this to be related to either an errata about the CPU that we are missing or a missing bit in the MMU initialization, though our code is pretty well tested and works on variants of Cortex-A9 including OMAP4.

    I suspect a missing errata for OMAP3. Can you provide background on your environment? It may lead to some pointers.

    Thanks,

    Bahadir

  • We have our own custom kernel that we are trying to run on the BeagleBoard rev C4. We set up some MMU tables and then enable the MMU by setting the M bit in the SCTLR. The AFE bit is 0, TRE is 0 and I have also tried to disable the cache by clearing the C bit. As far as I can tell, our setup follows all the rules.

    Not only do we have issues with the ldrex and strex bits, but also with access to memory mapped hardware. Reading from the UART3 registers (mapped in at 0xC0001000 always return 0, leading to an endless loop when polling the LSR register for UART empty status). The page in this case is mapped in as a non shared device page, so it should not be cached (and we tried to clear the C bit in the SCTLR to get around it (which according to the Cortex 8 docs should disable both L1 and L2 caches), but without success).

     

    / Mattias

  • Quick question: are you using the TEX remapping in you hypervisor?

    I am hypothesising that the errata would be that this happens if it is not used. As far as I can tell, Linux use the TEX remapping feature (and it does manage to run). So my next experiment to try to get around this would be to enable that part, but that would be pretty pointless if your hypervisor already does this.

     

    Thanks,

    Mattias

  • We use TEX remapping and also the simplified access permissions (AFE=1)

    Regarding your earlier points, we had this problem with pages we mapped about a year ago, the problem disappeared later after various changes but we did not bother to discover.  The AXI abort issue (LDREX/STREX problem) still stands though.

     

    I suspect 3 things:

    * L2 cache being enabled with misconfigured settings

    * CPU errata that we are missing

    * Secure/non-secure mode related issues.

    Do you have the ability to run your custom configured linux kernel? To rule out the errata issues, it might be worth disabling all errata config options and see if that boots.

  • I think you have other issues with the initialization to get to our state.

    Are you invalidating the entire data cache during mmu init? Also are you using correct TTB walk memory settings when setting the TTBR?

  • On the beagle bone, I found that when I set the memory as non shareable, i no longer got that exception. I hope that helps. Maybe it does not really make make sense to set the memory as sharable on a single core cpu.

  • Oh course setting the memory to non-shareable means the LDREX become simple LDR.

    I'm thinking maybe the global monitor might not be implemented in the am335x and maybe being single core, not relevant. I'm going for enable/disable interrupts and maybe even restartable atomic sequences.

  • Hi,

    I am using the OMAP3725. I have implemented a lock/unlock with the ldrex/strex on the ARM side

    and LL/Sl/CMTL on the DSP side. The reason is to protect against the shared memory ring buffer 

    descriptors. When I execute the ldrex on the ARM side I get a data abort exception. The memory

    area is not cached and I have set the shared bit in the page tables. What am I doing wrong???????