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

📄 arch.h

📁 fsmlabs的real time linux的内核
💻 H
📖 第 1 页 / 共 2 页
字号:
BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)*/void init_local_code(const struct func_table *pf){#ifdef CONFIG_SMP	local_code.smp_reschedule_interrupt =\	       	(void *)pf[pf_smp_reschedule_interrupt].address;	local_code.smp_invalidate_interrupt = \	       	(void *)pf[pf_smp_invalidate_interrupt].address;	local_code.smp_call_function_interrupt = \	       	(void *)pf[pf_smp_call_function_interrupt].address;	local_code.rtl_reschedule = \	       	(void *)pf[pf_rtl_reschedule].address;#endif	local_code.smp_spurious_interrupt=\	       	(void *)pf[pf_smp_spurious_interrupt].address;	local_code.smp_error_interrupt=\	       	(void *)pf[pf_smp_error_interrupt].address;        local_code.smp_apic_timer_interrupt = \	       	(void *)pf[pf_smp_apic_timer_interrupt].address;}#endif /* CONFIG_X86_LOCAL_APIC */static char * find_patch(unsigned long v ){       	const struct func_table *pfunc = (struct func_table *)&__start_rtlinux_funcs;       	struct patch_table *p = (struct patch_table *)pfunc[pf___start_rtlinux_patch].address;       	for(; (ulong)p < (ulong)pfunc[pf___stop_rtlinux_patch].address;p++) {	       	if(((unsigned long)p->magic) == v) {		       	return p->address;		}	}       	return 0;}int rtl_request_traps(int (*rtl_exception_intercept)(int vector, struct pt_regs *regs, int error_code)){	const struct func_table *pfunc = (struct func_table *)&__start_rtlinux_funcs;	*((long *)(pfunc[pf_rtl_exception_intercept].address)) = (long)rtl_exception_intercept;	return 0;}static rtl_local_handler_t rtl_reschedule_handlers[NR_CPUS];unsigned int default_reschedule_handler(struct pt_regs *r){	return 0;}static int patch_kernel (unsigned int cpu_id){	enum pfunctions i;	char *p;	irq_desc_t *h;	const struct func_table *pfunc = (struct func_table *)&__start_rtlinux_funcs;	/* make my func the pfunc */	/* rtl_intercept */	xdo_IRQ = (void *)pfunc[pf_do_IRQ].address; /*do_IRQ */        local_ret_from_intr = (void *)pfunc[pf_ret_from_intr].address; 	if( !(p = find_patch((ulong)pfunc[pf_do_IRQ].address)))	{		printk("RTLinux cannot patch intercept routine\n");		return -1;	}	else {#ifdef DEBUG_RTLINUX		printk("RTLinux patch intercept=%x\n",(int)rtl_intercept);#endif		save_jump(p,pf_do_IRQ);		patch_jump(p,(char *)rtl_intercept);	}		/* insert call to sti */#ifdef DEBUG_RTLINUX	printk("RTLinux patch kernel  skip emulate IRET DEBUG\n");#endif	*((long *)(pfunc[pf_rtl_emulate_iret].address)) = (long)rtl_soft_sti;#ifdef CONFIG_X86_LOCAL_APIC 	/* patch the calls to the smp handlers and zap their apic calls */	for(i=PF_LOCAL_START; i <= PF_LOCAL_END;i++){		p = find_patch((ulong)pfunc[i].address);		if(!p){			printk("RTLinux can't smp patch %d\n",i);			return -1;		}		else{			save_jump(p,i);#ifdef DEBUG_RTLINUX			printk("patching %x, jmp at %#x\n", (unsigned) (pfunc[i].address), (unsigned) p);#endif			patch_jump(p,(char *)rtl_local_intercept);			zap_ack_apic(pfunc[i].address);		}	}	init_local_code(pfunc);#endif	/* cli/sti etc */	pre_patch_control = irq_control; /* save old irq_control */	irq_control.do_save_flags = rtl_soft_save_flags;	irq_control.do_restore_flags = rtl_soft_restore_flags;	irq_control.do_cli = rtl_soft_cli;	irq_control.do_sti = rtl_soft_sti;	irq_control.do_local_irq_save = rtl_soft_local_irq_save;	irq_control.do_local_irq_restore = rtl_soft_restore_flags;	/* take over the descriptor table */	h = (irq_desc_t *)pfunc[pf_irq_desc].address;	for(i=0; i < NR_IRQS; i++){		save_linux_irq_desc[i] = h[i] . handler;#ifdef CONFIG_X86_IO_APIC#if LINUX_VERSION_CODE >= 0x020300		if (h[i].handler && !strcmp(h[i].handler->typename, "IO-APIC-level")) {			if (!linux_ioapic_level_irq_type_ptr) {				linux_ioapic_level_irq_type_ptr = h[i].handler;				rtl_ioapic_level_irq_type = *linux_ioapic_level_irq_type_ptr;				rtl_ioapic_level_irq_type . ack = rtl_mask_and_ack_level_ioapic_irq;				rtl_ioapic_level_irq_type . end = rtl_end_level_io_apic_irq;			}			rtl_irq_desc[i]= &rtl_ioapic_level_irq_type;		} else#endif#ifdef CONFIG_SMP		if (i == RTL_RESCHEDULE_VECTOR - 0x20) {			rtl_irq_desc[i] = &rtl_resched_irq_type;		} else #endif#endif			rtl_irq_desc[i]= h[i].handler;		h[i].handler = &rtl_generic_type;	}#ifdef DEBUG_RTLINUX	printk("RTLinux  patch kernel done \n");#endif	return 0;}inline static int unpatch_kernel(void){ 	irq_desc_t *h;	int i;       	const struct func_table *pfunc = (struct func_table *)&__start_rtlinux_funcs;	char *p;	*((long *)(pfunc[pf_rtl_exception_intercept].address)) = (long)0;	irq_control=	pre_patch_control;	*((long *)(pfunc[pf_rtl_emulate_iret].address)) = 0;	/* replace the descriptor table */	h = (irq_desc_t *)pfunc[pf_irq_desc].address;	for(i=0; i < NR_IRQS; i++){		h[i].handler = save_linux_irq_desc[i];	}/* 	rtl_hard_sti();		   */	/*unpatch jump do_IRQ */ 	if( !(p = find_patch((ulong)pfunc[pf_do_IRQ].address)))	{		printk("RTLinux cannot unpatch patch intercept routine\n");		return -1;	}	else { unpatch_jump(p,pf_do_IRQ); }#ifdef CONFIG_X86_LOCAL_APIC	for(i=PF_LOCAL_START; i <= PF_LOCAL_END;i++){		p = find_patch((ulong)pfunc[i].address);		if(!p){			printk("RTLinux can't smp unpatch %d\n",i);			return -1;		}		else{#ifdef DEBUG_RTLINUX			printk("unpatching %x, jmp at %#x\n", (unsigned) (pfunc[i].address), (unsigned) p);#endif			unpatch_jump(p,i);			unzap_ack_apic(pfunc[i].address);		}	}#endif	return 0;	}/* WARNING this fails on more than bits-per-word cpus machines   Stephen, don't try this on your desktop Galaxy */struct { atomic_t  waiting_with_cli;	atomic_t done_patch;	atomic_t waiting_for_unpatch;	atomic_t done_unpatch;} sync_data = {{0},{0},{0},{0}};void sync_on(void *unused){	int i;	rtl_hard_cli();	atomic_inc(&sync_data.waiting_with_cli);	i = 0;	while (!atomic_read(&sync_data.done_patch) && i < 1000000000) {		i++;	}	if (i == 1000000000) {		printk("timed out on sync_data.done_patch\n");	}	rtl_hard_sti();/* and never hard cli again in linux mode */}void sync_off(void *unused){	unsigned long f;	int i;	save_flags(f);	rtl_hard_cli();	atomic_inc(&sync_data.waiting_for_unpatch);	i = 0;	while(!atomic_read(&sync_data.done_unpatch) && i < 1000000000) {		i++;	}	if (i == 1000000000) {		printk("timed out on sync_data.done_unpatch\n");	}	mb();	restore_flags(f); /* this is hard restore now! */#ifdef DEBUG_RTLINUX	printk("sync off returned\n");#endif}#ifdef CONFIG_SMPint rtl_smp_synchronize( void (*sync_func)(void *),atomic_t  *waitpt){	int error;	int cpus = smp_num_cpus - 1;	int timeout;	error= smp_call_function (sync_func, 0, 0 /*atomic */,0 /*don't wait*/);#ifdef DEBUG_RTLINUX	printk("smp_call_function returned\n");#endif	if(error) {		printk("Cannot install due to smp call error %x\n",error);		return -1;	}	/* everyone else is now starting to exec sync_function */	timeout = jiffies + HZ;	while ((atomic_read(waitpt) != cpus)			&& time_before(jiffies, timeout));	if(atomic_read(waitpt) != cpus){	       printk("rtl_smp_synchronize timed out\n");       	       return -1;	}	/* now all cpus have disabled interrupts and are waiting completion */	return 0;}#else #define rtl_smp_synchronize(a,b) 0#endifunsigned int rtl_reschedule_interrupt(unsigned int irq, struct pt_regs *r);/* Start the RTLinux operation *//*TODO Must test smp synchronization!!! */inline int arch_takeover(void){int i;DeclareAndInit(cpu_id);rtl_hard_cli(); if(G_TEST_AND_SET(g_initialized)){ 	printk("Can't lock to install RTL. Already installed?\n");	rtl_hard_sti();	return -1;}#ifdef DEBUG_RTLINUX	printk("RTLinux takeover ok1\n");#endif	if( rtl_smp_synchronize(sync_on,&sync_data.waiting_with_cli)) return -1;#ifdef DEBUG_RTLINUX	printk("RTLinux takeover ok2\n");#endif/* initialize the main RTLinux structures */rtl_global.flags = (1<<g_initialized);for(i = 0; i < NR_CPUS; i++){	rtl_local[i].flags = POS_TO_BIT(l_ienable) | POS_TO_BIT(l_idle);	rtl_reschedule_handlers[i] = &default_reschedule_handler;}#ifdef DEBUG_RTLINUX	printk("RTLinux takeover ok3\n");#endifpatch_kernel(cpu_id); #ifdef CONFIG_SMPbarrier();atomic_inc(&sync_data.done_patch);mb();#endifrtl_hard_sti();rtl_soft_sti();#ifdef CONFIG_SMPrtl_request_global_irq (RTL_RESCHEDULE_VECTOR - 0x20, rtl_reschedule_interrupt);#endifreturn 0;}/*TODO on a failure, we should refuse to remove the module! */inline void arch_giveup(void){	/* TODO test sync*/unsigned long flags;#ifdef CONFIG_SMPrtl_free_global_irq (RTL_RESCHEDULE_VECTOR - 0x20);#endifsave_flags(flags);if(!G_TEST_AND_CLEAR(g_initialized)){ 	printk("Can't uninstall RTL. Not installed?\n");	return ;}#ifdef DEBUG_RTLINUX	printk("RTLinux giveup ok1\n");#endifif(rtl_smp_synchronize(sync_off,&sync_data.waiting_for_unpatch) ){       printk("Cannot synchronize RTLinux so cannot unpatch!\n\	       Save all files, give to the poor, reboot\n");	       return;}#ifdef DEBUG_RTLINUX	printk("RTLinux giveup ok2\n");#endifrtl_hard_cli(); unpatch_kernel(); /* machine dependent */#ifdef CONFIG_SMPbarrier();atomic_inc(&sync_data.done_unpatch);mb();#endifrestore_flags(flags); /* hard restore now */}#ifdef __LOCAL_IRQS__int rtl_request_local_irq(int i, unsigned int (*handler)(struct pt_regs *r),			  unsigned int cpu_id){	if (i == LOCAL_TIMER_VECTOR || i == RTL_RESCHEDULE_VECTOR) {		rtl_local[cpu_id].rt_handlers[VECTOR_TO_LOCAL_PND(i)] = handler;		L_SET_RTH(VECTOR_TO_LOCAL_PND(i));		return 0;	}	return -EINVAL;}int rtl_free_local_irq(int i, unsigned int cpu_id){	if (i == LOCAL_TIMER_VECTOR || i == RTL_RESCHEDULE_VECTOR) {		L_CLEAR_RTH(VECTOR_TO_LOCAL_PND(i));		return 0;	}	return -EINVAL;}#endif#ifdef CONFIG_SMPunsigned int rtl_reschedule_interrupt(unsigned int irq, struct pt_regs *r){	int cpu_id = rtl_getcpuid();/* 	rtl_printf("resched on %x\n", cpu_id); */	rtl_reschedule_handlers[cpu_id](r);	return 0;}void rtl_reschedule(unsigned int cpu){	local_code.rtl_reschedule(cpu);}int rtl_request_ipi (unsigned int (*f)(struct pt_regs *r), int cpu){	rtl_reschedule_handlers[cpu] = f;/* 	return rtl_request_local_irq (RTL_RESCHEDULE_VECTOR, rtl_reschedule_interrupt, cpu); */	return 0;}int rtl_free_ipi (int cpu){	rtl_reschedule_handlers[cpu] = &default_reschedule_handler;/* 	return rtl_free_local_irq (RTL_RESCHEDULE_VECTOR, cpu); */	return 0;}#endif

⌨️ 快捷键说明

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