summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu
diff options
context:
space:
mode:
authorDaniel Cederman <cederman@gaisler.com>2017-07-13 09:26:50 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-07-17 07:41:38 +0200
commit2f8704b6c8c3ce65cdf2b589a98de1d1d9dc8ffa (patch)
treebd540adf388432ec7db34e5d2c4a3d4b8574b344 /c/src/lib/libcpu
parentpsxtests: Add a mmap dedicated test case (diff)
downloadrtems-2f8704b6c8c3ce65cdf2b589a98de1d1d9dc8ffa.tar.bz2
sparc: Add assembly workaround for LEON3FT B2BST errata
This patch adds NOP instructions to prevent instruction sequences that are sensitive to the LEON3FT B2BST errata. See GRLIB-TN-0009: "LEON3FT Stale Cache Entry After Store with Data Tag Parity Error" for more information. The sequences are only modified if __FIX_LEON3FT_B2BST is defined. The patch works in conjunction with the -mfix-ut700, -mfix-gr712rc, and -mfix-ut699 GCC flags that prevents the sensitive sequences from being generated. Update #3057.
Diffstat (limited to 'c/src/lib/libcpu')
-rw-r--r--c/src/lib/libcpu/sparc/access/access.S28
-rw-r--r--c/src/lib/libcpu/sparc/reg_win/window.S12
2 files changed, 40 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/sparc/access/access.S b/c/src/lib/libcpu/sparc/access/access.S
index cb8693b776..9397cb815b 100644
--- a/c/src/lib/libcpu/sparc/access/access.S
+++ b/c/src/lib/libcpu/sparc/access/access.S
@@ -59,6 +59,33 @@ SYM(_ld64):
retl
ldd [%o0], %o0
+#if defined(__FIX_LEON3FT_B2BST)
+
+SYM(_st8):
+ stub %o1, [%o0]
+ retl
+ nop
+
+SYM(_st_be16):
+SYM(_st16):
+ stuh %o1, [%o0]
+ retl
+ nop
+
+SYM(_st_be32):
+SYM(_st32):
+ st %o1, [%o0]
+ retl
+ nop
+
+SYM(_st_be64):
+SYM(_st64):
+ std %o1, [%o0]
+ retl
+ nop
+
+#else
+
SYM(_st8):
retl
stb %o1, [%o0]
@@ -79,3 +106,4 @@ SYM(_st64):
mov %o1, %o2
retl
std %o2, [%o0]
+#endif
diff --git a/c/src/lib/libcpu/sparc/reg_win/window.S b/c/src/lib/libcpu/sparc/reg_win/window.S
index b8745593f5..5a36fd65be 100644
--- a/c/src/lib/libcpu/sparc/reg_win/window.S
+++ b/c/src/lib/libcpu/sparc/reg_win/window.S
@@ -51,19 +51,24 @@ SYM(window_overflow_trap_handler):
*/
std %l0, [%sp + 0x00] ! save local register set
+ SPARC_LEON3FT_B2BST_NOP
std %l2, [%sp + 0x08]
mov %wim, %l3
sll %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1 , %l2
! l2 = WIM << (Number Windows - 1)
std %l4, [%sp + 0x10]
+ SPARC_LEON3FT_B2BST_NOP
std %l6, [%sp + 0x18]
srl %l3, 1, %l3 ! l3 = WIM >> 1
wr %l3, %l2, %wim ! WIM = (WIM >> 1) ^
! (WIM << (Number Windows - 1))
! 3 instruction delay not needed here
std %i0, [%sp + 0x20] ! save input register set
+ SPARC_LEON3FT_B2BST_NOP
std %i2, [%sp + 0x28]
+ SPARC_LEON3FT_B2BST_NOP
std %i4, [%sp + 0x30]
+ SPARC_LEON3FT_B2BST_NOP
std %i6, [%sp + 0x38]
restore ! Go back to trap window.
jmp %l1 ! Re-execute save.
@@ -206,13 +211,20 @@ save_frame_loop:
*/
std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET]
+ SPARC_LEON3FT_B2BST_NOP
std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET]
+ SPARC_LEON3FT_B2BST_NOP
std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET]
+ SPARC_LEON3FT_B2BST_NOP
std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET]
+ SPARC_LEON3FT_B2BST_NOP
std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET]
+ SPARC_LEON3FT_B2BST_NOP
std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET]
+ SPARC_LEON3FT_B2BST_NOP
std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET]
+ SPARC_LEON3FT_B2BST_NOP
std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET]
ba save_frame_loop