
/* 
 * Mach Operating System
 * Copyright (c) 1989 Carnegie-Mellon University
 * All rights reserved.  The CMU software License Agreement specifies
 * the terms and conditions for use and redistribution.
 */
/*
 * HISTORY
 * $Log:	csw.s,v $
 * Revision 2.4  89/11/13  12:56:31  mrt
 * 	Removed include of regdef.h since those definitions
 * 	are now in asm.h
 * 	[89/11/13            mrt]
 * 
 * Revision 2.3  89/08/28  16:19:05  mrt
 * 	Changed include of asm.h and regdef.h to mips/
 * 	[89/08/15            mrt]
 * 
 * Revision 2.2  89/08/01  17:41:03  mrt
 * 	Created.
 * 	[89/07/06            af]
 * 
 */
/*
 * pmax/csw.s
 *
 * Context switch and cproc startup for MIPS COROUTINE implementation.
 */
#include <mips/asm.h>

	.text
	.align	2


/* XXX: space for 4 standard regsaves ? */
#define SAVED_PC	0
#define SAVED_FP	1
#define SAVED_S0	2
#define SAVED_S1	3
#define SAVED_S2	4
#define SAVED_S3	5
#define SAVED_S4	6
#define SAVED_S5	7
#define SAVED_S6	8
#define SAVED_S7	9
#define SAVED_BYTES	40

/*
 * Suspend the current thread and resume the next one.
 *
 *	void
 *	cproc_switch(cur, next)
 *		int *cur;
 *		int *next;
 */
LEAF(cproc_switch)
	subu	sp,sp,SAVED_BYTES	# allocate space for 10 registers
					# Save them registers
	sw	ra,SAVED_PC*4(sp)
	sw	fp,SAVED_FP*4(sp)
	sw	s0,SAVED_S0*4(sp)
	sw	s1,SAVED_S1*4(sp)
	sw	s2,SAVED_S2*4(sp)
	sw	s3,SAVED_S3*4(sp)
	sw	s4,SAVED_S4*4(sp)
	sw	s5,SAVED_S5*4(sp)
	sw	s6,SAVED_S6*4(sp)
	sw	s7,SAVED_S7*4(sp)

	sw	sp,0(a0)		# save current sp
	lw	sp,0(a1)		# restore next sp
					# Reload them registers
	lw	ra,SAVED_PC*4(sp)
	lw	fp,SAVED_FP*4(sp)
	lw	s0,SAVED_S0*4(sp)
	lw	s1,SAVED_S1*4(sp)
	lw	s2,SAVED_S2*4(sp)
	lw	s3,SAVED_S3*4(sp)
	lw	s4,SAVED_S4*4(sp)
	lw	s5,SAVED_S5*4(sp)
	lw	s6,SAVED_S6*4(sp)
	lw	s7,SAVED_S7*4(sp)
					# return to next thread
	addu	sp,sp,SAVED_BYTES
	j	ra
END(cproc_switch)

/*
 *	void
 *	cproc_start(parent_context, child, stackp)
 *		int *parent_context;
 *		cproc_t child;
 *		int stackp;
 */
LEAF(cproc_start)
	subu	sp,sp,SAVED_BYTES	# allocate space for 10 registers
					# Save parent registers
	sw	ra,SAVED_PC*4(sp)
	sw	fp,SAVED_FP*4(sp)
	sw	s0,SAVED_S0*4(sp)
	sw	s1,SAVED_S1*4(sp)
	sw	s2,SAVED_S2*4(sp)
	sw	s3,SAVED_S3*4(sp)
	sw	s4,SAVED_S4*4(sp)
	sw	s5,SAVED_S5*4(sp)
	sw	s6,SAVED_S6*4(sp)
	sw	s7,SAVED_S7*4(sp)

	sw	sp,0(a0)		# save parent sp
	move	sp,a2			# get child sp
	subu	sp,sp,4*4		# standard regsaves
	move	a0,a1
	jal	cthread_body		# cthread_body(child)
	/*
	 * Control never returns from cthread_body().
	 */
END(cproc_start)
