[PATCH 1/2] SPARC Floating Point Context switch
Gedare Bloom
gedare at rtems.org
Thu Apr 30 14:46:32 UTC 2015
On Thu, Apr 30, 2015 at 5:38 AM, Alexander Krutwig
<alexander.krutwig at embedded-brains.de> wrote:
> 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 | 283 +++++++++++++++++++++
> .../cpu/sparc/sparc-context-volatile-clobber.S | 92 +++++++
> 4 files changed, 379 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..b75cf83
> --- /dev/null
> +++ b/cpukit/score/cpu/sparc/sparc-context-validate.S
> @@ -0,0 +1,283 @@
> +/*
> + * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
> + *
> + * embedded brains GmbH
> + * Dornierstr. 4
> + * 82178 Puchheim
> + * Germany
> + * <rtems at 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 68
> +#define FRAME_OFFSET_L1 72
> +#define FRAME_OFFSET_L2 76
> +#define FRAME_OFFSET_L3 80
> +#define FRAME_OFFSET_L4 84
> +#define FRAME_OFFSET_L5 88
> +#define FRAME_OFFSET_L6 92
> +#define FRAME_OFFSET_L7 96
> +#define FRAME_OFFSET_I0 100
> +#define FRAME_OFFSET_I1 104
> +#define FRAME_OFFSET_I2 108
> +#define FRAME_OFFSET_I3 112
> +#define FRAME_OFFSET_I4 116
> +#define FRAME_OFFSET_I5 120
> +#define FRAME_OFFSET_I6 124
> +#define FRAME_OFFSET_I7 128
> +#define FRAME_OFFSET_O7 132
> +#define BUFFER_STORAGE 136
> +#define FRAME_SIZE (BUFFER_STORAGE + 8)
> +
These belong in sparc.h? Also it may be better to define each offset
in terms of the previous one + 4.
> +#if ((FRAME_SIZE % 8) != 0)
> +#error "Frame size alignment violated"
> +#endif
> +
How is this ever the case?
> + .align 4
> + PUBLIC(_CPU_Context_validate)
> +SYM(_CPU_Context_validate):
> +
> + add %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]
> +
> + /* Save callback address in case of error */
> +
> + st %o7, [%sp + FRAME_OFFSET_O7]
> +
> +.macro fill_register reg
> + add %g1, 1, %g1
> + mov %g1, \reg
> +.endm
> +
I forget if we have any recommendations for/against using .macro
directives in assembly. Anyone have thoughts?
> + /* Fill */
> +
This terminology is misleading on sparc, where filling registers has a
usual meaning while register windowing.
> + /* g1 is used for temporary values */
> + mov %o0, %g1
> +
> + mov %sp, %g2
> +
To use g2 i think you must declare it as scratch?
Some documentation on what this function does would be good, do we
have it somewhere else already?
> + fill_register %o1
> + fill_register %o2
> + fill_register %o3
> + fill_register %o4
> + fill_register %o5
Maybe mention that o6 (sp) isn't "filled'
> + fill_register %l0
> + fill_register %l1
> + fill_register %l2
> + fill_register %l3
> + fill_register %l4
> + fill_register %l5
> + fill_register %l6
> + fill_register %l7
> + fill_register %i0
> + fill_register %i1
> + fill_register %i2
> + fill_register %i3
> + fill_register %i4
> + fill_register %i5
> + /* Don't fill register $i6 => frame pointer */
> + fill_register %i7
> + fill_register %y
> +
> + /* g3 checks if the Floating Point Unit in the Processor Status
> + Register (PSR) is set */
> + mov %psr, %g3
> + sethi %hi(4096), %g4
g3 and g4 must be declared scratch. what does ABI say about using
these registers without saving them here
> + and %g3, %g4, %g3
> + cmp %g3, 0
> + be check
> + nop
> +
> +.macro fill_float_register reg
> + add %g1, 1, %g1
> + st %g1, [%sp+BUFFER_STORAGE]
> + ld [%sp+BUFFER_STORAGE], \reg
> +.endm
> +
> + fill_float_register %f0
> + fill_float_register %f1
> + fill_float_register %f2
> + fill_float_register %f3
> + fill_float_register %f4
> + fill_float_register %f5
> + fill_float_register %f6
> + fill_float_register %f7
> + fill_float_register %f8
> + fill_float_register %f9
> + fill_float_register %f10
> + fill_float_register %f11
> + fill_float_register %f12
> + fill_float_register %f13
> + fill_float_register %f14
> + fill_float_register %f15
> + fill_float_register %f16
> + fill_float_register %f17
> + fill_float_register %f18
> + fill_float_register %f19
> + fill_float_register %f20
> + fill_float_register %f21
> + fill_float_register %f22
> + fill_float_register %f23
> + fill_float_register %f24
> + fill_float_register %f25
> + fill_float_register %f26
> + fill_float_register %f27
> + fill_float_register %f28
> + fill_float_register %f29
> + fill_float_register %f30
> + fill_float_register %f31
> +
> + /* Check normal registers*/
> +
> +check:
> +
> +.macro check_register reg
> + add %g1, 1, %g1
> + cmp %g1, \reg
> + bne restore
> + nop
> +.endm
> +
> + cmp %g2, %sp
> + bne restore
> +
> + mov %o0, %g1
> + fill_register %o1
> +
> + mov %o0, %g1
> +
> + check_register %o1
> + check_register %o2
> + check_register %o3
> + check_register %o4
> + check_register %o5
> + check_register %l0
> + check_register %l1
> + check_register %l2
> + check_register %l3
> + check_register %l4
> + check_register %l5
> + check_register %l6
> + check_register %l7
> + check_register %i0
> + check_register %i1
> + check_register %i2
> + check_register %i3
> + check_register %i4
> + check_register %i5
> + check_register %i7
> +
> + /* Check special purpose register Y */
> + mov %y, %o1
> + check_register %o1
> +
> + cmp %g3, 0
> + bne check_float
> + nop
> +
> + be check
> + nop
> +
> + /* Restore non-volatile registers */
> +
> +restore:
> +
> + 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
> +
> + /* Load callback address and jump back*/
> + ld [%sp + FRAME_OFFSET_O7], %o7
> + jmp %o7+8
> + add %sp, FRAME_SIZE, %sp
> +
> + /* Check floating-point registers */
> +
> +check_float:
> +
> +.macro check_float_register reg
> + add %g1, 1, %g1
> + st \reg, [%sp+BUFFER_STORAGE]
> + ld [%sp+BUFFER_STORAGE], %o1
> + cmp %g1, %o1
> + bne restore
> + nop
> +.endm
> +
> + check_float_register %f0
> + check_float_register %f1
> + check_float_register %f2
> + check_float_register %f3
> + check_float_register %f4
> + check_float_register %f5
> + check_float_register %f6
> + check_float_register %f7
> + check_float_register %f8
> + check_float_register %f9
> + check_float_register %f10
> + check_float_register %f11
> + check_float_register %f12
> + check_float_register %f13
> + check_float_register %f14
> + check_float_register %f15
> + check_float_register %f16
> + check_float_register %f17
> + check_float_register %f18
> + check_float_register %f19
> + check_float_register %f20
> + check_float_register %f21
> + check_float_register %f22
> + check_float_register %f23
> + check_float_register %f24
> + check_float_register %f25
> + check_float_register %f26
> + check_float_register %f27
> + check_float_register %f28
> + check_float_register %f29
> + check_float_register %f30
> + check_float_register %f31
> +
> + mov %o0, %g1
> + fill_register %o1
> +
> + b check
> + nop
> 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..b30a303
> --- /dev/null
> +++ b/cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
> @@ -0,0 +1,92 @@
> +/*
> + * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
> + *
> + * embedded brains GmbH
> + * Dornierstr. 4
> + * 82178 Puchheim
> + * Germany
> + * <rtems at 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/system.h>
> +
> + .align 4
> + PUBLIC(_CPU_Context_volatile_clobber)
> +SYM(_CPU_Context_volatile_clobber):
> +
> +.macro clobber_register reg
> + sub %o0, 1, %o0
> + mov %o0, \reg
> +.endm
> +
> +.macro clobber_fp_register reg
> + sub %o0, 1, %o0
> + st %o0, [%sp+72]
72?
> + ld [%sp+72], \reg
> +.endm
> +
> + add %sp, -80, %sp
-80?
> + st %o7, [%sp+76]
76?
> +
> + clobber_register %o1
> + clobber_register %o2
> + clobber_register %o3
> + clobber_register %o4
> + clobber_register %o5
> + clobber_register %o7
> + clobber_register %y
> +
> + mov %psr, %o1
> + sethi %hi(4096), %o2
> + and %o1, %o2, %o2
> + cmp %o2, 0
> + be clobber_return
> + 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
> +
> +clobber_return:
> +
> + ld [%sp+76], %o7
> + jmp %o7+8
> + add %sp, 80, %sp
> --
> 1.8.4.5
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
More information about the devel
mailing list