//procedure address //stack size in words //proccess priority > 0 //name (for debugging) //number of args //argments SYSCALL create(int *procaddr,int ssize,int priority,char *name,int nargs,int args) { int pid; /* stores new process id */ struct pentry *pptr; /* pointer to proc. table entry */ int *saddr; /* stack address */ sigset_t ps; /* saved processor status */ disable(ps); ssize = roundew(ssize); pid = newpid(); if ((ssize < MINSTK) || (pid == SYSERR) || (priority < 1)) { restore(ps); return(SYSERR); } if ((int)(saddr = getstk(ssize)) == SYSERR) { proctab[pid].pstate=PRFREE; //free pid restore(ps); return(SYSERR); } numproc++; pptr = &proctab[pid]; pptr->pstate = PRSUSP; strcpy(pptr->pname,name); pptr->pprio = priority; pptr->pbase = (int) saddr; pptr->pstklen = ssize; pptr->psem = 0; pptr->phasmsg = FALSE; pptr->plimit = (int)(saddr - ssize + 1); pptr->pargs = nargs; pptr->posix_ctxt = posix_ctxt_init; pptr->posix_ctxt.uc_stack.ss_size = ssize; pptr->posix_ctxt.uc_stack.ss_sp = (void*)((int) saddr - ssize + 1); pptr->posix_ctxt.uc_stack.ss_flags = 0; pptr->posix_ctxt.uc_link = &return_ctxt; switch (nargs) { case 0: makecontext(&(pptr->posix_ctxt),(void *)procaddr,0); break; case 1: makecontext(&(pptr->posix_ctxt),(void *)procaddr,1,args); break; case 2: makecontext(&(pptr->posix_ctxt),(void *)procaddr,2,args,*(&args+1)); break; case 3: makecontext(&(pptr->posix_ctxt),(void *)procaddr,3,args,*(&args+1),*(&args+2)); break; } restore(ps); return(pid); }
void processSet( struct pcb_t *p, memaddr start, int priority){ // Abilita gli interrupt, il Local Timer e la kernel-mode p->p_s.cpsr = STATUS_ALL_INT_ENABLE(p->p_s.cpsr) | STATUS_SYS_MODE; // Disabilita la memoria virtuale p->p_s.CP15_Control = (p->p_s.CP15_Control) & ~(ENABLE_VM); p->p_s.cpsr = STATUS_ENABLE_TIMER(p->p_s.cpsr); p->p_s.sp = RAM_TOP - FRAME_SIZE; // Assegna a PC l'indirizzo della funzione esterna test() p->p_s.pc = (memaddr) start; p->priority = priority; //assegno un pid al processo p->pid = newpid(); activeProcesses[first->pid-1] = p; //inserisco il processo dove di competenza insertProcQ(priority_queue( priority ), p); }
/*------------------------------------------------------------------------ * create - create a process to start running a procedure *------------------------------------------------------------------------ */ pid32 create_9_4( void *procaddr, /* procedure address */ uint32 ssize, /* stack size in words */ pri16 priority, /* process priority > 0 */ char *name, /* name (for debugging) */ uint32 nargs, /* number of args that follow */ ... ) { uint32 savsp, *pushsp; intmask mask; /* interrupt mask */ pid32 pid; /* stores new process id */ struct procent *prptr; /* pointer to proc. table entry */ int32 i; uint32 *a; /* points to list of args */ uint32 *saddr; /* stack address */ mask = disable(); if (ssize < MINSTK) ssize = MINSTK; ssize = (uint32) roundew(ssize); if (((saddr = (uint32 *)getstk_new(ssize)) == (uint32 *)SYSERR ) || (pid=newpid()) == SYSERR || priority < 1 ) { restore(mask); return SYSERR; } prcount++; prptr = &proctab[pid]; /* initialize process table entry for new process */ prptr->prstate = PR_SUSP; /* initial state is suspended */ prptr->prprio = priority; prptr->prstkbase = (char *)saddr; prptr->prstklen = ssize; prptr->prname[PNMLEN-1] = NULLCH; for (i=0 ; i<PNMLEN-1 && (prptr->prname[i]=name[i])!=NULLCH; i++) ; prptr->prsem = -1; prptr->prparent = (pid32)getpid(); prptr->prhasmsg = FALSE; /* set up initial device descriptors for the shell */ prptr->prdesc[0] = CONSOLE; /* stdin is CONSOLE device */ prptr->prdesc[1] = CONSOLE; /* stdout is CONSOLE device */ prptr->prdesc[2] = CONSOLE; /* stderr is CONSOLE device */ /* Initialize stack as if the process was called */ *saddr = STACKMAGIC; savsp = (uint32)saddr; /* push arguments */ a = (uint32 *)(&nargs + 1); /* start of args */ a += nargs -1; /* last argument */ for ( ; nargs > 4 ; nargs--) /* machine dependent; copy args */ *--saddr = *a--; /* onto created process' stack */ *--saddr = (long)procaddr; for(i = 11; i >= 4; i--) *--saddr = 0; for(i = 4; i > 0; i--) { if(i <= nargs) *--saddr = *a--; else *--saddr = 0; } *--saddr = (long)INITRET; /* push on return address */ *--saddr = (long)0x00000053; /* CPSR, A, F bits set, */ /* Supervisor mode */ prptr->prstkptr = (char *)saddr; restore(mask); return pid; /* The following entries on the stack must match what ctxsw */ /* expects a saved process state to contain: ret address, */ /* ebp, interrupt mask, flags, registerss, and an old SP */ *--saddr = (long)procaddr; /* Make the stack look like it's*/ /* half-way through a call to */ /* ctxsw that "returns" to the */ /* new process */ *--saddr = savsp; /* This will be register ebp */ /* for process exit */ savsp = (uint32) saddr; /* start of frame for ctxsw */ *--saddr = 0x00000200; /* New process runs with */ /* interrupts enabled */ /* Basically, the following emulates a x86 "pushal" instruction */ *--saddr = 0; /* %eax */ *--saddr = 0; /* %ecx */ *--saddr = 0; /* %edx */ *--saddr = 0; /* %ebx */ *--saddr = 0; /* %esp; value filled in below */ pushsp = saddr; /* remember this location */ *--saddr = savsp; /* %ebp (while finishing ctxsw) */ *--saddr = 0; /* %esi */ *--saddr = 0; /* %edi */ *pushsp = (unsigned long) (prptr->prstkptr = (char *)saddr); restore(mask); return pid; }
/*------------------------------------------------------------------------ * create - Create a process to start running a function on x86 *------------------------------------------------------------------------ */ pid32 create( void *funcaddr, /* Address of the function */ uint32 ssize, /* Stack size in bytes */ pri16 priority, /* Process priority > 0 */ char *name, /* Name (for debugging) */ uint32 nargs, /* Number of args that follow */ ... ) { uint32 savsp, *pushsp; intmask mask; /* Interrupt mask */ pid32 pid; /* Stores new process id */ struct procent *prptr; /* Pointer to proc. table entry */ int32 i; uint32 *a; /* Points to list of args */ uint32 *saddr; /* Stack address */ mask = disable(); if (ssize < MINSTK) ssize = MINSTK; ssize = (uint32) roundmb(ssize); if ( (priority < 1) || ((pid=newpid()) == SYSERR) || ((saddr = (uint32 *)getstk(ssize)) == (uint32 *)SYSERR) ) { restore(mask); return SYSERR; } prcount++; prptr = &proctab[pid]; /* Initialize process table entry for new process */ prptr->prstate = PR_SUSP; /* Initial state is suspended */ prptr->prprio = priority; prptr->prstkbase = (char *)saddr; prptr->prstklen = ssize; prptr->prname[PNMLEN-1] = NULLCH; for (i=0 ; i<PNMLEN-1 && (prptr->prname[i]=name[i])!=NULLCH; i++) ; prptr->prsem = -1; prptr->prparent = (pid32)getpid(); prptr->prhasmsg = FALSE; // message queue for mysend<n> and myreceive<n> initMsgBuffer(&(prptr->mBuff)); prptr->prnmsgwait = 0; // initially waiting for 0 messages from mysendn /* Set up stdin, stdout, and stderr descriptors for the shell */ prptr->prdesc[0] = CONSOLE; prptr->prdesc[1] = CONSOLE; prptr->prdesc[2] = CONSOLE; /* Initialize stack as if the process was called */ *saddr = STACKMAGIC; savsp = (uint32)saddr; /* Push arguments */ a = (uint32 *)(&nargs + 1); /* Start of args */ a += nargs -1; /* Last argument */ for ( ; nargs > 0 ; nargs--) /* Machine dependent; copy args */ *--saddr = *a--; /* onto created process's stack */ *--saddr = (long)INITRET; /* Push on return address */ /* The following entries on the stack must match what ctxsw */ /* expects a saved process state to contain: ret address, */ /* ebp, interrupt mask, flags, registers, and an old SP */ *--saddr = (long)funcaddr; /* Make the stack look like it's*/ /* half-way through a call to */ /* ctxsw that "returns" to the*/ /* new process */ *--saddr = savsp; /* This will be register ebp */ /* for process exit */ savsp = (uint32) saddr; /* Start of frame for ctxsw */ *--saddr = 0x00000200; /* New process runs with */ /* interrupts enabled */ /* Basically, the following emulates an x86 "pushal" instruction*/ *--saddr = 0; /* %eax */ *--saddr = 0; /* %ecx */ *--saddr = 0; /* %edx */ *--saddr = 0; /* %ebx */ *--saddr = 0; /* %esp; value filled in below */ pushsp = saddr; /* Remember this location */ *--saddr = savsp; /* %ebp (while finishing ctxsw) */ *--saddr = 0; /* %esi */ *--saddr = 0; /* %edi */ *pushsp = (unsigned long) (prptr->prstkptr = (char *)saddr); restore(mask); return pid; }
SYSCALL create(int (*procaddr)(), int ssize, int priority, char *name, int nargs, ...) { STATWORD ps; int pid; /* stores new process id */ struct pentry *pptr; /* pointer to proc. table entry */ int i; unsigned char *saddr; /* stack address */ int INITRET(); va_list ap; disable(ps); ssize = (int) roundmb(ssize); if ( (saddr = (unsigned char *)getstk(ssize)) == (unsigned char *)SYSERR ) { restore(ps); return (SYSERR); } if ( ssize < MINSTK || (pid=newpid()) == SYSERR || priority < 1 ) { freestk((unsigned)saddr, (unsigned)ssize); restore(ps); return(SYSERR); } numproc++; pptr = &proctab[pid]; /* stderr set to &kprint_out (see kprintf.c and initialize.c) */ pptr->fildes[0] = fdopen(CONSOLE, "r"); /* stdin set to console */ pptr->fildes[1] = fdopen(CONSOLE, "w"); /* stdout set to console */ pptr->fildes[2] = &kprint_out; /* stderr set to &kprint_out */ for (i=2; i < _NFILE; i++) /* others set to unused */ pptr->fildes[i] = (FILE *)FDFREE; pptr->pstate = PRSUSP; for (i=0 ; i<PNMLEN && (int)(pptr->pname[i]=name[i])!=0 ; i++) ; pptr->pprio = priority; pptr->pbase = saddr; pptr->pstklen = ssize; pptr->psem = 0; pptr->phasmsg = FALSE; pptr->plimit = pptr->pbase - ssize + sizeof (WORD); *saddr-- = (char)MAGIC; /* Bottom of stack */ pptr->pargs = nargs; for (i=0 ; i<PNREGS ; i++) pptr->pregs[i] = INITREG; pptr->paddr = (int *)procaddr; pptr->pregs[SPC_L] = lobyte((unsigned) procaddr); pptr->pregs[SPC_H] = hibyte((unsigned) procaddr); pptr->pregs[SSREG] = INITPS; pptr->pnxtkin = BADPID; pptr->pdevs[0] = pptr->pdevs[1] = BADDEV; va_start(ap,nargs); for (i=0 ; i < nargs; i++) { pptr->parg[i] = va_arg(ap, unsigned int); } va_end(ap); pptr->parg[nargs] = 0; /* machine/compiler dependent pass arguments to created process */ pptr->pregs[24] = lobyte((unsigned)pptr->pargs); /*r24*/ pptr->pregs[25] = hibyte((unsigned)pptr->pargs); pptr->pregs[22] = lobyte((unsigned)&pptr->parg[0]); /*r22*/ pptr->pregs[23] = hibyte((unsigned)&pptr->parg[0]); *saddr-- = lobyte((unsigned)INITRET); /* push on initial return address*/ *saddr-- = hibyte((unsigned)INITRET); // *saddr-- = 0; /* 256Kb memory device */ /*TODO make conditional*/ *saddr-- = lobyte((unsigned)procaddr); /* push on procedure address */ *saddr-- = hibyte((unsigned)procaddr); // *saddr-- = 0; /* 256Kb memory device */ /*TODO make conditional*/ pptr->pregs[SSP_L] = lobyte((unsigned) saddr); pptr->pregs[SSP_H] = hibyte((unsigned) saddr); restore(ps); return(pid); }
/*------------------------------------------------------------------------ * create - create a process to start running a procedure *------------------------------------------------------------------------ */ SYSCALL create(int (*procaddr)(), int ssize, int priority, char *name, int nargs, ...) { va_list ap; unsigned long savsp, *pushsp; STATWORD ps; int pid; /* stores new process id */ struct pentry *pptr; /* pointer to proc. table entry */ int i; unsigned long *saddr, *uarg; /* stack address */ unsigned long *getstk(); int INITRET(); va_start(ap, nargs); disable(ps); if (ssize < MINSTK) ssize = MINSTK; ssize = (int) roundew(ssize); if (((saddr = (unsigned long *)getstk(ssize)) == (unsigned long *)SYSERR ) || (pid=newpid()) == SYSERR || priority < 1 ) { restore(ps); va_end(ap); return SYSERR; } numproc++; pptr = &proctab[pid]; pptr->fildes[0] = 0; /* stdin set to console */ pptr->fildes[1] = 0; /* stdout set to console */ pptr->fildes[2] = 0; /* stderr set to console */ for (i=3; i < _NFILE; i++) /* others set to unused */ pptr->fildes[i] = FDFREE; pptr->pstate = PRSUSP; for (i=0 ; i<PNMLEN && (int)(pptr->pname[i]=name[i])!=0 ; i++) ; pptr->pprio = priority; pptr->pbase = (long) saddr; pptr->pstklen = ssize; pptr->psem = 0; pptr->phasmsg = FALSE; pptr->plimit = pptr->pbase - ssize + sizeof (long); pptr->pirmask[0] = 0; pptr->pnxtkin = BADPID; pptr->pdevs[0] = pptr->pdevs[1] = BADDEV; /* Bottom of stack */ *saddr = MAGIC; savsp = (unsigned long)saddr; /* push arguments */ pptr->pargs = nargs; uarg = saddr - nargs; saddr = uarg; /* end of args for after the copy */ for (; nargs > 0 ; nargs--) *uarg++ = va_arg(ap, unsigned long); *--saddr = (long)INITRET; /* push on return address */ *--saddr = pptr->paddr = (long)procaddr; /* where we "ret" to */ *--saddr = savsp; /* fake frame ptr for procaddr */ savsp = (unsigned long) saddr; /* this must match what ctxsw expects: flags, regs, old SP */ /* emulate 386 "pushal" instruction */ *--saddr = 0; *--saddr = 0; /* %eax */ *--saddr = 0; /* %ecx */ *--saddr = 0; /* %edx */ *--saddr = 0; /* %ebx */ *--saddr = 0; /* %esp; fill in below */ pushsp = saddr; *--saddr = savsp; /* %ebp */ *--saddr = 0; /* %esi */ *--saddr = 0; /* %edi */ *pushsp = pptr->pesp = (unsigned long)saddr; restore(ps); va_end(ap); return pid; }
/*------------------------------------------------------------------------ * create, newpid - Create a process to start running a procedure *------------------------------------------------------------------------ */ pid32 create( void *funcaddr, /* address of function to run */ uint32 ssize, /* stack size in bytes */ pri16 priority, /* process priority */ char *name, /* process name (for debugging) */ uint32 nargs, /* number of args that follow */ ... ) { intmask mask; /* saved interrupt mask */ struct procent *prptr; /* ptr to process' table entry */ uint32 *saddr; /* stack address */ uint32 *savargs; /* pointer to arg save area */ pid32 pid; /* ID of newly created process */ uint32 *ap; /* points to list of var args */ int32 pad; /* padding needed for arg area */ uint32 i; void INITRET(void); mask = disable(); if ( (ssize < MINSTK) || (priority <= 0) || (((int32)(pid = newpid())) == (int32) SYSERR) || ((saddr = (uint32 *)getstk(ssize)) == (uint32 *)SYSERR)) { restore(mask); return SYSERR; } prcount++; prptr = &proctab[pid]; /* Initialize process table entry for new process */ prptr->prstate = PR_SUSP; /* initial state is suspended */ prptr->prprio = priority; prptr->prstkptr = (char *)saddr; prptr->prstkbase = (char *)saddr; prptr->prstklen = ssize; prptr->prname[PNMLEN-1] = NULLCH; for (i=0 ; i<PNMLEN-1 && (prptr->prname[i]=name[i])!=NULLCH; i++) ; prptr->prparent = (pid32)getpid(); prptr->prhasmsg = FALSE; /* Set up initial device descriptors for the shell */ prptr->prdesc[0] = CONSOLE; /* stdin is CONSOLE device */ prptr->prdesc[1] = CONSOLE; /* stdout is CONSOLE device */ prptr->prdesc[2] = CONSOLE; /* stderr is CONSOLE device */ /* Continue initialize process table entry for new process */ prptr->sndflag = FALSE; prptr->sndqueue = newqueue(); /* Initialize stack as if the process was called */ *saddr = STACKMAGIC; *--saddr = pid; *--saddr = (uint32)prptr->prstklen; *--saddr = (uint32)prptr->prstkbase - prptr->prstklen + sizeof(int); if (nargs == 0) { /* compute padding */ pad = 4; } else if ((nargs%4) == 0) { /* pad for A0 - A3 */ pad = 0; } else { pad = 4 - (nargs % 4); } for (i = 0; i < pad; i++) { /* pad stack by inserting zeroes*/ *--saddr = 0; } for (i = nargs; i > 0; i--) { /* reserve space for arguments */ *--saddr = 0; } savargs = saddr; /* loc. of args on the stack */ /* Build the context record that ctxsw expects */ for (i = (CONTEXT_WORDS); i > 0; i--) { *--saddr = 0; } prptr->prstkptr = (char *)saddr; /* Address of process entry point */ saddr[(CONTEXT_WORDS) - 1] = (uint32) funcaddr; /* Return address value */ saddr[(CONTEXT_WORDS) - 2] = (uint32) INITRET; /* Copy arguments into activation record */ ap = (uint32 *)(&nargs + 1); /* machine dependent code to */ for (i = 0; i < nargs; i++) { /* copy args onto process stack */ *savargs++ = *ap++; } restore(mask); return pid; }