⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adeos-ipipe-2.6.14-i386-1.2-01.patch

📁 xenomai 很好的linux实时补丁
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
++		if (test_bit(IPIPE_STALL_FLAG,+			     &next_domain->cpudata[cpuid].status))+			break;++		if (next_domain->cpudata[cpuid].irq_pending_hi == 0)+			continue;++		ipipe_percpu_domain[cpuid] = next_domain;++sync_stage:++		__ipipe_sync_stage(IPIPE_IRQMASK_ANY);++		ipipe_load_cpuid();	/* Processor might have changed. */++		if (ipipe_percpu_domain[cpuid] != next_domain)+			/*+			 * Something has changed the current domain under our+			 * feet, recycling the register set; take note.+			 */+			this_domain = ipipe_percpu_domain[cpuid];+	}++	ipipe_percpu_domain[cpuid] = this_domain;++	ipipe_unlock_cpu(flags);+}++/* ipipe_alloc_virq() -- Allocate a pipelined virtual/soft interrupt.+ * Virtual interrupts are handled in exactly the same way than their+ * hw-generated counterparts wrt pipelining.+ */+unsigned ipipe_alloc_virq(void)+{+	unsigned long flags, irq = 0;+	int ipos;++	spin_lock_irqsave_hw(&__ipipe_pipelock, flags);++	if (__ipipe_virtual_irq_map != ~0) {+		ipos = ffz(__ipipe_virtual_irq_map);+		set_bit(ipos, &__ipipe_virtual_irq_map);+		irq = ipos + IPIPE_VIRQ_BASE;+	}++	spin_unlock_irqrestore_hw(&__ipipe_pipelock, flags);++	return irq;+}++/* ipipe_virtualize_irq() -- Attach a handler (and optionally a hw+   acknowledge routine) to an interrupt for a given domain. */++int ipipe_virtualize_irq(struct ipipe_domain *ipd,+			 unsigned irq,+			 ipipe_irq_handler_t handler,+			 void *cookie,+			 ipipe_irq_ackfn_t acknowledge,+			 unsigned modemask)+{+	unsigned long flags;+	int err;++	if (irq >= IPIPE_NR_IRQS)+		return -EINVAL;++	if (ipd->irqs[irq].control & IPIPE_SYSTEM_MASK)+		return -EPERM;++	spin_lock_irqsave_hw(&__ipipe_pipelock, flags);++	if (handler != NULL) {++		if (handler == IPIPE_SAME_HANDLER) {+			handler = ipd->irqs[irq].handler;+			cookie = ipd->irqs[irq].cookie;++			if (handler == NULL) {+				err = -EINVAL;+				goto unlock_and_exit;+			}+		} else if ((modemask & IPIPE_EXCLUSIVE_MASK) != 0 &&+			   ipd->irqs[irq].handler != NULL) {+			err = -EBUSY;+			goto unlock_and_exit;+		}++		if ((modemask & (IPIPE_SHARED_MASK | IPIPE_PASS_MASK)) ==+		    IPIPE_SHARED_MASK) {+			err = -EINVAL;+			goto unlock_and_exit;+		}++		if ((modemask & IPIPE_STICKY_MASK) != 0)+			modemask |= IPIPE_HANDLE_MASK;+	} else+		modemask &=+		    ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK |+		      IPIPE_SHARED_MASK);++	if (acknowledge == NULL) {+		if ((modemask & IPIPE_SHARED_MASK) == 0)+			/* Acknowledge handler unspecified -- this is ok in+			   non-shared management mode, but we will force the use+			   of the Linux-defined handler instead. */+			acknowledge = ipipe_root_domain->irqs[irq].acknowledge;+		else {+			/* A valid acknowledge handler to be called in shared mode+			   is required when declaring a shared IRQ. */+			err = -EINVAL;+			goto unlock_and_exit;+		}+	}++	ipd->irqs[irq].handler = handler;+	ipd->irqs[irq].cookie = cookie;+	ipd->irqs[irq].acknowledge = acknowledge;+	ipd->irqs[irq].control = modemask;++	if (irq < NR_IRQS &&+	    handler != NULL &&+	    !ipipe_virtual_irq_p(irq) && (modemask & IPIPE_ENABLE_MASK) != 0) {+		if (ipd != ipipe_current_domain) {+			/* IRQ enable/disable state is domain-sensitive, so we may+			   not change it for another domain. What is allowed+			   however is forcing some domain to handle an interrupt+			   source, by passing the proper 'ipd' descriptor which+			   thus may be different from ipipe_current_domain. */+			err = -EPERM;+			goto unlock_and_exit;+		}++		__ipipe_enable_irq(irq);+	}++	err = 0;++      unlock_and_exit:++	spin_unlock_irqrestore_hw(&__ipipe_pipelock, flags);++	return err;+}++/* ipipe_control_irq() -- Change modes of a pipelined interrupt for+ * the current domain. */++int ipipe_control_irq(unsigned irq, unsigned clrmask, unsigned setmask)+{+	struct ipipe_domain *ipd;+	unsigned long flags;++	if (irq >= IPIPE_NR_IRQS)+		return -EINVAL;++	ipd = ipipe_current_domain;++	if (ipd->irqs[irq].control & IPIPE_SYSTEM_MASK)+		return -EPERM;++	if (((setmask | clrmask) & IPIPE_SHARED_MASK) != 0)+		return -EINVAL;++	if (ipd->irqs[irq].handler == NULL)+		setmask &= ~(IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK);++	if ((setmask & IPIPE_STICKY_MASK) != 0)+		setmask |= IPIPE_HANDLE_MASK;++	if ((clrmask & (IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK)) != 0)	/* If one goes, both go. */+		clrmask |= (IPIPE_HANDLE_MASK | IPIPE_STICKY_MASK);++	spin_lock_irqsave_hw(&__ipipe_pipelock, flags);++	ipd->irqs[irq].control &= ~clrmask;+	ipd->irqs[irq].control |= setmask;++	if ((setmask & IPIPE_ENABLE_MASK) != 0)+		__ipipe_enable_irq(irq);+	else if ((clrmask & IPIPE_ENABLE_MASK) != 0)+		__ipipe_disable_irq(irq);++	spin_unlock_irqrestore_hw(&__ipipe_pipelock, flags);++	return 0;+}++/* __ipipe_dispatch_event() -- Low-level event dispatcher. */++int fastcall __ipipe_dispatch_event (unsigned event, void *data)+{+	struct ipipe_domain *start_domain, *this_domain, *next_domain;+	struct list_head *pos, *npos;+	unsigned long flags;+	ipipe_declare_cpuid;+	int propagate = 1;++	ipipe_lock_cpu(flags);++	start_domain = this_domain = ipipe_percpu_domain[cpuid];++	list_for_each_safe(pos,npos,&__ipipe_pipeline) {++		next_domain = list_entry(pos,struct ipipe_domain,p_link);++		/*+		 * Note: Domain migration may occur while running+		 * event or interrupt handlers, in which case the+		 * current register set is going to be recycled for a+		 * different domain than the initiating one. We do+		 * care for that, always tracking the current domain+		 * descriptor upon return from those handlers.+		 */+		if (next_domain->evhand[event] != NULL)	{+			ipipe_percpu_domain[cpuid] = next_domain;+			ipipe_unlock_cpu(flags);+			propagate = !next_domain->evhand[event](event,start_domain,data);+			ipipe_lock_cpu(flags);+			if (ipipe_percpu_domain[cpuid] != next_domain)+				this_domain = ipipe_percpu_domain[cpuid];+		}++		if (next_domain != ipipe_root_domain &&	/* NEVER sync the root stage here. */+		    next_domain->cpudata[cpuid].irq_pending_hi != 0 &&+		    !test_bit(IPIPE_STALL_FLAG,&next_domain->cpudata[cpuid].status)) {+			ipipe_percpu_domain[cpuid] = next_domain;+			__ipipe_sync_stage(IPIPE_IRQMASK_ANY);+			ipipe_load_cpuid();+			if (ipipe_percpu_domain[cpuid] != next_domain)+				this_domain = ipipe_percpu_domain[cpuid];+		}++		ipipe_percpu_domain[cpuid] = this_domain;++		if (next_domain == this_domain || !propagate)+			break;+	}++	ipipe_unlock_cpu(flags);++	return !propagate;+}++#ifdef CONFIG_PROC_FS++#include <linux/proc_fs.h>++struct proc_dir_entry *ipipe_proc_root;++static int __ipipe_version_info_proc(char *page,+				     char **start,+				     off_t off, int count, int *eof, void *data)+{+	int len = sprintf(page, "%s\n", IPIPE_VERSION_STRING);++	len -= off;++	if (len <= off + count)+		*eof = 1;++	*start = page + off;++	if(len > count)+		len = count;++	if(len < 0)+		len = 0;++	return len;+}++static int __ipipe_common_info_proc(char *page,+				    char **start,+				    off_t off, int count, int *eof, void *data)+{+	struct ipipe_domain *ipd = (struct ipipe_domain *)data;+	unsigned long ctlbits;+	unsigned irq, _irq;+	char *p = page;+	int len;++	spin_lock(&__ipipe_pipelock);++	p += sprintf(p, "Priority=%d, Id=0x%.8x\n",+		     ipd->priority, ipd->domid);+	irq = 0;++	while (irq < IPIPE_NR_IRQS) {+		ctlbits =+			(ipd->irqs[irq].+			 control & (IPIPE_HANDLE_MASK | IPIPE_PASS_MASK |+				    IPIPE_STICKY_MASK));+		if (irq >= IPIPE_NR_XIRQS && !ipipe_virtual_irq_p(irq)) {+			/*+			 * There might be a hole between the last external+			 * IRQ and the first virtual one; skip it.+			 */+			irq++;+			continue;+		}++		if (ipipe_virtual_irq_p(irq)+		    && !test_bit(irq - IPIPE_VIRQ_BASE,+				 &__ipipe_virtual_irq_map)) {+			/* Non-allocated virtual IRQ; skip it. */+			irq++;+			continue;+		}++		/*+		 * Attempt to group consecutive IRQ numbers having the+		 * same virtualization settings in a single line.+		 */++		_irq = irq;++		while (++_irq < IPIPE_NR_IRQS) {+			if (ipipe_virtual_irq_p(_irq) !=+			    ipipe_virtual_irq_p(irq)+			    || (ipipe_virtual_irq_p(_irq)+				&& !test_bit(_irq - IPIPE_VIRQ_BASE,+					     &__ipipe_virtual_irq_map))+			    || ctlbits != (ipd->irqs[_irq].+			     control & (IPIPE_HANDLE_MASK |+					IPIPE_PASS_MASK |+					IPIPE_STICKY_MASK)))+				break;+		}++		if (_irq == irq + 1)+			p += sprintf(p, "irq%u: ", irq);+		else+			p += sprintf(p, "irq%u-%u: ", irq, _irq - 1);++		/*+		 * Statuses are as follows:+		 * o "accepted" means handled _and_ passed down the pipeline.+		 * o "grabbed" means handled, but the interrupt might be+		 * terminated _or_ passed down the pipeline depending on+		 * what the domain handler asks for to the I-pipe.+		 * o "passed" means unhandled by the domain but passed+		 * down the pipeline.+		 * o "discarded" means unhandled and _not_ passed down the+		 * pipeline. The interrupt merely disappears from the+		 * current domain down to the end of the pipeline.+		 */+		if (ctlbits & IPIPE_HANDLE_MASK) {+			if (ctlbits & IPIPE_PASS_MASK)+				p += sprintf(p, "accepted");+			else+				p += sprintf(p, "grabbed");+		} else if (ctlbits & IPIPE_PASS_MASK)+			p += sprintf(p, "passed");+		else+			p += sprintf(p, "discarded");++		if (ctlbits & IPIPE_STICKY_MASK)+			p += sprintf(p, ", sticky");++		if (ipipe_virtual_irq_p(irq))+			p += sprintf(p, ", virtual");++		p += sprintf(p, "\n");++		irq = _irq;+	}++	spin_unlock(&__ipipe_pipelock);++	len = p - page;++	if (len <= off + count)+		*eof = 1;++	*start = page + off;++	len -= off;++	if (len > count)+		len = count;++	if (len < 0)+		len = 0;++	return len;+}++#ifdef CONFIG_IPIPE_STATS++static int __ipipe_stat_info_proc(char *page,+				  char **start,+				  off_t off, int count, int *eof, void *data)+{+	struct ipipe_domain *ipd = (struct ipipe_domain *)data;+	int len = 0, cpu, irq;+	char *p = page;++	p += sprintf(p,"> STALL TIME:\n");++	for_each_online_cpu(cpu) {+		unsigned long eip = ipd->stats[cpu].max_stall_eip;+		char namebuf[KSYM_NAME_LEN+1];+		unsigned long offset, size, t;+		const char *name;+		char *modname;++		name = kallsyms_lookup(eip, &size, &offset, &modname, namebuf);+		t = ipipe_tsc2ns(ipd->stats[cpu].max_stall_time);++		if (name) {+			if (modname)+				p += sprintf(p,"CPU%d  %12lu  (%s+%#lx [%s])\n",+					     cpu,t,name,offset,modname);+			else+				p += sprintf(p,"CPU%d  %12lu  (%s+%#lx)\n",+					     cpu,t,name,offset);+		}+		else+			p += sprintf(p,"CPU%d  %12lu  (%lx)\n",+				     cpu,t,eip);+	}++	p += sprintf(p,"> PROPAGATION TIME:\nIRQ");++	for_each_online_cpu(cpu) {+		p += sprintf(p,"         CPU%d",cpu);+	}++	for (irq = 0; irq < IPIPE_NR_IRQS; irq++) {++		unsigned long long t = 0;++		for_each_online_cpu(cpu) {+			t += ipd->stats[cpu].irq_stats[irq].max_delivery_time;+		}++		if (!t)+			continue;++		p += sprintf(p,"\n%3d:",irq);++		for_each_online_cpu(cpu) {+			p += sprintf(p,"%13lu",+				     ipipe_tsc2ns(ipd->stats[cpu].irq_stats[irq].max_delivery_time));+		}+	}++	p += sprintf(p,"\n");++	len = p - page - off;+	if (len <= off + count) *eof = 1;+	*start = page + off;+	if (len > count) len = count;+	if (len < 0) len = 0;++	return len;+}++#endif /* CONFIG_IPIPE_STATS */++void __ipipe_add_domain_proc(struct ipipe_domain *ipd)+{++	create_proc_read_entry(ipd->name,0444,ipipe_proc_root,&__ipipe_common_info_proc,ipd);+#ifdef CONFIG_IPIPE_STATS+	{+		char name[64];+		snprintf(name,sizeof(name),"%s_stats",ipd->name);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -