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

📄 signal.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"			 "4:\n"			 ".section __ex_table,\"a\"\n"			 "   .align 4\n"			 "   .long 2b,4b\n"			 "   .long 3b,4b\n"			 ".previous"			 : /* no outputs, it doesn't ever return */			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),			   "n" (frame_offset), "a" (fp)			 : "a0");#undef frame_offset		/*		 * If we ever get here an exception occurred while		 * building the above stack-frame.		 */		goto badframe;	}#endif /* CONFIG_UCLINUX */	*pd0 = context.sc_d0;	return err;badframe:	return 1;}static inline intrt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,		    struct ucontext *uc, int *pd0){#ifndef CONFIG_UCLINUX	int fsize;#endif	int temp;	greg_t *gregs = uc->uc_mcontext.gregs;	unsigned long usp;	int err;	err = __get_user(temp, &uc->uc_mcontext.version);	if (temp != MCONTEXT_VERSION)		goto badframe;	/* restore passed registers */	err |= __get_user(regs->d0, &gregs[0]);	err |= __get_user(regs->d1, &gregs[1]);	err |= __get_user(regs->d2, &gregs[2]);	err |= __get_user(regs->d3, &gregs[3]);	err |= __get_user(regs->d4, &gregs[4]);	err |= __get_user(regs->d5, &gregs[5]);	err |= __get_user(sw->d6, &gregs[6]);	err |= __get_user(sw->d7, &gregs[7]);	err |= __get_user(regs->a0, &gregs[8]);	err |= __get_user(regs->a1, &gregs[9]);	err |= __get_user(regs->a2, &gregs[10]);	err |= __get_user(sw->a3, &gregs[11]);	err |= __get_user(sw->a4, &gregs[12]);	err |= __get_user(sw->a5, &gregs[13]);	err |= __get_user(sw->a6, &gregs[14]);	err |= __get_user(usp, &gregs[15]);	wrusp(usp);	err |= __get_user(regs->pc, &gregs[16]);	err |= __get_user(temp, &gregs[17]);	regs->sr = (regs->sr & 0xff00) | (temp & 0xff);	regs->orig_d0 = -1;		/* disable syscall checks */#if DAVIDM /* ifdef uc_formatvec */	err |= __get_user(temp, &uc->uc_formatvec);#endif	regs->format = temp >> 12;	regs->vector = temp & 0xfff;#if DAVIDM /* NO_FPU */	err |= rt_restore_fpu_state(uc);#endif	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)		goto badframe;#ifndef CONFIG_UCLINUX	fsize = frame_extra_sizes[regs->format];	if (fsize < 0) {		/*		 * user process trying to return with weird frame format		 */#if DEBUG		printk("user process returning with weird frame format\n");#endif		goto badframe;	}	/* OK.	Make room on the supervisor stack for the extra junk,	 * if necessary.	 */	if (fsize) {#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))		__asm__ __volatile__			("   movel %0,%/a0\n\t"			 "   subl %1,%/a0\n\t"     /* make room on stack */			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */			 /* move switch_stack and pt_regs */			 "1: movel %0@+,%/a0@+\n\t"			 "   dbra %2,1b\n\t"			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */			 "   lsrl  #2,%1\n\t"			 "   subql #1,%1\n\t"			 "2: movesl %4@+,%2\n\t"			 "3: movel %2,%/a0@+\n\t"			 "   dbra %1,2b\n\t"			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"			 "4:\n"			 ".section __ex_table,\"a\"\n"			 "   .align 4\n"			 "   .long 2b,4b\n"			 "   .long 3b,4b\n"			 ".previous"			 : /* no outputs, it doesn't ever return */			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),			   "n" (frame_offset), "a" (&uc->uc_extra)			 : "a0");#undef frame_offset		/*		 * If we ever get here an exception occurred while		 * building the above stack-frame.		 */		goto badframe;	}#endif /* CONFIG_UCLINUX */	*pd0 = regs->d0;	return err;badframe:	return 1;}asmlinkage int do_sigreturn(unsigned long __unused){	struct switch_stack *sw = (struct switch_stack *) &__unused;	struct pt_regs *regs = (struct pt_regs *) (sw + 1);	unsigned long usp = rdusp();	struct sigframe *frame = (struct sigframe *)(usp - 4);	sigset_t set;	int d0;	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))		goto badframe;	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||	    (_NSIG_WORDS > 1 &&	     __copy_from_user(&set.sig[1], &frame->extramask,			      sizeof(frame->extramask))))		goto badframe;	sigdelsetmask(&set, ~_BLOCKABLE);	current->blocked = set;	recalc_sigpending(current);		if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))		goto badframe;	return d0;badframe:	force_sig(SIGSEGV, current);	return 0;}asmlinkage int do_rt_sigreturn(unsigned long __unused){	struct switch_stack *sw = (struct switch_stack *) &__unused;	struct pt_regs *regs = (struct pt_regs *) (sw + 1);	unsigned long usp = rdusp();	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);	sigset_t set;	int d0;	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))		goto badframe;	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))		goto badframe;	sigdelsetmask(&set, ~_BLOCKABLE);	current->blocked = set;	recalc_sigpending(current);		if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))		goto badframe;	return d0;badframe:	force_sig(SIGSEGV, current);	return 0;}#ifndef NO_FPU/* * Set up a signal frame. */static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs){	if (FPU_IS_EMU) {		/* save registers */		memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);		memcpy(sc->sc_fpregs, current->thread.fp, 24);		return;	}	__asm__ volatile (".chip 68k/68881\n\t"			  "fsave %0\n\t"			  ".chip 68k"			  : : "m" (*sc->sc_fpstate) : "memory");	if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {		fpu_version = sc->sc_fpstate[0];		if (CPU_IS_020_OR_030 &&		    regs->vector >= (VEC_FPBRUC * 4) &&		    regs->vector <= (VEC_FPNAN * 4)) {			/* Clear pending exception in 68882 idle frame */			if (*(unsigned short *) sc->sc_fpstate == 0x1f38)				sc->sc_fpstate[0x38] |= 1 << 3;		}		__asm__ volatile (".chip 68k/68881\n\t"				  "fmovemx %/fp0-%/fp1,%0\n\t"				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"				  ".chip 68k"				  : /* no outputs */				  : "m" (*sc->sc_fpregs),				    "m" (*sc->sc_fpcntl)				  : "memory");	}}static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs){	unsigned char fpstate[FPCONTEXT_SIZE];	int context_size = CPU_IS_060 ? 8 : 0;	int err = 0;	if (FPU_IS_EMU) {		/* save fpu control register */		err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr,				current->thread.fpcntl, 12);		/* save all other fpu register */		err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,				current->thread.fp, 96);		return err;	}	__asm__ volatile (".chip 68k/68881\n\t"			  "fsave %0\n\t"			  ".chip 68k"			  : : "m" (*fpstate) : "memory");	err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {		fpregset_t fpregs;		if (!CPU_IS_060)			context_size = fpstate[1];		fpu_version = fpstate[0];		if (CPU_IS_020_OR_030 &&		    regs->vector >= (VEC_FPBRUC * 4) &&		    regs->vector <= (VEC_FPNAN * 4)) {			/* Clear pending exception in 68882 idle frame */			if (*(unsigned short *) fpstate == 0x1f38)				fpstate[0x38] |= 1 << 3;		}		__asm__ volatile (".chip 68k/68881\n\t"				  "fmovemx %/fp0-%/fp7,%0\n\t"				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"				  ".chip 68k"				  : /* no outputs */				  : "m" (*fpregs.f_fpregs),				    "m" (fpregs.f_pcr)				  : "memory");		err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,				    sizeof(fpregs));	}	if (context_size)		err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,				    context_size);	return err;}#endifstatic void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,			     unsigned long mask){	sc->sc_mask = mask;	sc->sc_usp = rdusp();	sc->sc_d0 = regs->d0;	sc->sc_d1 = regs->d1;	sc->sc_a0 = regs->a0;	sc->sc_a1 = regs->a1;	sc->sc_sr = regs->sr;	sc->sc_pc = regs->pc;	sc->sc_formatvec = regs->format << 12 | regs->vector;#ifndef NO_FPU	save_fpu_state(sc, regs);#endif}static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs){	struct switch_stack *sw = (struct switch_stack *)regs - 1;	greg_t *gregs = uc->uc_mcontext.gregs;	int err = 0;	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);	err |= __put_user(regs->d0, &gregs[0]);	err |= __put_user(regs->d1, &gregs[1]);	err |= __put_user(regs->d2, &gregs[2]);	err |= __put_user(regs->d3, &gregs[3]);	err |= __put_user(regs->d4, &gregs[4]);	err |= __put_user(regs->d5, &gregs[5]);	err |= __put_user(sw->d6, &gregs[6]);	err |= __put_user(sw->d7, &gregs[7]);	err |= __put_user(regs->a0, &gregs[8]);	err |= __put_user(regs->a1, &gregs[9]);	err |= __put_user(regs->a2, &gregs[10]);	err |= __put_user(sw->a3, &gregs[11]);	err |= __put_user(sw->a4, &gregs[12]);	err |= __put_user(sw->a5, &gregs[13]);	err |= __put_user(sw->a6, &gregs[14]);	err |= __put_user(rdusp(), &gregs[15]);	err |= __put_user(regs->pc, &gregs[16]);	err |= __put_user(regs->sr, &gregs[17]);#if DAVIDM /* ifdef uc_formatvec */	err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);#endif#ifndef NO_FPU	err |= rt_save_fpu_state(uc, regs);#endif	return err;}static inline void push_cache (unsigned long vaddr){#if 0 /* DAVIDM - implement this for 5407, maybe */	/*	 * Using the old cache_push_v() was really a big waste.	 *	 * What we are trying to do is to flush 8 bytes to ram.	 * Flushing 2 cache lines of 16 bytes is much cheaper than	 * flushing 1 or 2 pages, as previously done in	 * cache_push_v().	 *                                                     Jes	 */	if (CPU_IS_040) {		unsigned long temp;		__asm__ __volatile__ (".chip 68040\n\t"				      "nop\n\t"				      "ptestr (%1)\n\t"				      "movec %%mmusr,%0\n\t"				      ".chip 68k"				      : "=r" (temp)				      : "a" (vaddr));		temp &= PAGE_MASK;		temp |= vaddr & ~PAGE_MASK;		__asm__ __volatile__ (".chip 68040\n\t"				      "nop\n\t"				      "cpushl %%bc,(%0)\n\t"				      ".chip 68k"				      : : "a" (temp));	}	else if (CPU_IS_060) {		unsigned long temp;		__asm__ __volatile__ (".chip 68060\n\t"				      "plpar (%0)\n\t"				      ".chip 68k"				      : "=a" (temp)				      : "0" (vaddr));		__asm__ __volatile__ (".chip 68060\n\t"				      "cpushl %%bc,(%0)\n\t"				      ".chip 68k"				      : : "a" (temp));	}	else {		/*		 * 68030/68020 have no writeback cache;		 * still need to clear icache.		 * Note that vaddr is guaranteed to be long word aligned.		 */		unsigned long temp;		asm volatile ("movec %%cacr,%0" : "=r" (temp));		temp += 4;		asm volatile ("movec %0,%%caar\n\t"			      "movec %1,%%cacr"			      : : "r" (vaddr), "r" (temp));		asm volatile ("movec %0,%%caar\n\t"			      "movec %1,%%cacr"			      : : "r" (vaddr + 4), "r" (temp));	}#endif}static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size){	unsigned long usp;	/* Default to using normal stack.  */	usp = rdusp();	/* This is the X/Open sanctioned signal stack switching.  */	if (ka->sa.sa_flags & SA_ONSTACK) {		if (!on_sig_stack(usp))			usp = current->sas_ss_sp + current->sas_ss_size;	}	return (void *)((usp - frame_size) & -8UL);}static void setup_frame (int sig, struct k_sigaction *ka,			 sigset_t *set, struct pt_regs *regs){	struct sigframe *frame;	unsigned long a5;#ifndef CONFIG_UCLINUX	int fsize = frame_extra_sizes[regs->format];#endif	struct sigcontext context;	int err = 0;

⌨️ 快捷键说明

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