From 38ca68d664702b11ee417afa73363dccd945ceab Mon Sep 17 00:00:00 2001 From: Daniel Cederman Date: Tue, 4 Oct 2016 09:05:04 +0200 Subject: ERRATA-FIX: Change assembler sequence that can cause stst errata See GRLIB-TN-0009: "LEON3FT Stale Cache Entry After Store with Data Tag Parity Error". --- c/src/lib/libcpu/sparc/access/access.S | 29 +++++++++++++++++ c/src/lib/libcpu/sparc/reg_win/window.S | 14 ++++++++ cpukit/score/cpu/sparc/cpu_asm.S | 52 ++++++++++++++++++++++++++++++ cpukit/score/cpu/sparc/rtems/score/sparc.h | 6 ++++ 4 files changed, 101 insertions(+) diff --git a/c/src/lib/libcpu/sparc/access/access.S b/c/src/lib/libcpu/sparc/access/access.S index 7e69f64c9d..e72cebb5b4 100644 --- a/c/src/lib/libcpu/sparc/access/access.S +++ b/c/src/lib/libcpu/sparc/access/access.S @@ -45,6 +45,33 @@ SYM(_ld64): retl ldd [%o0], %o0 +#if defined(__FIX_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 stub %o1, [%o0] @@ -63,3 +90,5 @@ SYM(_st_be64): SYM(_st64): retl std %o1, [%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 3ec3f50a10..fa327ec28a 100644 --- a/c/src/lib/libcpu/sparc/reg_win/window.S +++ b/c/src/lib/libcpu/sparc/reg_win/window.S @@ -65,12 +65,19 @@ SYM(window_overflow_trap_handler): mov %g1, %wim ! load new WIM nop; nop; nop ! 3 slot delay std %l0, [%sp + 0x00] ! save local register set + B2BSTORE_FIX std %l2, [%sp + 0x08] + B2BSTORE_FIX std %l4, [%sp + 0x10] + B2BSTORE_FIX std %l6, [%sp + 0x18] + B2BSTORE_FIX std %i0, [%sp + 0x20] ! save input register set + B2BSTORE_FIX std %i2, [%sp + 0x28] + B2BSTORE_FIX std %i4, [%sp + 0x30] + B2BSTORE_FIX std %i6, [%sp + 0x38] restore ! Go back to trap window. mov %l7, %g1 ! restore g1 @@ -202,13 +209,20 @@ save_frame_loop: */ std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET] + B2BSTORE_FIX std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET] + B2BSTORE_FIX std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET] + B2BSTORE_FIX std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET] + B2BSTORE_FIX std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET] + B2BSTORE_FIX std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET] + B2BSTORE_FIX std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET] + B2BSTORE_FIX std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET] sll %g4, 1, %g5 ! rotate the "wim" left 1 diff --git a/cpukit/score/cpu/sparc/cpu_asm.S b/cpukit/score/cpu/sparc/cpu_asm.S index 56e98b1fbe..7cf698e51b 100644 --- a/cpukit/score/cpu/sparc/cpu_asm.S +++ b/cpukit/score/cpu/sparc/cpu_asm.S @@ -65,21 +65,37 @@ SYM(_CPU_Context_save_fp): #endif ld [%i0], %l0 ! active due to pipeline delay!!! std %f0, [%l0 + FO_F1_OFFSET] + B2BSTORE_FIX std %f2, [%l0 + F2_F3_OFFSET] + B2BSTORE_FIX std %f4, [%l0 + F4_F5_OFFSET] + B2BSTORE_FIX std %f6, [%l0 + F6_F7_OFFSET] + B2BSTORE_FIX std %f8, [%l0 + F8_F9_OFFSET] + B2BSTORE_FIX std %f10, [%l0 + F1O_F11_OFFSET] + B2BSTORE_FIX std %f12, [%l0 + F12_F13_OFFSET] + B2BSTORE_FIX std %f14, [%l0 + F14_F15_OFFSET] + B2BSTORE_FIX std %f16, [%l0 + F16_F17_OFFSET] + B2BSTORE_FIX std %f18, [%l0 + F18_F19_OFFSET] + B2BSTORE_FIX std %f20, [%l0 + F2O_F21_OFFSET] + B2BSTORE_FIX std %f22, [%l0 + F22_F23_OFFSET] + B2BSTORE_FIX std %f24, [%l0 + F24_F25_OFFSET] + B2BSTORE_FIX std %f26, [%l0 + F26_F27_OFFSET] + B2BSTORE_FIX std %f28, [%l0 + F28_F29_OFFSET] + B2BSTORE_FIX std %f30, [%l0 + F3O_F31_OFFSET] + B2BSTORE_FIX st %fsr, [%l0 + FSR_OFFSET] 1: ret restore @@ -156,7 +172,9 @@ SYM(_CPU_Context_switch): ! skip g0 st %g1, [%o0 + G1_OFFSET] ! save the global registers std %g2, [%o0 + G2_OFFSET] + B2BSTORE_FIX std %g4, [%o0 + G4_OFFSET] + B2BSTORE_FIX std %g6, [%o0 + G6_OFFSET] ! load the address of the ISR stack nesting prevention flag @@ -165,21 +183,32 @@ SYM(_CPU_Context_switch): ! save it a bit later so we do not waste a couple of cycles std %l0, [%o0 + L0_OFFSET] ! save the local registers + B2BSTORE_FIX std %l2, [%o0 + L2_OFFSET] + B2BSTORE_FIX std %l4, [%o0 + L4_OFFSET] + B2BSTORE_FIX std %l6, [%o0 + L6_OFFSET] + B2BSTORE_FIX ! Now actually save ISR stack nesting prevention flag st %g2, [%o0 + ISR_DISPATCH_DISABLE_STACK_OFFSET] std %i0, [%o0 + I0_OFFSET] ! save the input registers + B2BSTORE_FIX std %i2, [%o0 + I2_OFFSET] + B2BSTORE_FIX std %i4, [%o0 + I4_OFFSET] + B2BSTORE_FIX std %i6, [%o0 + I6_FP_OFFSET] + B2BSTORE_FIX std %o0, [%o0 + O0_OFFSET] ! save the output registers + B2BSTORE_FIX std %o2, [%o0 + O2_OFFSET] + B2BSTORE_FIX std %o4, [%o0 + O4_OFFSET] + B2BSTORE_FIX std %o6, [%o0 + O6_SP_OFFSET] rd %psr, %o2 @@ -261,13 +290,20 @@ save_frame_loop: */ std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET] + B2BSTORE_FIX std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET] + B2BSTORE_FIX std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET] + B2BSTORE_FIX std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET] + B2BSTORE_FIX std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET] + B2BSTORE_FIX std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET] + B2BSTORE_FIX std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET] + B2BSTORE_FIX std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET] ba save_frame_loop @@ -427,14 +463,22 @@ win_ovflow: */ std %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET] + B2BSTORE_FIX std %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET] + B2BSTORE_FIX std %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET] + B2BSTORE_FIX std %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET] + B2BSTORE_FIX std %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET] + B2BSTORE_FIX std %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET] + B2BSTORE_FIX std %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET] + B2BSTORE_FIX std %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET] + B2BSTORE_FIX restore nop @@ -460,15 +504,22 @@ save_isf: ! make space for ISF std %l0, [%sp + ISF_PSR_OFFSET] ! save psr, PC + B2BSTORE_FIX st %l2, [%sp + ISF_NPC_OFFSET] ! save nPC st %g1, [%sp + ISF_G1_OFFSET] ! save g1 std %g2, [%sp + ISF_G2_OFFSET] ! save g2, g3 + B2BSTORE_FIX std %l4, [%sp + ISF_G4_OFFSET] ! save g4, g5 -- see above + B2BSTORE_FIX std %g6, [%sp + ISF_G6_OFFSET] ! save g6, g7 + B2BSTORE_FIX std %i0, [%sp + ISF_I0_OFFSET] ! save i0, i1 + B2BSTORE_FIX std %i2, [%sp + ISF_I2_OFFSET] ! save i2, i3 + B2BSTORE_FIX std %i4, [%sp + ISF_I4_OFFSET] ! save i4, i5 + B2BSTORE_FIX std %i6, [%sp + ISF_I6_FP_OFFSET] ! save i6/fp, i7 rd %y, %g1 @@ -498,6 +549,7 @@ save_isf: add %l6, 1, %l6 st %l6, [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))] + B2BSTORE_FIX add %l7, 1, %l7 st %l7, [%l5 + %lo(SYM(_ISR_Nest_level))] diff --git a/cpukit/score/cpu/sparc/rtems/score/sparc.h b/cpukit/score/cpu/sparc/rtems/score/sparc.h index a145209139..18cc8ccf4d 100644 --- a/cpukit/score/cpu/sparc/rtems/score/sparc.h +++ b/cpukit/score/cpu/sparc/rtems/score/sparc.h @@ -83,6 +83,12 @@ extern "C" { #define SPARC_HAS_FPU 1 #endif +#if defined(__FIX_B2BST) + #define B2BSTORE_FIX nop +#else + #define B2BSTORE_FIX +#endif + #if SPARC_HAS_FPU #define CPU_MODEL_NAME "w/FPU" #else -- cgit v1.2.3