diff options
-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 | 85 | ||||
-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 | ||||
-rw-r--r-- | spec/build/cpukit/cpusparc.yml | 1 |
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 |