xref: /openbmc/linux/arch/mips/kernel/r4k_switch.S (revision 3eb66e91a25497065c5322b1268cbc3953642227)
11da177e4SLinus Torvalds/*
21da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public
31da177e4SLinus Torvalds * License.  See the file "COPYING" in the main directory of this archive
41da177e4SLinus Torvalds * for more details.
51da177e4SLinus Torvalds *
61da177e4SLinus Torvalds * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle
779add627SJustin P. Mattock * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
81da177e4SLinus Torvalds * Copyright (C) 1994, 1995, 1996, by Andreas Busse
91da177e4SLinus Torvalds * Copyright (C) 1999 Silicon Graphics, Inc.
101da177e4SLinus Torvalds * Copyright (C) 2000 MIPS Technologies, Inc.
111da177e4SLinus Torvalds *    written by Carsten Langgaard, carstenl@mips.com
121da177e4SLinus Torvalds */
131da177e4SLinus Torvalds#include <asm/asm.h>
141da177e4SLinus Torvalds#include <asm/cachectl.h>
151da177e4SLinus Torvalds#include <asm/mipsregs.h>
16048eb582SSam Ravnborg#include <asm/asm-offsets.h>
171da177e4SLinus Torvalds#include <asm/regdef.h>
181da177e4SLinus Torvalds#include <asm/stackframe.h>
191da177e4SLinus Torvalds#include <asm/thread_info.h>
201da177e4SLinus Torvalds
211da177e4SLinus Torvalds#include <asm/asmmacro.h>
221da177e4SLinus Torvalds
231da177e4SLinus Torvalds/*
241da177e4SLinus Torvalds * task_struct *resume(task_struct *prev, task_struct *next,
251a3d5957SPaul Burton *		       struct thread_info *next_ti)
261da177e4SLinus Torvalds */
271da177e4SLinus Torvalds	.align	5
281da177e4SLinus Torvalds	LEAF(resume)
295323180dSAtsushi Nemoto	mfc0	t1, CP0_STATUS
305323180dSAtsushi Nemoto	LONG_S	t1, THREAD_STATUS(a0)
311da177e4SLinus Torvalds	cpu_save_nonscratch a0
321da177e4SLinus Torvalds	LONG_S	ra, THREAD_REG31(a0)
331da177e4SLinus Torvalds
34*050e9baaSLinus Torvalds#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
358b3c569aSJames Hogan	PTR_LA	t8, __stack_chk_guard
361400eb65SGregory Fong	LONG_L	t9, TASK_STACK_CANARY(a1)
371400eb65SGregory Fong	LONG_S	t9, 0(t8)
381400eb65SGregory Fong#endif
391400eb65SGregory Fong
401da177e4SLinus Torvalds	/*
411da177e4SLinus Torvalds	 * The order of restoring the registers takes care of the race
421da177e4SLinus Torvalds	 * updating $28, $29 and kernelsp without disabling ints.
431da177e4SLinus Torvalds	 */
441da177e4SLinus Torvalds	move	$28, a2
451da177e4SLinus Torvalds	cpu_restore_nonscratch a1
461da177e4SLinus Torvalds
473bd39664SRalf Baechle	PTR_ADDU	t0, $28, _THREAD_SIZE - 32
481da177e4SLinus Torvalds	set_saved_sp	t0, t1, t2
491da177e4SLinus Torvalds	mfc0	t1, CP0_STATUS		/* Do we really need this? */
501da177e4SLinus Torvalds	li	a3, 0xff01
511da177e4SLinus Torvalds	and	t1, a3
521da177e4SLinus Torvalds	LONG_L	a2, THREAD_STATUS(a1)
531da177e4SLinus Torvalds	nor	a3, $0, a3
541da177e4SLinus Torvalds	and	a2, a3
551da177e4SLinus Torvalds	or	a2, t1
561da177e4SLinus Torvalds	mtc0	a2, CP0_STATUS
571da177e4SLinus Torvalds	move	v0, a0
581da177e4SLinus Torvalds	jr	ra
591da177e4SLinus Torvalds	END(resume)
60