Compare this file to the similar file:
Show the results in this format:

 * Copyright (c) 1988 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 *	@(#)mch_KScall.s	1.1 (2.10BSD Berkeley) 4/3/88

#include "DEFS.h"
#include "../machine/mch_iopage.h"

 * Inter-address-space procedure call subroutines.
 *	KScall -- kernel to supervisor

 * KScall(func, nbytes, a1, ..., aN)
 * C-call from kernel to supervisor.
 * Calls func(a1, ..., aN) in supervisor mode.
	mov	r5,-(sp)
	mov	PS,-(sp)	/ Save current PS
	mov	010(sp),r0	/ r0: # bytes of arguments to copy

	 * Allocate enough space on the supervisor stack to hold
	 * the call frame.  We must allocate space to hold all the
	 * arguments, plus:
	 *	a null R5 entry as a marker
	 *	a return address (Sretu)
	 * We assume here that the supervisor stack pointer is always
	 * in seg6 and further that both supervisor and kernel addresses
	 * in this region are mapped to the same physical memory.
	 * This means that it is NOT ok for the network code to move the
	 * supervisor SP outside of seg6, or for it to remap SDSA6 to
	 * point to something other than the stack, unless it can guarantee
	 * that KScall will not be called for the duration of the stack
	 * fiddling.
	mov	$010340,PS	/ Current KERN, prev SUPV, spl7 (paranoia)
	mfpd	sp		/ Supervisor stack pointer
	mov	(sp),r1		/ Pointer to base of call frame

	 * The following is just to make sure that the supervisor stack
	 * pointer looks reasonable and a check that *SDSA6 == *KDSA6
	cmp	r1,$_u
	blos	8f
	cmp	r1,$USIZE\<6.+_u
	bhis	8f
	cmp	SDSA6,KDSA6
	beq	9f
	spl	7		/ lock out interrupts
	halt			/ drop dead so people can see where we are
	br	.		/ go no further
#endif /* CHECKSTACK */

	sub	r0,(sp)
	sub	$4.,(sp)	/ New SP.
	mtpd	sp		/ Set up alternate stack ptr
	mov	(sp),PS		/ Restore current PS
	mov	r5,-(r1)	/ Old frame ptr
	mov	r1,r5		/ New frame ptr for other mode

	 * Copy arguments.
	 * Note that the stack offsets here are one word deeper than
	 * after we saved the PS.

	mov	r2,-(sp)	/ Save
	mov	r0,r2		/ r2: number of bytes of arguments to copy
	beq	2f		/ None to copy? if so, skip loop
	asr	r2		/ r2: number of words of arguments to copy
	add	sp,r0
	add	$12.,r0		/ r0: ptr to argN+1
	mov	-(r0),-(r1)
	sob	r2,1b
	mov	(sp)+,r2	/ Restore

	 * Build the remainder of the frame on the
	 * supervisor stack.
	mov	$Sretu,-(r1)	/ Return address in supervisor space

	 * Push the iothndlr <PS, PC> pair, and the
	 * <PS, PC> pair for calling the supervisor function
	 * on the kernel stack.
	mov	PS,r0		/ To get current priority
	bic	$170000,r0	/ Clear out current/previous modes
	bis	$050000,r0	/ Current SUPV, previous SUPV
	mov	$ret,-(sp)	/ Stack kernel PC to go with saved kernel PS
	mov	r0,-(sp)	/ Stack the new PS
	mov	10.(sp),-(sp)	/ Stack the address of function being called

	 * At this point, the stacks look like the following:
	 *	------			----------
	 *KSP->	<SUPV func address>	<Sretu>	<-SSP
	 *	<SUPV PS>		<arg0>
	 *	<KERN "ret">		 ...
	 *	<KERN saved PS>	<argN>
	 *	<R5>			 <0>
	 *	<caller's rtnaddr>
	 *	<SUPV func address>
	 *	<# bytes of args>
	 *	<arg0>
	 *	 ...
	 *	<argN>
	 * "<SUPV func address>" is the address in supervisor address
	 * space of the function being called.
	rtt			/ Call the function

	 * Return to caller of KScall.
	 * We arrive here with the same PS as that with which we were
	 * called, via the rtt in iothndlr.
	mov	(sp)+,r5
	rts	pc

 * Kretu is the exit point in kernel code that cleans up
 * the kernel stack for return to supervisor mode from a
 * net-to-kernel procedure call.
	mov	r5,sp		/ Throw away arguments from stack
	tst	(sp)+		/ Discard old frame pointer
	 * At this point, the stacks look like the following:
	 *	----------		------
	 *SSP->	<R5>
	 *	<caller's rtnaddr>	<_Kretu>
	 *	<KERN func address>	<arg0>
	 *	<# bytes of args>	 ...
	 *	<arg0>			<argN>
	 *	 ...			 <0>
	 *	<argN>			<ret in SUPV space>	<-KSP
	 *				<PS for SUPV mode>
	rtt			/ Back to previous address space