AnsweredAssumed Answered

SC58x anomaly 20000069: missing nop in os_cpu_a.asm (ucos-III)

Question asked by RichardJeske on Dec 8, 2016
Latest reply on Dec 9, 2016 by daveG

Hi,

when using the sec with ucos-III and the heap and stack are located in the L2/L3 we've encountered a bug that should have been solved due the fact that the anomaly 20000069 is already known since a long time. If you try to return from an ISR, the MODE1 Register is not restored properly. The consequence is that the IRPTEN will not be restored under some circumstances and all further interrupts will not be served.

 

Here is the original code (C:\Analog Devices\uCOS-III-Rel2.1.0\uCOS-III\SHARC\uCOS-III\Ports\os_cpu_a.asm, starting at line 1354):

#if defined(HAS_MODE1STK)
    MODE1STK = USTAT1;                   /* MODE1 has not been restored, 215xx allows access to the top of the STS         */
#else
                                         /* Restore MODE1 to a known value.  MMASK will have cleared most of these already */
                                         /* but as we need to clear some of the registers we do them all. The alternate    */
                                         /* register bits are not cleared by MMASK.                                        */
    BIT CLR MODE1 (OS_C_RUN_TIME_MODE1_CLR) | IRPTEN;   /* Disable ints */
    BIT SET MODE1 (OS_C_RUN_TIME_MODE1_SET);

    IMASK = R4;                            /* Restore IMASK now that interrupts are globally disabled                        */
#if defined(HAS_LIRPTL)
    LIRPTL_SET(R8)                         /* R8 holds the old LIRPTL value, R4 is used in the calculation.                  */
#endif
#endif


.RESTORE_SCRATCH_NONDATA_REGS:
   
    L7 = DM(SLOC(L7), I7);

It's easier to read after "else ..." is removed

    MODE1STK = USTAT1;                   /* MODE1 has not been restored, 215xx allows access to the top of the STS         */

.RESTORE_SCRATCH_NONDATA_REGS:
   
    L7 = DM(SLOC(L7), I7);

and it is also easy to fix:

#if defined(HAS_MODE1STK)
    MODE1STK = USTAT1;                   /* MODE1 has not been restored, 215xx allows access to the top of the STS         */

    /* FIX for Anomaly 20000069 */
    NOP;
#else
                                         /* Restore MODE1 to a known value.  MMASK will have cleared most of these already */
                                         /* but as we need to clear some of the registers we do them all. The alternate    */
                                         /* register bits are not cleared by MMASK.                                        */
    BIT CLR MODE1 (OS_C_RUN_TIME_MODE1_CLR) | IRPTEN;   /* Disable ints */
    BIT SET MODE1 (OS_C_RUN_TIME_MODE1_SET);

    IMASK = R4;                            /* Restore IMASK now that interrupts are globally disabled                        */
#if defined(HAS_LIRPTL)
    LIRPTL_SET(R8)                         /* R8 holds the old LIRPTL value, R4 is used in the calculation.                  */
#endif
#endif


.RESTORE_SCRATCH_NONDATA_REGS:

 

I hope I could help those people, who had the same problem. The bug exists in ucos-III 2.0.0 to 2.4.0

Outcomes