int timer_handler(int irq, void* data) {
  ticks++;
  assert(current != NULL);
  run_timer_list();
  lapiceoi();
  return 0;
}
예제 #2
0
void irq_handler(){
  uint32_t pending = inw(VIC_VBASE+INTERRUPT_STATUS);
  uint32_t irq = 0;
  while(pending > 0){
    irq = inw(VIC_VBASE+INTERRUPT_NUMBER);
    if(actions[irq].handler){
      (*actions[irq].handler)(irq, actions[irq].opaque);
    }else{
      pic_disable(irq);
    }
    pending = inw(VIC_VBASE+INTERRUPT_STATUS);
  }
#if 0
  if(status & (1<<TIMER0_IRQ)){
    //kprintf("@");
    ticks++;
		//assert(pls_read(current) != NULL);
    run_timer_list();
    clock_clear();
  }
  if( status & (1<<UART_IRQ) ){
    //if ((c = cons_getc()) == 13) {
    //  debug_monitor(tf);
    //}
    //else {
      extern void dev_stdin_write(char c);
      char c = cons_getc();
      dev_stdin_write(c);
    //}
    //kprintf("#");
    serial_clear();
  }
#endif
}
예제 #3
0
파일: clock.c 프로젝트: TySag/project
int clock_int_handler(void * data)
{
  ticks++;
//  if( (ticks & 0x1F) == 0)
//    cons_putc('A');
  run_timer_list();  
  reload_timer(); 
  return 0;
}
예제 #4
0
파일: trap.c 프로젝트: jefjin/ucore
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret;

    switch (tf->tf_trapno) {
    case T_DEBUG:
    case T_BRKPT:
        debug_monitor(tf);
        break;
    case T_PGFLT:
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            if (current == NULL) {
                panic("handle pgfault failed. %e\n", ret);
            }
            else {
                if (trap_in_kernel(tf)) {
                    panic("handle pgfault failed in kernel mode. %e\n", ret);
                }
                cprintf("killed by kernel.\n");
                do_exit(-E_KILLED);
            }
        }
        break;
    case T_SYSCALL:
        syscall();
        break;
    case IRQ_OFFSET + IRQ_TIMER:
        ticks ++;
        assert(current != NULL);
        run_timer_list();
        break;
    case IRQ_OFFSET + IRQ_COM1:
    case IRQ_OFFSET + IRQ_KBD:
        if ((c = cons_getc()) == 13) {
            debug_monitor(tf);
        }
        else {
            cprintf("%s [%03d] %c\n",
                    (tf->tf_trapno != IRQ_OFFSET + IRQ_KBD) ? "serial" : "kbd", c, c);
        }
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        print_trapframe(tf);
        if (current != NULL) {
            cprintf("unhandled trap.\n");
            do_exit(-E_KILLED);
        }
        panic("unexpected trap in kernel.\n");
    }
}
예제 #5
0
파일: sched.c 프로젝트: Mellvik/elks
void do_timer(struct pt_regs *regs)
{
    jiffies++;

#ifdef NEED_RESCHED		/* need_resched is not checked anywhere */
    if (!((int) jiffies & 7))
	need_resched = 1;	/* how primitive can you get? */
#endif

    run_timer_list();

}
예제 #6
0
파일: trap.c 프로젝트: czy941030/ucore_lab
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret=0;

    switch (tf->tf_trapno) {
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            if (current == NULL) {
                panic("handle pgfault failed. ret=%d\n", ret);
            }
            else {
                if (trap_in_kernel(tf)) {
                    panic("handle pgfault failed in kernel mode. ret=%d\n", ret);
                }
                cprintf("killed by kernel.\n");
                panic("handle user mode pgfault failed. ret=%d\n", ret); 
                do_exit(-E_KILLED);
            }
        }
        break;
    case T_SYSCALL:
        syscall();
        break;
    case IRQ_OFFSET + IRQ_TIMER:
#if 0
    LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
    then you can add code here. 
#endif
        /* LAB1 YOUR CODE : STEP 3 */
        /* handle the timer interrupt */
        /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c
         * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
         * (3) Too Simple? Yes, I think so!
         */
        /* LAB5 YOUR CODE */
        /* you should upate you lab1 code (just add ONE or TWO lines of code):
         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
         */
        /* LAB6 YOUR CODE */
        /* IMPORTANT FUNCTIONS:
	     * run_timer_list
	     *----------------------
	     * you should update your lab5 code (just add ONE or TWO lines of code):
         *    Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler.
         *    You can use one funcitons to finish all these things.
         */
		ticks ++;
		run_timer_list();

        break;
    case IRQ_OFFSET + IRQ_COM1:
        c = cons_getc();
        cprintf("serial [%03d] %c\n", c, c);
        break;
    case IRQ_OFFSET + IRQ_KBD:
        c = cons_getc();
        cprintf("kbd [%03d] %c\n", c, c);
        break;
    //LAB1 CHALLENGE 1 : 13307130148 you should modify below codes.
    case T_SWITCH_TOU:
		cprintf("To user mode\n");
		if (tf->tf_cs != USER_CS) {
			tfk2u = *tf;
			tfk2u.tf_cs = USER_CS;
			tfk2u.tf_ds = tfk2u.tf_es = tfk2u.tf_ss = USER_DS;
			tfk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8;
			tfk2u.tf_eflags |= (3 << 12);
			*((uint32_t *)tf - 1) = (uint32_t)&tfk2u;
		}
		break;
    case T_SWITCH_TOK:
		cprintf("To kernel mode\n");
        //panic("T_SWITCH_** ??\n");
		struct trapframe *tfu2k;
		if (tf->tf_cs != KERNEL_CS) {
			tf->tf_cs = KERNEL_CS;
			tf->tf_ds = tf->tf_es = KERNEL_DS;
			tf->tf_eflags &= ~(3 << 12);
			tfu2k = (struct trapframe*)((uint32_t)tf->tf_esp - sizeof(struct trapframe) + 8);
			memmove(tfu2k, tf, sizeof(struct trapframe)-8);
			*((uint32_t *)tf - 1) = (uint32_t)tfu2k;
		}
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        print_trapframe(tf);
        if (current != NULL) {
            cprintf("unhandled trap.\n");
            do_exit(-E_KILLED);
        }
        // in kernel, it must be a mistake
        panic("unexpected trap in kernel.\n");

    }
}
예제 #7
0
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret=0;

    switch (tf->tf_trapno) {
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            if (current == NULL) {
                panic("handle pgfault failed. ret=%d\n", ret);
            }
            else {
                if (trap_in_kernel(tf)) {
                    panic("handle pgfault failed in kernel mode. ret=%d\n", ret);
                }
                cprintf("killed by kernel.\n");
                panic("handle user mode pgfault failed. ret=%d\n", ret); 
                do_exit(-E_KILLED);
            }
        }
        break;
    case T_SYSCALL:
        syscall();
        break;
    case IRQ_OFFSET + IRQ_TIMER:
#if 0
    LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages, 
    then you can add code here. 
#endif
        /* LAB1 YOUR CODE : STEP 3 */
        /* handle the timer interrupt */
        /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c
         * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
         * (3) Too Simple? Yes, I think so!
         */
        /* LAB5 YOUR CODE */
        /* you should upate you lab1 code (just add ONE or TWO lines of code):
         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
         */
        ticks ++;
        assert(current != NULL);
        run_timer_list();
        break;
    case IRQ_OFFSET + IRQ_COM1:
        c = cons_getc();
        cprintf("serial [%03d] %c\n", c, c);
        break;
    case IRQ_OFFSET + IRQ_KBD:
        c = cons_getc();
        cprintf("kbd [%03d] %c\n", c, c);
        break;
    //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
    case T_SWITCH_TOU:
    case T_SWITCH_TOK:
        panic("T_SWITCH_** ??\n");
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        print_trapframe(tf);
        if (current != NULL) {
            cprintf("unhandled trap.\n");
            do_exit(-E_KILLED);
        }
        // in kernel, it must be a mistake
        panic("unexpected trap in kernel.\n");

    }
}
예제 #8
0
파일: time.c 프로젝트: feng-lei/mario
static void PIT_bh(void *unused)
{
	run_timer_list();
}
예제 #9
0
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret=0;

    switch (tf->tf_trapno) {
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            if (current == NULL) {
                panic("handle pgfault failed. ret=%d\n", ret);
            }
            else {
                if (trap_in_kernel(tf)) {
                    panic("handle pgfault failed in kernel mode. ret=%d\n", ret);
                }
                cprintf("killed by kernel.\n");
                panic("handle user mode pgfault failed. ret=%d\n", ret);
                do_exit(-E_KILLED);
            }
        }
        break;
    case T_SYSCALL:
        syscall();
        break;
    case IRQ_OFFSET + IRQ_TIMER:
#if 0
LAB3 :
        If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
        then you can add code here.
#endif
        /* LAB1 2013011365 : STEP 3 */
        /* handle the timer interrupt */
        /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c
         * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
         * (3) Too Simple? Yes, I think so!
         */
        /* LAB5 YOUR CODE */
        /* you should upate you lab1 code (just add ONE or TWO lines of code):
         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
         */
        /* LAB6 YOUR CODE */
        /* you should upate you lab5 code
         * IMPORTANT FUNCTIONS:
         * sched_class_proc_tick
         */
        /* LAB7 YOUR CODE */
        /* you should upate you lab6 code
         * IMPORTANT FUNCTIONS:
         * run_timer_list
         */
        ticks++;
        run_timer_list();
        sched_class_proc_tick(current);
        break;
    case IRQ_OFFSET + IRQ_COM1:
    case IRQ_OFFSET + IRQ_KBD:
        // There are user level shell in LAB8, so we need change COM/KBD interrupt processing.
        c = cons_getc();
        {
            extern void dev_stdin_write(char c);
            dev_stdin_write(c);
        }
        break;
    //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
    case T_SWITCH_TOU:
        if(tf->tf_cs != USER_CS) {
            user_stack = *tf;
            user_stack.tf_cs = USER_CS;
            user_stack.tf_ds = USER_DS;
            user_stack.tf_ss = USER_DS;
            user_stack.tf_es = USER_DS;
            user_stack.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8;
            user_stack.tf_eflags |= FL_IOPL_MASK;
            *((uint32_t *)tf - 1) = (uint32_t)&user_stack;
        }
        break;
    case T_SWITCH_TOK:
        if(tf->tf_cs != KERNEL_CS) {
            tf->tf_cs = KERNEL_CS;
            tf->tf_ds = KERNEL_DS;
            tf->tf_es = KERNEL_DS;
            tf->tf_eflags &= ~FL_IOPL_MASK;
            struct trapframe* k = (struct trapframe*)(tf->tf_esp - (sizeof(struct trapframe) - 8));
            memmove(k, tf, sizeof(struct trapframe) -8);
            *((uint32_t *)tf - 1) = (uint32_t)k;

        }
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        print_trapframe(tf);
        if (current != NULL) {
            cprintf("unhandled trap.\n");
            do_exit(-E_KILLED);
        }
        // in kernel, it must be a mistake
        panic("unexpected trap in kernel.\n");

    }
}
예제 #10
0
파일: trap.c 프로젝트: dongyp13/os_lab
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret=0;

    switch (tf->tf_trapno) {
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            if (current == NULL) {
                panic("handle pgfault failed. ret=%d\n", ret);
            }
            else {
                if (trap_in_kernel(tf)) {
                    panic("handle pgfault failed in kernel mode. ret=%d\n", ret);
                }
                cprintf("killed by kernel.\n");
                panic("handle user mode pgfault failed. ret=%d\n", ret); 
                do_exit(-E_KILLED);
            }
        }
        break;
    case T_SYSCALL:
        syscall();
        break;
    case IRQ_OFFSET + IRQ_TIMER:
#if 0
    LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
    then you can add code here. 
#endif
        /* LAB1 YOUR CODE : STEP 3 */
        /* handle the timer interrupt */
        /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c
         * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
         * (3) Too Simple? Yes, I think so!
         */
        /* LAB5 YOUR CODE */
        /* you should upate you lab1 code (just add ONE or TWO lines of code):
         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
         */
        /* LAB6 YOUR CODE */
        /* you should upate you lab5 code
         * IMPORTANT FUNCTIONS:
	     * sched_class_proc_tick
         */
        ticks++;
        run_timer_list(current);
        break;
    case IRQ_OFFSET + IRQ_COM1:
        c = cons_getc();
        cprintf("serial [%03d] %c\n", c, c);
        break;
    case IRQ_OFFSET + IRQ_KBD:
        c = cons_getc();
        cprintf("kbd [%03d] %c\n", c, c);
        break;
    //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
    case T_SWITCH_TOU:
        if (tf->tf_cs != USER_CS) {
            switchk2u = *tf;
            switchk2u.tf_cs = USER_CS;
            switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS;
            switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8;
        
            // set eflags, make sure ucore can use io under user mode.
            // if CPL > IOPL, then cpu will generate a general protection.
            switchk2u.tf_eflags |= FL_IOPL_MASK;
        
            // set temporary stack
            // then iret will jump to the right stack
            *((uint32_t *)tf - 1) = (uint32_t)&switchk2u;
        }
        break;
    case T_SWITCH_TOK:
        if (tf->tf_cs != KERNEL_CS) {
            tf->tf_cs = KERNEL_CS;
            tf->tf_ds = tf->tf_es = KERNEL_DS;
            tf->tf_eflags &= ~FL_IOPL_MASK;
            switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8));
            memmove(switchu2k, tf, sizeof(struct trapframe) - 8);
            *((uint32_t *)tf - 1) = (uint32_t)switchu2k;
        }
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        print_trapframe(tf);
        if (current != NULL) {
            cprintf("unhandled trap.\n");
            do_exit(-E_KILLED);
        }
        // in kernel, it must be a mistake
        panic("unexpected trap in kernel.\n");

    }
}
예제 #11
0
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret=0;

    switch (tf->tf_trapno) {
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            if (current == NULL) {
                panic("handle pgfault failed. ret=%d\n", ret);
            }
            else {
                if (trap_in_kernel(tf)) {
                    panic("handle pgfault failed in kernel mode. ret=%d\n", ret);
                }
                cprintf("killed by kernel.\n");
                panic("handle user mode pgfault failed. ret=%d\n", ret); 
                do_exit(-E_KILLED);
            }
        }
        break;
    case T_SYSCALL:
        syscall();
        break;
    case IRQ_OFFSET + IRQ_TIMER:
#if 0
    LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
    then you can add code here. 
#endif
        /* LAB1 2012011359 : STEP 3 */
        /* handle the timer interrupt */
        /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c
         * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
         * (3) Too Simple? Yes, I think so!
         */
        /* LAB5 2012011359 */
        /* you should upate you lab1 code (just add ONE or TWO lines of code):
         *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
         */
        /* LAB6 2012011359 */
        /* IMPORTANT FUNCTIONS:
	     * run_timer_list
	     *----------------------
	     * you should update your lab5 code (just add ONE or TWO lines of code):
         *    Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler.
         *    You can use one funcitons to finish all these things.
         */
		ticks ++;
		run_timer_list();
		break;
    case IRQ_OFFSET + IRQ_COM1:
    	//c = cons_getc();
    	//cprintf("serial [%03d] %c\n", c, c);
    //	break;
    case IRQ_OFFSET + IRQ_KBD:
        // There are user level shell in LAB8, so we need change COM/KBD interrupt processing.
        c = cons_getc();
        {
          extern void dev_stdin_write(char c);
          dev_stdin_write(c);
        }
        break;
    //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
    case T_SWITCH_TOU:
    case T_SWITCH_TOK:
        panic("T_SWITCH_** ??\n");
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        print_trapframe(tf);
        if (current != NULL) {
            cprintf("unhandled trap.\n");
            do_exit(-E_KILLED);
        }
        // in kernel, it must be a mistake
        panic("unexpected trap in kernel.\n");

    }
}
예제 #12
0
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret;
	
	int int_num;

    switch ((tf->tf_Cause & 0x0000007c) >> 2) {
    case EXC_TLBL:
    case EXC_TLBS:
        if ((ret = tlb_miss_handler(tf)) != 0) {
            print_trapframe(tf);
            panic("handle TLB Miss failed. %e\n", ret);
        }
        break;
    case EXC_SYS:
        syscall();
        break;
    case EXC_INT:
        //switch ((tf->tf_Cause & tf->tf_Status & 0x0000ff00) >> 8) {
		int_num = (tf->tf_Cause & tf->tf_Status & 0x0000ff00) >> 8;
        //case (1 << IRQ_TIMER):
		if (int_num & (1 << IRQ_TIMER)) {
#if 0
    LAB3 : If some page replacement algorithm(such as CLOCK PRA) need tick to change the priority of pages,
    then you can add code here.
#endif
            /* LAB1 2011011278 : STEP 3 */
            /* handle the timer interrupt */
            /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c
             * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks().
             * (3) Too Simple? Yes, I think so!
             */
            ticks++;
            if (ticks % TICK_NUM == 0) {
                // print_ticks();
                current -> need_resched = 1;
            }
            /* LAB5 2011011278 */
            /* you should upate you lab1 code (just add ONE or TWO lines of code):
             *    Every TICK_NUM cycle, you should set current process's current->need_resched = 1
             */
            /* LAB6 2011011278 */
            /* IMPORTANT FUNCTIONS:
	         * run_timer_list
	         *----------------------
	         * you should update your lab5 code (just add ONE or TWO lines of code):
             *    Every tick, you should update the system time, iterate the timers, and trigger the timers which are end to call scheduler.
             *    You can use one funcitons to finish all these things.
             */
            run_timer_list();
            clock_intr();
            //break;
		}
		else if (int_num & ((1 << IRQ_KBD) | (1 << IRQ_COM1)))
		//case (1 << IRQ_KBD):
        //case (1 << IRQ_COM1):
            // There are user level shell in LAB8, so we need change COM/KBD interrupt processing.
            {
                // cprintf("serial [%03d] %c\n", c, c);
                extern void dev_stdin_write(char c);
                while ((c = cons_getc()) != 0)
                    dev_stdin_write(c);
            }
            //break;
		else if (int_num & (1 << IRQ_ETH))
		//case (1 << IRQ_ETH):
			ethernet_intr();
			//break;
        //default:
		else {
            print_trapframe(tf);
            panic("unknown int.\n");
        }
        break;
    case EXC_RI:
        if ((ret = ri_handler(tf)) != 0) {
            print_trapframe(tf);
            if (current != NULL)
                do_exit(-E_KILLED);
            panic("unexpected RI in kernel.\n");
        }
        break;
    //LAB1 CHALLENGE 1 : 2011011278 you should modify below codes.
    default:
        print_trapframe(tf);
        if (current != NULL) {
            cprintf("unhandled trap.\n");
            do_exit(-E_KILLED);
        }
        // in kernel, it must be a mistake
        panic("unexpected trap in kernel.\n");

    }
}
예제 #13
0
파일: trap.c 프로젝트: peterfyj/u12proj
static void
trap_dispatch(struct trapframe *tf) {
#ifdef DEBUG_PRINT_SYSCALL_NUM
	static const char * const syscallnames[] = {
		[SYS_exit]              "sys_exit",
		[SYS_fork]              "sys_fork",
		[SYS_wait]              "sys_wait",
		[SYS_exec]              "sys_exec",
		[SYS_clone]             "sys_clone",
		[SYS_yield]             "sys_yield",
		[SYS_kill]              "sys_kill",
		[SYS_sleep]             "sys_sleep",
		[SYS_gettime]           "sys_gettime",
		[SYS_getpid]            "sys_getpid",
		[SYS_brk]               "sys_brk",
		[SYS_mmap]              "sys_mmap",
		[SYS_munmap]            "sys_munmap",
		[SYS_shmem]             "sys_shmem",
		[SYS_putc]              "sys_putc",
		[SYS_pgdir]             "sys_pgdir",
		[SYS_sem_init]          "sys_sem_init",
		[SYS_sem_post]          "sys_sem_post",
		[SYS_sem_wait]          "sys_sem_wait",
		[SYS_sem_free]          "sys_sem_free",
		[SYS_sem_get_value]     "sys_sem_get_value",
		[SYS_event_send]        "sys_event_send",
		[SYS_event_recv]        "sys_event_recv",
		[SYS_mbox_init]         "sys_mbox_init",
		[SYS_mbox_send]         "sys_mbox_send",
		[SYS_mbox_recv]         "sys_mbox_recv",
		[SYS_mbox_free]         "sys_mbox_free",
		[SYS_mbox_info]         "sys_mbox_info",
		[SYS_open]              "sys_open",
		[SYS_close]             "sys_close",
		[SYS_read]              "sys_read",
		[SYS_write]             "sys_write",
		[SYS_seek]              "sys_seek",
		[SYS_fstat]             "sys_fstat",
		[SYS_fsync]             "sys_fsync",
		[SYS_chdir]             "sys_chdir",
		[SYS_getcwd]            "sys_getcwd",
		[SYS_mkdir]             "sys_mkdir",
		[SYS_link]              "sys_link",
		[SYS_rename]            "sys_rename",
		[SYS_unlink]            "sys_unlink",
		[SYS_getdirentry]       "sys_getdirentry",
		[SYS_dup]               "sys_dup",
		[SYS_pipe]              "sys_pipe",
		[SYS_mkfifo]            "sys_mkfifo",
		[SYS_modify_ldt]		"sys_modify_ldt",
		[SYS_gettimeofday]		"sys_gettimeofday",
		[SYS_exit_group]		"sys_exit_group",
    };
#endif
	
    char c;

    int ret;

    switch (tf->tf_trapno) {
    case T_DEBUG:
    case T_BRKPT:
        debug_monitor(tf);
        break;
    case T_PGFLT:
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            if (current == NULL) {
                panic("handle pgfault failed. %e\n", ret);
            }
            else {
                if (trap_in_kernel(tf)) {
                    panic("handle pgfault failed in kernel mode. %e\n", ret);
                }
                cprintf("killed by kernel.\n");
                do_exit(-E_KILLED);
            }
        }
        break;
    case T_SYSCALL:
#ifdef DEBUG_PRINT_SYSCALL_NUM
		if (tf->tf_regs.reg_eax != SYS_write && 
				tf->tf_regs.reg_eax != SYS_read &&
				tf->tf_regs.reg_eax != SYS_putc)
			cprintf("Syscall [%d] (%s) detected!\n", tf->tf_regs.reg_eax, syscallnames[tf->tf_regs.reg_eax]);
#endif
        syscall();
        break;
    case IRQ_OFFSET + IRQ_TIMER:
        ticks ++;
        assert(current != NULL);
        run_timer_list();
        break;
    case IRQ_OFFSET + IRQ_COM1:
    case IRQ_OFFSET + IRQ_KBD:
        if ((c = cons_getc()) == 13) {
            debug_monitor(tf);
        }
        else {
            extern void dev_stdin_write(char c);
            dev_stdin_write(c);
        }
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        print_trapframe(tf);
        if (current != NULL) {
            cprintf("unhandled trap %d.\n", tf->tf_trapno);
            do_exit(-E_KILLED);
        }
        panic("unexpected trap in kernel.\n");
    }
}