forked from Imagelibrary/rtems
sparc: Add support for sptests/spcontext01
Implement _CPU_Context_validate() and _CPU_Context_volatile_clobber(). Update #2270.
This commit is contained in:
committed by
Sebastian Huber
parent
a9c4f15dbe
commit
1c59cad4aa
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
368
cpukit/score/cpu/sparc/sparc-context-validate.S
Normal file
368
cpukit/score/cpu/sparc/sparc-context-validate.S
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright (c) 2015 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@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_BUFFER (CPU_MINIMUM_STACK_FRAME_SIZE)
|
||||
#define FRAME_OFFSET_L0 (FRAME_OFFSET_BUFFER + 0x04)
|
||||
#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_SP (FRAME_OFFSET_I7 + 0x04)
|
||||
#define FRAME_END (FRAME_OFFSET_SP + 0x04)
|
||||
#define FRAME_SIZE \
|
||||
((FRAME_END + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1))
|
||||
|
||||
.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 + FRAME_OFFSET_BUFFER]
|
||||
ld [%sp + FRAME_OFFSET_BUFFER], %o1
|
||||
cmp %g1, %o1
|
||||
bne restore_registers
|
||||
nop
|
||||
.endm
|
||||
|
||||
.macro check_fsr_register reg
|
||||
st \reg, [%sp + FRAME_OFFSET_BUFFER]
|
||||
ld [%sp + FRAME_OFFSET_BUFFER], %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
|
||||
|
||||
.macro write_register reg
|
||||
add %g1, 1, %g1
|
||||
mov %g1, \reg
|
||||
.endm
|
||||
|
||||
.macro write_float_register reg
|
||||
add %g1, 1, %g1
|
||||
st %g1, [%sp + FRAME_OFFSET_BUFFER]
|
||||
ld [%sp + FRAME_OFFSET_BUFFER], \reg
|
||||
.endm
|
||||
|
||||
.macro write_fsr_register reg
|
||||
st \reg, [%sp + FRAME_OFFSET_BUFFER]
|
||||
ld [%sp + FRAME_OFFSET_BUFFER], %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 + FRAME_OFFSET_BUFFER]
|
||||
ld [%sp + FRAME_OFFSET_BUFFER], \reg
|
||||
.endm
|
||||
|
||||
.align 4
|
||||
PUBLIC(_CPU_Context_validate)
|
||||
SYM(_CPU_Context_validate):
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
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]
|
||||
st %sp, [%sp + FRAME_OFFSET_SP]
|
||||
|
||||
cmp %g4, 0
|
||||
bne write_locals_and_outputs
|
||||
nop
|
||||
be check_for_fp
|
||||
nop
|
||||
|
||||
new_check_cycle:
|
||||
clr %g4
|
||||
sub %g1, 1, %g1
|
||||
|
||||
/* Write pattern values into registers */
|
||||
|
||||
check_for_fp:
|
||||
cmp %g2, 0
|
||||
be write_y
|
||||
nop
|
||||
|
||||
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_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 */
|
||||
b write_locals_and_outputs
|
||||
nop
|
||||
|
||||
switch_to_next_window:
|
||||
save %sp, -FRAME_SIZE, %sp
|
||||
|
||||
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 */
|
||||
|
||||
add %g4, 1, %g4
|
||||
cmp %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
|
||||
bne switch_to_next_window
|
||||
nop
|
||||
|
||||
/* Dummy increment to set up reverse mechanism for checking process */
|
||||
add %g1, 1, %g1
|
||||
clr %g4
|
||||
|
||||
/* Checking begins here */
|
||||
window_checking:
|
||||
cmp %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
|
||||
be y_checking
|
||||
nop
|
||||
|
||||
further_checking:
|
||||
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.
|
||||
*/
|
||||
add %g4, 1, %g4
|
||||
cmp %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS
|
||||
bne dont_check_i0
|
||||
nop
|
||||
check_register %i0
|
||||
b y_checking
|
||||
nop
|
||||
|
||||
dont_check_i0:
|
||||
restore
|
||||
|
||||
ba window_checking
|
||||
nop
|
||||
|
||||
/* Check Y register */
|
||||
y_checking:
|
||||
mov %y, %o1
|
||||
check_register %o1
|
||||
cmp %g2, 0
|
||||
be new_check_cycle
|
||||
nop
|
||||
|
||||
/* Check floating point registers */
|
||||
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 new_check_cycle
|
||||
nop
|
||||
|
||||
/****** RESTORE STARTS HERE *******/
|
||||
|
||||
/* Restore non-volatile registers */
|
||||
|
||||
restore_registers:
|
||||
and %g4, (SPARC_NUMBER_OF_REGISTER_WINDOWS - 1), %g4
|
||||
cmp %g4, 0
|
||||
be real_restore
|
||||
nop
|
||||
restore
|
||||
sub %g4, 1, %g4
|
||||
bne restore_registers
|
||||
nop
|
||||
|
||||
real_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
|
||||
|
||||
sub %sp, -FRAME_SIZE, %sp
|
||||
|
||||
return_value:
|
||||
/* Load callback address and jump back */
|
||||
jmp %o7 + 8
|
||||
add %sp, FRAME_SIZE, %sp
|
||||
156
cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
Normal file
156
cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2015 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@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_END (SCRATCH_1 + 0x04)
|
||||
#define FRAME_SIZE \
|
||||
((FRAME_END + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1))
|
||||
|
||||
.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
|
||||
|
||||
.section ".bss"
|
||||
.align 4
|
||||
|
||||
/*
|
||||
* Use a global variable to vary the clobbered windows in each
|
||||
* invocation to test the window overflow and underflow conditions.
|
||||
*/
|
||||
window_clobber_count:
|
||||
.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(window_clobber_count), %o1
|
||||
ld [%o1 + %lo(window_clobber_count)], %o2
|
||||
add %o2, 1, %o2
|
||||
st %o2, [%o1 + %lo(window_clobber_count)]
|
||||
|
||||
/* Clear window counter number */
|
||||
clr %g1
|
||||
|
||||
/* Save pattern to global register */
|
||||
mov %o0, %g2
|
||||
|
||||
window_clobber:
|
||||
|
||||
/* Switch window */
|
||||
|
||||
save %sp, -FRAME_SIZE, %sp
|
||||
|
||||
/* Check how many windows shall be flushed */
|
||||
sethi %hi(window_clobber_count), %o1
|
||||
ld [%o1 + %lo(window_clobber_count)], %o2
|
||||
st %o2, [%o1 + %lo(window_clobber_count)]
|
||||
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
|
||||
sub %g1, 1, %g1
|
||||
ba restore_check
|
||||
nop
|
||||
|
||||
clobber_return:
|
||||
|
||||
jmp %o7 + 8
|
||||
add %sp, FRAME_SIZE, %sp
|
||||
Reference in New Issue
Block a user