Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Fri, 4 Oct 2002 10:50:02 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Fri, 4 Oct 2002 10:48:28 -0400 Received: from d06lmsgate-5.uk.ibm.com ([195.212.29.5]:29874 "EHLO d06lmsgate-5.uk.ibm.com") by vger.kernel.org with ESMTP id convert rfc822-to-8bit; Fri, 4 Oct 2002 10:37:34 -0400 Content-Type: text/plain; charset="us-ascii" From: Martin Schwidefsky Organization: IBM Deutschland GmbH To: linux-kernel@vger.kernel.org, torvalds@transmeta.com Subject: [PATCH] 2.5.40 s390 (18/27): fpu registers. Date: Fri, 4 Oct 2002 16:40:28 +0200 X-Mailer: KMail [version 1.4] MIME-Version: 1.0 Content-Transfer-Encoding: 8BIT Message-Id: <200210041632.04992.schwidefsky@de.ibm.com> Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 24335 Lines: 829 Cleanup load/store of fpu register on s390. diff -urN linux-2.5.40/arch/s390/kernel/Makefile linux-2.5.40-s390/arch/s390/kernel/Makefile --- linux-2.5.40/arch/s390/kernel/Makefile Fri Oct 4 16:14:42 2002 +++ linux-2.5.40-s390/arch/s390/kernel/Makefile Fri Oct 4 16:16:11 2002 @@ -8,7 +8,7 @@ export-objs := debug.o ebcdic.o s390_ext.o smp.o s390_ksyms.o obj-y := entry.o bitmap.o traps.o time.o process.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - semaphore.o s390fpu.o reipl.o s390_ext.o debug.o + semaphore.o reipl.o s390_ext.o debug.o obj-$(CONFIG_MODULES) += s390_ksyms.o obj-$(CONFIG_SMP) += smp.o diff -urN linux-2.5.40/arch/s390/kernel/process.c linux-2.5.40-s390/arch/s390/kernel/process.c --- linux-2.5.40/arch/s390/kernel/process.c Fri Oct 4 16:16:11 2002 +++ linux-2.5.40-s390/arch/s390/kernel/process.c Fri Oct 4 16:16:11 2002 @@ -199,8 +199,13 @@ /* fake return stack for resume(), don't go back to schedule */ frame->gprs[9] = (unsigned long) frame; - /* save fprs, if used in last task */ - save_fp_regs(&p->thread.fp_regs); + /* + * save fprs to current->thread.fp_regs to merge them with + * the emulated registers and then copy the result to the child. + */ + save_fp_regs(¤t->thread.fp_regs); + memcpy(&p->thread.fp_regs, ¤t->thread.fp_regs, + sizeof(s390_fp_regs)); p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _SEGMENT_TABLE; /* start process with ar4 pointing to the correct address space */ p->thread.ar4 = get_fs().ar4; @@ -262,20 +267,13 @@ error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, (char **) regs.gprs[3], (char **) regs.gprs[4], ®s); - if (error == 0) - { + error = do_execve(filename, (char **) regs.gprs[3], + (char **) regs.gprs[4], ®s); + if (error == 0) { current->ptrace &= ~PT_DTRACE; - current->thread.fp_regs.fpc=0; - if(MACHINE_HAS_IEEE) - { - __asm__ __volatile__ - ("sr 0,0\n\t" - "sfpc 0,0\n\t" - : - : - :"0"); - } + current->thread.fp_regs.fpc = 0; + if (MACHINE_HAS_IEEE) + asm volatile("sfpc %0,%0" : : "d" (0)); } putname(filename); out: @@ -288,7 +286,12 @@ */ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs) { - save_fp_regs(fpregs); + /* + * save fprs to current->thread.fp_regs to merge them with + * the emulated registers and then copy the result to the dump. + */ + save_fp_regs(¤t->thread.fp_regs); + memcpy(fpregs, ¤t->thread.fp_regs, sizeof(s390_fp_regs)); return 1; } diff -urN linux-2.5.40/arch/s390/kernel/s390fpu.c linux-2.5.40-s390/arch/s390/kernel/s390fpu.c --- linux-2.5.40/arch/s390/kernel/s390fpu.c Tue Oct 1 09:06:17 2002 +++ linux-2.5.40-s390/arch/s390/kernel/s390fpu.c Thu Jan 1 01:00:00 1970 @@ -1,138 +0,0 @@ -/* - * arch/s390/kernel/s390fpu.c - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) - * - * s390fpu.h functions for saving & restoring the fpu state. - * - * I couldn't inline these as linux/sched.h included half the world - * & was required to at the task structure. - * & the functions were too complex to make macros from. - * ( & as usual I didn't feel like debugging inline code ). - */ - -#include -#include - -int save_fp_regs1(s390_fp_regs *fpregs) -{ - int has_ieee=MACHINE_HAS_IEEE; -/* - I don't think we can use STE here as this would load - fp registers 0 & 2 into memory locations 0 & 1 etc. - */ - asm volatile ("STD 0,8(%0)\n\t" - "STD 2,24(%0)\n\t" - "STD 4,40(%0)\n\t" - "STD 6,56(%0)" - : - : "a" (fpregs) - : "memory" - ); - if(has_ieee) - { - asm volatile ("STFPC 0(%0)\n\t" - "STD 1,16(%0)\n\t" - "STD 3,32(%0)\n\t" - "STD 5,48(%0)\n\t" - "STD 7,64(%0)\n\t" - "STD 8,72(%0)\n\t" - "STD 9,80(%0)\n\t" - "STD 10,88(%0)\n\t" - "STD 11,96(%0)\n\t" - "STD 12,104(%0)\n\t" - "STD 13,112(%0)\n\t" - "STD 14,120(%0)\n\t" - "STD 15,128(%0)\n\t" - : - : "a" (fpregs) - : "memory" - ); - } - return(has_ieee); -} - - -void save_fp_regs(s390_fp_regs *fpregs) -{ -#if CONFIG_MATHEMU - s390_fp_regs *currentfprs; - - if(!save_fp_regs1(fpregs)) - { - currentfprs=¤t->thread.fp_regs; - fpregs->fpc=currentfprs->fpc; - fpregs->fprs[1].d=currentfprs->fprs[1].d; - fpregs->fprs[3].d=currentfprs->fprs[3].d; - fpregs->fprs[5].d=currentfprs->fprs[5].d; - fpregs->fprs[7].d=currentfprs->fprs[7].d; - memcpy(&fpregs->fprs[8].d,¤tfprs->fprs[8].d,sizeof(freg_t)*8); - } -#else - save_fp_regs1(fpregs); -#endif -} - - -int restore_fp_regs1(s390_fp_regs *fpregs) -{ - int has_ieee=MACHINE_HAS_IEEE; - - /* If we don't mask with the FPC_VALID_MASK here - * we've got a very quick shutdown -h now command - * via a kernel specification exception. - */ - fpregs->fpc&=FPC_VALID_MASK; - asm volatile ("LD 0,8(%0)\n\t" - "LD 2,24(%0)\n\t" - "LD 4,40(%0)\n\t" - "LD 6,56(%0)" - : - : "a" (fpregs) - : "memory" - ); - if(has_ieee) - { - asm volatile ("LFPC 0(%0)\n\t" - "LD 1,16(%0)\n\t" - "LD 3,32(%0)\n\t" - "LD 5,48(%0)\n\t" - "LD 7,64(%0)\n\t" - "LD 8,72(%0)\n\t" - "LD 9,80(%0)\n\t" - "LD 10,88(%0)\n\t" - "LD 11,96(%0)\n\t" - "LD 12,104(%0)\n\t" - "LD 13,112(%0)\n\t" - "LD 14,120(%0)\n\t" - "LD 15,128(%0)\n\t" - : - : "a" (fpregs) - : "memory" - ); - } - return(has_ieee); -} - -void restore_fp_regs(s390_fp_regs *fpregs) -{ -#if CONFIG_MATHEMU - s390_fp_regs *currentfprs; - - if(!restore_fp_regs1(fpregs)) - { - currentfprs=¤t->thread.fp_regs; - currentfprs->fpc=fpregs->fpc; - currentfprs->fprs[1].d=fpregs->fprs[1].d; - currentfprs->fprs[3].d=fpregs->fprs[3].d; - currentfprs->fprs[5].d=fpregs->fprs[5].d; - currentfprs->fprs[7].d=fpregs->fprs[7].d; - memcpy(¤tfprs->fprs[8].d,&fpregs->fprs[8].d,sizeof(freg_t)*8); - } -#else - restore_fp_regs1(fpregs); -#endif -} - diff -urN linux-2.5.40/arch/s390/kernel/signal.c linux-2.5.40-s390/arch/s390/kernel/signal.c --- linux-2.5.40/arch/s390/kernel/signal.c Fri Oct 4 16:14:42 2002 +++ linux-2.5.40-s390/arch/s390/kernel/signal.c Fri Oct 4 16:16:11 2002 @@ -49,13 +49,14 @@ struct ucontext uc; } rt_sigframe; -asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); +int do_signal(struct pt_regs *regs, sigset_t *oldset); /* * Atomically swap in the new signal mask, and wait for a signal. */ asmlinkage int -sys_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask) +sys_sigsuspend(struct pt_regs * regs, int history0, int history1, + old_sigset_t mask) { sigset_t saveset; @@ -147,37 +148,39 @@ static int save_sigregs(struct pt_regs *regs,_sigregs *sregs) { int err; - s390_fp_regs fpregs; - err = __copy_to_user(&sregs->regs,regs,sizeof(_s390_regs_common)); - if(!err) - { - save_fp_regs(&fpregs); - err=__copy_to_user(&sregs->fpregs,&fpregs,sizeof(fpregs)); - } - return(err); - + err = __copy_to_user(&sregs->regs, regs, sizeof(_s390_regs_common)); + if (err != 0) + return err; + /* + * We have to store the fp registers to current->thread.fp_regs + * to merge them with the emulated registers. + */ + save_fp_regs(¤t->thread.fp_regs); + return __copy_to_user(&sregs->fpregs, ¤t->thread.fp_regs, + sizeof(s390_fp_regs)); } /* Returns positive number on error */ static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs) { int err; - s390_fp_regs fpregs; - psw_t saved_psw=regs->psw; - err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common)); - if(!err) - { - regs->trap = -1; /* disable syscall checks */ - regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)| - (regs->psw.mask&PSW_MASK_DEBUGCHANGE); - regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)| - (regs->psw.addr&PSW_ADDR_DEBUGCHANGE); - err=__copy_from_user(&fpregs,&sregs->fpregs,sizeof(fpregs)); - if(!err) - restore_fp_regs(&fpregs); - } - return(err); + + err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common)); + regs->psw.mask = _USER_PSW_MASK | (regs->psw.mask & PSW_MASK_DEBUGCHANGE); + regs->psw.addr |= _ADDR_31; + if (err) + return err; + + err = __copy_from_user(¤t->thread.fp_regs, &sregs->fpregs, + sizeof(s390_fp_regs)); + current->thread.fp_regs.fpc &= FPC_VALID_MASK; + if (err) + return err; + + restore_fp_regs(¤t->thread.fp_regs); + regs->trap = -1; /* disable syscall checks */ + return 0; } asmlinkage long sys_sigreturn(struct pt_regs *regs) diff -urN linux-2.5.40/arch/s390x/kernel/Makefile linux-2.5.40-s390/arch/s390x/kernel/Makefile --- linux-2.5.40/arch/s390x/kernel/Makefile Fri Oct 4 16:14:42 2002 +++ linux-2.5.40-s390/arch/s390x/kernel/Makefile Fri Oct 4 16:16:11 2002 @@ -10,7 +10,7 @@ obj-y := entry.o bitmap.o traps.o time.o process.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - semaphore.o s390fpu.o reipl.o s390_ext.o debug.o + semaphore.o reipl.o s390_ext.o debug.o obj-$(CONFIG_MODULES) += s390_ksyms.o obj-$(CONFIG_SMP) += smp.o diff -urN linux-2.5.40/arch/s390x/kernel/process.c linux-2.5.40-s390/arch/s390x/kernel/process.c --- linux-2.5.40/arch/s390x/kernel/process.c Fri Oct 4 16:16:11 2002 +++ linux-2.5.40-s390/arch/s390x/kernel/process.c Fri Oct 4 16:16:11 2002 @@ -257,15 +257,12 @@ error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; - error = do_execve(filename, (char **) regs.gprs[3], (char **) regs.gprs[4], ®s); - if (error == 0) - { + error = do_execve(filename, (char **) regs.gprs[3], + (char **) regs.gprs[4], ®s); + if (error == 0) { current->ptrace &= ~PT_DTRACE; - current->thread.fp_regs.fpc=0; - __asm__ __volatile__ - ("sr 0,0\n\t" - "sfpc 0,0\n\t" - : : :"0"); + current->thread.fp_regs.fpc = 0; + asm volatile("sfpc %0,%0" : : "d" (0)); } putname(filename); out: diff -urN linux-2.5.40/arch/s390x/kernel/s390fpu.c linux-2.5.40-s390/arch/s390x/kernel/s390fpu.c --- linux-2.5.40/arch/s390x/kernel/s390fpu.c Tue Oct 1 09:07:44 2002 +++ linux-2.5.40-s390/arch/s390x/kernel/s390fpu.c Thu Jan 1 01:00:00 1970 @@ -1,87 +0,0 @@ -/* - * arch/s390/kernel/s390fpu.c - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) - * - * s390fpu.h functions for saving & restoring the fpu state. - * - * I couldn't inline these as linux/sched.h included half the world - * & was required to at the task structure. - * & the functions were too complex to make macros from. - * ( & as usual I didn't feel like debugging inline code ). - */ - -#include - -void save_fp_regs(s390_fp_regs *fpregs) -{ -/* - * I don't think we can use STE here as this would load - * fp registers 0 & 2 into memory locations 0 & 1 etc. - */ - asm volatile ("STFPC 0(%0)\n\t" - "STD 0,8(%0)\n\t" - "STD 1,16(%0)\n\t" - "STD 2,24(%0)\n\t" - "STD 3,32(%0)\n\t" - "STD 4,40(%0)\n\t" - "STD 5,48(%0)\n\t" - "STD 6,56(%0)\n\t" - "STD 7,64(%0)\n\t" - "STD 8,72(%0)\n\t" - "STD 9,80(%0)\n\t" - "STD 10,88(%0)\n\t" - "STD 11,96(%0)\n\t" - "STD 12,104(%0)\n\t" - "STD 13,112(%0)\n\t" - "STD 14,120(%0)\n\t" - "STD 15,128(%0)\n\t" - : - : "a" (fpregs) - : "memory" - ); -} - -void restore_fp_regs(s390_fp_regs *fpregs) -{ - /* If we don't mask with the FPC_VALID_MASK here - * we've got a very quick shutdown -h now command - * via a kernel specification exception. - */ - fpregs->fpc&=FPC_VALID_MASK; - asm volatile ("LFPC 0(%0)\n\t" - "LD 0,8(%0)\n\t" - "LD 1,16(%0)\n\t" - "LD 2,24(%0)\n\t" - "LD 3,32(%0)\n\t" - "LD 4,40(%0)\n\t" - "LD 5,48(%0)\n\t" - "LD 6,56(%0)\n\t" - "LD 7,64(%0)\n\t" - "LD 8,72(%0)\n\t" - "LD 9,80(%0)\n\t" - "LD 10,88(%0)\n\t" - "LD 11,96(%0)\n\t" - "LD 12,104(%0)\n\t" - "LD 13,112(%0)\n\t" - "LD 14,120(%0)\n\t" - "LD 15,128(%0)\n\t" - : - : "a" (fpregs) - : "memory" - ); -} - - - - - - - - - - - - diff -urN linux-2.5.40/arch/s390x/kernel/signal.c linux-2.5.40-s390/arch/s390x/kernel/signal.c --- linux-2.5.40/arch/s390x/kernel/signal.c Fri Oct 4 16:14:42 2002 +++ linux-2.5.40-s390/arch/s390x/kernel/signal.c Fri Oct 4 16:16:11 2002 @@ -144,40 +144,37 @@ /* Returns non-zero on fault */ -static int save_sigregs(struct pt_regs *regs,_sigregs *sregs) +static int save_sigregs(struct pt_regs *regs, _sigregs *sregs) { int err; - s390_fp_regs fpregs; - err = __copy_to_user(&sregs->regs,regs,sizeof(_s390_regs_common)); - if(!err) - { - save_fp_regs(&fpregs); - err=__copy_to_user(&sregs->fpregs,&fpregs,sizeof(fpregs)); - } - return(err); - + err = __copy_to_user(&sregs->regs, regs, sizeof(_s390_regs_common)); + if (err != 0) + return err; + save_fp_regs(¤t->thread.fp_regs); + return __copy_to_user(&sregs->fpregs, ¤t->thread.fp_regs, + sizeof(s390_fp_regs)); } /* Returns positive number on error */ -static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs) +static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs) { int err; - s390_fp_regs fpregs; - psw_t saved_psw=regs->psw; - err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common)); - if(!err) - { - regs->trap = -1; /* disable syscall checks */ - regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)| - (regs->psw.mask&PSW_MASK_DEBUGCHANGE); - regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)| - (regs->psw.addr&PSW_ADDR_DEBUGCHANGE); - err=__copy_from_user(&fpregs,&sregs->fpregs,sizeof(fpregs)); - if(!err) - restore_fp_regs(&fpregs); - } - return(err); + + err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common)); + regs->psw.mask = _USER_PSW_MASK | (regs->psw.mask & PSW_MASK_DEBUGCHANGE); + if (err) + return err; + + err = __copy_from_user(¤t->thread.fp_regs, &sregs->fpregs, + sizeof(s390_fp_regs)); + current->thread.fp_regs.fpc &= FPC_VALID_MASK; + if (err) + return err; + + restore_fp_regs(¤t->thread.fp_regs); + regs->trap = -1; /* disable syscall checks */ + return 0; } asmlinkage long sys_sigreturn(struct pt_regs *regs) diff -urN linux-2.5.40/arch/s390x/kernel/signal32.c linux-2.5.40-s390/arch/s390x/kernel/signal32.c --- linux-2.5.40/arch/s390x/kernel/signal32.c Fri Oct 4 16:14:42 2002 +++ linux-2.5.40-s390/arch/s390x/kernel/signal32.c Fri Oct 4 16:16:11 2002 @@ -32,7 +32,11 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) +#define _ADDR_31 0x80000000 +#define _USER_PSW_MASK_EMU32 0x070DC000 #define _USER_PSW_MASK32 0x0705C00080000000 +#define PSW_MASK_DEBUGCHANGE32 0x00003000UL +#define PSW_ADDR_DEBUGCHANGE32 0x7FFFFFFFUL typedef struct { @@ -290,55 +294,48 @@ static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs) { - int err = 0; - s390_fp_regs fpregs; - int i; - - for(i=0; igprs[i], &sregs->regs.gprs[i]); - for(i=0; iacrs[i], &sregs->regs.acrs[i]); - err |= __copy_to_user(&sregs->regs.psw.mask, ®s->psw.mask, 4); - err |= __copy_to_user(&sregs->regs.psw.addr, ((char*)®s->psw.addr)+4, 4); - if(!err) - { - save_fp_regs(&fpregs); - __put_user(fpregs.fpc, &sregs->fpregs.fpc); - for(i=0; ifpregs.fprs[i].d); - } - return(err); - + _s390_regs_common32 regs32; + int err, i; + + regs32.psw.mask = _USER_PSW_MASK_EMU32 | + (__u32)((regs->psw.mask & PSW_MASK_DEBUGCHANGE) >> 32); + regs32.psw.addr = _ADDR_31 | (__u32) regs->psw.addr; + for (i = 0; i < NUM_GPRS; i++) + regs32.gprs[i] = (__u32) regs->gprs[i]; + memcpy(regs32.acrs, regs->acrs, sizeof(regs32.acrs)); + err = __copy_to_user(&sregs->regs, ®s32, sizeof(regs32)); + if (err) + return err; + save_fp_regs(¤t->thread.fp_regs); + /* s390_fp_regs and _s390_fp_regs32 are the same ! */ + return __copy_to_user(&sregs->fpregs, ¤t->thread.fp_regs, + sizeof(_s390_fp_regs32)); } static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs) { - int err = 0; - s390_fp_regs fpregs; - psw_t saved_psw=regs->psw; - int i; - - for(i=0; igprs[i], &sregs->regs.gprs[i]); - for(i=0; iacrs[i], &sregs->regs.acrs[i]); - err |= __copy_from_user(®s->psw.mask, &sregs->regs.psw.mask, 4); - err |= __copy_from_user(((char*)®s->psw.addr)+4, &sregs->regs.psw.addr, 4); - - if(!err) - { - regs->trap = -1; /* disable syscall checks */ - regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)| - (regs->psw.mask&PSW_MASK_DEBUGCHANGE); - regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)| - (regs->psw.addr&PSW_ADDR_DEBUGCHANGE); - __get_user(fpregs.fpc, &sregs->fpregs.fpc); - for(i=0; ifpregs.fprs[i].d); - if(!err) - restore_fp_regs(&fpregs); - } - return(err); + _s390_regs_common32 regs32; + int err, i; + + err = __copy_from_user(®s32, &sregs->regs, sizeof(regs32)); + if (err) + return err; + regs->psw.mask = _USER_PSW_MASK32 | + (__u64)(regs32.psw.mask & PSW_MASK_DEBUGCHANGE32) << 32; + regs->psw.addr = (__u64)(regs32.psw.addr & PSW_ADDR_DEBUGCHANGE32); + for (i = 0; i < NUM_GPRS; i++) + regs->gprs[i] = (__u64) regs32.gprs[i]; + memcpy(regs->acrs, regs32.acrs, sizeof(regs32.acrs)); + + err = __copy_from_user(¤t->thread.fp_regs, &sregs->fpregs, + sizeof(_s390_fp_regs32)); + current->thread.fp_regs.fpc &= FPC_VALID_MASK; + if (err) + return err; + + restore_fp_regs(¤t->thread.fp_regs); + regs->trap = -1; /* disable syscall checks */ + return 0; } asmlinkage long sys32_sigreturn(struct pt_regs *regs) diff -urN linux-2.5.40/include/asm-s390/system.h linux-2.5.40-s390/include/asm-s390/system.h --- linux-2.5.40/include/asm-s390/system.h Fri Oct 4 16:16:11 2002 +++ linux-2.5.40-s390/include/asm-s390/system.h Fri Oct 4 16:16:11 2002 @@ -12,22 +12,79 @@ #define __ASM_SYSTEM_H #include +#include #include +#include +#include + #ifdef __KERNEL__ -#include -#endif -#include + +struct task_struct; + +extern struct task_struct *resume(void *, void *); + +static inline void save_fp_regs(s390_fp_regs *fpregs) +{ + asm volatile ( + " std 0,8(%0)\n" + " std 2,24(%0)\n" + " std 4,40(%0)\n" + " std 6,56(%0)" + : : "a" (fpregs) : "memory" ); + if (!MACHINE_HAS_IEEE) + return; + asm volatile( + " stfpc 0(%0)\n" + " std 1,16(%0)\n" + " std 3,32(%0)\n" + " std 5,48(%0)\n" + " std 7,64(%0)\n" + " std 8,72(%0)\n" + " std 9,80(%0)\n" + " std 10,88(%0)\n" + " std 11,96(%0)\n" + " std 12,104(%0)\n" + " std 13,112(%0)\n" + " std 14,120(%0)\n" + " std 15,128(%0)\n" + : : "a" (fpregs) : "memory" ); +} + +static inline void restore_fp_regs(s390_fp_regs *fpregs) +{ + asm volatile ( + " ld 0,8(%0)\n" + " ld 2,24(%0)\n" + " ld 4,40(%0)\n" + " ld 6,56(%0)" + : : "a" (fpregs)); + if (!MACHINE_HAS_IEEE) + return; + asm volatile( + " lfpc 0(%0)\n" + " ld 1,16(%0)\n" + " ld 3,32(%0)\n" + " ld 5,48(%0)\n" + " ld 7,64(%0)\n" + " ld 8,72(%0)\n" + " ld 9,80(%0)\n" + " ld 10,88(%0)\n" + " ld 11,96(%0)\n" + " ld 12,104(%0)\n" + " ld 13,112(%0)\n" + " ld 14,120(%0)\n" + " ld 15,128(%0)\n" + : : "a" (fpregs)); +} #define switch_to(prev,next,last) do { \ if (prev == next) \ break; \ - save_fp_regs1(&prev->thread.fp_regs); \ - restore_fp_regs1(&next->thread.fp_regs); \ + save_fp_regs(&prev->thread.fp_regs); \ + restore_fp_regs(&next->thread.fp_regs); \ resume(prev,next); \ } while (0) -struct task_struct; - #define nop() __asm__ __volatile__ ("nop") #define xchg(ptr,x) \ @@ -281,23 +338,13 @@ #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit) #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit) -#endif - -#ifdef __KERNEL__ -extern struct task_struct *resume(void *, void *); - -extern int save_fp_regs1(s390_fp_regs *fpregs); -extern void save_fp_regs(s390_fp_regs *fpregs); -extern int restore_fp_regs1(s390_fp_regs *fpregs); -extern void restore_fp_regs(s390_fp_regs *fpregs); +#endif /* CONFIG_SMP */ extern void (*_machine_restart)(char *command); extern void (*_machine_halt)(void); extern void (*_machine_power_off)(void); -#endif +#endif /* __KERNEL__ */ #endif - - diff -urN linux-2.5.40/include/asm-s390x/system.h linux-2.5.40-s390/include/asm-s390x/system.h --- linux-2.5.40/include/asm-s390x/system.h Fri Oct 4 16:16:11 2002 +++ linux-2.5.40-s390/include/asm-s390x/system.h Fri Oct 4 16:16:11 2002 @@ -12,11 +12,62 @@ #define __ASM_SYSTEM_H #include +#include #include +#include +#include + #ifdef __KERNEL__ -#include -#endif -#include + +struct task_struct; + +extern struct task_struct *resume(void *, void *); + +static inline void save_fp_regs(s390_fp_regs *fpregs) +{ + asm volatile ( + " stfpc 0(%0)\n" + " std 0,8(%0)\n" + " std 1,16(%0)\n" + " std 2,24(%0)\n" + " std 3,32(%0)\n" + " std 4,40(%0)\n" + " std 5,48(%0)\n" + " std 6,56(%0)\n" + " std 7,64(%0)\n" + " std 8,72(%0)\n" + " std 9,80(%0)\n" + " std 10,88(%0)\n" + " std 11,96(%0)\n" + " std 12,104(%0)\n" + " std 13,112(%0)\n" + " std 14,120(%0)\n" + " std 15,128(%0)\n" + : : "a" (fpregs) : "memory" ); +} + +static inline void restore_fp_regs(s390_fp_regs *fpregs) +{ + asm volatile ( + " lfpc 0(%0)\n" + " ld 0,8(%0)\n" + " ld 1,16(%0)\n" + " ld 2,24(%0)\n" + " ld 3,32(%0)\n" + " ld 4,40(%0)\n" + " ld 5,48(%0)\n" + " ld 6,56(%0)\n" + " ld 7,64(%0)\n" + " ld 8,72(%0)\n" + " ld 9,80(%0)\n" + " ld 10,88(%0)\n" + " ld 11,96(%0)\n" + " ld 12,104(%0)\n" + " ld 13,112(%0)\n" + " ld 14,120(%0)\n" + " ld 15,128(%0)\n" + : : "a" (fpregs)); +} #define switch_to(prev,next,last) do { \ if (prev == next) \ @@ -26,8 +77,6 @@ resume(prev,next); \ } while (0) -struct task_struct; - #define nop() __asm__ __volatile__ ("nop") #define xchg(ptr,x) \ @@ -297,23 +346,13 @@ #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit) #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit) -#endif - -#ifdef __KERNEL__ -extern struct task_struct *resume(void *, void *); - -extern int save_fp_regs1(s390_fp_regs *fpregs); -extern void save_fp_regs(s390_fp_regs *fpregs); -extern int restore_fp_regs1(s390_fp_regs *fpregs); -extern void restore_fp_regs(s390_fp_regs *fpregs); +#endif /* CONFIG_SMP */ extern void (*_machine_restart)(char *command); extern void (*_machine_halt)(void); extern void (*_machine_power_off)(void); -#endif +#endif /* __KERNEL __ */ #endif - - - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/