[RTEMS Project] #4155: Add a workaround for the LEON3FT RETT Restart errata: TN-0018

RTEMS trac trac at rtems.org
Thu Mar 11 16:52:57 UTC 2021

#4155: Add a workaround for the LEON3FT RETT Restart errata: TN-0018
 Reporter:  Sebastian Huber  |       Owner:  Daniel Hellstrom
     Type:  defect           |      Status:  closed
 Priority:  normal           |   Milestone:  6.1
Component:  arch/sparc       |     Version:  5
 Severity:  normal           |  Resolution:  fixed
 Keywords:                   |  Blocked By:
 Blocking:                   |
Changes (by Daniel Hellstrom <daniel@…>):

 * status:  assigned => closed
 * resolution:   => fixed


 In [changeset:"b2da982c87e9e86561d1b6db18c01ea98c628467/rtems"
 #!CommitTicketReference repository="rtems"
 leon,tn-0018: work around GRLIB-TN-0018 errata


 The errata is worked around in the kernel without requiring toolchain
 modifications. It is triggered the JMPL/RETT return from trap instruction
 sequence never generated by the compiler and. There are also other
 conditions that must must be true to trigger the errata, for example the
 instruction that the trap returns to has to be a JMPL instruction. The
 errata can only be triggered if certain data is corrected by ECC
 (inflicted by radiation), thus it can not be triggered under normal
 operation. For more information see:

 Affected RTEMS target BSPs:
  * GR712RC
  * UT699
  * UT700/699E

 The work around is enabled by defining __FIX_LEON3_TN0018 at build time.
 After applying the following GCC patch, GCC will set the define when
 compiling for an affected multilib:
   * GR712RC (-mcpu=leon3 -mfix-gr712rc)
   * UT700/UT699E (-mpcu=leon3 -mfix-ut700)
   * UT699 (-mcpu=leon -mfix-ut699)
 When building for another multilib and TN0018 is still required, it
 is possible to enable it on the RTEMS kernel configure line using the
 TARGET_CFLAGS (-D__FIX_LEON3FT_TN0018) or other by other means.

 The following GCC patch sets __FIX_LEON3FT_TN0018 for the affected RTEMS
 diff --git a/gcc/config/sparc/rtemself.h b/gcc/config/sparc/rtemself.h
 index 6570590..ddec98c 100644
 --- a/gcc/config/sparc/rtemself.h
 +++ b/gcc/config/sparc/rtemself.h
 @@ -33,6 +33,8 @@
         builtin_assert ("system=rtems");        \
         if (sparc_fix_b2bst)                    \
           builtin_define ("__FIX_LEON3FT_B2BST"); \
 +       if (sparc_fix_gr712rc || sparc_fix_ut700 || sparc_fix_ut699) \
 +         builtin_define ("__FIX_LEON3FT_TN0018"); \
      }                                          \
    while (0)

 Workaround Implementation

 In general there are two approaches that the workaround uses:
  A) avoid ECC restarting the RETT instruction
  B) avoid returning from trap to a JMPL instruction

 Where A) comes at a higher performance cost than B), so B) is used
 where posssible. B) can be achived for certain returns from trap
 handlers if trap entry is controlled by assembly, such as system calls.

 A special JMPL/RETT sequence where instruction cache is disabled
 temporarily to avoid RETT containing ECC errors, and reading of RETT
 source registers to "clean" them from incorrect ECC just before RETT
 is executed.

 The work around prevents JMPL after system calls (TA instruction) and
 modifies assembly code on return from traps jumping back to application
 code. Note that for some traps the trapped instruction is always
 re-executed and can therefore not trigger the errata, for example the
 SAVE instruction causing window overflow or an float instruction causing
 FPU disabled trap.

 RTEMS SPARC traps workaround implementation:
    NAME                 NOTE   TRAP   COMMENT
  * window overflow         1 - 0x05   always returns to a SAVE
  * window underflow        1 - 0x06   always returns to a RESTORE
  * interrupt traps         2 - 0x10..1f special rett sequence workaround
  * syscall                 3 - 0x80   shutdown system - never returns
  * ABI flush windows       2 - 0x83   special rett sequence workaround
  * syscall_irqdis          4 - 0x89
  * syscall_irqen           4 - 0x8A
  * syscall_irqdis_fp       1 - 0x8B   always jumps back to FP instruction
  * syscall_lazy_fp_switch  5 - 0x04   A) jumps back to FP instruction, or
                                       B) _Internal_error() starting with

  1) no workaround needed because trap always returns to non-JMPL
  2) workaround implemented by special rett sequence
  3) no workaround needed because system call never returns
  4) workaround implemented by inserting NOP in system call generation.
     fall into 1) when workaround is enabled and no trap handler fix
  5) trap handler branches into both 1) and returning to _Internal_error()
     which starts with a SAVE and besides since it shuts down the system
     RETT should never be in cache (only executed once) so fix not
     in this case.

 Any custom trap handlers may also have to be updated. To simplify that,
 helper work around assembly code in macros are available in a separate
 include file <libcpu/grlib-tn-0018.h>.

 Close #4155.

Ticket URL: <http://devel.rtems.org/ticket/4155#comment:4>
RTEMS Project <http://www.rtems.org/>
RTEMS Project

More information about the bugs mailing list