Exemplo n.º 1
0
Arquivo: 1.c Projeto: TySag/project
/* use software emulated X86 pgfault */
static void handle_tlbmiss(struct trapframe* tf, int write)
{
#if 0
  if(!trap_in_kernel(tf)){
    print_trapframe(tf);
    while(1);
  }
#endif

  static int entercnt = 0;
  entercnt ++;
  //kprintf("## enter handle_tlbmiss %d times\n", entercnt);
  int in_kernel = trap_in_kernel(tf);
  assert(current_pgdir != NULL);
  //print_trapframe(tf);
  uint32_t badaddr = tf->tf_vaddr;
  int ret = 0;
  pte_t *pte = get_pte(current_pgdir, tf->tf_vaddr, 0);
  if(pte==NULL || ptep_invalid(pte)){   //PTE miss, pgfault
    //panic("unimpl");
    //TODO
    //tlb will not be refill in do_pgfault,
    //so a vmm pgfault will trigger 2 exception
    //permission check in tlb miss
    ret = pgfault_handler(tf, badaddr, get_error_code(write, pte));
  }else{ //tlb miss only, reload it
    /* refill two slot */
    /* check permission */
    if(in_kernel){
      tlb_refill(badaddr, pte); 
    //kprintf("## refill K\n");
      return;
    }else{
      if(!ptep_u_read(pte)){
        ret = -1;
        goto exit;
      }
      if(write && !ptep_u_write(pte)){
        ret = -2;
        goto exit;
      }
    //kprintf("## refill U %d %08x\n", write, badaddr);
      tlb_refill(badaddr, pte);
      return ;
    }
  }

exit:
  if(ret){
    print_trapframe(tf);
    if(in_kernel){
      panic("unhandled pgfault");
    }else{
      do_exit(-E_KILLED);
    }
  }
  return ;
}
Exemplo n.º 2
0
Arquivo: 1.c Projeto: TySag/project
/*
 * General trap (exception) handling function for mips.
 * This is called by the assembly-language exception handler once
 * the trapframe has been set up.
 */
  void
mips_trap(struct trapframe *tf)
{//kprintf("mips_trap:epc=0x%x cause=%x badvaddr=0x%08x\n", tf->tf_epc, (tf->tf_cause >> 2) & 0x1F, tf->tf_vaddr);
  // dispatch based on what type of trap occurred
  // used for previous projects
  if (current == NULL) {
    trap_dispatch(tf);
  }
  else {
    // keep a trapframe chain in stack
    struct trapframe *otf = current->tf;
    current->tf = tf;

    bool in_kernel = trap_in_kernel(tf);

    trap_dispatch(tf);

    current->tf = otf;
    if (!in_kernel) {
      if (current->flags & PF_EXITING) {
        do_exit(-E_KILLED);
      }
      if (current->need_resched) {
        schedule();
      }
    }
  }
}
Exemplo n.º 3
0
// forkret -- the first kernel entry point of a new thread/process
// NOTE: the addr of forkret is setted in copy_thread function
//       after switch_to, the current proc will execute here.
void forkret(void)
{
	if (!trap_in_kernel(current->tf)) {
		kern_leave();
	}
	forkrets(current->tf);
}
Exemplo n.º 4
0
/* *
 * trap - handles or dispatches an exception/interrupt. if and when trap() returns,
 * the code in kern/trap/trapentry.S restores the old CPU state saved in the
 * trapframe and then uses the iret instruction to return from the exception.
 * */
void
trap(struct trapframe *tf) {
    // dispatch based on what type of trap occurred
    // used for previous projects
    if (current == NULL) {
        trap_dispatch(tf);
    }
    else {
        // keep a trapframe chain in stack
        struct trapframe *otf = current->tf;
        current->tf = tf;
    
        bool in_kernel = trap_in_kernel(tf);
    
        trap_dispatch(tf);
    
        current->tf = otf;
        if (!in_kernel) {
            if (current->flags & PF_EXITING) {
                do_exit(-E_KILLED);
            }
            if (current->need_resched) {
                schedule();
            }
        }
    }
}
Exemplo n.º 5
0
void
print_trapframe(struct trapframe *tf) {
    cprintf("trapframe at %p\n", tf);
    print_regs(&tf->tf_regs);
    cprintf("  ds   0x----%04x\n", tf->tf_ds);
    cprintf("  es   0x----%04x\n", tf->tf_es);
    cprintf("  fs   0x----%04x\n", tf->tf_fs);
    cprintf("  gs   0x----%04x\n", tf->tf_gs);
    cprintf("  trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
    cprintf("  err  0x%08x\n", tf->tf_err);
    cprintf("  eip  0x%08x\n", tf->tf_eip);
    cprintf("  cs   0x----%04x\n", tf->tf_cs);
    cprintf("  flag 0x%08x ", tf->tf_eflags);

    int i, j;
    for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) {
        if ((tf->tf_eflags & j) && IA32flags[i] != NULL) {
            cprintf("%s,", IA32flags[i]);
        }
    }
    cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12);

    if (!trap_in_kernel(tf)) {
        cprintf("  esp  0x%08x\n", tf->tf_esp);
        cprintf("  ss   0x----%04x\n", tf->tf_ss);
    }
}
Exemplo n.º 6
0
Arquivo: trap.c Projeto: 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");
    }
}
Exemplo n.º 7
0
static int udef_handler(struct trapframe *tf)
{
//  print_trapframe(tf);
	uint32_t inst = *(uint32_t *) (tf->tf_epc - 4);
	if (inst == KGDB_BP_INSTR) {
		return kgdb_trap(tf);
	} else {
		print_trapframe(tf);
		if (trap_in_kernel(tf)) {
			panic("undefined instruction\n");
		} else {
			killed_by_kernel();
		}
	}
	return 0;
}
Exemplo n.º 8
0
void print_trapframe(struct trapframe *tf)
{
	PRINT_HEX("trapframe at ", tf);
	print_regs(&tf->tf_regs);
	PRINT_HEX(" $ra\t: ", tf->tf_ra);
	PRINT_HEX(" BadVA\t: ", tf->tf_vaddr);
	PRINT_HEX(" Status\t: ", tf->tf_status);
	PRINT_HEX(" Cause\t: ", tf->tf_cause);
	PRINT_HEX(" EPC\t: ", tf->tf_epc);
	if (!trap_in_kernel(tf)) {
		kprintf("Trap in usermode: ");
	} else {
		kprintf("Trap in kernel: ");
	}
	kprintf(trapname(GET_CAUSE_EXCODE(tf->tf_cause)));
	kputchar('\n');
}
Exemplo n.º 9
0
Arquivo: 1.c Projeto: TySag/project
static void
trap_dispatch(struct trapframe *tf) {
  int code = GET_CAUSE_EXCODE(tf->tf_cause);
  switch(code){
    case EX_IRQ:
      interrupt_handler(tf);
      break;
    case EX_TLBL:
      handle_tlbmiss(tf, 0);
      break;
    case EX_TLBS:
      handle_tlbmiss(tf, 1);
      break;
    case EX_RI:
      print_trapframe(tf);
      kprintf("inst not include, I will use software to implement\n");
      tf->tf_epc += 4;
      //panic("hey man! Do NOT use that insn!");
      break;
    case EX_SYS:
      //print_trapframe(tf);
      tf->tf_epc += 4;
      syscall();
      break;
      /* alignment error or access kernel
       * address space in user mode */
    case EX_ADEL:
    case EX_ADES:
      if(trap_in_kernel(tf)){
        print_trapframe(tf);
        panic("Alignment Error");
      }else{
        print_trapframe(tf);
        do_exit(-E_KILLED);
      }
      break;
    default:
      print_trapframe(tf);
      panic("Unhandled Exception");
  }

}
Exemplo n.º 10
0
// do syscall sigreturn, reset the user stack and eip
int do_sigreturn()
{
	struct mm_struct *mm = current->mm;
	if (!current)
		return -E_INVAL;
	struct sighand_struct *sighand = current->signal_info.sighand;
	if (!sighand)
		return -E_INVAL;

	struct sigframe *kframe = kmalloc(sizeof(struct sigframe));
	if (!kframe)
		return -E_NO_MEM;

	struct sigframe *frame =
	    (struct sigframe *)(current->tf->tf_esp);
	lock_mm(mm);
	{
		if (!copy_from_user
		    (mm, kframe, frame, sizeof(struct sigframe), 0)) {
			unlock_mm(mm);
			kfree(kframe);
			return -E_INVAL;
		}
	}
	unlock_mm(mm);
	/* check the trapframe */
	if (trap_in_kernel(&kframe->tf)) {
		do_exit(-E_KILLED);
		return -E_INVAL;
	}

	lock_sig(sighand);
	current->signal_info.blocked = kframe->old_blocked;
	sig_recalc_pending(current);
	unlock_sig(sighand);

	*(current->tf) = kframe->tf;
	kfree(kframe);

	return 0;
}
Exemplo n.º 11
0
Arquivo: trap.c Projeto: TySag/project
void trap(struct trapframe *tf)
{
	// used for previous projects
	if (pls_read(current) == NULL) {
		trap_dispatch(tf);
	} else {
		// keep a trapframe chain in stack
		struct trapframe *otf = pls_read(current)->tf;
		pls_read(current)->tf = tf;

		bool in_kernel = trap_in_kernel(tf);

		trap_dispatch(tf);

		pls_read(current)->tf = otf;
		if (!in_kernel) {
			may_killed();
			if (pls_read(current)->need_resched) {
				schedule();
			}
		}
	}
}
Exemplo n.º 12
0
Arquivo: 1.c Projeto: TySag/project
void
print_trapframe(struct trapframe *tf) {
    PRINT_HEX("trapframe at ", tf);
    print_regs(&tf->tf_regs);
    PRINT_HEX(" $ra\t: ", tf->tf_ra);
    PRINT_HEX(" BadVA\t: ", tf->tf_vaddr);
    PRINT_HEX(" Status\t: ", tf->tf_status);
    PRINT_HEX(" Cause\t: ", tf->tf_cause);
    PRINT_HEX(" EPC\t: ", tf->tf_epc);
    if (!trap_in_kernel(tf)) {
      kprintf("Trap in usermode: ");
    }else{
      kprintf("Trap in kernel: ");
    }
    kprintf(trapname(GET_CAUSE_EXCODE(tf->tf_cause)));
    kputchar('\n'); 
 //   /*
    int i;
    for (i = 0; i < 20; ++i) {
        int *addr = (int*)(tf->tf_epc + i * 4);
        kprintf("0x%08x=0x%08x\n", addr, *addr);
    }
 //   */
}
Exemplo n.º 13
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");
    }
}
Exemplo n.º 14
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");

    }
}
Exemplo n.º 15
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");

    }
}
Exemplo n.º 16
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");

    }
}
Exemplo n.º 17
0
/* trap_dispatch - dispatch based on what type of trap occurred */
static void trap_dispatch(struct trapframe *tf)
{
	char c;

	int ret;

	//kprintf("Trap [%03d %03d]\n", tf->tf_trapno, tf->tf_trapsubno);

	switch (tf->tf_trapno) {
		// Prefetch Abort service routine
		// Data Abort service routine
	case T_PABT:
	case T_DABT:
		if ((ret = pgfault_handler(tf)) != 0) {
			print_pgfault(tf);
			print_trapframe(tf);
			if (pls_read(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);
				}
				killed_by_kernel();
			}
		}
		break;
	case T_SWI:
		syscall();
		break;
		// IRQ Service Routine
		/*        case IRQ_OFFSET + INT_TIMER4:
		   ticks ++;
		   if (ticks % TICK_NUM == 0) {
		   print_ticks();
		   //print_trapframe(tf);
		   }
		   break;
		   case IRQ_OFFSET + INT_UART0:
		   c = cons_getc();
		   kprintf("serial [%03d] %c\n", c, c);
		   break;
		 */
		// SWI Service Routine
#if 0
	case T_SWITCH_TOK:	// a random System call
		kprintf("Random system call\n");
		print_cur_status();
		//print_stackframe();
		break;
#endif
	case T_IRQ:
		__irq_level++;
#if 0
		if (!trap_in_kernel(tf)) {
			uint32_t sp;
			asm volatile ("mov %0, sp":"=r" (sp));
			kprintf("### iRQnotK %08x\n", sp);
		}
#endif
		irq_handler();
		__irq_level--;
		break;
#if 0
	case T_PANIC:
		print_cur_status();
		//print_stackframe();
		break;
#endif
		/* for debugging */
	case T_UNDEF:
		udef_handler(tf);
		break;
	default:
		print_trapframe(tf);
		if (pls_read(current) != NULL) {
			kprintf("unhandled trap.\n");
			do_exit(-E_KILLED);
		}
		panic("unexpected trap in kernel.\n");
	}
Exemplo n.º 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 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");

    }
}
Exemplo n.º 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 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");

    }
}