Exemple #1
0
static void trap_dispatch(struct trapframe *tf)
{
	int i;
	int code = GET_CAUSE_EXCODE(tf->tf_cause);
	switch (code) {
	case EX_IRQ:
		interrupt_handler(tf);
		break;
	case EX_MOD:
		handle_tlbmiss(tf, 1, 1);
		break;
	case EX_TLBL:
		handle_tlbmiss(tf, 0, 0);
		break;
	case EX_TLBS:
		handle_tlbmiss(tf, 1, 0);
		break;
  case EX_RI: {
    if(tf->tf_cause & (1 << 31)) {
      print_trapframe(tf);
      panic("Cannot fix unimplemented instruction in branch delay slot.");
    }
    const uint32_t DIV_OPCODE_MASK = 0xFC00FFFF;
    const uint32_t DIV_OPCODE = 0x0000001A;
    const uint32_t DIVU_OPCODE = 0x0000001B;
    const uint32_t MULTU_OPCODE = 0x00000019;
    uint32_t instruction = *(uint32_t*)tf->tf_epc;
    if((instruction & DIV_OPCODE_MASK) == DIV_OPCODE) {
      int rt = (instruction >> 16) & 0x1F;
      int rs = (instruction >> 21) & 0x1F;
      int dividend = rs == 0 ? 0 : tf->tf_regs.reg_r[rs - 1];
      int division = rt == 0 ? 0 : tf->tf_regs.reg_r[rt - 1];
      tf->tf_lo = __divsi3(dividend, division);
      tf->tf_hi = __modsi3(dividend, division);
      tf->tf_epc = (void*)((uint32_t)tf->tf_epc + 4);
      break;
    }
    else if((instruction & DIV_OPCODE_MASK) == DIVU_OPCODE) {
      int rt = (instruction >> 16) & 0x1F;
      int rs = (instruction >> 21) & 0x1F;
      int dividend = rs == 0 ? 0 : tf->tf_regs.reg_r[rs - 1];
      int division = rt == 0 ? 0 : tf->tf_regs.reg_r[rt - 1];
      tf->tf_lo = udivmodsi4(dividend, division, 0);
      tf->tf_hi = udivmodsi4(dividend, division, 1);
      tf->tf_epc = (void*)((uint32_t)tf->tf_epc + 4);
      break;
    }
Exemple #2
0
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");
  }

}