X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/ec98d05af80e6e68c889dac10b8478ce92bd5161..43487eff262637a59a4c2c0272d7c4a824af3944:/lunaix-os/arch/x86/exceptions/interrupts.c diff --git a/lunaix-os/arch/x86/exceptions/interrupts.c b/lunaix-os/arch/x86/exceptions/interrupts.c index ceb3853..9941a5c 100644 --- a/lunaix-os/arch/x86/exceptions/interrupts.c +++ b/lunaix-os/arch/x86/exceptions/interrupts.c @@ -5,11 +5,28 @@ #include #include #include +#include -#include +#include LOG_MODULE("INTR") +extern void +intr_routine_page_fault(const struct hart_state* state); + +extern void +syscall_hndlr(const struct hart_state* hstate); + +extern void +apic_ack_interrupt(irq_t irq); + +static void noret +__set_panic(const char* msg, const struct hart_state* state) +{ + ERROR("panic: %s", msg); + failsafe_diagnostic(); +} + static inline void update_thread_context(struct hart_state* state) { @@ -26,23 +43,83 @@ update_thread_context(struct hart_state* state) } } + +static bool +__handle_internal_vectors(const struct hart_state* state) +{ + switch (hart_vector_stamp(state)) + { + case FAULT_DIVISION_ERROR: + __set_panic("div zero", state); + break; + + case FAULT_GENERAL_PROTECTION: + __set_panic("general protection", state); + break; + + case FAULT_PAGE_FAULT: + intr_routine_page_fault(state); + break; + + case FAULT_INVALID_OPCODE: + __set_panic("invalid opcode", state);; + break; + + case LUNAIX_SCHED: + apic_ack_interrupt(NULL); + schedule(); + break; + + case APIC_SPIV_IV: + break; + + case APIC_ERROR_IV: + __set_panic("apic error", state);; + break; + + case LUNAIX_SYS_CALL: + syscall_hndlr(state); + break; + + default: + return false; + } + + return true; +} + +static bool +__handle_external_irq(const struct hart_state* state) +{ + irq_t irq; + int ex_iv; + + ex_iv = hart_vector_stamp(state); + irq = irq_find(irq_get_default_domain(), ex_iv); + + if (unlikely(!irq)) { + return false; + } + + irq_serve(irq, state); + apic_ack_interrupt(irq); + return true; +} + struct hart_state* intr_handler(struct hart_state* state) { update_thread_context(state); volatile struct exec_param* execp = state->execp; - if (execp->vector <= 255) { - isr_cb subscriber = isrm_get(execp->vector); - subscriber(state); - goto done; + + if (__handle_internal_vectors(state)) { + return state; } -done: - - if (execp->vector > IV_BASE_END) { - isrm_notify_eoi(0, execp->vector); + if (__handle_external_irq(state)) { + return state; } - return state; + __set_panic("unknown interrupt", state); } \ No newline at end of file