static void unhandled_trap(struct hw_trapframe *state, const char* name) { static spinlock_t screwup_lock = SPINLOCK_INITIALIZER; spin_lock(&screwup_lock); if(in_kernel(state)) { print_trapframe(state); panic("Unhandled trap in kernel!\nTrap type: %s", name); } else { char tf_buf[1024]; format_trapframe(state, tf_buf, sizeof(tf_buf)); warn("Unhandled trap in user!\nTrap type: %s\n%s", name, tf_buf); backtrace(); spin_unlock(&screwup_lock); assert(current); enable_irq(); proc_destroy(current); } }
static void oprof_alarm_handler(struct alarm_waiter *waiter, struct hw_trapframe *hw_tf) { int coreid = core_id(); struct timer_chain *tchain = &per_cpu_info[coreid].tchain; if (in_kernel(hw_tf)) oprofile_add_backtrace(get_hwtf_pc(hw_tf), get_hwtf_fp(hw_tf)); else oprofile_add_userpc(get_hwtf_pc(hw_tf)); reset_alarm_rel(tchain, waiter, oprof_timer_period); }
// Puts a character to stdout void putC(char c) { if(!in_kernel()) { write(STDOUT,&c,1); } else if(current_video_mode->visible) { if(c != 1) { char a[] = { c, defaultStyle }; video_write(a,2); incrementCursor(); } } }
//--------------------------------------------------------------------------- IMPLEMENTATION [arm]: IMPLEMENT inline Mword Kmem::is_kmem_page_fault( Mword pfa, Mword /*error*/ ) { return in_kernel(pfa); } IMPLEMENT inline Mword Kmem::is_io_bitmap_page_fault( Mword /*pfa*/ ) { return 0; }
static void handle_fault_store(struct hw_trapframe *state) { if(in_kernel(state)) { print_trapframe(state); panic("Store Page Fault in the Kernel at %p!", state->badvaddr); } set_current_ctx_hw(&per_cpu_info[core_id()], state); if(handle_page_fault(current, state->badvaddr, PROT_WRITE)) unhandled_trap(state, "Store Page Fault"); }
static void handle_illegal_instruction(struct hw_trapframe *state) { assert(!in_kernel(state)); struct per_cpu_info *pcpui = &per_cpu_info[core_id()]; set_current_ctx_hw(pcpui, state); if (emulate_fpu(state) == 0) { advance_pc(&pcpui->cur_ctx->tf.hw_tf); return; } unhandled_trap(state, "Illegal Instruction"); }
static void handle_fault_load(struct hw_trapframe *state) { if(in_kernel(state)) { print_trapframe(state); panic("Load Page Fault in the Kernel at %p!", state->badvaddr); } set_current_ctx_hw(&per_cpu_info[core_id()], state); #warning "returns EAGAIN if you should reflect the fault" if(handle_page_fault(current, state->badvaddr, PROT_READ)) unhandled_trap(state, "Load Page Fault"); }
static void handle_fault_fetch(struct hw_trapframe *state) { if(in_kernel(state)) { print_trapframe(state); panic("Instruction Page Fault in the Kernel at %p!", state->epc); } set_current_ctx_hw(&per_cpu_info[core_id()], state); #warning "returns EAGAIN if you should reflect the fault" if(handle_page_fault(current, state->epc, PROT_EXEC)) unhandled_trap(state, "Instruction Page Fault"); }
//--------------------------------------------------------------------------- IMPLEMENTATION [arm]: #include "mem_unit.h" #include "kmem_space.h" #include "paging.h" #include <cassert> IMPLEMENT inline Mword Kmem::is_kmem_page_fault(Mword pfa, Mword) { return in_kernel(pfa); } IMPLEMENT inline Mword Kmem::is_io_bitmap_page_fault(Mword) { return 0; } PUBLIC static Address Kmem::mmio_remap(Address phys) { static Address ndev = 0; Address v = phys_to_pmem(phys); if (v != ~0UL) return v; Address dm = Mem_layout::Registers_map_start + ndev; assert(dm < Mem_layout::Registers_map_end); ndev += Config::SUPERPAGE_SIZE; auto m = Kmem_space::kdir()->walk(Virt_addr(dm), Pte_ptr::Super_level); assert (!m.is_valid()); assert (m.page_order() == Config::SUPERPAGE_SHIFT); Address phys_page = cxx::mask_lsb(phys, Config::SUPERPAGE_SHIFT); m.create_page(Phys_mem_addr(phys_page), Page::Attr(Page::Rights::RWX(), Page::Type::Uncached(), Page::Kern::Global())); m.write_back_if(true, Mem_unit::Asid_kernel); add_pmem(phys_page, dm, Config::SUPERPAGE_SIZE); return phys_to_pmem(phys); }