two new Assembler Files for SPCONTEXT01 test on sparc
1) _CPU_Context_validate
2) _CPU_Context_volatile_clobber

Update #2270.
---
 cpukit/score/cpu/sparc/Makefile.am                 |   2 +
 cpukit/score/cpu/sparc/rtems/score/cpu.h           |  12 +-
 cpukit/score/cpu/sparc/sparc-context-validate.S    | 367 +++++++++++++++++++++
 .../cpu/sparc/sparc-context-volatile-clobber.S     | 153 +++++++++
 4 files changed, 524 insertions(+), 10 deletions(-)
 create mode 100644 cpukit/score/cpu/sparc/sparc-context-validate.S
 create mode 100644 cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S

diff --git a/cpukit/score/cpu/sparc/Makefile.am 
b/cpukit/score/cpu/sparc/Makefile.am
index c6ea1c3..8cf4f4a 100644
--- a/cpukit/score/cpu/sparc/Makefile.am
+++ b/cpukit/score/cpu/sparc/Makefile.am
@@ -11,6 +11,8 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
 
 noinst_LIBRARIES = libscorecpu.a
 libscorecpu_a_SOURCES = cpu.c cpu_asm.S
+libscorecpu_a_SOURCES += sparc-context-volatile-clobber.S
+libscorecpu_a_SOURCES += sparc-context-validate.S
 libscorecpu_a_SOURCES += sparc-counter.c
 libscorecpu_a_SOURCES += sparcv8-atomic.c
 libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h 
b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index 235b365..64e8750 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -1216,17 +1216,9 @@ void _CPU_Context_restore_fp(
   Context_Control_fp **fp_context_ptr
 );
 
-static inline void _CPU_Context_volatile_clobber( uintptr_t pattern )
-{
-  /* TODO */
-}
+void _CPU_Context_volatile_clobber( uintptr_t pattern );
 
-static inline void _CPU_Context_validate( uintptr_t pattern )
-{
-  while (1) {
-    /* TODO */
-  }
-}
+void _CPU_Context_validate( uintptr_t pattern );
 
 typedef struct {
   uint32_t trap;
diff --git a/cpukit/score/cpu/sparc/sparc-context-validate.S 
b/cpukit/score/cpu/sparc/sparc-context-validate.S
new file mode 100644
index 0000000..9e3f425
--- /dev/null
+++ b/cpukit/score/cpu/sparc/sparc-context-validate.S
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rt...@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+
+#define FRAME_OFFSET_L0 (CPU_MINIMUM_STACK_FRAME_SIZE)
+#define FRAME_OFFSET_L1 (FRAME_OFFSET_L0 + 0x04)
+#define FRAME_OFFSET_L2 (FRAME_OFFSET_L1 + 0x04)
+#define FRAME_OFFSET_L3 (FRAME_OFFSET_L2 + 0x04)
+#define FRAME_OFFSET_L4 (FRAME_OFFSET_L3 + 0x04)
+#define FRAME_OFFSET_L5 (FRAME_OFFSET_L4 + 0x04)
+#define FRAME_OFFSET_L6 (FRAME_OFFSET_L5 + 0x04)
+#define FRAME_OFFSET_L7 (FRAME_OFFSET_L6 + 0x04)
+#define FRAME_OFFSET_I0 (FRAME_OFFSET_L7 + 0x04)
+#define FRAME_OFFSET_I1 (FRAME_OFFSET_I0 + 0x04)
+#define FRAME_OFFSET_I2 (FRAME_OFFSET_I1 + 0x04)
+#define FRAME_OFFSET_I3 (FRAME_OFFSET_I2 + 0x04)
+#define FRAME_OFFSET_I4 (FRAME_OFFSET_I3 + 0x04)
+#define FRAME_OFFSET_I5 (FRAME_OFFSET_I4 + 0x04)
+#define FRAME_OFFSET_I6 (FRAME_OFFSET_I5 + 0x04)
+#define FRAME_OFFSET_I7 (FRAME_OFFSET_I6 + 0x04)
+#define FRAME_OFFSET_STACK_POINTER (FRAME_OFFSET_I7 + 0x04)
+#define BUFFER_STORAGE (FRAME_OFFSET_STACK_POINTER + 0x04)
+#define FRAME_SIZE (BUFFER_STORAGE + 0x04)
+
+#if ((FRAME_SIZE % CPU_ALIGNMENT) != 0)
+#define FRAME_SIZE (BUFFER_STORAGE + 0x04)
+#endif
+
+        .align 4
+        PUBLIC(_CPU_Context_validate)
+SYM(_CPU_Context_validate):
+
+startup:
+
+/* g2 checks if the Floating Point Unit in the Processor Status
+   Register (PSR) is set. */
+       mov     %psr, %g2
+       sethi   %hi(SPARC_PSR_EF_MASK), %g3
+       and     %g2, %g3, %g2
+
+/* g1 is used to save the original pattern. */
+       mov     %o0, %g1
+
+/* g4 establishes window counter. */
+       clr     %g4
+
+window_processing:
+
+       save    %sp, -FRAME_SIZE, %sp
+
+       st      %l0, [%sp + FRAME_OFFSET_L0]
+       st      %l1, [%sp + FRAME_OFFSET_L1]
+       st      %l2, [%sp + FRAME_OFFSET_L2]
+       st      %l3, [%sp + FRAME_OFFSET_L3]
+       st      %l4, [%sp + FRAME_OFFSET_L4]
+       st      %l5, [%sp + FRAME_OFFSET_L5]
+       st      %l6, [%sp + FRAME_OFFSET_L6]
+       st      %l7, [%sp + FRAME_OFFSET_L7]
+       st      %i0, [%sp + FRAME_OFFSET_I0]
+       st      %i1, [%sp + FRAME_OFFSET_I1]
+       st      %i2, [%sp + FRAME_OFFSET_I2]
+       st      %i3, [%sp + FRAME_OFFSET_I3]
+       st      %i4, [%sp + FRAME_OFFSET_I4]
+       st      %i5, [%sp + FRAME_OFFSET_I5]
+       st      %i6, [%sp + FRAME_OFFSET_I6]
+       st      %i7, [%sp + FRAME_OFFSET_I7]
+       st      %sp, [%sp + FRAME_OFFSET_STACK_POINTER]
+
+       cmp     %g4, 0
+       bne     write_locals_and_outputs
+        nop
+
+.macro write_register reg
+       add     %g1, 1, %g1
+       mov     %g1, \reg
+.endm
+
+.macro write_float_register reg
+       add     %g1, 1, %g1
+       st      %g1, [%sp+BUFFER_STORAGE]
+       ld      [%sp+BUFFER_STORAGE], \reg
+.endm
+
+.macro write_fsr_register reg
+       st      \reg, [%sp+BUFFER_STORAGE]
+       ld      [%sp+BUFFER_STORAGE], %o1
+       add     %g1, 1, %g1
+       clr     %g3
+/* FSR is masked with undefined, reserved or system-specific values
+   (e.g. FPU architecture version, FP queue). */
+       sethi   %hi(0xCF800000), %g3
+       or      %g3, %lo(0x0FFF), %g3
+       and     %g1, %g3, %g3
+       or      %o1, %g3, %g3
+       st      %g3, [%sp+BUFFER_STORAGE]
+       ld      [%sp+BUFFER_STORAGE], \reg
+.endm
+
+/* Write pattern values into registers. */
+
+       cmp     %g2, 0
+       be      write_y
+        nop
+
+write_floats:
+       write_fsr_register      %fsr
+       write_float_register    %f0
+       write_float_register    %f1
+       write_float_register    %f2
+       write_float_register    %f3
+       write_float_register    %f4
+       write_float_register    %f5
+       write_float_register    %f6
+       write_float_register    %f7
+       write_float_register    %f8
+       write_float_register    %f9
+       write_float_register    %f10
+       write_float_register    %f11
+       write_float_register    %f12
+       write_float_register    %f13
+       write_float_register    %f14
+       write_float_register    %f15
+       write_float_register    %f16
+       write_float_register    %f17
+       write_float_register    %f18
+       write_float_register    %f19
+       write_float_register    %f20
+       write_float_register    %f21
+       write_float_register    %f22
+       write_float_register    %f23
+       write_float_register    %f24
+       write_float_register    %f25
+       write_float_register    %f26
+       write_float_register    %f27
+       write_float_register    %f28
+       write_float_register    %f29
+       write_float_register    %f30
+       write_float_register    %f31
+
+write_y:
+       write_register  %y
+
+write_inputs:
+       write_register  %i0
+       write_register  %i1
+       write_register  %i2
+       write_register  %i3
+       write_register  %i4
+       write_register  %i5
+/* Don't write register $i6 => frame pointer. */
+/* Don't write register $i7 => return address. */
+
+write_locals_and_outputs:
+
+/* l0 is used as a scratch register */
+       write_register  %l1
+       write_register  %l2
+       write_register  %l3
+       write_register  %l4
+       write_register  %l5
+       write_register  %l6
+       write_register  %l7
+       write_register  %o1
+       write_register  %o2
+       write_register  %o3
+       write_register  %o4
+       write_register  %o5
+/* Don't write register $o6 => stack pointer. */
+/* Don't write register $o7 => return address. */
+
+write_all_registers:
+       add     %g4, 1, %g4
+       cmp     %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
+       bne     window_processing
+        nop
+
+dummy_increment:
+/* Dummy increment to set up reverse mechanism for checking process. */
+       add     %g1, 1, %g1
+       clr     %g4
+
+/* Checking begins here. */
+
+.macro check_register reg
+       sub     %g1, 1, %g1
+       cmp     %g1, \reg
+       bne     restore_registers
+        nop
+.endm
+
+.macro check_float_register reg
+       sub     %g1, 1, %g1
+       st      \reg, [%sp+BUFFER_STORAGE]
+       ld      [%sp+BUFFER_STORAGE], %o1
+       cmp     %g1, %o1
+       bne     restore_registers
+        nop
+.endm
+
+.macro check_fsr_register reg
+       st      \reg, [%sp+BUFFER_STORAGE]
+       ld      [%sp+BUFFER_STORAGE], %o1
+       sub     %g1, 1, %g1
+       clr     %g3
+       sethi   %hi(0xCF800000), %g3
+       or      %g3, %lo(0x0FFF), %g3
+       and     %g1, %g3, %g3
+       and     %o1, %g3, %o1
+       cmp     %o1, %g3
+       bne     restore_registers
+        nop
+.endm
+
+
+window_checking:
+       cmp     %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
+       be      y_checking
+        nop
+
+further_checking:
+       ld      [%sp + FRAME_OFFSET_STACK_POINTER], %l0
+       cmp     %l0, %sp
+       bne     restore_registers
+        nop
+       cmp     %g4, 0
+       bne     goto_local_registers
+        nop
+
+/* Check normal registers*/
+       check_register  %o5
+       check_register  %o4
+       check_register  %o3
+       check_register  %o2
+       check_register  %o1
+
+goto_local_registers:
+       check_register  %l7
+       check_register  %l6
+       check_register  %l5
+       check_register  %l4
+       check_register  %l3
+       check_register  %l2
+       check_register  %l1
+       
+       check_register  %i5
+       check_register  %i4
+       check_register  %i3
+       check_register  %i2
+       check_register  %i1
+
+/* For the last window i0 also needs to be checked as this variable
+   is not overwritten by the outputs of another window. */
+       cmp     %g4, (SPARC_NUMBER_OF_REGISTER_WINDOWS - 1)
+       bne     dont_check_i0
+        nop
+       check_register  %i0
+
+dont_check_i0:
+       restore
+       add     %g4, 1, %g4
+
+       ba      window_checking
+        nop
+
+/* Check Y register. */
+
+y_checking:
+       mov     %y, %o1
+       check_register  %o1
+       cmp     %g2, 0
+       be      startup
+        nop
+
+/* Check floating point registers. */
+
+float_checking:
+
+       check_float_register    %f31
+       check_float_register    %f30
+       check_float_register    %f29
+       check_float_register    %f28
+       check_float_register    %f27
+       check_float_register    %f26
+       check_float_register    %f25
+       check_float_register    %f24
+       check_float_register    %f23
+       check_float_register    %f22
+       check_float_register    %f21
+       check_float_register    %f20
+       check_float_register    %f19
+       check_float_register    %f18
+       check_float_register    %f17
+       check_float_register    %f16
+       check_float_register    %f15
+       check_float_register    %f14
+       check_float_register    %f13
+       check_float_register    %f12
+       check_float_register    %f11
+       check_float_register    %f10
+       check_float_register    %f9
+       check_float_register    %f8
+       check_float_register    %f7
+       check_float_register    %f6
+       check_float_register    %f5
+       check_float_register    %f4
+       check_float_register    %f3
+       check_float_register    %f2
+       check_float_register    %f1
+       check_float_register    %f0
+       check_fsr_register      %fsr
+
+       be      startup
+        nop
+
+/****** RESTORE STARTS HERE *******/
+
+/* Restore non-volatile registers. */
+
+restore_registers:
+
+       ld      [%sp + FRAME_OFFSET_L0], %l0
+       ld      [%sp + FRAME_OFFSET_L1], %l1
+       ld      [%sp + FRAME_OFFSET_L2], %l2
+       ld      [%sp + FRAME_OFFSET_L3], %l3
+       ld      [%sp + FRAME_OFFSET_L4], %l4
+       ld      [%sp + FRAME_OFFSET_L5], %l5
+       ld      [%sp + FRAME_OFFSET_L6], %l6
+       ld      [%sp + FRAME_OFFSET_L7], %l7
+       ld      [%sp + FRAME_OFFSET_I0], %i0
+       ld      [%sp + FRAME_OFFSET_I1], %i1
+       ld      [%sp + FRAME_OFFSET_I2], %i2
+       ld      [%sp + FRAME_OFFSET_I3], %i3
+       ld      [%sp + FRAME_OFFSET_I4], %i4
+       ld      [%sp + FRAME_OFFSET_I5], %i5
+       ld      [%sp + FRAME_OFFSET_I6], %i6
+       ld      [%sp + FRAME_OFFSET_I7], %i7
+
+       and     %g4, (SPARC_NUMBER_OF_REGISTER_WINDOWS - 1), %g4
+       cmp     %g4, 0
+       be      return_value
+        nop
+       restore
+       sub     %g4, 1, %g4
+       bne     restore_registers
+        nop
+
+return_value:
+/* Load callback address and jump back. */
+       jmp     %o7+8
+        add    %sp, FRAME_SIZE, %sp
diff --git a/cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S 
b/cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
new file mode 100644
index 0000000..8fbbac7
--- /dev/null
+++ b/cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rt...@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+
+#define SCRATCH_0 (CPU_MINIMUM_STACK_FRAME_SIZE)
+#define SCRATCH_1 (SCRATCH_0 + 0x04)
+#define FRAME_SIZE (SCRATCH_1 + 0x04)
+
+       .global i
+       .section        ".bss"
+       .align 4
+       .type   i, #object
+       .size   i, 4
+i:
+
+       .skip   4
+       .section        ".text"
+       .align  4
+
+        PUBLIC(_CPU_Context_volatile_clobber)
+SYM(_CPU_Context_volatile_clobber):
+
+       /* increment number of flushed windows by one */
+       sethi   %hi(i), %o1
+       ld      [%o1+%lo(i)], %o2
+       add     %o2, 1, %o2
+       st      %o2, [%o1+%lo(i)]
+
+       /* clear window counter number */
+       clr     %g1
+
+       /* save pattern to global register */
+       mov     %o0, %g2
+
+.macro clobber_register reg
+       sub     %g2, 1, %g2
+       mov     %g2, \reg
+.endm
+
+.macro clobber_fp_register reg
+       sub     %g2, 1, %g2
+       st      %g2, [%sp+SCRATCH_0]
+       ld      [%sp+SCRATCH_0], \reg
+.endm
+
+window_clobber:
+
+       /* switch window */
+
+       save    %sp, -FRAME_SIZE, %sp
+
+       /* check how many windows shall be flushed*/
+       sethi   %hi(i), %o1
+       ld      [%o1+%lo(i)], %o2
+       st      %o2, [%o1+%lo(i)]
+       and     %o2, (SPARC_NUMBER_OF_REGISTER_WINDOWS - 1), %o1
+       cmp     %o1, 0
+       bne     no_manual_update
+        nop
+       add     %o1, SPARC_NUMBER_OF_REGISTER_WINDOWS, %o1
+
+no_manual_update:
+       /* register to determine whether FPU is switched on */
+       mov     %psr, %o2
+       sethi   %hi(SPARC_PSR_EF_MASK), %o3
+       and     %o3, %o2, %o2
+
+       clobber_register        %o3
+       clobber_register        %o4
+       clobber_register        %o5
+/* don't overwrite return address $o7 */
+       clobber_register        %g3
+       clobber_register        %g4
+       clobber_register        %y
+
+       cmp     %o2, 0
+       be      window_update_check
+        nop
+
+       clobber_fp_register     %f0
+       clobber_fp_register     %f1
+       clobber_fp_register     %f2
+       clobber_fp_register     %f3
+       clobber_fp_register     %f4
+       clobber_fp_register     %f5
+       clobber_fp_register     %f6
+       clobber_fp_register     %f7
+       clobber_fp_register     %f8
+       clobber_fp_register     %f9
+       clobber_fp_register     %f10
+       clobber_fp_register     %f11
+       clobber_fp_register     %f12
+       clobber_fp_register     %f13
+       clobber_fp_register     %f14
+       clobber_fp_register     %f15
+       clobber_fp_register     %f16
+       clobber_fp_register     %f17
+       clobber_fp_register     %f18
+       clobber_fp_register     %f19
+       clobber_fp_register     %f20
+       clobber_fp_register     %f21
+       clobber_fp_register     %f22
+       clobber_fp_register     %f23
+       clobber_fp_register     %f24
+       clobber_fp_register     %f25
+       clobber_fp_register     %f26
+       clobber_fp_register     %f27
+       clobber_fp_register     %f28
+       clobber_fp_register     %f29
+       clobber_fp_register     %f30
+       clobber_fp_register     %f31
+
+window_update_check:
+
+       /* counter to how many windows were switched */
+       add     %g1, 1, %g1
+       cmp     %g1, %o1
+       bl      window_clobber
+        nop
+
+restore_check:
+
+       cmp     %g1, 0
+       be      clobber_return
+        nop
+
+restore_instance:
+       restore
+       sub     %g1, 1, %g1
+       ba      restore_check
+        nop
+
+clobber_return:
+
+       jmp     %o7+8
+        add    %sp, FRAME_SIZE, %sp
-- 
1.8.4.5

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to