/*
 * _start.s
 *
 * Assembly code to get a new team started off on the right foot.
 *
 * The initial team space layout is:
 *   | code | data | bss | istack | TEB |
 * where	code=	program code space
 *      data=   initialized data
 *	bss=	uninitialized data (actually initialized to 0, in this code)
 *      istack= initial stack space; used for the root stack
 *		until the TEB has been unpacked.
 *	TEB=	team environment block; contains the command line args,
 *		environment variables, etc.
 *
 * This assembly code points the stack into the istack space, calls
 *   TeamRoot to initialize the standard I/O and unpack the TEB,
 *   then resets the stack to the size called for by RootStackSize,
 *   and finally calls main().  If main() returns, we call exit(0).
 *
 * The team layout when it starts execution is:
 *   | code | data | bss | root stack | heap |
 * The root process's PerProcess area is at the start of its stack, as
 *   with all PerProcess areas.
 */

	.set    _INIT_STACK_SIZE, 1024

	.text
	.globl	_start
_start:

/* First, fetch the root message. */

	moval   _RootMsg, r2
	movl    r3, *(r2)+        /* Stored in r3-r10 */
	movl    r4, *(r2)+
	movl    r5, *(r2)+
	movl    r6, *(r2)+
	movl    r7, *(r2)+
	movl    r8, *(r2)+
	movl    r9, *(r2)+
	movl    r10, *(r2)+

/*
 * Temporarily position the stack pointer at _end + _INIT_STACK_SIZE so we
 *   are using only the small istack area, to be sure the stack doesn't
 *   smash the TEB or go past the end of our team space.
 */
	moval   _end + _INIT_STACK_SIZE, sp

/* Zero the bss segment */

	subl3   $_edata, $_end, r0  /* Length of bss */
	movc5   $0, 0, $0, r0, _edata /* Set to zeroes */

/* Call TeamRoot() to do the rest of the setup */

	calls   $0, _TeamRoot

/* Move the end of the stack where it belongs */

	moval   _end, sp
	addl2   _RootStackSize, sp

/* Call main(argc, argv) */

	pushl   _Argv
	pushl   _Argc
	calls   $2, _main

/* Call exit(0) if main() returns. */

	pushl   $0
	calls   $1, _exit

/* Die with a privilege violation if exit() returns -- it isn't supposed to! */

	bugl    $0x911
