summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/score/cpu/sparc/cpu_asm.S3
-rw-r--r--cpukit/score/cpu/sparc/headers.am1
-rw-r--r--cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h85
-rw-r--r--cpukit/score/cpu/sparc/include/rtems/score/sparc.h4
-rw-r--r--cpukit/score/cpu/sparc/sparc-counter-asm.S4
-rw-r--r--cpukit/score/cpu/sparc/window.S9
-rw-r--r--spec/build/cpukit/cpusparc.yml1
7 files changed, 106 insertions, 1 deletions
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..62f33da6e8
--- /dev/null
+++ b/cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 Cobham Gailer AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* 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 a65acb89b1..166e89d58a 100644
--- a/cpukit/score/cpu/sparc/include/rtems/score/sparc.h
+++ b/cpukit/score/cpu/sparc/include/rtems/score/sparc.h
@@ -404,7 +404,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
diff --git a/spec/build/cpukit/cpusparc.yml b/spec/build/cpukit/cpusparc.yml
index c1f4d0720c..85fbdc4b3c 100644
--- a/spec/build/cpukit/cpusparc.yml
+++ b/spec/build/cpukit/cpusparc.yml
@@ -13,6 +13,7 @@ install:
source:
- cpukit/score/cpu/sparc/include/libcpu/access.h
- cpukit/score/cpu/sparc/include/libcpu/byteorder.h
+ - cpukit/score/cpu/sparc/include/libcpu/grlib-tn-0018.h
- destination: ${BSP_INCLUDEDIR}/machine
source:
- cpukit/score/cpu/sparc/include/machine/elf_machdep.h