📄 hal13c2-2.4.26.patch
字号:
++ 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 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 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.4.26/adeos/x86.c linux-2.4.26-adeos/adeos/x86.c--- linux-2.4.26/adeos/x86.c 1970-01-01 01:00:00.000000000 +0100+++ linux-2.4.26-adeos/adeos/x86.c 2004-03-21 19:46:26.000000000 +0100@@ -0,0 +1,986 @@+/*+ * 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 unsigned long __adeos_virtual_irq_map;++extern struct list_head __adeos_pipeline;++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_IRQ_BODY() \+__asm__( \+ "\n" __ALIGN_STR"\n" \+ SYMBOL_NAME_STR(__adeos_irq_common) ":\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" \+ "movl %edx,%ds\n\t" \+ "movl %edx,%es\n\t" \+ "call " SYMBOL_NAME_STR(__adeos_handle_irq) "\n\t" \+ "testl %eax,%eax\n\t" \+ "jnz 1f\n\t" \+ "popl %ebx\n\t" \+ "popl %ecx\n\t" \+ "popl %edx\n\t" \+ "popl %esi\n\t" \+ "popl %edi\n\t" \+ "popl %ebp\n\t" \+ "popl %eax\n\t" \+ "popl %ds\n\t" \+ "popl %es\n\t" \+ "addl $4,%esp\n\t" \+ "iret\n\t" \+ "1: cld\n\t" \+ __adeos_bump_count_noarg /* Depends on CONFIG_PREEMPT. */ \+ "jmp " SYMBOL_NAME_STR(ret_from_intr) "\n");+++#define BUILD_IRQ_PROTO(irq) __adeos_irq_##irq(void)+#define BUILD_1_IRQ(irq) \+asmlinkage void BUILD_IRQ_PROTO(irq); \+__asm__( \+ "\n" __ALIGN_STR"\n" \+ SYMBOL_NAME_STR(__adeos_irq_) #irq ":\n\t" \+ "pushl $"#irq"-256 \n\t" \+ "jmp " SYMBOL_NAME_STR(__adeos_irq_common) "\n");++#define BUILD_IRQ_N(x,y) \+BUILD_1_IRQ(x##y)++#define BUILD_16_IRQS(x) \+BUILD_IRQ_N(x,0) BUILD_IRQ_N(x,1) BUILD_IRQ_N(x,2) BUILD_IRQ_N(x,3) \+BUILD_IRQ_N(x,4) BUILD_IRQ_N(x,5) BUILD_IRQ_N(x,6) BUILD_IRQ_N(x,7) \+BUILD_IRQ_N(x,8) BUILD_IRQ_N(x,9) BUILD_IRQ_N(x,a) BUILD_IRQ_N(x,b) \+BUILD_IRQ_N(x,c) BUILD_IRQ_N(x,d) BUILD_IRQ_N(x,e) BUILD_IRQ_N(x,f)++BUILD_IRQ_BODY();++BUILD_16_IRQS(0x0)+#if defined(CONFIG_X86_LOCAL_APIC) || defined(CONFIG_X86_IO_APIC)+BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3) BUILD_16_IRQS(0x4)+BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) BUILD_16_IRQS(0x8)+BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) BUILD_16_IRQS(0xc)+BUILD_16_IRQS(0xd)+#endif /* CONFIG_X86_LOCAL_APIC || CONFIG_X86_IO_APIC */++#define LIST_1_IRQ(irq) &__adeos_irq_ ## irq++#define LIST_IRQ_N(x,y) \+LIST_1_IRQ(x##y)++#define LIST_16_IRQS(x) \+LIST_IRQ_N(x,0), LIST_IRQ_N(x,1), LIST_IRQ_N(x,2), LIST_IRQ_N(x,3), \+LIST_IRQ_N(x,4), LIST_IRQ_N(x,5), LIST_IRQ_N(x,6), LIST_IRQ_N(x,7), \+LIST_IRQ_N(x,8), LIST_IRQ_N(x,9), LIST_IRQ_N(x,a), LIST_IRQ_N(x,b), \+LIST_IRQ_N(x,c), LIST_IRQ_N(x,d), LIST_IRQ_N(x,e), LIST_IRQ_N(x,f)++static void (*__adeos_irq_trampolines[])(void) = {+ LIST_16_IRQS(0x0),+#if defined(CONFIG_X86_LOCAL_APIC) || defined(CONFIG_X86_IO_APIC)+ LIST_16_IRQS(0x1), LIST_16_IRQS(0x2), LIST_16_IRQS(0x3), LIST_16_IRQS(0x4),+ LIST_16_IRQS(0x5), LIST_16_IRQS(0x6), LIST_16_IRQS(0x7), LIST_16_IRQS(0x8),+ LIST_16_IRQS(0x9), LIST_16_IRQS(0xa), LIST_16_IRQS(0xb), LIST_16_IRQS(0xc),+ LIST_16_IRQS(0xd)+#endif /* CONFIG_X86_LOCAL_APIC || CONFIG_X86_IO_APIC */+};++#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 ("__stringify(__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 " __stringify(__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" \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -