📄 hal5-2.6.5.patch
字号:
+{+ if (!adeos_spin_trylock(&mutex->lock) &&+ adp_current != adp_root &&+ mutex->owner != adp_current)+ return -EBUSY;++ return 0;+}++static inline void __adeos_sleepon_mutex (admutex_t *mutex, adomain_t *sleeper, int cpuid)++{+ adomain_t *owner = mutex->owner;++ /* Make the current domain (== sleeper) wait for the mutex to be+ released. Adeos' pipelined scheme guarantees that the new+ sleeper _is_ more prioritary than any aslept domain since we+ have stalled each sleeper's stage. Must be called with local hw+ interrupts off. */++ sleeper->m_link = mutex->sleepq;+ mutex->sleepq = sleeper;+ __adeos_switch_to(owner,cpuid);+ mutex->owner = sleeper;+ adeos_spin_unlock(&mutex->lock);+}++static inline void __adeos_signal_mutex (admutex_t *mutex, int cpuid)++{+ adomain_t *sleeper;++ /* Wake up first most prioritary sleeper. Must be called with+ local hw interrupts off. */++ sleeper = mutex->sleepq;+ mutex->sleepq = sleeper->m_link;+ __adeos_switch_to(sleeper,cpuid);+}++unsigned long fastcall adeos_lock_mutex (admutex_t *mutex)++{+ unsigned long flags, hwflags;+ adeos_declare_cpuid;+ adomain_t *adp;++ if (unlikely(!adp_pipelined))+ {+ adeos_hw_local_irq_save(hwflags);+ flags = !adeos_hw_test_iflag(hwflags);+ adeos_spin_lock(&mutex->lock);+ return flags;+ }++ adeos_lock_cpu(hwflags);++ adp = adp_cpu_current[cpuid];++ flags = test_and_set_bit(IPIPE_STALL_FLAG,&adp->cpudata[cpuid].status);++ /* Two cases to handle here on SMP systems, only one for UP:+ 1) in case of a conflicting access from a prioritary domain+ running on the same cpu, make this domain sleep on the mutex,+ and resume the current owner so it can release the lock asap.+ 2) in case of a conflicting access from any domain on a+ different cpu than the current owner's, simply enter a spinning+ loop. Note that testing mutex->owncpu is safe since it is only+ changed by the current owner, and set to -1 when the mutex is+ unlocked. */++#ifdef CONFIG_SMP+ while (!adeos_spin_trylock(&mutex->lock))+ {+ if (mutex->owncpu == cpuid)+ {+ __adeos_sleepon_mutex(mutex,adp,cpuid);+ adeos_load_cpuid();+ }+ }++ mutex->owncpu = cpuid;+#else /* !CONFIG_SMP */+ while (mutex->owner != NULL && mutex->owner != adp)+ __adeos_sleepon_mutex(mutex,adp,cpuid);+#endif /* CONFIG_SMP */++ mutex->owner = adp;++ adeos_unlock_cpu(hwflags);++ return flags;+}++void fastcall adeos_unlock_mutex (admutex_t *mutex, unsigned long flags)++{+ unsigned long hwflags;+ adeos_declare_cpuid;+ adomain_t *adp;++ if (unlikely(!adp_pipelined))+ {+ adeos_spin_unlock(&mutex->lock);++ if (flags)+ adeos_hw_cli();+ else+ adeos_hw_sti();++ return;+ }++#ifdef CONFIG_SMP+ mutex->owncpu = -1;+#endif /* CONFIG_SMP */++ if (!flags)+ adeos_hw_sti(); /* Absolutely needed. */+ + adeos_lock_cpu(hwflags);++ if (unlikely(mutex->sleepq != NULL))+ {+ __adeos_signal_mutex(mutex,cpuid); /* Wake up one sleeper. */+ adeos_load_cpuid();+ }+ else+ {+ mutex->owner = NULL;+ adeos_spin_unlock(&mutex->lock);+ }++ adp = adp_cpu_current[cpuid];++ if (flags)+ set_bit(IPIPE_STALL_FLAG,&adp->cpudata[cpuid].status);+ else+ {+ clear_bit(IPIPE_STALL_FLAG,&adp->cpudata[cpuid].status);+ + if (adp->cpudata[cpuid].irq_pending_hi != 0)+ __adeos_sync_stage(IPIPE_IRQMASK_ANY);+ }++ adeos_unlock_cpu(hwflags);+}++void __adeos_takeover (void)++{+ __adeos_enable_pipeline();+ printk(KERN_WARNING "Adeos: Pipelining started.\n");+}++#ifdef MODULE++static int __init adeos_init_module (void)++{+ __adeos_takeover();+ return 0;+}++static void __exit adeos_exit_module (void)++{+ __adeos_disable_pipeline();+ printk(KERN_WARNING "Adeos: Pipelining stopped.\n");+}++module_init(adeos_init_module);+module_exit(adeos_exit_module);++#endif /* MODULE */++EXPORT_SYMBOL(adeos_register_domain);+EXPORT_SYMBOL(adeos_unregister_domain);+EXPORT_SYMBOL(adeos_renice_domain);+EXPORT_SYMBOL(adeos_virtualize_irq_from);+EXPORT_SYMBOL(adeos_control_irq);+EXPORT_SYMBOL(adeos_propagate_irq);+EXPORT_SYMBOL(adeos_schedule_irq);+EXPORT_SYMBOL(adeos_free_irq);+EXPORT_SYMBOL(adeos_trigger_ipi);+EXPORT_SYMBOL(adeos_stall_pipeline);+EXPORT_SYMBOL(adeos_unstall_pipeline);+EXPORT_SYMBOL(adeos_unstall_pipeline_from);+EXPORT_SYMBOL(adeos_catch_event_from);+EXPORT_SYMBOL(adeos_hook_dswitch);+EXPORT_SYMBOL(adeos_init_attr);+EXPORT_SYMBOL(adeos_get_sysinfo);+EXPORT_SYMBOL(adeos_tune_timer);+EXPORT_SYMBOL(adeos_alloc_ptdkey);+EXPORT_SYMBOL(adeos_free_ptdkey);+EXPORT_SYMBOL(adeos_set_ptd);+EXPORT_SYMBOL(adeos_get_ptd);+EXPORT_SYMBOL(adeos_set_irq_affinity);+EXPORT_SYMBOL(adeos_init_mutex);+EXPORT_SYMBOL(adeos_destroy_mutex);+EXPORT_SYMBOL(adeos_lock_mutex);+EXPORT_SYMBOL(adeos_unlock_mutex);diff -uNrp linux-2.6.5/adeos/x86.c linux-2.6.5-adeos/adeos/x86.c--- linux-2.6.5/adeos/x86.c 1970-01-01 01:00:00.000000000 +0100+++ linux-2.6.5-adeos/adeos/x86.c 2004-06-01 12:41:54.000000000 +0200@@ -0,0 +1,897 @@+/*+ * linux/adeos/x86.c+ *+ * Copyright (C) 2002 Philippe Gerum.+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,+ * USA; either version 2 of the License, or (at your option) any later+ * version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+ *+ * Architecture-dependent ADEOS support for x86.+ */++#include <linux/config.h>+#include <linux/kernel.h>+#include <linux/smp.h>+#include <linux/sched.h>+#include <linux/irq.h>+#include <linux/slab.h>+#include <asm/system.h>+#include <asm/atomic.h>+#include <asm/hw_irq.h>+#include <asm/irq.h>+#include <asm/desc.h>+#include <asm/io.h>+#ifdef CONFIG_X86_LOCAL_APIC+#include <asm/fixmap.h>+#include <asm/bitops.h>+#include <asm/mpspec.h>+#ifdef CONFIG_X86_IO_APIC+#include <asm/io_apic.h>+#endif /* CONFIG_X86_IO_APIC */+#include <asm/apic.h>+#endif /* CONFIG_X86_LOCAL_APIC */++extern struct desc_struct idt_table[];++extern spinlock_t __adeos_pipelock;++extern void (*__adeos_irq_trampolines[])(void); /* in entry.S */++static void (*__adeos_std_vector_table[256])(void);++static struct hw_interrupt_type __adeos_std_irq_dtype[NR_IRQS];++/* Lifted from arch/i386/kernel/traps.c */ +#define __adeos_set_gate(gate_addr,type,dpl,addr) \+do { \+ int __d0, __d1; \+ __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \+ "movw %4,%%dx\n\t" \+ "movl %%eax,%0\n\t" \+ "movl %%edx,%1" \+ :"=m" (*((long *) (gate_addr))), \+ "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \+ :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \+ "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \+} while (0)++#define __adeos_get_gate_addr(v) \+ ((void *)((idt_table[v].b & 0xffff0000)|(idt_table[v].a & 0xffff)))++#define __adeos_set_irq_gate(vector,addr) \+__adeos_set_gate(idt_table+vector,14,0,addr)++#define __adeos_set_trap_gate(vector,addr) \+__adeos_set_gate(idt_table+vector,15,0,addr)++#define __adeos_set_sys_gate(vector,addr) \+__adeos_set_gate(idt_table+vector,15,3,addr)++#define BUILD_TRAP_PROTO(trapnr) __adeos_trap_##trapnr(void)++#define BUILD_TRAP_ERRCODE(trapnr) \+asmlinkage void BUILD_TRAP_PROTO(trapnr); \+__asm__ ( \+ "\n" __ALIGN_STR"\n\t" \+ SYMBOL_NAME_STR(__adeos_trap_) #trapnr ":\n\t" \+ "cld\n\t" \+ "pushl %es\n\t" \+ "pushl %ds\n\t" \+ "pushl %eax\n\t" \+ "pushl %ebp\n\t" \+ "pushl %edi\n\t" \+ "pushl %esi\n\t" \+ "pushl %edx\n\t" \+ "pushl %ecx\n\t" \+ "pushl %ebx\n\t" \+ "movl $" STR(__KERNEL_DS) ",%edx\n\t" \+ "mov %dx,%ds\n\t" \+ "mov %dx,%es\n\t" \+ "movl ("SYMBOL_NAME_STR(__adeos_event_monitors + 4 * trapnr)"),%eax\n\t" \+ "testl %eax,%eax\n\t" \+ "jz 1f\n\t" \+ "movl %esp,%eax\n\t" \+ "pushl %eax\n\t" \+ "pushl $"#trapnr"\n\t" \+ "call " SYMBOL_NAME_STR(__adeos_handle_event) "\n\t" \+ "addl $8,%esp\n\t" \+ "testl %eax,%eax\n\t" \+"1: popl %ebx\n\t" \+ "popl %ecx\n\t" \+ "popl %edx\n\t" \+ "popl %esi\n\t" \+ "popl %edi\n\t" \+ "popl %ebp\n\t" \+ "jz 2f\n\t" \+ "popl %eax\n\t" \+ "popl %ds\n\t" \+ "popl %es\n\t" \+ "addl $4,%esp\n\t" \+ "iret\n" \+"2: movl ("SYMBOL_NAME_STR(__adeos_std_vector_table + 4 * trapnr)"),%eax\n\t" \+ "movl 8(%esp),%es\n\t" \+ "movl %eax,8(%esp)\n\t" \+ "popl %eax\n\t" \+ "popl %ds\n\t" \+ "ret\n");++#define BUILD_TRAP_NOERRCODE(trapnr) \+asmlinkage void BUILD_TRAP_PROTO(trapnr); \+__asm__ ( \+ "\n" __ALIGN_STR"\n\t" \+ SYMBOL_NAME_STR(__adeos_trap_) #trapnr ":\n\t" \+ "cld\n\t" \+ "pushl $0\n\t" \+ "pushl %es\n\t" \+ "pushl %ds\n\t" \+ "pushl %eax\n\t" \+ "pushl %ebp\n\t" \+ "pushl %edi\n\t" \+ "pushl %esi\n\t" \+ "pushl %edx\n\t" \+ "pushl %ecx\n\t" \+ "pushl %ebx\n\t" \+ "movl $" STR(__KERNEL_DS) ",%edx\n\t" \+ "mov %dx,%ds\n\t" \+ "mov %dx,%es\n\t" \+ "movl ("SYMBOL_NAME_STR(__adeos_event_monitors + 4 * trapnr)"),%eax\n\t" \+ "testl %eax,%eax\n\t" \+ "jz 1f\n\t" \+ "movl %esp,%eax\n\t" \+ "pushl %eax\n\t" \+ "pushl $"#trapnr"\n\t" \+ "call " SYMBOL_NAME_STR(__adeos_handle_event) "\n\t" \+ "addl $8,%esp\n\t" \+ "testl %eax,%eax\n\t" \+"1: popl %ebx\n\t" \+ "popl %ecx\n\t" \+ "popl %edx\n\t" \+ "popl %esi\n\t" \+ "popl %edi\n\t" \+ "popl %ebp\n\t" \+ "jz 2f\n\t" \+ "popl %eax\n\t" \+ "popl %ds\n\t" \+ "popl %es\n\t" \+ "addl $4,%esp\n\t" \+ "iret\n" \+"2: movl ("SYMBOL_NAME_STR(__adeos_std_vector_table + 4 * trapnr)"),%eax\n\t" \+ "movl %eax,12(%esp)\n\t" \+ "popl %eax\n\t" \+ "popl %ds\n\t" \+ "popl %es\n\t" \+ "ret\n");++BUILD_TRAP_NOERRCODE(0x0) BUILD_TRAP_NOERRCODE(0x1) BUILD_TRAP_NOERRCODE(0x2)+BUILD_TRAP_NOERRCODE(0x3) BUILD_TRAP_NOERRCODE(0x4) BUILD_TRAP_NOERRCODE(0x5)+BUILD_TRAP_NOERRCODE(0x6) BUILD_TRAP_NOERRCODE(0x7) BUILD_TRAP_ERRCODE(0x8)+BUILD_TRAP_NOERRCODE(0x9) BUILD_TRAP_ERRCODE(0xa) BUILD_TRAP_ERRCODE(0xb)+BUILD_TRAP_ERRCODE(0xc) BUILD_TRAP_ERRCODE(0xd) BUILD_TRAP_ERRCODE(0xe)+BUILD_TRAP_NOERRCODE(0xf) BUILD_TRAP_NOERRCODE(0x10) BUILD_TRAP_ERRCODE(0x11)+BUILD_TRAP_NOERRCODE(0x12) BUILD_TRAP_NOERRCODE(0x13) BUILD_TRAP_ERRCODE(0x14)+BUILD_TRAP_ERRCODE(0x15) BUILD_TRAP_ERRCODE(0x16) BUILD_TRAP_ERRCODE(0x17)+BUILD_TRAP_ERRCODE(0x18) BUILD_TRAP_ERRCODE(0x19) BUILD_TRAP_ERRCODE(0x1a)+BUILD_TRAP_ERRCODE(0x1b) BUILD_TRAP_ERRCODE(0x1c) BUILD_TRAP_ERRCODE(0x1d)+BUILD_TRAP_ERRCODE(0x1e) BUILD_TRAP_ERRCODE(0x1f)++#define LIST_TRAP(trapnr) &__adeos_trap_ ## trapnr++static void (*__adeos_trap_trampolines[])(void) = {+ LIST_TRAP(0x0), LIST_TRAP(0x1), LIST_TRAP(0x2), LIST_TRAP(0x3),+ LIST_TRAP(0x4), LIST_TRAP(0x5), LIST_TRAP(0x6), LIST_TRAP(0x7),+ LIST_TRAP(0x8), LIST_TRAP(0x9), LIST_TRAP(0xa), LIST_TRAP(0xb),+ LIST_TRAP(0xc), LIST_TRAP(0xd), LIST_TRAP(0xe), LIST_TRAP(0xf),+ LIST_TRAP(0x10), LIST_TRAP(0x11), LIST_TRAP(0x12), LIST_TRAP(0x13),+ LIST_TRAP(0x14), LIST_TRAP(0x15), LIST_TRAP(0x16), LIST_TRAP(0x17),+ LIST_TRAP(0x18), LIST_TRAP(0x19), LIST_TRAP(0x1a), LIST_TRAP(0x1b),+ LIST_TRAP(0x1c), LIST_TRAP(0x1d), LIST_TRAP(0x1e), LIST_TRAP(0x1f)+};++static int __adeos_ack_common_irq (unsigned irq)++{+ irq_desc_t *desc = irq_desc + irq;+#ifdef CONFIG_PREEMPT+ preempt_disable();+#endif /* CONFIG_PREEMPT */+ desc->handler->ack(irq);+#ifdef CONFIG_PREEMPT+ preempt_enable_no_resched();+#endif /* CONFIG_PREEMPT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -