summaryrefslogblamecommitdiffstats
path: root/cpukit/score/cpu/sparc/sparc-context-volatile-clobber.S
blob: ebbaec59a642caca114f687a6827a66749a9b886 (plain) (tree)
1
2
3
4
5

                                           
  
                                                   
  



















                                                                              


                    
                   


                      
                                
 
                                                  




































































































































                                                                           
            
/* SPDX-License-Identifier: BSD-2-Clause */

/*
 * Copyright (c) 2015 embedded brains GmbH & Co. KG
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <rtems/asm.h>
#include <rtems/score/cpuimpl.h>

#define SCRATCH_0 (SPARC_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
	 nop