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.

TMS570LC4357: Problem with software breakpoint triggering in monitor mode.

Part Number: TMS570LC4357


Hello, we have encountered a problem with hardware breakpoint triggering during development of our project. Please look at the following code for set and reset the breakpoint:

void enableBreakpoint(void)
{
   extern unsigned int startBkpt;

   MEMORY_MAPPED_DEBUG_REGS *regs = get_debug_regs();

   _disable_interrupts_();

   /* Unlock DBGLAR. */
   regs->LOCKACCESS = 0xC5ACCE55;

   /* Enable monitor mode. */
   regs->DBGDSCR.bits.monitor_mode = 1;

   /* Disable the breakpoint being set. */
   regs->DBGBCR[5].all = 0;

   asm volatile(" dsb\n");
   asm volatile(" dmb\n");
   asm volatile(" isb\n");

   /* startFlush(); */

   regs->DBGBVR[5].all = ((unsigned long)&startBkpt) & 0xFFFFFFFC;
   regs->DBGBCR[5].all = 7 | (0xF << 5);

   asm volatile(" dsb\n");
   asm volatile(" dmb\n");
   asm volatile(" isb\n");

   /* startFlush(); */

   asm volatile("startBkpt:\n");
   asm volatile(" nop\n");

   _enable_interrupts_();
}

void disableBreakpoint(void)
{
   MEMORY_MAPPED_DEBUG_REGS *regs = get_debug_regs();

   _disable_interrupts_();

   /* Disable the breakpoint. */
   regs->DBGBCR[5].all = 0;

   /* Clear the DBGBVR register. */
   regs->DBGBVR[5].all = 0;

   asm volatile(" dsb\n");
   asm volatile(" dmb\n");
   asm volatile(" isb\n");

   /* startFlush(); */

   _enable_interrupts_();
}

MEMORY_MAPPED_DEBUG_REGS *get_debug_regs(void)

{

   UINT32T addr = _read_debug_DBGDRAR_() & 0xFFFFFFF0;

   addr += _read_debug_DBGDSAR_() & 0xFFFFFFF0;


   return ((MEMORY_MAPPED_DEBUG_REGS *)addr);

}

 

.def _read_debug_DBGDRAR_

.asmfunc

_read_debug_DBGDRAR_

   MRC p14, #0, r0, c1, c0, #0

   bx lr

.endasmfunc

.def _read_debug_DBGDSAR_

.asmfunc

_read_debug_DBGDSAR_

   MRC p14, #0, r0, c2, c0, #0

   bx lr

.endasmfunc


The problem is that the prefetch abort exception is not always triggered even though the breakpoint is set. It looks like it has something to do with the code padding in the executable image. I have found some very strange workaround, which temporarily resolves this problem but I really don't understand why it works.

The workaround is to create separate sections for enableBreakpoint and disableBreakpoint and then align them with padding to 32 bytes. The additional function also has to be created:

extern void startFlush void;

void flushFunction(void)
{
   asm volatile(" nop\n");
   asm volatile(" nop\n");
   asm volatile(" nop\n");
   asm volatile("startFlush:\n");
   asm volatile(" nop\n");
}

Now, the startFlush (function with just one nop instruction created inside the flushFunction in assembly) must be called in enableBreakpoint and disableBreakpoint functions right after the ISB instructions (it is commented out in the code above). What is really strange is that the startFlush function must be aligned to 32 bytes plus offset 0xC. That's why there is a flushFunction wrapper needed (it is placed in the separate section and also aligned with padding to 32 bytes. The first three nop instructions in the flushFunction are used to create 0xC offset for startFlush).

The cache is not enabled.

Maybe someone encountered the similar problem and knows the resolution?

  • Hello,

    Can you also paste the source code where you try to set the breakpoint and expect a prefetch abort exception? Do you enable the CPU response to an abort exception? Also could you clear the "halting mode" enable bit in DBGDSCR before enabling monitor mode?