00001 00007 /* Embedded XINU, Copyright (C) 2007. All rights reserved. */ 00008 00009 #include <kernel.h> 00010 #include <proc.h> 00011 #include <vararg.h> 00012 #include <mips.h> 00013 #include <memory.h> 00014 #include <string.h> 00015 00016 local newpid(void); 00017 void userret(void); 00018 00028 syscall create(void *procaddr, ulong ssize, ushort priority, 00029 char *name, ulong nargs, ...) 00030 { 00031 ulong *saddr; /* stack address */ 00032 ulong *savargs; /* pointer to arg saving region */ 00033 ulong pid; /* stores new process id */ 00034 pcb *ppcb; /* pointer to proc control blk */ 00035 ulong i; 00036 va_list ap; /* points to list of var args */ 00037 ulong pads; /* padding entries in record. */ 00038 void INITRET(void); 00039 00040 if (ssize < MINSTK) ssize = MINSTK; 00041 ssize = (ulong)roundew(ssize); /* round up to even boundary */ 00042 saddr = (ulong *)getmem(ssize); /* allocate new stack and pid */ 00043 pid = newpid(); 00044 /* a little error checking */ 00045 if ( (((ulong *)SYSERR) == saddr) || (SYSERR == pid) ) 00046 { return SYSERR; } 00047 00048 numproc++; 00049 ppcb = &proctab[ pid ]; 00050 /* setup PCB entry for new proc */ 00051 ppcb->state = PRSUSP; 00052 ppcb->prio = priority; 00053 ppcb->stkbase = saddr; 00054 saddr = (ulong *)(((ulong)saddr) + ssize - sizeof(ulong)); 00055 ppcb->stklen = ((ulong)saddr) - (ulong)ppcb->stkbase; 00056 ppcb->stkptr = saddr; 00057 strncpy(ppcb->name, name, PNMLEN); 00058 ppcb->parent = (ushort)getpid(); 00059 00060 /* Initialize stack with accounting block. */ 00061 *saddr = STACKMAGIC; 00062 *--saddr = pid; 00063 *--saddr = ppcb->stklen; 00064 *--saddr = (ulong)ppcb->stkbase; 00065 00066 if (0 == nargs) 00067 { pads = 4; } 00068 else if (0 == (nargs % 4)) /* Must pad record size to */ 00069 { pads = 0; } /* multiple of native memory */ 00070 else /* transfer size. */ 00071 { pads = 4 - (nargs % 4); } 00072 00073 for (i = 0; i < pads; i++) { *--saddr = 0; } 00074 /* Reserve space for all args. */ 00075 for (i = nargs ; i > 0 ; i--) { *--saddr = 0; } 00076 savargs = saddr; 00077 00078 /* Build the context record as expected by ctxsw. */ 00079 /* Clear room for saved state. */ 00080 for (i = (CONTEXT_WORDS); i > 0; i--) { *--saddr = 0; } 00081 ppcb->stkptr = saddr; 00082 /* Address of proc entry point */ 00083 saddr[(CONTEXT_WORDS) - 1] = (ulong)procaddr; 00084 /* Return Address value */ 00085 saddr[(CONTEXT_WORDS) - 2] = (ulong)INITRET; 00086 00087 /* Place arguments into activation records. */ 00088 va_start(ap, nargs); 00089 for (i = 0; i < nargs; i++) 00090 { savargs[i] = va_arg(ap, ulong); } 00091 va_end(ap); 00092 00093 return pid; 00094 } 00095 00100 local newpid(void) 00101 { 00102 int pid; /* process id to return */ 00103 static int nextpid = 0; 00104 00105 for (pid = 0 ; pid < NPROC ; pid++) 00106 { /* check all NPROC slots */ 00107 nextpid = (nextpid + 1) % NPROC; 00108 if (PRFREE == proctab[nextpid].state) 00109 { return nextpid; } 00110 } 00111 return SYSERR; 00112 } 00113 00117 void userret(void) 00118 { 00119 kill( getpid() ); 00120 }