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.

Again: Prefetch_abort locating issue

Hi there,

I tried something simple - as i was not sure i got the result of the abort handler correctly...

This is my code:

asm(" MOV R14,#0xffff"); /* copy lower 16 Bits */

asm(" MOVT R14,#0xffff"); /* copy higher 16 Bits */

asm(" MOV PC,R14");  /* set program counter to 0xffffffff */

 

Which results in an (expected) prefetch abort....

my handler executes coreGetInstructionFaultAddress (which runs        mrc   p15, #0, r0, c6, c0, #2).The return value is "0xffffffff" - i get that. 

But is there any chance, geting the adress of the last "asm" (which caused the abort) - thus being able to track down the source (so to say) of the abort not the destination where the last jump was aimed at?

 

all the best

 Dominik

  • Dominik,

    In the prefetch abort ISR, you can check the value of the LR register. It contains the address before CPU jumps to ISR.

    Thanks and regards,

    Zhaohong

  • Thanks Zhaohong,

    I think we are into something important right now. I re-ran the above assembly code, which should set the PC to the (illegal) address 0xffffffff. What i get is this:

     

    From my understanding this shows an LR value of 0x00000002 - which should be totally off - being not aligned properly. If i proceed into the "prefetchaborthandler" the LR values stays to "0x000002" - however the aborthandler returns the address i wanted the processor to jump to - so this works.

    What am i doing wrong? from my understanding the LR should contain the value (address) from where i executed the last asm token... ?

     

    Thanks very much

     

    Dominik

     

    edit: I looked into the arm exception handling. As far as i understood: R14_abt is set to PC+4. As i set the PC to 0xffffffff via brute force, the value i get (0x00002) maybe due to an alignment correction taking place. I did a re-run, in which i set the pc to 0xffffff00 - and got a LR entry of 0xffffff04 - which confirms what i suspected.
    If this conlcusion of mine is correct, what chance do i have to catch the location an indirect jump is called - or - in other words...

    I need to know, where the "CALL _ILLEGAL_ADDRESS_" is placed in my source code, _not_ the value of "_ILLEGAL_ADDRESS"...

  • Dominik,

    Sorry for the late reply.

    According to ARM's Cortex-R4 TRM, the r14_abt register (LR) is updated to provide information about the address of the instruction that the exception was taken on. In your test, the instruction before abort is "ldr PC,R0" CPU will not able to recorder this address because there is no error. I personally do not consider it a major issue in debugging a prefetch abort problem. Most prefetch aborts are caused by memory errors. Uncorrectable ECC error in code fetching will cause a prefetch abort. You can even program R4 system control register to generate abort on correctable ECC errors. The address recoded by R4 status registers or LR is the actually the address of the error.

    Thanks and regards,

    Zhaohong

  • Hello Dominik,

    This is an area of the design where the behavior is solely defined by ARM.  If the built in functions of the CPU are not satisfying your need to debug your software, have you considered either a board which include program trace capability using the ARM ETM tool or a CPU simulator?

    Thanks and Regards,

    Karl

  • Thanks for both of your replies.

    this is indeed a major issue. So in may case  the info generated by the abort handler is worthless. If you are using the _non_bga CPU there is no ETM traceability.

    We have to build a develpoment system using an bga based TMS570 - just for the reason, that there is no way to find the last "correct" instruction which really caused the trouble.

     

    Very ;-(

    Dominik

     

     

  • Hello Dominik,

    The abort handler is behaving exactly as ARM defines it will behave in the TRM.  It has identified that the location where the fault occurred is 0xFFFFFFFF.  The CPU attempted to execute whatever was at this location and this resulted in a fault.  The handler notes the location of the faulted instruction.  

    What you are asking for is not to identify the faulted instruction location, but to identify that last good instruction executed before the fault. In the specific case you note, there is no CPU register or memory which holds the location.  If your code were written differently, such that you did not directly manipulate the program flow by changing the PC (and instead used branches with link), you may be able to inspect the stack and check for past locations of execution.

    Regards,
    Karl