From cfaeb74dd3fbca234d8354cf429ef763b4cf41ca Mon Sep 17 00:00:00 2001 From: p-szafonimateusz Date: Wed, 13 Nov 2024 12:25:35 +0100 Subject: [PATCH] arch/intel64: allow to attach handlers to ISR arch/intel64: allow to attach handlers to ISR Signed-off-by: p-szafonimateusz --- arch/x86_64/src/intel64/intel64_handlers.c | 107 +-------------------- arch/x86_64/src/intel64/intel64_irq.c | 52 +++++++++- arch/x86_64/src/intel64/intel64_vectors.S | 70 +------------- 3 files changed, 53 insertions(+), 176 deletions(-) diff --git a/arch/x86_64/src/intel64/intel64_handlers.c b/arch/x86_64/src/intel64/intel64_handlers.c index 623fdb9706..aca4e7981c 100644 --- a/arch/x86_64/src/intel64/intel64_handlers.c +++ b/arch/x86_64/src/intel64/intel64_handlers.c @@ -135,115 +135,12 @@ static uint64_t *common_handler(int irq, uint64_t *regs) * Public Functions ****************************************************************************/ -/**************************************************************************** - * Name: isr_handler - * - * Description: - * This gets called from ISR vector handling logic in broadwell_vectors.S - * - ****************************************************************************/ - -uint64_t *isr_handler(uint64_t *regs, uint64_t irq) -{ - struct tcb_s **running_task = &g_running_tasks[this_cpu()]; - struct tcb_s *tcb; - - if (*running_task != NULL) - { - (*running_task)->xcp.regs = regs; - } - - board_autoled_on(LED_INIRQ); - -#ifdef CONFIG_SUPPRESS_INTERRUPTS - /* Doesn't return */ - - PANIC(); - - /* To keep the compiler happy */ - - return regs; -#else - - DEBUGASSERT(!up_interrupt_context()); - - /* Set irq flag */ - - up_set_interrupt_context(true); - - switch (irq) - { - case 0: - case 16: - __asm__ volatile("fnclex":::"memory"); - nxsig_kill(this_task()->pid, SIGFPE); - break; - - default: - /* Let's say, all ISR are asserted when REALLY BAD things happened. - * Don't even brother to recover, just dump the regs and PANIC. - */ - - _alert("PANIC:\n"); - _alert("Exception %" PRId64 " occurred " - "with error code %" PRId64 ":\n", - irq, regs[REG_ERRCODE]); - - PANIC_WITH_REGS("panic", regs); - - up_trash_cpu(); - break; - } - - tcb = this_task(); - - /* Check for a context switch. If a context switch occurred, then - * g_current_regs will have a different value than it did on entry. If an - * interrupt level context switch has occurred, then the establish the - * correct address environment before returning from the interrupt. - */ - - if (*running_task != tcb) - { -#ifdef CONFIG_ARCH_ADDRENV - /* Make sure that the address environment for the previously - * running task is closed down gracefully (data caches dump, - * MMU flushed) and set up the address environment for the new - * thread at the head of the ready-to-run list. - */ - - addrenv_switch(NULL); -#endif - - /* Update scheduler parameters */ - - nxsched_suspend_scheduler(*running_task); - nxsched_resume_scheduler(tcb); - - /* Record the new "running" task when context switch occurred. - * g_running_tasks[] is only used by assertion logic for reporting - * crashes. - */ - - *running_task = tcb; - - /* Restore the cpu lock */ - - restore_critical_section(tcb, this_cpu()); - } - - /* Clear irq flag */ - - up_set_interrupt_context(false); - return tcb->xcp.regs; -#endif -} - /**************************************************************************** * Name: irq_handler * * Description: - * This gets called from IRQ vector handling logic in intel64_vectors.S + * This gets called from IRQ or ISR vector handling logic in + * intel64_vectors.S * ****************************************************************************/ diff --git a/arch/x86_64/src/intel64/intel64_irq.c b/arch/x86_64/src/intel64/intel64_irq.c index 84c25de2f9..733f9a3e9f 100644 --- a/arch/x86_64/src/intel64/intel64_irq.c +++ b/arch/x86_64/src/intel64/intel64_irq.c @@ -40,7 +40,9 @@ #include #include +#include +#include "sched/sched.h" #include "x86_64_internal.h" #include "intel64_cpu.h" #include "intel64.h" @@ -430,10 +432,6 @@ static inline void up_idtinit(void) setidt(&g_idt_entries, sizeof(struct idt_entry_s) * NR_IRQS - 1); } -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Name: arm_color_intstack * @@ -453,6 +451,43 @@ static inline void x86_64_color_intstack(void) # define x86_64_color_intstack() #endif +/**************************************************************************** + * Name: x86_64_fault_panic_isr + ****************************************************************************/ + +static int x86_64_fault_panic_isr(int irq, void *c, void *arg) +{ + uint64_t *regs = (uint64_t *)running_regs(); + + /* Let's say, all ISR are asserted when REALLY BAD things happened. + * Don't even brother to recover, just dump the regs and PANIC. + */ + + _alert("PANIC:\n"); + _alert("Exception %" PRId32 " occurred " + "with error code %" PRId64 ":\n", + irq, regs[REG_ERRCODE]); + + PANIC_WITH_REGS("panic", regs); + + up_trash_cpu(); + + return 0; +} + +/**************************************************************************** + * Name: x86_64_fault_kill_isr + ****************************************************************************/ + +static int x86_64_fault_kill_isr(int irq, void *c, void *arg) +{ + __asm__ volatile("fnclex":::"memory"); + + nxsig_kill(running_task()->pid, SIGFPE); + + return 0; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -503,6 +538,15 @@ void up_irqinitialize(void) #ifndef CONFIG_SUPPRESS_INTERRUPTS up_irq_restore(X86_64_RFLAGS_IF); #endif + + /* Attach default handlers for faults */ + + irq_attach(ISR0, x86_64_fault_kill_isr, NULL); + irq_attach(ISR6, x86_64_fault_panic_isr, NULL); + irq_attach(ISR8, x86_64_fault_panic_isr, NULL); + irq_attach(ISR13, x86_64_fault_panic_isr, NULL); + irq_attach(ISR14, x86_64_fault_panic_isr, NULL); + irq_attach(ISR16, x86_64_fault_kill_isr, NULL); } /**************************************************************************** diff --git a/arch/x86_64/src/intel64/intel64_vectors.S b/arch/x86_64/src/intel64/intel64_vectors.S index 41a297ed4f..56c019524a 100644 --- a/arch/x86_64/src/intel64/intel64_vectors.S +++ b/arch/x86_64/src/intel64/intel64_vectors.S @@ -41,7 +41,6 @@ ****************************************************************************/ .globl irq_handler - .globl isr_handler .globl irq_xcp_regs .globl g_interrupt_stack .globl g_interrupt_stack_end @@ -69,7 +68,7 @@ vector_isr\intno: pushq %rdi pushq %rsi movq $\intno, %rsi /* INT Number is saved to 2nd parameter of function call */ - jmp isr_common /* Go to the common ISR handler code. */ + jmp irq_common /* Go to the common IRQ handler code. */ .endm /* This macro creates a stub for an ISR which passes it's own @@ -87,7 +86,7 @@ vector_isr\intno: pushq %rdi pushq %rsi movq $\intno, %rsi /* INT Number is saved to 2nd parameter of function call */ - jmp isr_common /* Go to the common ISR handler code. */ + jmp irq_common /* Go to the common IRQ handler code. */ .endm /* This macro creates a stub for an IRQ - the first parameter is @@ -692,69 +691,6 @@ vector_isr\intno: IRQ 255, IRQ255 .balign 16 -/**************************************************************************** - * Name: isr_common - * - * Description: - * This is the common ISR logic. It saves the processor state, sets up for - * kernel mode segments, calls the C-level fault handler, and finally - * restores the stack frame. - * - ****************************************************************************/ - -isr_common: - /* Already swap to the interrupt stack */ - /* stack is automatically recovered by iretq using task state */ - - /* x86_64 don't have pusha, we have to do things manually */ - /* RDI and RSI are pushed above for handling IRQ no */ - pushq %rdx - pushq %rcx - pushq %r8 - pushq %r9 - - pushq %r15 - pushq %r14 - pushq %r13 - pushq %r12 - pushq %r11 - pushq %r10 - pushq %rbp - pushq %rbx - pushq %rax - - xor %rax, %rax /* Reset rax */ - mov %ds, %ax /* Lower 16-bits of rax. */ - pushq %rax /* Save the data segment descriptor */ - mov %es, %ax /* Lower 16-bits of rax. */ - pushq %rax /* Save the data segment descriptor */ - mov %gs, %ax /* Lower 16-bits of rax. */ - pushq %rax /* Save the data segment descriptor */ - mov %fs, %ax /* Lower 16-bits of rax. */ - pushq %rax /* Save the data segment descriptor */ - - /* Align to 64-bytes boundary */ - leaq -(XMMAREA_REG_ALIGN * 8)(%rsp), %rsp - - /* Save xmm registers */ - leaq -XCPTCONTEXT_XMM_AREA_SIZE(%rsp), %rsp -#ifndef CONFIG_ARCH_X86_64_HAVE_XSAVE - fxsaveq (%rsp) -#else - movl $XSAVE_STATE_COMPONENTS, %eax - xor %edx, %edx - xsave (%rsp) -#endif - - /* The current value of the SP points to the beginning of the state save - * structure. Save that in RDI as the input parameter to isr_handler. - */ - - mov %rsp, %rdi - call isr_handler - jmp .Lreturn - .size isr_common, . - isr_common - /**************************************************************************** * Name: irq_common * @@ -850,7 +786,7 @@ irq_common: add $8, %rsp popq %rdi - /* The common return point for both isr_handler and irq_handler */ + /* The common return point for irq_handler */ .Lreturn: