summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Cederman <cederman@gaisler.com>2016-10-04 09:05:04 +0200
committerDaniel Cederman <cederman@gaisler.com>2016-10-04 09:05:04 +0200
commit38ca68d664702b11ee417afa73363dccd945ceab (patch)
tree023a07ac249c2a8df67103ef589b27500709c839
parentc7d624eedc3995f4554505e565013a5103d37c48 (diff)
ERRATA-FIX: Change assembler sequence that can cause stst erratarcc-v1.2.20
See GRLIB-TN-0009: "LEON3FT Stale Cache Entry After Store with Data Tag Parity Error".
-rw-r--r--c/src/lib/libcpu/sparc/access/access.S29
-rw-r--r--c/src/lib/libcpu/sparc/reg_win/window.S14
-rw-r--r--cpukit/score/cpu/sparc/cpu_asm.S52
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/sparc.h6
4 files changed, 101 insertions, 0 deletions
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