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