Exemple #1
0
/* trap_dispatch - dispatch based on what type of trap occurred */
static void trap_dispatch(struct trapframe *tf) {
	char c;

	switch (tf->tf_trapno) {
	case IRQ_OFFSET + IRQ_TIMER:
		/* 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!
		 */
		if(++ticks % TICK_NUM == 0) {
			print_ticks();
		}
		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) {
			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:
		// in kernel, it must be a mistake
		if ((tf->tf_cs & 3) == 0) {
			print_trapframe(tf);
			panic("unexpected trap in kernel.\n");
		}
	}
}
Exemple #2
0
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret;

    switch (tf->tf_trapno) {
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            panic("handle pgfault failed. %e\n", ret);
        }
        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!
         */

 ticks ++;
        if (ticks % TICK_NUM == 0) {
            print_ticks();
        }
        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:
        // in kernel, it must be a mistake
        if ((tf->tf_cs & 3) == 0) {
            print_trapframe(tf);
            panic("unexpected trap in kernel.\n");
        }
    }
}
Exemple #3
0
/* trap_dispatch - dispatch based on what type of trap occurred */
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    switch (tf->tf_trapno) {
    case IRQ_OFFSET + IRQ_TIMER:
        /* LAB1 2012012139 : 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) {
          print_ticks();
          ticks = 0;
        }
        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 : 2012012139 you should modify below codes.
    case T_SWITCH_TOU:
        tf->tf_cs = USER_CS;
        tf->tf_ds = USER_DS;
        tf->tf_es = USER_DS;
        tf->tf_ss = USER_DS;
        // 改变IO输出所需要的权限,使得用户可以写
        tf->tf_eflags |= 0x3000;
        break;
    case T_SWITCH_TOK:
        tf->tf_cs = KERNEL_CS;
        tf->tf_ds = KERNEL_DS;
        tf->tf_es = KERNEL_DS;
        // tf->tf_ss = KERNEL_DS;
        // panic("T_SWITCH_** ??\n");
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        // in kernel, it must be a mistake
        if ((tf->tf_cs & 3) == 0) {
            print_trapframe(tf);
            panic("unexpected trap in kernel.\n");
        }
    }
}
Exemple #4
0
/* getchar - reads a single non-zero character from stdin */
int
getchar(void) {
    int c;
    while ((c = cons_getc()) == 0)
        /* do nothing */;
    return c;
}
static int serial_int_handler(int irq, void * data)
{
  extern void dev_stdin_write(char c);
  char c = cons_getc();
  dev_stdin_write(c);
  return 0;
}
Exemple #6
0
/* trap_dispatch - dispatch based on what type of trap occurred */
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    switch (tf->tf_trapno) {
    case T_DEBUG:
    case T_BRKPT:
        debug_monitor(tf);
        break;
    case IRQ_OFFSET + IRQ_TIMER:
        ticks ++;
        if (ticks % TICK_NUM == 0) {
            cprintf("%d ticks\n",TICK_NUM);
        }
        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;
    default:
        // in kernel, it must be a mistake
        if ((tf->tf_cs & 3) == 0) {
            print_trapframe(tf);
            panic("unexpected trap in kernel.\n");
        }
    }
}
Exemple #7
0
// Synchronize the root process's console special files
// with the actual console I/O device.
bool
cons_io(void)
{
	int num_io = 0;

	// Get output file
	fileinode *fi = &files->fi[FILEINO_CONSOUT];
	int c;
	// spinlock_acquire(&cons_lock);
	while(cons_out_pos < fi->size) {
		c = ((char*)FILEDATA(FILEINO_CONSOUT))[cons_out_pos];
		cons_putc(c);
		num_io++;
		cons_out_pos++;
	}
	// spinlock_release(&cons_lock);
	// Input file
	fi = &files->fi[FILEINO_CONSIN];
	// Read from console
	while(fi->size <= FILE_MAXSIZE && (c = cons_getc())) {
		// And appened to CONSIN
		((char*)FILEDATA(FILEINO_CONSIN))[fi->size++] = c;
		num_io++;
	}

	return num_io;
}
Exemple #8
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
}
Exemple #9
0
/* trap_dispatch - dispatch based on what type of trap occurred */
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    switch (tf->tf_trapno) {
    case IRQ_OFFSET + IRQ_TIMER:
        ticks ++;
        if (ticks % TICK_NUM == 0) {
            print_ticks();
        }
        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;
    case T_SWITCH_TOU:
        if (tf->tf_cs != USER_CS) {
            tf->tf_cs = USER_CS;
            tf->tf_ds = tf->tf_es = USER_DS;
            tf->tf_ss = USER_DS;
            // set eflags, make sure ucore can use io under user mode.
            // if CPL > IOPL, then cpu will generate a general protection.
            tf->tf_rflags |= FL_IOPL_MASK;
        }
        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_ss = KERNEL_DS;
            tf->tf_rflags &= ~FL_IOPL_MASK;
        }
        break;
    default:
        // in kernel, it must be a mistake
        if ((tf->tf_cs & 3) == 0) {
            print_trapframe(tf);
            panic("unexpected trap in kernel.\n");
        }
    }
}
Exemple #10
0
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");
    }
}
Exemple #11
0
/* trap_dispatch - dispatch based on what type of trap occurred */
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    switch (tf->tf_trapno) {
    case IRQ_OFFSET + IRQ_TIMER:
        /* 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!
         */
        ticks++;
        if (ticks % TICK_NUM == 0)
        {
		    print_ticks();
        }
        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:
        // in kernel, it must be a mistake
        if ((tf->tf_cs & 3) == 0) {
            print_trapframe(tf);
            panic("unexpected trap in kernel.\n");
        }
    }
}
Exemple #12
0
void serial_int_handler(void *opaque)
{
  unsigned char id = inb(COM1+COM_IIR);
  if(id & 0x01)
    return ;
  //int c = serial_proc_data();
  int c = cons_getc(c);
  extern void dev_stdin_write(char c);
  dev_stdin_write(c);
}
Exemple #13
0
void arch_init()
{
	pci_init();
#ifdef __CONFIG_ENABLE_MPTABLES__
	mptables_parse();
	ioapic_init(); // MUST BE AFTER PCI/ISA INIT!
	// TODO: move these back to regular init.  requires fixing the 
	// __CONFIG_NETWORKING__ inits to not need multiple cores running.
#endif
	// this returns when all other cores are done and ready to receive IPIs
	#ifdef __CONFIG_SINGLE_CORE__
		smp_percpu_init();
	#else
		smp_boot();
	#endif
	proc_init();

	/* EXPERIMENTAL NETWORK FUNCTIONALITY
	 * To enable, define __CONFIG_NETWORKING__ in your Makelocal
	 * If enabled, will load the rl8168 driver (if device exists)
	 * and will a boot into userland matrix, so remote syscalls can be performed.
 	 * If in simulation, will do some debugging information with the ne2k device
	 *
	 * Note: If you use this, you should also define the mac address of the 
	 * teathered machine via USER_MAC_ADDRESS in Makelocal.
	 *
	 * Additionally, you should have a look at the syscall server in the tools directory
	 */
	#ifdef __CONFIG_NETWORKING__
	#ifdef __CONFIG_SINGLE_CORE__
		warn("You currently can't have networking if you boot into single core mode!!\n");
	#else
		rl8168_init();		
		ne2k_init();
		e1000_init();
	#endif // __CONFIG_SINGLE_CORE__
	#endif // __CONFIG_NETWORKING__

	perfmon_init();
		
#ifdef __CONFIG_MONITOR_ON_INT__
	/* Handler to read a char from the interrupt source and call the monitor.
	 * Need to read the character so the device will send another interrupt.
	 * Note this will read from both the serial and the keyboard, and throw away
	 * the result.  We condition, since we don't want to trigger on a keyboard
	 * up interrupt */
	void mon_int(struct trapframe *tf, void *data)
	{
		// Enable interrupts here so that we can receive 
		// other interrupts (e.g. from the NIC)
		enable_irq();
		if (cons_getc())
			monitor(0);
	}
Exemple #14
0
// Read a character from the system console.
// Returns the character.
static int
sys_cgetc(void)
{
    int c;

    // The cons_getc() primitive doesn't wait for a character,
    // but the sys_cgetc() system call does.
    while ((c = cons_getc()) == 0)
        /* do nothing */;

    return c;
}
Exemple #15
0
// Read a character from the system console.
// Returns the character.
static int
sys_cgetc(void)
{
	int c;

	/* The cons_getc() primitive doesn't wait for a character, But we do.
	 * TODO: Make kernel interruptable later
	 * Now just a makeshift, without kernel being interruptable, Ether
	 * device refuses to function properly.
	 */
	while ((c = cons_getc()) == 0);
/*  { */
/* 		assert(curenv->env_status == ENV_RUNNING); */
/* 		spin_lock(&curenv->env_lock); */
/* 		curenv->env_status = ENV_RUNNABLE; */
/* 		spin_unlock(&curenv->env_lock); */
/* 		sched_yield();/\* This enables daemons to get CPU cycles when */
/* 			       * sh is running. */
/* 			       *\/ */
/* 	} */
	return c;
}
// Read a character from the system console without blocking.
// Returns the character, or 0 if there is no input waiting.
static int
sys_cgetc(void)
{
	return cons_getc();
}
Exemple #17
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 2011010312 : 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 2011010312 */
        /* 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++;
        if(ticks == TICK_NUM) {
            ticks = 0;
            current->need_resched = 1;
        }
        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");

    }
}
Exemple #18
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
         */
        /* 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");

    }
}
Exemple #19
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
         */
        if(++ticks % TICK_NUM == 0) {
			//print_ticks();
			current->need_resched = 1;
		}
        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) {
			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");

    }
}
Exemple #20
0
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret;

    switch (tf->tf_trapno) {
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            panic("handle pgfault failed. %e\n", ret);
        }
        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!
         */
        ticks ++;
        if (ticks % TICK_NUM == 0)
       		print_ticks();
        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);
        if (c == '0')
        {
        	user2kernel(tf);
        }
        if (c == '3')
        {
			kernel2user(tf);
        }
        print_trapframe(tf);
        break;
    //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
    case T_SWITCH_TOU:
    	kernel2user(tf);
/*    	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;

    		switchk2u.tf_eflags |= FL_IOPL_MASK;

    		*((uint32_t *)tf -1) = (uint32_t)&switchk2u;
    	}*/
    	break;
    case T_SWITCH_TOK:
        //panic("T_SWITCH_** ??\n");
        user2kernel(tf);
/*        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:
        // in kernel, it must be a mistake
        if ((tf->tf_cs & 3) == 0) {
            print_trapframe(tf);
            panic("unexpected trap in kernel.\n");
        }
    }
}
Exemple #21
0
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");
    }
}
Exemple #22
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 2014011421 */
        /* 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 2014011421 */
        /* you should upate you lab5 code
         * IMPORTANT FUNCTIONS:
	     * sched_class_proc_tick
         */         
        /* LAB7 2014011421 */
        /* you should upate you lab6 code
         * IMPORTANT FUNCTIONS:
	     * run_timer_list
         */
        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:
        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");

    }
}
Exemple #23
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");

    }
}
Exemple #24
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!
         */
ticks++;
	if(ticks % TICK_NUM ==0)
	{
	//	print_ticks();
        /* 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
         */
		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.
         */
		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");

    }
}
Exemple #25
0
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret;

    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) {
        case (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
             */

            clock_intr();
            break;
        case (1 << IRQ_COM1):
            c = cons_getc();
            cprintf("serial [%03d] %c\n", c, c);
            break;
        default:
            print_trapframe(tf);
            panic("unknown int.\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");

    }
}
Exemple #26
0
/* trap_dispatch - dispatch based on what type of trap occurred */
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    switch (tf->tf_trapno) {
    case IRQ_OFFSET + IRQ_TIMER:
        /* LAB1 2012011363 : 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();
        }
        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 : 2012011363 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:
        // in kernel, it must be a mistake
        if ((tf->tf_cs & 3) == 0) {
            print_trapframe(tf);
            panic("unexpected trap in kernel.\n");
        }
    }
}
Exemple #27
0
static void
trap_dispatch(struct trapframe *tf) {
    char c;

    int ret;

    switch (tf->tf_trapno) {
    case T_PGFLT:  //page fault
        if ((ret = pgfault_handler(tf)) != 0) {
            print_trapframe(tf);
            panic("handle pgfault failed. %e\n", ret);
        }
        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 2011011384 : 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 % 100 == 0) {
            print_ticks();
        }
        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 : 2011011384 you should modify below codes.
    case T_SWITCH_TOU:
        //The idea is iret pops EFLAGS, EIP, CS to CPU registers
        //So we push to the stack these registers we want and then directly jump to iret
        tf->tf_gs = USER_DS;
        tf->tf_fs = USER_DS;
        tf->tf_es = USER_DS;
        tf->tf_ds = USER_DS;
        tf->tf_ss = USER_DS;
        tf->tf_cs = USER_CS;
        //we also have to set IOPL, else cprintf will cause general protection fault
        //tf->tf_esp doesn't matter here because it will be reset by %ebp in switch_to_user
        tf->tf_eflags |= FL_IOPL_MASK;
        break;
    case T_SWITCH_TOK:
        tf->tf_gs = KERNEL_DS;
        tf->tf_fs = KERNEL_DS;
        tf->tf_es = KERNEL_DS;
        tf->tf_ds = KERNEL_DS;
        tf->tf_ss = KERNEL_DS;
        tf->tf_cs = KERNEL_CS;
        //we also have to set IOPL, else cprintf will cause general protection fault
        //tf->tf_esp doesn't matter here because it will be reset by %ebp in switch_to_user
        tf->tf_eflags &= ~FL_IOPL_MASK;
        break;
    case IRQ_OFFSET + IRQ_IDE1:
    case IRQ_OFFSET + IRQ_IDE2:
        /* do nothing */
        break;
    default:
        // in kernel, it must be a mistake
        if ((tf->tf_cs & 3) == 0) {
            print_trapframe(tf);
            panic("unexpected trap in kernel.\n");
        }
    }
}