summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg3
-rw-r--r--c/src/lib/libcpu/sparc/reg_win/window.S10
-rw-r--r--c/src/lib/libcpu/sparc/syscall/syscall.S2
-rw-r--r--cpukit/score/cpu/sparc/Makefile.am2
-rw-r--r--cpukit/score/cpu/sparc/cpu_asm.S3
-rw-r--r--cpukit/score/cpu/sparc/preinstall.am4
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/grlib-tn-0018.h58
7 files changed, 79 insertions, 3 deletions
diff --git a/c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg b/c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg
index 48f125b551..14cd029513 100644
--- a/c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg
+++ b/c/src/lib/libbsp/sparc/leon3/make/custom/leon3.cfg
@@ -11,7 +11,8 @@ RTEMS_CPU_MODEL=leon3
# This contains the compiler options necessary to select the CPU model
# and (hopefully) optimize for it.
-CPU_CFLAGS = -mcpu=cypress -msoft-float -mtune=ut699 -mfix-ut700 -mfix-gr712rc
+CPU_CFLAGS = -mcpu=cypress -msoft-float -mtune=ut699 -mfix-ut700 -mfix-gr712rc -D__FIX_LEON3FT_TN0018
+# -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/c/src/lib/libcpu/sparc/reg_win/window.S b/c/src/lib/libcpu/sparc/reg_win/window.S
index fa327ec28a..3c3443f850 100644
--- a/c/src/lib/libcpu/sparc/reg_win/window.S
+++ b/c/src/lib/libcpu/sparc/reg_win/window.S
@@ -24,6 +24,8 @@
*/
#include <rtems/asm.h>
+#include <rtems/score/grlib-tn-0018.h>
+
.seg "text"
/*
@@ -254,12 +256,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
diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.S b/c/src/lib/libcpu/sparc/syscall/syscall.S
index aa69f45d48..029027e7c9 100644
--- a/c/src/lib/libcpu/sparc/syscall/syscall.S
+++ b/c/src/lib/libcpu/sparc/syscall/syscall.S
@@ -63,6 +63,7 @@ SYM(sparc_disable_interrupts):
mov SYS_irqdis, %g1
ta 0
+ nop
retl
nop
@@ -72,6 +73,7 @@ SYM(sparc_enable_interrupts):
mov SYS_irqen, %g1
ta 0
+ nop
retl
nop
diff --git a/cpukit/score/cpu/sparc/Makefile.am b/cpukit/score/cpu/sparc/Makefile.am
index 6d4c4aead1..714d2e1c1b 100644
--- a/cpukit/score/cpu/sparc/Makefile.am
+++ b/cpukit/score/cpu/sparc/Makefile.am
@@ -9,7 +9,7 @@ include_rtems_HEADERS = rtems/asm.h
include_rtems_scoredir = $(includedir)/rtems/score
include_rtems_score_HEADERS = rtems/score/sparc.h rtems/score/cpu.h \
- rtems/score/types.h
+ rtems/score/types.h rtems/score/grlib-tn-0018.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
diff --git a/cpukit/score/cpu/sparc/cpu_asm.S b/cpukit/score/cpu/sparc/cpu_asm.S
index 7cf698e51b..fa2262a8af 100644
--- a/cpukit/score/cpu/sparc/cpu_asm.S
+++ b/cpukit/score/cpu/sparc/cpu_asm.S
@@ -26,6 +26,7 @@
#endif
#include <rtems/asm.h>
+#include <rtems/score/grlib-tn-0018.h>
#if (SPARC_HAS_FPU == 1)
@@ -937,11 +938,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/preinstall.am b/cpukit/score/cpu/sparc/preinstall.am
index da9dde121f..bf7045abdc 100644
--- a/cpukit/score/cpu/sparc/preinstall.am
+++ b/cpukit/score/cpu/sparc/preinstall.am
@@ -39,3 +39,7 @@ $(PROJECT_INCLUDE)/rtems/score/types.h: rtems/score/types.h $(PROJECT_INCLUDE)/r
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/types.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/types.h
+$(PROJECT_INCLUDE)/rtems/score/grlib-tn-0018.h: rtems/score/grlib-tn-0018.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/grlib-tn-0018.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/grlib-tn-0018.h
+
diff --git a/cpukit/score/cpu/sparc/rtems/score/grlib-tn-0018.h b/cpukit/score/cpu/sparc/rtems/score/grlib-tn-0018.h
new file mode 100644
index 0000000000..f0154ab636
--- /dev/null
+++ b/cpukit/score/cpu/sparc/rtems/score/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
+