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

📄 arch.c

📁 fsmlabs的real time linux的内核
💻 C
字号:
/* * (C) Finite State Machine Labs Inc. 2000 <business@fsmlabs.com> * * Released under the terms of GPL 2. * Open RTLinux makes use of a patented process described in * US Patent 5,995,745. Use of this process is governed * by the Open RTLinux Patent License which can be obtained from * www.fsmlabs.com/PATENT or by sending email to * licensequestions@fsmlabs.com */#include <asm/uaccess.h>#include <asm/system.h>#include <linux/irq.h>#include <asm/irq.h>#include <asm/machvec.h>#include "arch.h"#include <rtl_core.h>#include <rtl_sync.h>extern unsigned long linux_soft_sti;irq_desc_t rtl_hard_irq_desc[NR_IRQS];void (*hard_do_IRQ)(unsigned long, struct pt_regs *);void (*hard_smp_percpu_timer_interrupt)(struct pt_regs *);void rtl_local_intercept(struct pt_regs *regs);int last_irq[NR_CPUS] = {-1, };int last_local[NR_CPUS] = {-1, };unsigned long pad, pad1;void (*hard_handle_ipi)(struct pt_regs *);void rtl_soft_sti_no_emulation(void);void alpha_ack(unsigned int irq){}void alpha_end(unsigned int irq){	rtl_virt_enable(irq);}unsigned int alpha_startup(unsigned int irq){	rtl_virt_enable(irq);	return 0;}int rtl_irq_set_affinity (unsigned int irq, const unsigned long *mask, unsigned long *oldmask){	return -1;}hw_irq_controller rtl_fake_pic ={ " RTLinux PIC  ", alpha_startup, rtl_virt_disable, rtl_virt_enable,  rtl_virt_disable, alpha_ack, alpha_end };unsigned long alpha_soft_rdps(void){	unsigned long x;	rtl_soft_save_flags(&x);	return (rdps()&~7) | (x&7);}unsigned long alpha_soft_swpipl(unsigned long ipl){	unsigned long prev = alpha_soft_rdps()&7;	extern unsigned long last_cli[NR_CPUS];	unsigned int cpu_id = rtl_getcpuid();	ipl &= 7;		/* special case since IPL_MIN can be a variable */	if ( ipl == IPL_MIN )	{		rtl_soft_sti();		return prev;	}	switch ( ipl )	{	case IPL_MAX:		{			unsigned long flags;			rtl_soft_save_flags(&flags);			rtl_soft_cli();			if ( !(flags & 7) )				last_cli[cpu_id] = (ulong)__builtin_return_address(0);		}		break;	case 0:		rtl_soft_sti();		break;	default:		rtl_printf("alpha_soft_setipl: unknown IPL %x\n", ipl );		break;	}	return prev;}#ifdef CONFIG_SMPstatic void alpha_handle_ipi(struct pt_regs *regs){	unsigned int cpu_id = rtl_getcpuid();	/*	 * alpha_handle_ipi cannot run with concurrently with itself because	 * of the last_irq hack.  the cli protects us from higher	 * priority interrupts coming in. -- Cort	 */	rtl_hard_cli();	if ( last_local[cpu_id] != -1 )		printk("alpha_intercept: last_local set to %d\n",		       last_local[cpu_id]);	last_local[cpu_id] = LOCAL_IPI_VECTOR;	rtl_local_intercept(regs);}static void alpha_handle_percpu_timer(struct pt_regs *regs){	unsigned int cpu_id = rtl_getcpuid();	/*	 * alpha_intercept cannot be re-entered because of the last_irq	 * hack.  the cli protects us from higher priority interrupts	 * coming in. -- Cort	 */	rtl_hard_cli();	if ( last_local[cpu_id] != -1 )		printk("alpha_intercept: last_local set to %d on cpu %d",		       last_local[cpu_id], cpu_id);	last_local[cpu_id] = LOCAL_TIMER_VECTOR;	rtl_local_intercept(regs);}#endif /* CONFIG_SMP */static void alpha_intercept(unsigned long irq, struct pt_regs *regs){	unsigned int cpu_id = rtl_getcpuid();	/*	 * alpha_intercept cannot be re-entered because of the last_irq	 * hack.  the cli protects us from higher priority interrupts	 * coming in. -- Cort	 */	rtl_hard_cli();	if ( last_irq[cpu_id] != -1 )		printk("alpha_intercept: last_irq set to %d current %ld\n",		       last_irq[cpu_id], irq);	last_irq[cpu_id] = irq;	rtl_intercept(regs);}struct {	atomic_t waiting;	atomic_t done;} sync_data = {{0},{0}};void sync_takeover(void *unused){	int i;	rtl_hard_cli();	atomic_inc(&sync_data.waiting);	i = 0;	while ( !atomic_read(&sync_data.done) && (i < 1000000000) )	{		i++;		if (i == 1000000000)			printk("timed out on sync_data.done\n");	}	rtl_hard_sti();}int arch_takeover(void){	int i;	void rtl_soft_sti_no_emulation(void);	#ifdef CONFIG_SMP		int timeout, cpus = smp_num_cpus - 1;#endif /* CONFIG_SMP */	if ( IPL_MIN != 0 )	{		printk("Your alpha system is not supported.\n");		return -1;	}		__cli();#ifdef CONFIG_SMP		smp_call_function( sync_takeover, 0, 0 /*atomic */,0 /*don't wait*/ );	/* everyone else is now starting to exec sync_function */	timeout = jiffies + HZ;	while ((atomic_read(&sync_data.waiting) != cpus)			&& time_before(jiffies, timeout));	if(atomic_read(&sync_data.waiting) != cpus)	{	       printk("rtl_smp_synchronize timed out\n");       	       return -1;	}	hard_smp_percpu_timer_interrupt = smp_percpu_timer_interrupt;	smp_percpu_timer_interrupt = alpha_handle_percpu_timer;	hard_handle_ipi = handle_ipi;	handle_ipi = alpha_handle_ipi;	for ( i = 0; i < smp_num_cpus; i++ )		last_local[i] = last_irq[i] = -1;#endif /* CONFIG_SMP */	memcpy(rtl_hard_irq_desc, irq_desc, sizeof(irq_desc_t)*NR_IRQS);	pad = (ulong)__rdps;	pad1 = (ulong)__swpipl;	__rdps = alpha_soft_rdps;	__swpipl = alpha_soft_swpipl; 	for ( i = 0 ; i < NR_IRQS; i++ )		if ( irq_desc[i].handler )			irq_desc[i].handler = &rtl_fake_pic;	hard_do_IRQ = handle_irq;	handle_irq = alpha_intercept;	linux_soft_sti = (ulong)rtl_soft_sti_no_emulation;	rtl_hard_sti();#ifdef CONFIG_SMP	atomic_set( &sync_data.done, 1);#endif /* CONFIG_SMP */		return 0;}void arch_giveup(void){	rtl_hard_cli();	(ulong)__rdps = pad;	(ulong)__swpipl = pad1;	memcpy(irq_desc, rtl_hard_irq_desc, sizeof(irq_desc_t)*NR_IRQS);	linux_soft_sti = 0;	handle_irq = hard_do_IRQ;#ifdef CONFIG_SMP		handle_ipi = hard_handle_ipi;	smp_percpu_timer_interrupt = hard_smp_percpu_timer_interrupt;#endif /* CONFIG_SMP */		__sti();}int rtl_free_local_irq(int i, unsigned int cpu){	return 0;}int rtl_request_local_irq(int i, unsigned int (*handler)(struct pt_regs *r),			  unsigned int cpu){	return 0;}

⌨️ 快捷键说明

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