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; }
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'); }
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"); } }
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); } // */ }
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: case EX_TLBS: break; case EX_RI: print_trapframe(tf); while(1); break; case EX_SYS: print_trapframe(tf); tf->tf_epc += 4; break; default: print_trapframe(tf); while(1); } }