createthread.c 2.63 KB
/**************************************************************************
 *									  *
 *		 Copyright (C) 1994, Silicon Graphics, Inc.		  *
 *									  *
 *  These coded instructions, statements, and computer programs  contain  *
 *  unpublished  proprietary  information of Silicon Graphics, Inc., and  *
 *  are protected by Federal copyright law.  They  may  not be disclosed  *
 *  to  third  parties  or copied or duplicated in any form, in whole or  *
 *  in part, without the prior written consent of Silicon Graphics, Inc.  *
 *									  *
 **************************************************************************/

#include <R4300.h>
#include "osint.h"

#define	ARGSAVE	16	/* Save room for all four argument registers
			   even though there is only a single argument
			   just in case the app accidentally declares more. */

extern __OSThreadprofile_s thprof[];

/*
 * osCreateThread
 *
 * Initializes a given thread structure with the initial state of the thread.
 */
void
osCreateThread(OSThread *t, OSId id, void (*entry)(void *), void *arg,
	       void *sp, OSPri p)
{
	register u32	saveMask;
	OSIntMask	mask;

#ifdef _DEBUG
	if ((u32)sp & 0x7) {
	    __osError(ERR_OSCREATETHREAD_SP, 1, sp);
	    return;
	}

	if ((p < OS_PRIORITY_IDLE) || (p > OS_PRIORITY_MAX)) {
	    __osError(ERR_OSCREATETHREAD_PRI, 1, p);
	    return;
	}
#endif
	/*
	 * The stack pointer is adjusted since the argument register(s)
	 * are stored into the *caller's* stack frame with the current
	 * calling convention.
	 *
	 * The SR_EXL bit is turned on to ensure interrupts are locked out
	 * for the dispatcher (see __osThreadDispatch).
	 *
	 * Initialize the return address to a procedure that will destroy
	 * the thread if the thread simply returns.
	 */

	t->id = id;
	t->priority = p;
	t->next = (OSThread *)NULL;
	t->queue = (OSThread **)NULL;
	t->context.pc = (u32)entry;
	t->context.a0 = (u64)arg;
	t->context.sp = (u64)sp - ARGSAVE;
	t->context.ra = (u64)__osCleanupThread;
	mask = OS_IM_ALL;
	t->context.sr = (mask & OS_IM_CPU)|SR_EXL;
	t->context.rcp = (mask & RCP_IMASK) >> RCP_IMASKSHIFT;
	t->context.fpcsr = FPCSR_FS | FPCSR_EV;
	t->fp = 0;
	t->state = OS_STATE_STOPPED;
	t->flags = 0;

#ifndef _FINALROM

	/*
         * for thread profiler
         * THPROF_IDMAXを越えるidの場合には、最大値にまとめる
	 */
	if (id < THPROF_IDMAX)
	  t->thprof = &thprof[id];
	else
	  t->thprof = &thprof[THPROF_IDMAX-1];

#endif /* _FINALROM */

	/*
	 * Put the thread onto a list of all active threads for the debugger.
	 */

	/* Disable interrupts */
	saveMask = __osDisableInt();

	t->tlnext = __osActiveQueue;
	__osActiveQueue = t;

	/* Restore interrupts */
	__osRestoreInt(saveMask);
}