Exemplo n.º 1
0
/************** syscall routing table ***********/
int kcinth() 
{
  u16 x, y, z, w, r; 
  u16 seg, off;

  seg = running->uss; off = running->usp;

  x = get_word(seg, off+13*2);
  y = get_word(seg, off+14*2);
  z = get_word(seg, off+15*2);
  w = get_word(seg, off+16*2);
  
   switch(x){
       case 0 : r = running->pid;    break;
       case 1 : r = kps();           break;
       case 2 : r = chname(y);       break;
       case 3 : r = kmode();         break;
       case 4 : r = tswitch();       break;
       case 5 : r = kwait();         break;
       case 6 : r = kexit();         break;
       case 7 : r = fork();          break;
       case 8 : r = kexec(y);        break;

       case 9 : r = sout(y); break;
       case 10: r = sin(y); break;

       case 99: r = kexit();                break;

       default: printf("invalid syscall # : %d\n", x);

   }
   put_word(r, seg, off+2*8);
}
Exemplo n.º 2
0
int body()
{ 
char c;
int event;
while(1){
	printf("\n***************************************\n");
	print();
	printf("\nI am task %d My parent=%d\n", running->pid, running->ppid);
	printf("input a char [fork:f|switch:s|exit:q|sleep:z|wakeup:a|wait:w] : ");  
	c = getchar();
	switch(c){
		case 'f': kfork();      break;
		case 's': tswitch();    break;
		case 'q': kexit(0); 	break;
		case 'z': {printf("enter event to put process to sleep");
			  scanf("%d",&event);		
			  ksleep(event);}	
			  break;
		case 'a': {printf("enter event to wake up process");
			  scanf("%d",&event);		
			  kwakeup(event);}	
			  break;
		case 'w': kwait(0); 	break;
		default: printf("invalid char\n"); break;
		}	
	}
return;
}
Exemplo n.º 3
0
Arquivo: vx32.c Projeto: 0intro/vx32
/*
 * Newly forked processes start executing at forkret.
 * The very first process, init, starts executing at touser(sp),
 * where sp is its stack pointer.
 */
void
forkret(void)
{
	extern void kexit(Ureg*);

	kexit(nil);
	touser(0);
}
Exemplo n.º 4
0
int kkexit(int value)
{
    if(running->pid == 1 && nproc > 2){
    	printf("other procs still exist, P1 can't die yet !%c\n",007);
    	return -1;
    }

    kexit(value);
}
Exemplo n.º 5
0
Arquivo: t.c Projeto: shank8/CS460
int do_exit(){
  int val;
  char c;

  printf("Enter an exit value (0-9): ");
  c = getc();
  val = c-'0';

  kexit(val);
}
Exemplo n.º 6
0
do_exit(){

	int val = 0;
	bzero(buf, BUF_SIZE);
	printf("enter exitValue: ");
	gets(buf);

	val = atoi(buf);
	//printf("exitValue: %d\n", val);

	kexit(val);
}
Exemplo n.º 7
0
int do_exit()
{
  int exitValue;
  if (running->pid == 1 && nproc > 2){
      printf("other killMods still exist, P1 can't die yet !%c\n",007);
      return -1;
  }
  printf("enter an exitValue : ");
  exitValue = geti();
  printf("\n");
  kexit(exitValue);
}
Exemplo n.º 8
0
/**
 * Handles a request for a task.
 *
 */
int handle(Task *task, Request *req) {
    // Handle Interrupts.
    if (req == 0) {
        int data;
        int event = process_interrupt(&data); 
        kevent(event, data);
        make_ready(task);
        return 0;
    }


    // Handle System Calls.
    switch (req->request) {
    case MY_TID:
        kmytid(task);
        break;
    case CREATE:
        kcreate(task, (int)req->args[0] /* priority */, req->args[1] /* code */, (int)req->args[2] /* args */);
        break;
    case MY_PARENT_TID:
        kmy_parent_tid(task);
        break;
    case PASS:
        make_ready(task);
        break;
    case EXIT:
        kexit(task);
        break;
    case SEND:
        ksend(task, (int)req->args[0], (char *)req->args[1], (int)req->args[2], (char *)req->args[3], (int)req->args[4]);
        break;
    case RECEIVE:
        krecieve(task, (int *)req->args[0], (char *)req->args[1], (int)req->args[2]);
        break;
    case REPLY:
        kreply(task, (int)req->args[0], (char *)req->args[1], (int)req->args[2]);
        break;
    case AWAIT_EVENT:
        kawait(task, (int)req->args[0]);
        break;
    case WAIT_TID:
        kwait_tid(task, (int)req->args[0]);
        break;
    case SHUTDOWN:
        return -1;
    default:
        bwprintf(COM2, "Undefined request number %u\n", req->request);
        break;
    }

    return 0;
}
Exemplo n.º 9
0
int do_exit(){
	int exitValue;
	char buf[32];

	printf("please enter an exitValue: ");
	gets(buf);

	exitValue = stoi(buf);

	printf("\nExiting with %d...\n", exitValue);
	kexit(exitValue);	
	
}
Exemplo n.º 10
0
int do_exit(int exitValue)
{
  //int exitValue;
  if (running->pid == 1 && nproc > 2){
      printf("other procs still exist, P1 can't die yet !%c\n",007);
      return -1;
  }
  /***************************************
  printf("enter an exitValue (0-9) : ");
  exitValue = (getc()&0x7F) - '0'; 
  printf("%d\n", exitValue);
  **************************************/
  kexit(exitValue);
}
Exemplo n.º 11
0
int kwait_tid_test() {
    reset();

    kexit(t0);
    vassert(t0->state == ZOMBIE);

    // Shouldn't block when calling wait on ZOMBIE task
    kwait_tid(t1, t0->tid);
    vassert(t1->state == READY);
    vassert(task_get_return_value(t1) == 0);
    vassert(t0->state == ZOMBIE);

    // Should block on non zombie.
    kwait_tid(t1, t2->tid);
    vassert(t2->state != ZOMBIE);
    vassert(t1->state == WAIT_BLOCKED);

    // Should unblock when non zombie exits.
    kexit(t2);
    vassert(t2->state == ZOMBIE);
    vassert(t1->state == READY);

    return 0;
}
Exemplo n.º 12
0
int ksend_transaction_failed() {
    reset();

    char *msg = "Hello!";
    int msglen = 7;
    char reply[5];
    int replylen = 5;
    ksend(t0, t1->tid, msg, msglen, reply, replylen);

    vassert(t0->state == SEND_BLOCKED);

    kexit(t1);
    vassert(t0->state == READY);
    vassert(task_get_return_value(t0) == -3);
    vassert(t1->state == ZOMBIE);

    return 0;
}
Exemplo n.º 13
0
int
system(
    char *  path, /* Path to the executable to run */
    int     argc, /* Argument count (ie, /bin/echo hello world = 3) */
    char ** argv  /* Argument strings (including executable path) */
) {
    int child = fork();
    if (child == 0) {
        char * env[] = {NULL};
        exec(path,argc,argv,env);
        debug_print(ERROR, "Failed to execute process!");
        kexit(-1);
        return -1;
    } else {
        switch_next();
        return -1;
    }
}
Exemplo n.º 14
0
int write_pipe(int fd, char *buf, int n)
{
  char c;   int r=0;
  PIPE *p;  OFT *op;

  if (fd < 0 || fd > NFD || running->fd[fd] == 0){
     printf("bad fd %d\n", fd);
     return -1;
  }
  op = running->fd[fd];
  if (op->mode != WRITE_PIPE){
     printf("fd = %d is NOT for write\n", fd);
     return -1;
  }
  p = op->pipe_ptr;
  printf("pipe before writing\n");
  show_pipe(p);

  while(n){
    if (!p->nreader){                // no more readers
       printf("proc %d : BROKEN_PIPE error\n", running->pid);
       kexit(0x0D);              // simulate SIGPIPE=13
     }
     while(p->room && n){
        p->buf[p->head++] = get_byte(running->uss, buf); 
        p->head %= PSIZE;
        p->data++; p->room--; 
        n--; r++; buf++;
     }
     kwakeup(&p->data);            // wakeup ALL readers, if any.
     if (n==0){
        printf("pipe after writing\n");
        show_pipe(p);

        return r;          // finished writing n bytes 
     }
     // still has data to write but pipe has no room
     printf("pipe before writer goes to sleep\n");
     show_pipe(p);

     ksleep(&p->room);             // sleep for room   
  }
  return r;
}
Exemplo n.º 15
0
int kcinth() {
    
    u16 segment, offset;
    int a,b,c,d,r;

    segment = running->uss;
    offset  = running->usp;

    a = get_word(segment, offset + 2*PA);
    b = get_word(segment, offset + 2*(PA+1));
    c = get_word(segment, offset + 2*(PA+2));
    d = get_word(segment, offset + 2*(PA+3));

    switch(a) {

        case 0:
            r = getpid();
            break;
        case 1:
            r = kps();
            break;
        case 2:
            k = kchname();
            break;
        case 3:
            r = kkfork();
            break;
        case 4:
            r = kswitch();
            break;
        case 5:
            r = kwait(b);
            break;
        case 6:
            kexit();
            break;
        default:
            printf("invalid syscall %d\n", a);
    }

    put_word(r, segment, offset + 2*AX);

}
Exemplo n.º 16
0
Arquivo: t.c Projeto: shank8/CS460
int body()
{
   char c, CR, buf[64];
   while(1){
      printf("=======================================\n");
      printQueue(readyQueue);      

      printf("proc %d %s in Kmode\n", running->pid, running->name);
      printf("input a command (s|f|u|q|i|o) : ");
      c=getc(); putc(c); CR=getc(); putc(CR);
      switch(c){
          case 's' : tswitch(); break;
          case 'u' : printf("\nProc %d ready to go U mode\n", running->pid);
                     goUmode(); break;
          case 'f':  fork();  break;
          case 'q' : kexit();   break;
          case 'i' : iline();   break;
          case 'o' : oline();   break;
      }
   }
}
Exemplo n.º 17
0
int
system(
		char *  path, /* Path to the executable to run */
		int     argc, /* Argument count (ie, /bin/echo hello world = 3) */
		char ** argv  /* Argument strings (including executable path) */
	) {
	char ** argv_ = malloc(sizeof(char *) * (argc + 1));
	for (int j = 0; j < argc; ++j) {
		argv_[j] = malloc((strlen(argv[j]) + 1) * sizeof(char));
		memcpy(argv_[j], argv[j], strlen(argv[j]) + 1);
	}
	argv_[argc] = 0;
	char * env[] = {NULL};
	set_process_environment((process_t*)current_process, clone_directory(current_directory));
	current_directory = current_process->thread.page_directory;
	switch_page_directory(current_directory);
	exec(path,argc,argv_,env);
	debug_print(ERROR, "Failed to execute process!");
	kexit(-1);
	return -1;
}
Exemplo n.º 18
0
int body() {
    char c;
    printf("proc %d resumes to body()\n", running->pid);
    
    while(1) {
	printLists();
	printf("proc %d[%d] running: parent=%d\n",
	       running->pid, running->priority, running->ppid);
	
	printf("enter a char [Debug|Fork|Umode|Ps|Quit|Sleep|Wait] : ");
	c = getc(); printf("%c\n", c);
	switch(c) {
	    case 's' : tswitch();   break;
	    case 'f' : kfork();     break;
	    case 'q' : kexit();     break; 
	    case 'p' : kps();       break; 
	    case 'w' : kwait();     break;
	    case 'd' : debugStatement();	break;
            case 'u' : goUmode();   break;
	}
    }
}
Exemplo n.º 19
0
/*
 * Cleanup done by runacore to pretend we are going back to user space.
 * We won't return and won't do what syscall() would normally do.
 * Do it here instead.
 */
static void
fakeretfromsyscall(Ureg *ureg)
{
	Proc *up = externup();
	int s;

	poperror();	/* as syscall() would do if we would return */
	if(up->procctl == Proc_tracesyscall){	/* Would this work? */
		up->procctl = Proc_stopme;
		s = splhi();
		procctl(up);
		splx(s);
	}

	up->insyscall = 0;
	/* if we delayed sched because we held a lock, sched now */
	if(up->delaysched){
		sched();
		splhi();
	}
	kexit(ureg);
}
Exemplo n.º 20
0
/* it should be unsigned. FIXME */
void
syscall(int badscallnr, Ureg* ureg)
{
	unsigned int scallnr = (unsigned int) badscallnr;
	char *e;
	uintptr	sp;
	int s;
	vlong startns, stopns;
	Ar0 ar0;
	static Ar0 zar0;

	if(!userureg(ureg))
		panic("syscall: cs %#llux\n", ureg->cs);

	cycles(&up->kentry);

	m->syscall++;
	up->nsyscall++;
	up->nqsyscall++;
	up->insyscall = 1;
	up->pc = ureg->ip;
	up->dbgreg = ureg;
	sp = ureg->sp;
	startns = 0;

	if(up->procctl == Proc_tracesyscall){
		/*
		 * Redundant validaddr.  Do we care?
		 * Tracing syscalls is not exactly a fast path...
		 * Beware, validaddr currently does a pexit rather
		 * than an error if there's a problem; that might
		 * change in the future.
		 */
		if(sp < (USTKTOP-BIGPGSZ) || sp > (USTKTOP-sizeof(up->arg)-BY2SE))
			validaddr(UINT2PTR(sp), sizeof(up->arg)+BY2SE, 0);

		syscallfmt(scallnr, (va_list)(sp+BY2SE));	
		up->procctl = Proc_stopme;
		procctl(up);
		if(up->syscalltrace)
			free(up->syscalltrace);
		up->syscalltrace = nil;
		startns = todget(nil);		
	}

	up->scallnr = scallnr;
	if(scallnr == RFORK)
		fpusysrfork(ureg);
	spllo();

	sp = ureg->sp;
	up->nerrlab = 0;
	ar0 = zar0;
	if(!waserror()){
		if(scallnr >= nsyscall || systab[scallnr].f == nil){
			pprint("bad sys call number %d pc %#llux\n",
				scallnr, ureg->ip);
			postnote(up, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}

		if(sp < (USTKTOP-BIGPGSZ) || sp > (USTKTOP-sizeof(up->arg)-BY2SE))
			validaddr(UINT2PTR(sp), sizeof(up->arg)+BY2SE, 0);

		memmove(up->arg, UINT2PTR(sp+BY2SE), sizeof(up->arg));
		up->psstate = systab[scallnr].n;

		systab[scallnr].f(&ar0, (va_list)up->arg);
		if(scallnr == SYSR1){
			/*
			 * BUG: must go when ron binaries go.
			 * NIX: Returning from execac().
			 * This means that the process is back to the
			 * time sharing core. However, the process did
			 * already return from the system call, when dispatching
			 * the user code to the AC. The only thing left is to
			 * return. The user registers should be ok, because
			 * up->dbgreg has been the user context for the process.
			 */
			return;
		}
		poperror();
	}
	else{
		/* failure: save the error buffer for errstr */
		e = up->syserrstr;
		up->syserrstr = up->errstr;
		up->errstr = e;
		if(DBGFLG && up->pid == 1)
			iprint("%s: syscall %s error %s\n",
				up->text, systab[scallnr].n, up->syserrstr);
		ar0 = systab[scallnr].r;
	}

	/*
	 * NIX: for the execac() syscall, what follows is done within
	 * the system call, because it never returns.
	 * See acore.c:/^retfromsyscall
	 */

	noerrorsleft();

	/*
	 * Put return value in frame.
	 */
	ureg->ax = ar0.p;

	if(up->procctl == Proc_tracesyscall){
		stopns = todget(nil);
		up->procctl = Proc_stopme;
		sysretfmt(scallnr, (va_list)(sp+BY2SE), &ar0, startns, stopns);
		s = splhi();
		procctl(up);
		splx(s);
		if(up->syscalltrace)
			free(up->syscalltrace);
		up->syscalltrace = nil;		
	}else if(up->procctl == Proc_totc || up->procctl == Proc_toac)
		procctl(up);


	up->insyscall = 0;
	up->psstate = 0;

	if(scallnr == NOTED)
		noted(ureg, *(uintptr*)(sp+BY2SE));

	splhi();
	if(scallnr != RFORK && (up->procctl || up->nnote))
		notify(ureg);

	/* if we delayed sched because we held a lock, sched now */
	if(up->delaysched){
		sched();
		splhi();
	}
	kexit(ureg);
}
Exemplo n.º 21
0
// exits a process
int kkexit(int value)
{
    // use your kexit() in LAB3. do NOT let P1 die
    kexit(value);
}
Exemplo n.º 22
0
Arquivo: trap.c Projeto: npe9/harvey
/*
 *  All traps come here.  It is slower to have all traps call trap()
 *  rather than directly vectoring the handler.  However, this avoids a
 *  lot of code duplication and possible bugs.  The only exception is
 *  VectorSYSCALL.
 *  Trap is called with interrupts disabled via interrupt-gates.
 */
void
trap(Ureg* ureg)
{
	int clockintr, vno, user;
	// cache the previous vno to see what might be causing
	// trouble
	static int lastvno;
	vno = ureg->type;
	uint64_t gsbase = rdmsr(GSbase);
	//if (sce > scx) iprint("====================");
	if (vno == 8) {
		iprint("Lstar is %p\n", (void *)rdmsr(Lstar));
		iprint("GSbase is %p\n", (void *)gsbase);
		iprint("ire %d irx %d sce %d scx %d lastvno %d\n", 
			ire, irx, sce, scx, lastvno);
		iprint("irxe %d \n",
			irxe);
		die("8");
	}
	lastvno = vno;
	if (gsbase < 1ULL<<63)
		die("bogus gsbase");
	Mach *m = machp();
	char buf[ERRMAX];
	Vctl *ctl, *v;

	if (0 && m && m->externup && m->externup->pid == 6) {
		//iprint("type %x\n", ureg->type);
		if (ureg->type != 0x49)
			die("6\n");
	}
	m->perf.intrts = perfticks();
	user = userureg(ureg);
	if(user && (m->nixtype == NIXTC)){
		m->externup->dbgreg = ureg;
		cycles(&m->externup->kentry);
	}

	clockintr = 0;

	//_pmcupdate(m);

	if(ctl = vctl[vno]){
		if(ctl->isintr){
			m->intr++;
			if(vno >= VectorPIC && vno != VectorSYSCALL)
				m->lastintr = ctl->irq;
		}else
			if(m->externup)
				m->externup->nqtrap++;

		if(ctl->isr)
			ctl->isr(vno);
		for(v = ctl; v != nil; v = v->next){
			if(v->f)
				v->f(ureg, v->a);
		}
		if(ctl->eoi)
			ctl->eoi(vno);
		intrtime(vno);
		if(ctl->isintr){
			if(ctl->irq == IrqCLOCK || ctl->irq == IrqTIMER)
				clockintr = 1;

			if(m->externup && !clockintr)
				preempted();
		}
	}
	else if(vno < nelem(excname) && user){
		spllo();
		snprint(buf, sizeof buf, "sys: trap: %s", excname[vno]);
		postnote(m->externup, 1, buf, NDebug);
	}
	else if(vno >= VectorPIC && vno != VectorSYSCALL){
		/*
		 * An unknown interrupt.
		 * Check for a default IRQ7. This can happen when
		 * the IRQ input goes away before the acknowledge.
		 * In this case, a 'default IRQ7' is generated, but
		 * the corresponding bit in the ISR isn't set.
		 * In fact, just ignore all such interrupts.
		 */

		/* clear the interrupt */
		i8259isr(vno);

		iprint("cpu%d: spurious interrupt %d, last %d\n",
			m->machno, vno, m->lastintr);
		intrtime(vno);
		if(user)
			kexit(ureg);
		return;
	}
	else{
		if(vno == VectorNMI){
			nmienable();
			if(m->machno != 0){
				iprint("cpu%d: PC %#llux\n",
					m->machno, ureg->ip);
				for(;;);
			}
		}
		dumpregs(ureg);
		if(!user){
			ureg->sp = PTR2UINT(&ureg->sp);
			dumpstackwithureg(ureg);
		}
		if(vno < nelem(excname))
			panic("%s", excname[vno]);
		panic("unknown trap/intr: %d\n", vno);
	}
	splhi();

	/* delaysched set because we held a lock or because our quantum ended */
	if(m->externup && m->externup->delaysched && clockintr){
		if(0)
		if(user && m->externup->ac == nil && m->externup->nqtrap == 0 && m->externup->nqsyscall == 0){
			if(!waserror()){
				m->externup->ac = getac(m->externup, -1);
				poperror();
				runacore();
				return;
			}
		}
		sched();
		splhi();
	}


	if(user){
		if(m->externup && m->externup->procctl || m->externup->nnote)
			notify(ureg);
		kexit(ureg);
	}
}
Exemplo n.º 23
0
/*
 * Move the current process to an application core.
 * This is performed at the end of execac(), and
 * we pretend to be returning to user-space, but instead we
 * dispatch the process to another core.
 * 1. We do the final bookkeeping that syscall() would do after
 *    a return from sysexec(), because we are not returning.
 * 2. We dispatch the process to an AC using an ICC.
 *
 * This function won't return unless the process is reclaimed back
 * to the time-sharing core, and is the handler for the process
 * to deal with traps and system calls until the process dies.
 *
 * Remember that this function is the "line" between user and kernel
 * space, it's not expected to raise|handle any error.
 *
 * We install a safety error label, just in case we raise errors,
 * which we shouldn't. (noerrorsleft knows that for exotic processes
 * there is an error label pushed by us).
 */
void
runacore(void)
{
	Proc *up = externup();
	Ureg *ureg;
	void (*fn)(void);
	int rc, flush, s;
	char *n;
	uint64_t t1;

	if(waserror())
		panic("runacore: error: %s\n", up->errstr);
	ureg = up->dbgreg;
	fakeretfromsyscall(ureg);
	fpusysrfork(ureg);

	procpriority(up, PriKproc, 1);
	rc = runac(up->ac, actouser, 1, nil, 0);
	procpriority(up, PriNormal, 0);
	for(;;){
		t1 = fastticks(nil);
		flush = 0;
		fn = nil;
		switch(rc){
		case ICCTRAP:
			s = splhi();
			machp()->MMU.cr2 = up->ac->MMU.cr2;
			DBG("runacore: trap %llu cr2 %#llx ureg %#p\n",
				ureg->type, machp()->MMU.cr2, ureg);
			switch(ureg->type){
			case IdtIPI:
				if(up->procctl || up->nnote)
					notify(up->dbgreg);
				if(up->ac == nil)
					goto ToTC;
				kexit(up->dbgreg);
				break;
			case IdtNM:
			case IdtMF:
			case IdtXF:
				/* these are handled in the AC;
				 * If we get here, they left in m->NIX.icc->data
				 * a note to be posted to the process.
				 * Post it, and make the vector a NOP.
				 */
				n = up->ac->NIX.icc->note;
				if(n != nil)
					postnote(up, 1, n, NDebug);
				ureg->type = IdtIPI;		/* NOP */
				break;
			default:
				cr3put(machp()->MMU.pml4->pa);
				if(0 && ureg->type == IdtPF){
					print("before PF:\n");
					print("AC:\n");
					dumpptepg(4, up->ac->MMU.pml4->pa);
					print("\n%s:\n", rolename[NIXTC]);
					dumpptepg(4, machp()->MMU.pml4->pa);
				}
				trap(ureg);
			}
			splx(s);
			flush = 1;
			fn = actrapret;
			break;
		case ICCSYSCALL:
			DBG("runacore: syscall ax %#llx ureg %#p\n",
				ureg->ax, ureg);
			cr3put(machp()->MMU.pml4->pa);
			//syscall(ureg->ax, ureg);
			flush = 1;
			fn = acsysret;
			if(0)
			if(up->nqtrap > 2 || up->nsyscall > 1)
				goto ToTC;
			if(up->ac == nil)
				goto ToTC;
			break;
		default:
			panic("runacore: unexpected rc = %d", rc);
		}
		up->tctime += fastticks2us(fastticks(nil) - t1);
		procpriority(up, PriExtra, 1);
		rc = runac(up->ac, fn, flush, nil, 0);
		procpriority(up, PriNormal, 0);
	}
ToTC:
	/*
	 *  to procctl, then syscall,  to
	 *  be back in the TC
	 */
	DBG("runacore: up %#p: return\n", up);
}
Exemplo n.º 24
0
/*
 *  All traps come here.  It is slower to have all traps call trap()
 *  rather than directly vectoring the handler.  However, this avoids a
 *  lot of code duplication and possible bugs.  The only exception is
 *  VectorSYSCALL.
 *  Trap is called with interrupts disabled via interrupt-gates.
 */
void
trap(Ureg* ureg)
{
	int clockintr, vno, user;
	// cache the previous vno to see what might be causing
	// trouble
	vno = ureg->type;
	uint64_t gsbase = rdmsr(GSbase);
	//if (sce > scx) iprint("====================");
	lastvno = vno;
	if (gsbase < 1ULL<<63)
		die("bogus gsbase");
	Proc *up = externup();
	char buf[ERRMAX];
	Vctl *ctl, *v;

	machp()->perf.intrts = perfticks();
	user = userureg(ureg);
	if(user && (machp()->NIX.nixtype == NIXTC)){
		up->dbgreg = ureg;
		cycles(&up->kentry);
	}

	clockintr = 0;

	//_pmcupdate(machp());

	if((ctl = vctl[vno]) != nil){
		if(ctl->isintr){
			machp()->intr++;
			if(vno >= VectorPIC && vno != VectorSYSCALL)
				machp()->lastintr = ctl->Vkey.irq;
		}else
			if(up)
				up->nqtrap++;

		if(ctl->isr){
			ctl->isr(vno);
			if(islo())print("trap %d: isr %p enabled interrupts\n", vno, ctl->isr);
		}
		for(v = ctl; v != nil; v = v->next){
			if(v->f){
				v->f(ureg, v->a);
				if(islo())print("trap %d: ctlf %p enabled interrupts\n", vno, v->f);
			}
		}
		if(ctl->eoi){
			ctl->eoi(vno);
			if(islo())print("trap %d: eoi %p enabled interrupts\n", vno, ctl->eoi);
		}

		intrtime(vno);
		if(ctl->isintr){
			if(ctl->Vkey.irq == IrqCLOCK || ctl->Vkey.irq == IrqTIMER)
				clockintr = 1;

			if (ctl->Vkey.irq == IrqTIMER)
				oprof_alarm_handler(ureg);

			if(up && !clockintr)
				preempted();
		}
	}
	else if(vno < nelem(excname) && user){
		spllo();
		snprint(buf, sizeof buf, "sys: trap: %s", excname[vno]);
		postnote(up, 1, buf, NDebug);
	}
	else if(vno >= VectorPIC && vno != VectorSYSCALL){
		/*
		 * An unknown interrupt.
		 * Check for a default IRQ7. This can happen when
		 * the IRQ input goes away before the acknowledge.
		 * In this case, a 'default IRQ7' is generated, but
		 * the corresponding bit in the ISR isn't set.
		 * In fact, just ignore all such interrupts.
		 */

		/* clear the interrupt */
		i8259isr(vno);

		iprint("cpu%d: spurious interrupt %d, last %d\n",
			machp()->machno, vno, machp()->lastintr);
		intrtime(vno);
		if(user)
			kexit(ureg);
		return;
	}
	else{
		if(vno == VectorNMI){
			nmienable();
			if(machp()->machno != 0){
				iprint("cpu%d: PC %#llx\n",
					machp()->machno, ureg->ip);
				for(;;);
			}
		}
		dumpregs(ureg);
		if(!user){
			ureg->sp = PTR2UINT(&ureg->sp);
			dumpstackwithureg(ureg);
		}
		if(vno < nelem(excname))
			panic("%s", excname[vno]);
		panic("unknown trap/intr: %d\n", vno);
	}
	splhi();

	/* delaysched set because we held a lock or because our quantum ended */
	if(up && up->delaysched && clockintr){
		if(0)
		if(user && up->ac == nil && up->nqtrap == 0 && up->nqsyscall == 0){
			if(!waserror()){
				up->ac = getac(up, -1);
				poperror();
				runacore();
				return;
			}
		}
		sched();
		splhi();
	}


	if(user){
		if(up != nil && (up->procctl || up->nnote))
			notify(ureg);
		kexit(ureg);
	}
}
Exemplo n.º 25
0
int kwrite_pipe(int fd, char *buf, int n){

  char c; int r = 0;
  PIPE *pp; OFT* op;



  printf("Attempt pipe write of %d bytes to fd (%d)\n", n, fd);

  //  if(n <= 0){
  //   return 0;
  // }

  if(fd >= NFD || fd < 0){
    printf("invalid file descriptor (out of bounds).\n");
    return -1;
  }

  if(!running->fd[fd]){
    printf("invalid file descriptor (not opened).\n");
    return -1;
  }

  op = running->fd[fd];
  pp = op->pipe_ptr;

  if(op->mode != WRITE_PIPE){
    printf("fd (%d) is not for pipe read\n", fd);
    return -1;
  }

  printf("pipe before writing\n");
  show_pipe(pp);

  while(n){
    if(!pp->nreader){
      printf("proc %d : BROKEN_PIPE error\n", running->pid);
      kexit(0x0D);
    }

    while(pp->room && n){
      pp->buf[pp->head++] = get_byte(running->uss, buf);
      pp->head = pp->head % PSIZE;

      pp->data++; pp->room--;
      n--; r++; buf++;
    }

    kwakeup(&(pp->data));

    if(n==0){
      printf("pipe after writing\n");
      show_pipe(pp);

      return r;
    }

    printf("pipe before writer goes to sleep\n");
    show_pipe(pp);

    ksleep(&(pp->room));

  }
  
  return r;
}
Exemplo n.º 26
0
/**
 * Call by the exeption to handle the syscall
 * \private
 */
void
syscall_handler(registers_t * regs)
{
  int32_t         res = 0;
  int32_t         syscall = regs->v_reg[0];     // code of the syscall

  switch (syscall)
  {
  case FOURCHETTE:
    res =
      create_proc(get_arg((char **) regs->a_reg[2], 0), regs->a_reg[0],
                  regs->a_reg[1], (char **) regs->a_reg[2]);
    break;
  case PRINT:
    res = print_string((char *) regs->a_reg[0]);
    return;                     /* We save the good return value in the pcb */
  case READ:
    res = read_string((char *) regs->a_reg[0], regs->a_reg[1]);
    return;                     /* We save the good return value in the pcb */
  case FPRINT:
    if (regs->a_reg[0] == CONSOLE)
      kprint((char *) regs->a_reg[1]);
    else
      kmaltaprint8((char *) regs->a_reg[1]);
    break;
  case SLEEP:
    res = go_to_sleep(regs->a_reg[0]);
    break;
  case BLOCK:
    res = kblock(regs->a_reg[0], BLOCKED);
    break;
  case UNBLOCK:
    kwakeup(regs->a_reg[0]);
    break;
  case WAIT:
    res = waitfor(regs->a_reg[0], (int32_t *) regs->a_reg[1]);
    break;
  case SEND:
    res =
      send_msg(pcb_get_pid(get_current_pcb()), (msg_arg *) regs->a_reg[0]);
    break;
  case RECV:
    res =
      recv_msg(pcb_get_pid(get_current_pcb()), (msg_arg *) regs->a_reg[0]);
    if (res == NOTFOUND)
      go_to_sleep(((msg_arg *) regs->a_reg[0])->timeout);
    break;
  case PERROR:
    kperror((char *) regs->a_reg[0]);
    break;
  case GERROR:
    res = kgerror();
    break;
  case SERROR:
    kserror(regs->a_reg[0]);
    break;
  case GETPINFO:
    res = get_pinfo(regs->a_reg[0], (pcbinfo *) regs->a_reg[1]);
    break;
  case GETPID:
    res = pcb_get_pid(get_current_pcb());
    break;
  case GETALLPID:
    res = get_all_pid((int *) regs->a_reg[0]);
    break;
  case CHGPPRI:
    res = chg_ppri(regs->a_reg[0], regs->a_reg[1]);
    break;
  case KILL:
    res = kkill(regs->a_reg[0]);
    break;
  case EXIT:
    kexit(regs->a_reg[0]);
    break;
  default:
    kprintln("ERROR: Unknown syscall");
    break;
  }

  // saves the return code
  regs->v_reg[0] = res;

  return;
}
Exemplo n.º 27
0
void
syscall(Ureg* ureg)
{
	char *e;
	u32int s;
	ulong sp;
	long ret;
	int i, scallnr;
	vlong startns, stopns;

	if(!userureg(ureg))
		panic("syscall: from kernel: pc %#lux r14 %#lux psr %#lux",
			ureg->pc, ureg->r14, ureg->psr);

	cycles(&up->kentry);

	m->syscall++;
	up->insyscall = 1;
	up->pc = ureg->pc;
	up->dbgreg = ureg;

	scallnr = ureg->r0;
	up->scallnr = scallnr;
	if(scallnr == RFORK)
		fpusysrfork(ureg);
	spllo();
	sp = ureg->sp;

	if(up->procctl == Proc_tracesyscall){
		/*
		 * Redundant validaddr.  Do we care?
		 * Tracing syscalls is not exactly a fast path...
		 * Beware, validaddr currently does a pexit rather
		 * than an error if there's a problem; that might
		 * change in the future.
		 */
		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
			validaddr(sp, sizeof(Sargs)+BY2WD, 0);

		syscallfmt(scallnr, ureg->pc, (va_list)(sp+BY2WD));
		up->procctl = Proc_stopme;
		procctl(up);
		if (up->syscalltrace) 
			free(up->syscalltrace);
		up->syscalltrace = nil;
	}

	up->nerrlab = 0;
	ret = -1;
	startns = todget(nil);
	if(!waserror()){
		if(scallnr >= nsyscall){
			pprint("bad sys call number %d pc %#lux\n",
				scallnr, ureg->pc);
			postnote(up, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}

		if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
			validaddr(sp, sizeof(Sargs)+BY2WD, 0);

		up->s = *((Sargs*)(sp+BY2WD));
		up->psstate = sysctab[scallnr];

	/*	iprint("%s: syscall %s\n", up->text, sysctab[scallnr]?sysctab[scallnr]:"huh?"); */

		ret = systab[scallnr](up->s.args);
		poperror();
	}else{
		/* failure: save the error buffer for errstr */
		e = up->syserrstr;
		up->syserrstr = up->errstr;
		up->errstr = e;
	}
	if(up->nerrlab){
		print("bad errstack [%d]: %d extra\n", scallnr, up->nerrlab);
		for(i = 0; i < NERR; i++)
			print("sp=%#p pc=%#p\n",
				up->errlab[i].sp, up->errlab[i].pc);
		panic("error stack");
	}

	/*
	 *  Put return value in frame.  On the x86 the syscall is
	 *  just another trap and the return value from syscall is
	 *  ignored.  On other machines the return value is put into
	 *  the results register by caller of syscall.
	 */
	ureg->r0 = ret;

	if(up->procctl == Proc_tracesyscall){
		stopns = todget(nil);
		up->procctl = Proc_stopme;
		sysretfmt(scallnr, (va_list)(sp+BY2WD), ret, startns, stopns);
		s = splhi();
		procctl(up);
		splx(s);
		if(up->syscalltrace)
			free(up->syscalltrace);
		up->syscalltrace = nil;
	}

	up->insyscall = 0;
	up->psstate = 0;

	if(scallnr == NOTED)
		noted(ureg, *(ulong*)(sp+BY2WD));

	splhi();
	if(scallnr != RFORK && (up->procctl || up->nnote))
		notify(ureg);

	/* if we delayed sched because we held a lock, sched now */
	if(up->delaysched){
		sched();
		splhi();
	}
	kexit(ureg);
}
Exemplo n.º 28
0
/*
 *  All traps come here.  It is slower to have all traps call trap()
 *  rather than directly vectoring the handler.  However, this avoids a
 *  lot of code duplication and possible bugs.  The only exception is
 *  VectorSYSCALL.
 *  Trap is called with interrupts disabled via interrupt-gates.
 */
void
trap(Ureg* ureg)
{
	int clockintr, i, vno, user;
	char buf[ERRMAX];
	Vctl *ctl, *v;
	Mach *mach;

	if(!trapinited){
		/* fault386 can give a better error message */
		if(ureg->trap == VectorPF)
			fault386(ureg, nil);
		panic("trap %lud: not ready", ureg->trap);
	}

	m->perf.intrts = perfticks();
	user = (ureg->cs & 0xFFFF) == UESEL;
	if(user){
		up->dbgreg = ureg;
		cycles(&up->kentry);
	}

	clockintr = 0;

	vno = ureg->trap;
	if(ctl = vctl[vno]){
		if(ctl->isintr){
			m->intr++;
			if(vno >= VectorPIC && vno != VectorSYSCALL)
				m->lastintr = ctl->irq;
		}

		if(ctl->isr)
			ctl->isr(vno);
		for(v = ctl; v != nil; v = v->next){
			if(v->f)
				v->f(ureg, v->a);
		}
		if(ctl->eoi)
			ctl->eoi(vno);

		if(ctl->isintr){
			intrtime(m, vno);

			if(ctl->irq == IrqCLOCK || ctl->irq == IrqTIMER)
				clockintr = 1;

			if(up && !clockintr)
				preempted();
		}
	}
	else if(vno < nelem(excname) && user){
		spllo();
		sprint(buf, "sys: trap: %s", excname[vno]);
		postnote(up, 1, buf, NDebug);
	}
	else if(vno >= VectorPIC && vno != VectorSYSCALL){
		/*
		 * An unknown interrupt.
		 * Check for a default IRQ7. This can happen when
		 * the IRQ input goes away before the acknowledge.
		 * In this case, a 'default IRQ7' is generated, but
		 * the corresponding bit in the ISR isn't set.
		 * In fact, just ignore all such interrupts.
		 */

		/* call all interrupt routines, just in case */
		for(i = VectorPIC; i <= MaxIrqLAPIC; i++){
			ctl = vctl[i];
			if(ctl == nil)
				continue;
			if(!ctl->isintr)
				continue;
			for(v = ctl; v != nil; v = v->next){
				if(v->f)
					v->f(ureg, v->a);
			}
			/* should we do this? */
			if(ctl->eoi)
				ctl->eoi(i);
		}

		/* clear the interrupt */
		i8259isr(vno);

		if(0)print("cpu%d: spurious interrupt %d, last %d\n",
			m->machno, vno, m->lastintr);
		if(0)if(conf.nmach > 1){
			for(i = 0; i < 32; i++){
				if(!(active.machs & (1<<i)))
					continue;
				mach = MACHP(i);
				if(m->machno == mach->machno)
					continue;
				print(" cpu%d: last %d",
					mach->machno, mach->lastintr);
			}
			print("\n");
		}
		m->spuriousintr++;
		if(user)
			kexit(ureg);
		return;
	}
	else{
		if(vno == VectorNMI){
			/*
			 * Don't re-enable, it confuses the crash dumps.
			nmienable();
			 */
			iprint("cpu%d: PC %#8.8lux\n", m->machno, ureg->pc);
			while(m->machno != 0)
				;
		}
		dumpregs(ureg);
		if(!user){
			ureg->sp = (ulong)&ureg->sp;
			_dumpstack(ureg);
		}
		if(vno < nelem(excname))
			panic("%s", excname[vno]);
		panic("unknown trap/intr: %d", vno);
	}
	splhi();

	/* delaysched set because we held a lock or because our quantum ended */
	if(up && up->delaysched && clockintr){
		sched();
		splhi();
	}

	if(user){
		if(up->procctl || up->nnote)
			notify(ureg);
		kexit(ureg);
	}
}
Exemplo n.º 29
0
/*
 *  Syscall is called directly from assembler without going through trap().
 */
void
syscall(Ureg* ureg)
{
	char *e;
	ulong	sp;
	long	ret;
	int	i, s;
	ulong scallnr;

	if((ureg->cs & 0xFFFF) != UESEL)
		panic("syscall: cs 0x%4.4luX", ureg->cs);

	cycles(&up->kentry);

	m->syscall++;
	up->insyscall = 1;
	up->pc = ureg->pc;
	up->dbgreg = ureg;

	if(up->procctl == Proc_tracesyscall){
		up->procctl = Proc_stopme;
		procctl(up);
	}

	scallnr = ureg->ax;
	up->scallnr = scallnr;
	if(scallnr == RFORK && up->fpstate == FPactive){
		fpsave(&up->fpsave);
		up->fpstate = FPinactive;
	}
	spllo();

	sp = ureg->usp;
	up->nerrlab = 0;
	ret = -1;
	if(!waserror()){
		if(scallnr >= nsyscall || systab[scallnr] == 0){
			pprint("bad sys call number %lud pc %lux\n",
				scallnr, ureg->pc);
			postnote(up, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}

		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
			validaddr(sp, sizeof(Sargs)+BY2WD, 0);

		up->s = *((Sargs*)(sp+BY2WD));
		up->psstate = sysctab[scallnr];

		ret = systab[scallnr](up->s.args);
		poperror();
	}else{
		/* failure: save the error buffer for errstr */
		e = up->syserrstr;
		up->syserrstr = up->errstr;
		up->errstr = e;
		if(0 && up->pid == 1)
			print("syscall %lud error %s\n", scallnr, up->syserrstr);
	}
	if(up->nerrlab){
		print("bad errstack [%lud]: %d extra\n", scallnr, up->nerrlab);
		for(i = 0; i < NERR; i++)
			print("sp=%lux pc=%lux\n",
				up->errlab[i].sp, up->errlab[i].pc);
		panic("error stack");
	}

	/*
	 *  Put return value in frame.  On the x86 the syscall is
	 *  just another trap and the return value from syscall is
	 *  ignored.  On other machines the return value is put into
	 *  the results register by caller of syscall.
	 */
	ureg->ax = ret;

	if(up->procctl == Proc_tracesyscall){
		up->procctl = Proc_stopme;
		s = splhi();
		procctl(up);
		splx(s);
	}

	up->insyscall = 0;
	up->psstate = 0;

	if(scallnr == NOTED)
		noted(ureg, *(ulong*)(sp+BY2WD));

	if(scallnr!=RFORK && (up->procctl || up->nnote)){
		splhi();
		notify(ureg);
	}
	/* if we delayed sched because we held a lock, sched now */
	if(up->delaysched)
		sched();
	kexit(ureg);
}
Exemplo n.º 30
0
Arquivo: int.c Projeto: konorati/cs460
int kkexit(int value)
{
    int i = kexit(value);
    return i;
}