diff options
author | Daniel Cederman <cederman@gaisler.com> | 2017-07-13 09:26:50 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-07-17 07:41:38 +0200 |
commit | 2f8704b6c8c3ce65cdf2b589a98de1d1d9dc8ffa (patch) | |
tree | bd540adf388432ec7db34e5d2c4a3d4b8574b344 /c/src/lib/libcpu | |
parent | psxtests: Add a mmap dedicated test case (diff) | |
download | rtems-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.S | 28 | ||||
-rw-r--r-- | c/src/lib/libcpu/sparc/reg_win/window.S | 12 |
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 |