📄 hal5-2.6.5.patch
字号:
+ return 1;+}++static unsigned __adeos_override_irq_startup (unsigned irq)++{+ unsigned long adflags, hwflags;+ adeos_declare_cpuid;+ unsigned s;++ adeos_lock_cpu(hwflags);+ adflags = adeos_test_and_stall_pipeline();+#ifdef CONFIG_PREEMPT+ preempt_disable();+#endif /* CONFIG_PREEMPT */+ __adeos_unlock_irq(adp_cpu_current[cpuid],irq);+ s = __adeos_std_irq_dtype[irq].startup(irq);+#ifdef CONFIG_PREEMPT+ preempt_enable_no_resched();+#endif /* CONFIG_PREEMPT */+ adeos_restore_pipeline_nosync(adp_cpu_current[cpuid],adflags,cpuid);+ adeos_unlock_cpu(hwflags);++ return s;+}++static void __adeos_override_irq_shutdown (unsigned irq)++{+ unsigned long adflags, hwflags;+ adeos_declare_cpuid;++ adeos_lock_cpu(hwflags);+ adflags = adeos_test_and_stall_pipeline();+#ifdef CONFIG_PREEMPT+ preempt_disable();+#endif /* CONFIG_PREEMPT */+ __adeos_std_irq_dtype[irq].shutdown(irq);+ __adeos_clear_irq(adp_cpu_current[cpuid],irq);+#ifdef CONFIG_PREEMPT+ preempt_enable_no_resched();+#endif /* CONFIG_PREEMPT */+ adeos_restore_pipeline_nosync(adp_cpu_current[cpuid],adflags,cpuid);+ adeos_unlock_cpu(hwflags);+}++static void __adeos_override_irq_enable (unsigned irq)++{+ unsigned long adflags, hwflags;+ adeos_declare_cpuid;++ adeos_lock_cpu(hwflags);+ adflags = adeos_test_and_stall_pipeline();+#ifdef CONFIG_PREEMPT+ preempt_disable();+#endif /* CONFIG_PREEMPT */+ __adeos_unlock_irq(adp_cpu_current[cpuid],irq);+ __adeos_std_irq_dtype[irq].enable(irq);+#ifdef CONFIG_PREEMPT+ preempt_enable_no_resched();+#endif /* CONFIG_PREEMPT */+ adeos_restore_pipeline_nosync(adp_cpu_current[cpuid],adflags,cpuid);+ adeos_unlock_cpu(hwflags);+}++static void __adeos_override_irq_disable (unsigned irq)++{+ unsigned long adflags, hwflags;+ adeos_declare_cpuid;++ adeos_lock_cpu(hwflags);+ adflags = adeos_test_and_stall_pipeline();+#ifdef CONFIG_PREEMPT+ preempt_disable();+#endif /* CONFIG_PREEMPT */+ __adeos_std_irq_dtype[irq].disable(irq);+ __adeos_lock_irq(adp_cpu_current[cpuid],cpuid,irq);+#ifdef CONFIG_PREEMPT+ preempt_enable_no_resched();+#endif /* CONFIG_PREEMPT */+ adeos_restore_pipeline_nosync(adp_cpu_current[cpuid],adflags,cpuid);+ adeos_unlock_cpu(hwflags);+}++static void __adeos_override_irq_end (unsigned irq)++{+ unsigned long adflags, hwflags;+ adeos_declare_cpuid;++ adeos_lock_cpu(hwflags);+ adflags = adeos_test_and_stall_pipeline();+#ifdef CONFIG_PREEMPT+ preempt_disable();+#endif /* CONFIG_PREEMPT */++#ifdef CONFIG_X86_IO_APIC+ if (!IO_APIC_IRQ(irq) || !(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))+#else /* !CONFIG_X86_IO_APIC */+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))+#endif /* CONFIG_X86_IO_APIC */+ __adeos_unlock_irq(adp_cpu_current[cpuid],irq);++ __adeos_std_irq_dtype[irq].end(irq);++#ifdef CONFIG_PREEMPT+ preempt_enable_no_resched();+#endif /* CONFIG_PREEMPT */+ adeos_restore_pipeline_nosync(adp_cpu_current[cpuid],adflags,cpuid);+ adeos_unlock_cpu(hwflags);+}++static void __adeos_override_irq_affinity (unsigned irq, unsigned long mask)++{+ unsigned long adflags, hwflags;+ adeos_declare_cpuid;++ adeos_lock_cpu(hwflags);+ adflags = adeos_test_and_stall_pipeline();+#ifdef CONFIG_PREEMPT+ preempt_disable();+#endif /* CONFIG_PREEMPT */+ __adeos_std_irq_dtype[irq].set_affinity(irq,mask);+#ifdef CONFIG_PREEMPT+ preempt_enable_no_resched();+#endif /* CONFIG_PREEMPT */+ adeos_restore_pipeline_nosync(adp_cpu_current[cpuid],adflags,cpuid);+ adeos_unlock_cpu(hwflags);+}++/* __adeos_enable_pipeline() -- Take over the interrupt control from+ the root domain (i.e. Linux). After this routine has returned, all+ interrupts go through the pipeline. */++void __adeos_enable_pipeline (void)++{+ unsigned vector, irq;+ unsigned long flags;++ /* Collect the original vector table. */++ for (vector = 0; vector < 256; vector++)+ __adeos_std_vector_table[vector] = __adeos_get_gate_addr(vector);++#ifdef CONFIG_SMP++ /* This vector must be set up prior to call+ adeos_critical_enter(). */++ __adeos_set_irq_gate(ADEOS_CRITICAL_VECTOR,+ __adeos_irq_trampolines[ADEOS_CRITICAL_IPI]);++#endif /* CONFIG_SMP */++ flags = adeos_critical_enter(NULL);++ /* First, grab the ISA and IO-APIC interrupts. */++ for (irq = 0; irq < NR_IRQS && irq + FIRST_EXTERNAL_VECTOR < FIRST_SYSTEM_VECTOR; irq++)+ {+#ifdef CONFIG_X86_IO_APIC+ if (IO_APIC_IRQ(irq))+ {+ vector = IO_APIC_VECTOR(irq);++ if (vector == 0)+ continue;+ }+ else+#endif /* CONFIG_X86_IO_APIC */+ {+ vector = irq + FIRST_EXTERNAL_VECTOR;++ if (vector == SYSCALL_VECTOR)+ continue;+ }++ /* Fails for ADEOS_CRITICAL_IPI but that's ok. */++ adeos_virtualize_irq(irq,+ (void (*)(unsigned))__adeos_std_vector_table[vector],+ &__adeos_ack_common_irq,+ IPIPE_CALLASM_MASK|IPIPE_HANDLE_MASK|IPIPE_PASS_MASK);++ __adeos_set_irq_gate(vector,__adeos_irq_trampolines[irq]);+ }++ /* Interpose on the IRQ control routines so we can make them+ atomic using hw masking and prevent the interrupt log from+ being untimely flushed. Since we don't want to be too smart+ about what's going on into irq.c and we want to change only+ some of the controller members, let's be dumb and interpose the+ rough way. */++ for (irq = 0; irq < NR_IRQS; irq++)+ __adeos_std_irq_dtype[irq] = *irq_desc[irq].handler;++ /* The original controller structs are often shared, so we first+ save them all before changing any of them. Notice that we don't+ redirect the ack handler since the relevant XT-PIC/IO-APIC+ management code is already Adeos-aware. */++ for (irq = 0; irq < NR_IRQS; irq++)+ {+ irq_desc[irq].handler->startup = &__adeos_override_irq_startup;+ irq_desc[irq].handler->shutdown = &__adeos_override_irq_shutdown;+ irq_desc[irq].handler->enable = &__adeos_override_irq_enable;+ irq_desc[irq].handler->disable = &__adeos_override_irq_disable;+ irq_desc[irq].handler->end = &__adeos_override_irq_end;++ if (irq_desc[irq].handler->set_affinity != NULL)+ irq_desc[irq].handler->set_affinity = &__adeos_override_irq_affinity;+ }++#ifdef CONFIG_X86_LOCAL_APIC++ /* Map the APIC system vectors including the unused ones so that+ client domains can virtualize the corresponding IRQs. */++ for (vector = FIRST_SYSTEM_VECTOR; vector < CALL_FUNCTION_VECTOR; vector++)+ {+ adeos_virtualize_irq(vector - FIRST_EXTERNAL_VECTOR,+ (void (*)(unsigned))__adeos_std_vector_table[vector],+ &__adeos_ack_system_irq,+ IPIPE_CALLASM_MASK|IPIPE_HANDLE_MASK|IPIPE_PASS_MASK);+ + __adeos_set_irq_gate(vector,+ __adeos_irq_trampolines[vector - FIRST_EXTERNAL_VECTOR]);+ }++ __adeos_tick_irq = using_apic_timer ? LOCAL_TIMER_VECTOR - FIRST_EXTERNAL_VECTOR : 0;++#else /* !CONFIG_X86_LOCAL_APIC */++ __adeos_tick_irq = 0;++#endif /* CONFIG_X86_LOCAL_APIC */++#ifdef CONFIG_SMP++ /* All interrupts must be pipelined, but the spurious one since we+ don't even want to acknowledge it. */++ for (vector = CALL_FUNCTION_VECTOR; vector < SPURIOUS_APIC_VECTOR; vector++)+ {+ adeos_virtualize_irq(vector - FIRST_EXTERNAL_VECTOR,+ (void (*)(unsigned))__adeos_std_vector_table[vector],+ &__adeos_ack_system_irq,+ IPIPE_CALLASM_MASK|IPIPE_HANDLE_MASK|IPIPE_PASS_MASK);+ + __adeos_set_irq_gate(vector,+ __adeos_irq_trampolines[vector - FIRST_EXTERNAL_VECTOR]);+ }++ __adeos_set_irq_gate(ADEOS_SERVICE_VECTOR,+ __adeos_irq_trampolines[ADEOS_SERVICE_IPI]);++#endif /* CONFIG_SMP */++ /* Redirect traps and exceptions (except NMI). */++ __adeos_set_trap_gate(0,__adeos_trap_trampolines[0]);+ __adeos_set_trap_gate(1,__adeos_trap_trampolines[1]);+ __adeos_set_sys_gate(3,__adeos_trap_trampolines[3]);+ __adeos_set_sys_gate(4,__adeos_trap_trampolines[4]);+ __adeos_set_sys_gate(5,__adeos_trap_trampolines[5]);+ __adeos_set_trap_gate(6,__adeos_trap_trampolines[6]);+ __adeos_set_trap_gate(7,__adeos_trap_trampolines[7]);+ __adeos_set_trap_gate(8,__adeos_trap_trampolines[8]);+ __adeos_set_trap_gate(9,__adeos_trap_trampolines[9]);+ __adeos_set_trap_gate(10,__adeos_trap_trampolines[10]);+ __adeos_set_trap_gate(11,__adeos_trap_trampolines[11]);+ __adeos_set_trap_gate(12,__adeos_trap_trampolines[12]);+ __adeos_set_trap_gate(13,__adeos_trap_trampolines[13]);+ __adeos_set_irq_gate(14,__adeos_trap_trampolines[14]);+ __adeos_set_trap_gate(15,__adeos_trap_trampolines[15]);+ __adeos_set_trap_gate(16,__adeos_trap_trampolines[16]);+ __adeos_set_trap_gate(17,__adeos_trap_trampolines[17]);+ __adeos_set_trap_gate(18,__adeos_trap_trampolines[18]);+ __adeos_set_trap_gate(19,__adeos_trap_trampolines[19]);++#if defined(CONFIG_ADEOS_MODULE) || defined(CONFIG_X86_IO_APIC)+ adp_pipelined = 1;+#endif /* CONFIG_ADEOS_MODULE || CONFIG_X86_IO_APIC */++ adeos_critical_exit(flags);+}++/* __adeos_disable_pipeline() -- Disengage the pipeline. */++void __adeos_disable_pipeline (void)++{+ unsigned vector, irq;+ unsigned long flags;++ flags = adeos_critical_enter(NULL);++ /* Restore interrupt controllers. */++ for (irq = 0; irq < NR_IRQS; irq++)+ *irq_desc[irq].handler = __adeos_std_irq_dtype[irq];++ /* Restore original IDT settings. */++ for (irq = 0; irq < NR_IRQS && irq + FIRST_EXTERNAL_VECTOR < FIRST_SYSTEM_VECTOR; irq++)+ {+#ifdef CONFIG_X86_IO_APIC+ if (IO_APIC_IRQ(irq))+ {+ vector = IO_APIC_VECTOR(irq);++ if (vector == 0)+ continue;+ }+ else+#endif /* CONFIG_X86_IO_APIC */+ {+ vector = irq + FIRST_EXTERNAL_VECTOR;++ if (vector == SYSCALL_VECTOR)+ continue;+ }++ __adeos_set_irq_gate(vector,__adeos_std_vector_table[vector]);+ }++#ifdef CONFIG_X86_LOCAL_APIC++ for (vector = FIRST_SYSTEM_VECTOR; vector < CALL_FUNCTION_VECTOR; vector++)+ __adeos_set_irq_gate(vector,__adeos_std_vector_table[vector]);++#endif /* CONFIG_X86_LOCAL_APIC */++#ifdef CONFIG_SMP++ for (vector = CALL_FUNCTION_VECTOR; vector < SPURIOUS_APIC_VECTOR; vector++)+ __adeos_set_irq_gate(vector,__adeos_std_vector_table[vector]);++ __adeos_set_irq_gate(ADEOS_SERVICE_VECTOR,__adeos_std_vector_table[ADEOS_SERVICE_VECTOR]);+ __adeos_set_irq_gate(ADEOS_CRITICAL_VECTOR,__adeos_std_vector_table[ADEOS_CRITICAL_VECTOR]);++#endif /* CONFIG_SMP */++ __adeos_set_trap_gate(0,__adeos_std_vector_table[0]);+ __adeos_set_trap_gate(1,__adeos_std_vector_table[1]);+ __adeos_set_sys_gate(3,__adeos_std_vector_table[3]);+ __adeos_set_sys_gate(4,__adeos_std_vector_table[4]);+ __adeos_set_sys_gate(5,__adeos_std_vector_table[5]);+ __adeos_set_trap_gate(6,__adeos_std_vector_table[6]);+ __adeos_set_trap_gate(7,__adeos_std_vector_table[7]);+ __adeos_set_trap_gate(8,__adeos_std_vector_table[8]);+ __adeos_set_trap_gate(9,__adeos_std_vector_table[9]);+ __adeos_set_trap_gate(10,__adeos_std_vector_table[10]);+ __adeos_set_trap_gate(11,__adeos_std_vector_table[11]);+ __adeos_set_trap_gate(12,__adeos_std_vector_table[12]);+ __adeos_set_trap_gate(13,__adeos_std_vector_table[13]);+ __adeos_set_irq_gate(14,__adeos_std_vector_table[14]);+ __adeos_set_trap_gate(15,__adeos_std_vector_table[15]);+ __adeos_set_trap_gate(16,__adeos_std_vector_table[16]);+ __adeos_set_trap_gate(17,__adeos_std_vector_table[17]);+ __adeos_set_trap_gate(18,__adeos_std_vector_table[18]);+ __adeos_set_trap_gate(19,__adeos_std_vector_table[19]);++#if defined(CONFIG_ADEOS_MODULE) || defined(CONFIG_X86_IO_APIC)+ adp_pipelined = 0;+#endif /* CONFIG_ADEOS_MODULE || CONFIG_X86_IO_APIC */++ adeos_critical_exit(flags);+}++/* adeos_virtualize_irq_from() -- Attach a handler (and optionally a+ hw acknowledge routine) to an interrupt for the given domain. */++int adeos_virtualize_irq_from (adomain_t *adp,+ unsigned irq,+ void (*handler)(unsigned irq),+ int (*acknowledge)(unsigned irq),+ unsigned modemask)+{+ unsigned long flags;+ int err;++ if (irq >= IPIPE_NR_IRQS)+ return -EINVAL;++ if (adp->irqs[irq].control & IPIPE_SYSTEM_MASK)+ return -EPERM;+ + adeos_spin_lock_irqsave(&__adeos_pipelock,flags);++ if (handler != NULL)+ {+ /* A bit of hack here: if we are re-virtualizing an IRQ just+ to change the acknowledge routine by passing the special+ ADEOS_SAME_HANDLER value, then allow to recycle the current+ handler for the IRQ. This allows Linux device drivers+ managing shared IRQ lines to call adeos_virtualize_irq() in+ addition to request_irq() just for the purpose of+ interposing their own shared acknowledge routine. */++ if (handler == ADEOS_SAME_HANDLER)+ {+ handler = adp->irqs[irq].handler;++ if (handler == NULL)+ {+ err = -EINVAL;+ goto unlock_and_exit;+ }+ }+ else if ((modemask & IPIPE_EXCLUSIVE_MASK) != 0 &&+ adp->irqs[irq].handler != NULL)+ {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -