Files
Arquivotheca.AIX-4.1.3/bos/kernel/proc/POWER/m_thread.c
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

179 lines
5.4 KiB
C

static char sccsid[] = "@(#)31 1.7 src/bos/kernel/proc/POWER/m_thread.c, sysproc, bos41J, 9517B_all 4/27/95 13:43:40";
/*
* COMPONENT_NAME: SYSPROC
*
* FUNCTIONS: threadentry
* threadinit
*
* ORIGINS: 27, 83
*
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
* SOURCE MATERIALS
*
* (C) COPYRIGHT International Business Machines Corp. 1993, 1995
* All Rights Reserved
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/*
* LEVEL 1, 5 Years Bull Confidential Information
*/
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/pseg.h>
#include <sys/intr.h>
#include <sys/syspest.h>
#include <sys/vmuser.h>
#include <sys/vmker.h>
#include <sys/adspace.h>
#include <sys/lockl.h>
#include <sys/errno.h>
#include <sys/machine.h>
extern void waitproc(void);
extern struct vmmdseg vmmdseg;
extern union ptaseg ptaseg;
extern threadentry();
/*
* NAME: threadinit
*
* FUNCTION: Initialize kernel thread machine state.
*
* NOTES:
* This routine is platform specific. It is called by procinit() and
* kthread_start() during kernel thread start up to initialize the
* machine state for this platform. It is also called by thread_setstate()
* during user thread startup.
*
* Offset is used to access the intended kernel stack (init_stk) from the
* current address space. Init_stk is the address where the newly
* initialized thread will see its stack, however this thread may belong
* to another process and the segment about to contain the kernel stack
* may have been attached at a different address to the current address
* space. Offset is the offset between this temporary address and the
* intended address.
*
* RETURNS:
* None.
*/
void
threadinit(ut, kstksr, pprivsr, init_func, init_data, length, init_stk, offset)
register struct uthread *ut; /* uthread block to initialize */
register vmhandle_t kstksr; /* kernel stack seg VM handle */
register vmhandle_t pprivsr; /* process private seg VM handle*/
void (*init_func)(void *); /* pointer to initial function */
register void *init_data; /* init data to copy in init_stk*/
register int length; /* length of init data */
register void *init_stk; /* kernel stack base */
register int offset; /* to reach init_stk from here */
{
register int i; /* register index */
register char *stack_data; /* address of data in stack */
register char *stack_top;
struct func_desc *thread_desc = (struct func_desc *)threadentry;
/*
* initialize the new kernel address space
*/
as_init(&ut->ut_save.as); /* initialize new address space */
as_ralloc(&ut->ut_save.as, KERNELORG);
as_seth(&ut->ut_save.as, vm_setkey(vmker.kernsrval,VM_PRIV), KERNELORG);
as_ralloc(&ut->ut_save.as, &U);
as_seth(&ut->ut_save.as, vm_setkey(pprivsr, VM_PRIV), &U);
as_ralloc(&ut->ut_save.as, KERNEXORG);
as_seth(&ut->ut_save.as, vm_setkey(vmker.kexsrval, VM_PRIV), KERNEXORG);
/*
* complete kernel address space
*/
as_ralloc(&ut->ut_save.as, TEXTORG);
as_ralloc(&ut->ut_save.as, &vmmdseg);
as_ralloc(&ut->ut_save.as, &ptaseg);
as_ralloc(&ut->ut_save.as, SHTEXTORG);
/*
* give access to the kernel stack segment if it exists (it's TEXTORG)!
*/
if (kstksr != NULLSEGVAL)
as_seth(&ut->ut_save.as, vm_setkey(kstksr, VM_PRIV), KSTACKORG);
/*
* If this is a wait thread, then reset the kernel stack to the
* default kernel stack, of which the first 0x400 bytes is pinned.
* The waitproc cannot page fault. This leads to the following
* restriction: the waitproc must operate in 0x400 bytes of stack
* space. The ublock is not page aligned.
*/
if ((ulong)init_func == (ulong)waitproc)
init_stk = &__ublock;
/*
* Copy initialization data to stack.
* Note that the stack must be quadword aligned.
*/
ut->ut_error = 0;
ut->ut_kstack = init_stk;
stack_data = (char *)(((int)init_stk - length) & ~15);
bcopy(init_data, stack_data + offset, length);
/*
* Initialize GPRs
*/
for (i = 0; i < NGPRS; i++)
ut->ut_save.gpr[i] = DEFAULT_GPR;
#ifdef _POWER /* R2 System machine-dependency */
/*
* Initialize FPRs by clearing to binary zeros
*/
bzero(ut->ut_save.fpr, NFPRS*sizeof(double));
#endif
/*
* Initialize parameters. Stack is set to stack_data less STKMIN
* (stack_data was aligned on double word boundary above).
*/
#ifdef _POWER /* R2 System machine-dependency */
ut->ut_save.gpr[3] = 0;
ut->ut_save.gpr[4] = (ulong_t) stack_data;
ut->ut_save.gpr[5] = (ulong_t) length;
ut->ut_save.gpr[6] = (ulong_t) init_func;
ut->ut_save.gpr[1] = ((ulong_t) stack_data - STKMIN);
ut->ut_save.gpr[2] = (ulong_t) thread_desc->toc_ptr;
ut->ut_save.iar = (ulong_t) thread_desc->entry_point;
ut->ut_save.msr = DEFAULT_MSR;
ut->ut_save.fpscr = 0;
ut->ut_save.fpscrx = 0;
ut->ut_save.fpinfo = 0;
ut->ut_save.cr = 0;
ut->ut_save.ctr = 0;
ut->ut_save.xer = 0;
#endif
}
/*
* FUNCTION: threadentry()
*
* This routine is the front end of all kernel threads.
* If the kthread returns, call thread_terminate()
*/
threadentry(int param, void *data, int length, void (*func)(void *))
{
/* Call the kthread entry point */
(*func)(data);
/* Cause the kernel thread to terminate */
thread_terminate();
}