diff options
-rw-r--r-- | bsps/sparc/leon3/config/gr712rc.cfg | 5 | ||||
-rw-r--r-- | bsps/sparc/leon3/config/ut699.cfg | 3 | ||||
-rw-r--r-- | bsps/sparc/leon3/config/ut700.cfg | 3 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/cpu_asm.S | 3 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/headers.am | 1 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h | 58 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/include/rtems/score/sparc.h | 4 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/sparc-counter-asm.S | 4 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/window.S | 9 |
9 files changed, 85 insertions, 5 deletions
diff --git a/bsps/sparc/leon3/config/gr712rc.cfg b/bsps/sparc/leon3/config/gr712rc.cfg index 385293275c..e8f07315e7 100644 --- a/bsps/sparc/leon3/config/gr712rc.cfg +++ b/bsps/sparc/leon3/config/gr712rc.cfg @@ -10,10 +10,11 @@ RTEMS_CPU=sparc # and (hopefully) optimize for it. # GCC and clang use different switches to select target: ifneq (,$(findstring clang,$(CC))) - CPU_CFLAGS = -mcpu=gr712rc + CPU_CFLAGS = -mcpu=gr712rc -D__FIX_LEON3FT_TN0018 else - CPU_CFLAGS = -mcpu=leon3 -mfix-gr712rc + CPU_CFLAGS = -mcpu=leon3 -mfix-gr712rc -D__FIX_LEON3FT_TN0018 endif +# -D__FIX_LEON3FT_TN0018 enables kernel work around for GRLIB-TN-0018 errata # optimize flag: typically -O2 CFLAGS_OPTIMIZE_V = -O2 -g diff --git a/bsps/sparc/leon3/config/ut699.cfg b/bsps/sparc/leon3/config/ut699.cfg index a8fff49b3a..ed70cf5ee1 100644 --- a/bsps/sparc/leon3/config/ut699.cfg +++ b/bsps/sparc/leon3/config/ut699.cfg @@ -8,7 +8,8 @@ RTEMS_CPU=sparc # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. -CPU_CFLAGS = -mcpu=leon -mfix-ut699 +# -D__FIX_LEON3FT_TN0018 enables kernel work around for GRLIB-TN-0018 errata +CPU_CFLAGS = -mcpu=leon -mfix-ut699 -D__FIX_LEON3FT_TN0018 # optimize flag: typically -O2 CFLAGS_OPTIMIZE_V = -O2 -g diff --git a/bsps/sparc/leon3/config/ut700.cfg b/bsps/sparc/leon3/config/ut700.cfg index bcca9010ed..5c6fff8098 100644 --- a/bsps/sparc/leon3/config/ut700.cfg +++ b/bsps/sparc/leon3/config/ut700.cfg @@ -8,7 +8,8 @@ RTEMS_CPU=sparc # This contains the compiler options necessary to select the CPU model # and (hopefully) optimize for it. -CPU_CFLAGS = -mcpu=leon3 -mfix-ut700 +# -D__FIX_LEON3FT_TN0018 enables kernel work around for GRLIB-TN-0018 errata +CPU_CFLAGS = -mcpu=leon3 -mfix-ut700 -D__FIX_LEON3FT_TN0018 # optimize flag: typically -O2 CFLAGS_OPTIMIZE_V = -O2 -g diff --git a/cpukit/score/cpu/sparc/cpu_asm.S b/cpukit/score/cpu/sparc/cpu_asm.S index 1251faa2f7..e884fb2f9e 100644 --- a/cpukit/score/cpu/sparc/cpu_asm.S +++ b/cpukit/score/cpu/sparc/cpu_asm.S @@ -23,6 +23,7 @@ #include <rtems/asm.h> #include <rtems/score/percpu.h> +#include <libcpu/grlib-tn-0018.h> #if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH) #define FP_FRAME_OFFSET_FO_F1 (SPARC_MINIMUM_STACK_FRAME_SIZE + 0) @@ -895,11 +896,13 @@ simple_return: save ! Back to ISR dispatch window good_task_window: + TN0018_WAIT_IFLUSH %l3,%l4 ! GRLIB-TN-0018 work around macro mov %l0, %psr ! **** DISABLE TRAPS **** nop; nop; nop ! and restore condition codes. ld [%g1 + ISF_G1_OFFSET], %g1 ! restore g1 + TN0018_FIX %l3,%l4 ! GRLIB-TN-0018 work around macro jmp %l1 ! transfer control and rett %l2 ! go back to tasks window diff --git a/cpukit/score/cpu/sparc/headers.am b/cpukit/score/cpu/sparc/headers.am index f5fc1aa9e2..25eaeaa74a 100644 --- a/cpukit/score/cpu/sparc/headers.am +++ b/cpukit/score/cpu/sparc/headers.am @@ -1,6 +1,7 @@ ## This file was generated by "./boostrap -H". include_libcpu_HEADERS += score/cpu/sparc/include/libcpu/access.h include_libcpu_HEADERS += score/cpu/sparc/include/libcpu/byteorder.h +include_libcpu_HEADERS += score/cpu/sparc/include/libcpu/grlib-tn-0018.h include_machine_HEADERS += score/cpu/sparc/include/machine/elf_machdep.h include_rtems_HEADERS += score/cpu/sparc/include/rtems/asm.h include_rtems_score_HEADERS += score/cpu/sparc/include/rtems/score/cpu.h diff --git a/cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h b/cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h new file mode 100644 index 0000000000..f0154ab636 --- /dev/null +++ b/cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h @@ -0,0 +1,58 @@ +/* NOTE: the lda should be on offset 0x18 */ +#if defined(__FIX_LEON3FT_TN0018) + +/* LEON3 Cache controller register accessed via ASI 2 */ +#define ASI_CTRL 0x02 +#define CCTRL_IP_BIT 15 +#define CCTRL_ICS 0x3 + +/* + * l3: (out) original cctrl + * l4: (out) original cctrl with ics=0 + * NOTE: This macro modifies psr.icc. + */ +.macro TN0018_WAIT_IFLUSH out1 out2 +1: + ! wait for pending iflush to complete + lda [%g0] ASI_CTRL, \out1 + srl \out1, CCTRL_IP_BIT, \out2 + andcc \out2, 1, %g0 + bne 1b + andn \out1, CCTRL_ICS, \out2 +.endm + + +.macro TN0018_WRITE_PSR src + wr \src, %psr +.endm + +/* Prevent following jmp;rett sequence from "re-executing" due to cached RETT or source + * registers (l1 and l2) containing bit faults triggering ECC. + * + * l3: (in) original cctrl + * l4: (in) original cctrl with ics=0 + * NOTE: This macro MUST be immediately followed by the "jmp;rett" pair. + */ +.macro TN0018_FIX in1 in2 + .align 0x20 ! align the sta for performance + sta \in2, [%g0] ASI_CTRL ! disable icache + nop ! delay for sta to have effect on rett + or %l1, %l1, %l1 ! delay + catch rf parity error on l1 + or %l2, %l2, %l2 ! delay + catch rf parity error on l2 + sta \in1, [%g0] ASI_CTRL ! re-enable icache after rett + nop ! delay ensures insn after gets cached +.endm + +#else + +.macro TN0018_WAIT_IFLUSH out1 out2 +.endm + +.macro TN0018_WRITE_PSR src +.endm + +.macro TN0018_FIX in1 in2 +.endm + +#endif + diff --git a/cpukit/score/cpu/sparc/include/rtems/score/sparc.h b/cpukit/score/cpu/sparc/include/rtems/score/sparc.h index 4846520b46..3ef3d17847 100644 --- a/cpukit/score/cpu/sparc/include/rtems/score/sparc.h +++ b/cpukit/score/cpu/sparc/include/rtems/score/sparc.h @@ -319,7 +319,11 @@ void _SPARC_Set_TBR( uint32_t new_tbr ); static inline uint32_t sparc_disable_interrupts(void) { register uint32_t psr __asm__("g1"); /* return value of trap handler */ +#ifdef __FIX_LEON3FT_TN0018 + __asm__ volatile ( "ta %1\n\tnop\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS)); +#else __asm__ volatile ( "ta %1\n\t" : "=r" (psr) : "i" (SPARC_SWTRAP_IRQDIS)); +#endif return psr; } diff --git a/cpukit/score/cpu/sparc/sparc-counter-asm.S b/cpukit/score/cpu/sparc/sparc-counter-asm.S index fb7783e096..44c3fa8edb 100644 --- a/cpukit/score/cpu/sparc/sparc-counter-asm.S +++ b/cpukit/score/cpu/sparc/sparc-counter-asm.S @@ -116,6 +116,10 @@ SYM(_SPARC_Get_timecount_clock): bne .Lpending ld [%o5 + 20], %o4 ta SPARC_SWTRAP_IRQEN +#ifdef __FIX_LEON3FT_TN0018 + /* A nop is added to work around the GRLIB-TN-0018 errata */ + nop +#endif jmp %o7 + 8 sub %o4, %o0, %o0 .Lpending: diff --git a/cpukit/score/cpu/sparc/window.S b/cpukit/score/cpu/sparc/window.S index 5a36fd65be..4675248fe0 100644 --- a/cpukit/score/cpu/sparc/window.S +++ b/cpukit/score/cpu/sparc/window.S @@ -22,6 +22,7 @@ */ #include <rtems/asm.h> +#include <libcpu/grlib-tn-0018.h> .section ".text" /* @@ -247,12 +248,18 @@ done_flushing: * Restore the global registers we used */ - mov %l3, %g1 mov %l4, %g2 mov %l5, %g3 + + TN0018_WAIT_IFLUSH %l4,%l5 + TN0018_WRITE_PSR %g1 + + mov %l3, %g1 mov %l6, %g4 mov %l7, %g5 + TN0018_FIX %l4,%l5 + jmpl %l2, %g0 rett %l2 + 4 |